PageRenderTime 40ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/application/Espo/Core/Utils/Util.php

https://gitlab.com/johanlindberg/irvato-crm
PHP | 542 lines | 275 code | 78 blank | 189 comment | 75 complexity | ffacf194791cce2cd0e84a4cd331a6c5 MD5 | raw file
  1. <?php
  2. /************************************************************************
  3. * This file is part of EspoCRM.
  4. *
  5. * EspoCRM - Open Source CRM application.
  6. * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
  7. * Website: http://www.espocrm.com
  8. *
  9. * EspoCRM is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * EspoCRM is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with EspoCRM. If not, see http://www.gnu.org/licenses/.
  21. *
  22. * The interactive user interfaces in modified source and object code versions
  23. * of this program must display Appropriate Legal Notices, as required under
  24. * Section 5 of the GNU General Public License version 3.
  25. *
  26. * In accordance with Section 7(b) of the GNU General Public License version 3,
  27. * these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
  28. ************************************************************************/
  29. namespace Espo\Core\Utils;
  30. class Util
  31. {
  32. /**
  33. * @var string - default directory separator
  34. */
  35. protected static $separator = DIRECTORY_SEPARATOR;
  36. protected static $reservedWords = array('Case');
  37. /**
  38. * Get a folder separator
  39. *
  40. * @return string
  41. */
  42. public static function getSeparator()
  43. {
  44. return static::$separator;
  45. }
  46. /**
  47. * Convert to format with defined delimeter
  48. * ex. Espo/Utils to Espo\Utils
  49. *
  50. * @param string $name
  51. * @param string $delim - delimiter
  52. *
  53. * @return string
  54. */
  55. public static function toFormat($name, $delim = '/')
  56. {
  57. return preg_replace("/[\/\\\]/", $delim, $name);
  58. }
  59. /**
  60. * Convert name to Camel Case format, ex. camel_case to camelCase
  61. *
  62. * @param string $name
  63. * @param string | array $symbol
  64. * @param boolean $capitaliseFirstChar
  65. *
  66. * @return string
  67. */
  68. public static function toCamelCase($name, $symbol = '_', $capitaliseFirstChar = false)
  69. {
  70. if (is_array($name)) {
  71. foreach ($name as &$value) {
  72. $value = static::toCamelCase($value, $symbol, $capitaliseFirstChar);
  73. }
  74. return $name;
  75. }
  76. if($capitaliseFirstChar) {
  77. $name[0] = strtoupper($name[0]);
  78. }
  79. return preg_replace_callback('/'.$symbol.'([a-z])/', 'static::toCamelCaseConversion', $name);
  80. }
  81. protected static function toCamelCaseConversion($matches)
  82. {
  83. return strtoupper($matches[1]);
  84. }
  85. /**
  86. * Convert name from Camel Case format.
  87. * ex. camelCase to camel-case
  88. *
  89. * @param string | array $name
  90. *
  91. * @return string
  92. */
  93. public static function fromCamelCase($name, $symbol = '_')
  94. {
  95. if (is_array($name)) {
  96. foreach ($name as &$value) {
  97. $value = static::fromCamelCase($value, $symbol);
  98. }
  99. return $name;
  100. }
  101. $name[0] = strtolower($name[0]);
  102. return preg_replace_callback('/([A-Z])/', function ($matches) use ($symbol) {
  103. return $symbol . strtolower($matches[1]);
  104. }, $name);
  105. }
  106. /**
  107. * Convert name from Camel Case format to underscore.
  108. * ex. camelCase to camel_case
  109. *
  110. * @param string | array $name
  111. *
  112. * @return string
  113. */
  114. public static function toUnderScore($name)
  115. {
  116. return static::fromCamelCase($name, '_');
  117. }
  118. /**
  119. * Merge arrays recursively (default PHP function is not suitable)
  120. *
  121. * @param array $currentArray
  122. * @param array $newArray - chief array (priority is same as for array_merge())
  123. *
  124. * @return array
  125. */
  126. public static function merge($currentArray, $newArray)
  127. {
  128. $mergeIdentifier = '__APPEND__';
  129. if (is_array($currentArray) && (!is_array($newArray) || empty($newArray))) {
  130. return $currentArray;
  131. } else if ((!is_array($currentArray) || empty($currentArray)) && is_array($newArray)) {
  132. return $newArray;
  133. } else if ((!is_array($currentArray) || empty($currentArray)) && (!is_array($newArray) || empty($newArray))) {
  134. return array();
  135. }
  136. foreach ($newArray as $newName => $newValue) {
  137. if (is_array($newValue) && empty($newValue)) {
  138. continue;
  139. }
  140. if (is_array($newValue) && array_key_exists($newName, $currentArray) && is_array($currentArray[$newName])) {
  141. // check __APPEND__ identifier
  142. $appendKey = array_search($mergeIdentifier, $newValue, true);
  143. if ($appendKey !== false) {
  144. unset($newValue[$appendKey]);
  145. $newValue = array_merge($currentArray[$newName], $newValue);
  146. } else if (!static::isSingleArray($newValue) || !static::isSingleArray($currentArray[$newName])) {
  147. $newValue = static::merge($currentArray[$newName], $newValue);
  148. }
  149. }
  150. //check if exists __APPEND__ identifier and remove its
  151. if (!isset($currentArray[$newName]) && is_array($newValue)) {
  152. $newValue = static::unsetInArrayByValue($mergeIdentifier, $newValue);
  153. }
  154. $currentArray[$newName] = $newValue;
  155. }
  156. return $currentArray;
  157. }
  158. /**
  159. * Unset a value in array recursively
  160. *
  161. * @param string $needle
  162. * @param array $haystack
  163. * @param bool $reIndex
  164. * @return array
  165. */
  166. public static function unsetInArrayByValue($needle, array $haystack, $reIndex = true)
  167. {
  168. $doReindex = false;
  169. foreach($haystack as $key => $value) {
  170. if (is_array($value)) {
  171. $haystack[$key] = static::unsetInArrayByValue($needle, $value);
  172. } else if ($needle === $value) {
  173. unset($haystack[$key]);
  174. if ($reIndex) {
  175. $doReindex = true;
  176. }
  177. }
  178. }
  179. if ($doReindex) {
  180. $haystack = array_values($haystack);
  181. }
  182. return $haystack;
  183. }
  184. /**
  185. * Get a full path of the file
  186. *
  187. * @param string | array $folderPath - Folder path, Ex. myfolder
  188. * @param string $filePath - File path, Ex. file.json
  189. *
  190. * @return string
  191. */
  192. public static function concatPath($folderPath, $filePath = null)
  193. {
  194. if (is_array($folderPath)) {
  195. $fullPath = '';
  196. foreach ($folderPath as $path) {
  197. $fullPath = static::concatPath($fullPath, $path);
  198. }
  199. return static::fixPath($fullPath);
  200. }
  201. if (empty($filePath)) {
  202. return static::fixPath($folderPath);
  203. }
  204. if (empty($folderPath)) {
  205. return static::fixPath($filePath);
  206. }
  207. if (substr($folderPath, -1) == static::getSeparator() || substr($folderPath, -1) == '/') {
  208. return static::fixPath($folderPath . $filePath);
  209. }
  210. return $folderPath . static::getSeparator() . $filePath;
  211. }
  212. /**
  213. * Fix path separator
  214. *
  215. * @param string $path
  216. * @return string
  217. */
  218. public static function fixPath($path)
  219. {
  220. return str_replace('/', static::getSeparator(), $path);
  221. }
  222. /**
  223. * Convert array to object format recursively
  224. *
  225. * @param array $array
  226. * @return object
  227. */
  228. public static function arrayToObject($array)
  229. {
  230. if (is_array($array)) {
  231. return (object) array_map("static::arrayToObject", $array);
  232. } else {
  233. return $array; // Return an object
  234. }
  235. }
  236. /**
  237. * Convert object to array format recursively
  238. *
  239. * @param object $object
  240. * @return array
  241. */
  242. public static function objectToArray($object)
  243. {
  244. if (is_object($object)) {
  245. $object = (array) $object;
  246. }
  247. return is_array($object) ? array_map("static::objectToArray", $object) : $object;
  248. }
  249. /**
  250. * Appends 'Obj' if name is reserved PHP word.
  251. *
  252. * @param string $name
  253. * @return string
  254. */
  255. public static function normilizeClassName($name)
  256. {
  257. if (in_array($name, self::$reservedWords)) {
  258. $name .= 'Obj';
  259. }
  260. return $name;
  261. }
  262. /**
  263. * Remove 'Obj' if name is reserved PHP word.
  264. *
  265. * @param string $name
  266. * @return string
  267. */
  268. public static function normilizeScopeName($name)
  269. {
  270. foreach (self::$reservedWords as $reservedWord) {
  271. if ($reservedWord.'Obj' == $name) {
  272. return $reservedWord;
  273. }
  274. }
  275. return $name;
  276. }
  277. /**
  278. * Get Naming according to prefix or postfix type
  279. *
  280. * @param string $name
  281. * @param string $prePostFix
  282. * @param string $type
  283. *
  284. * @return string
  285. */
  286. public static function getNaming($name, $prePostFix, $type = 'prefix', $symbol = '_')
  287. {
  288. if ($type == 'prefix') {
  289. return static::toCamelCase($prePostFix.$symbol.$name, $symbol);
  290. } else if ($type == 'postfix') {
  291. return static::toCamelCase($name.$symbol.$prePostFix, $symbol);
  292. }
  293. return null;
  294. }
  295. /**
  296. * Replace $search in array recursively
  297. *
  298. * @param string $search
  299. * @param string $replace
  300. * @param string $array
  301. * @param string $isKeys
  302. *
  303. * @return array
  304. */
  305. public static function replaceInArray($search = '', $replace = '', $array = false, $isKeys = true)
  306. {
  307. if (!is_array($array)) {
  308. return str_replace($search, $replace, $array);
  309. }
  310. $newArr = array();
  311. foreach ($array as $key => $value) {
  312. $addKey = $key;
  313. if ($isKeys) { //Replace keys
  314. $addKey = str_replace($search, $replace, $key);
  315. }
  316. // Recurse
  317. $newArr[$addKey] = static::replaceInArray($search, $replace, $value, $isKeys);
  318. }
  319. return $newArr;
  320. }
  321. /**
  322. * Unset content items defined in the unset.json
  323. *
  324. * @param array $content
  325. * @param string | array $unsets in format
  326. * array(
  327. * 'EntityName1' => array( 'unset1', 'unset2' ),
  328. * 'EntityName2' => array( 'unset1', 'unset2' ),
  329. * )
  330. * OR
  331. * array('EntityName1.unset1', 'EntityName1.unset2', .....)
  332. * OR
  333. * 'EntityName1.unset1'
  334. * @param bool $unsetParentEmptyArray - If unset empty parent array after unsets
  335. *
  336. * @return array
  337. */
  338. public static function unsetInArray(array $content, $unsets, $unsetParentEmptyArray = false)
  339. {
  340. if (empty($unsets)) {
  341. return $content;
  342. }
  343. if (is_string($unsets)) {
  344. $unsets = (array) $unsets;
  345. }
  346. foreach ($unsets as $rootKey => $unsetItem) {
  347. $unsetItem = is_array($unsetItem) ? $unsetItem : (array) $unsetItem;
  348. foreach ($unsetItem as $unsetString) {
  349. if (is_string($rootKey)) {
  350. $unsetString = $rootKey . '.' . $unsetString;
  351. }
  352. $keyСhain = explode('.', $unsetString);
  353. $keyChainCount = count($keyСhain) - 1;
  354. $elem = & $content;
  355. for ($i = 0; $i <= $keyChainCount; $i++) {
  356. if (is_array($elem) && array_key_exists($keyСhain[$i], $elem)) {
  357. if ($i == $keyChainCount) {
  358. unset($elem[$keyСhain[$i]]);
  359. if ($unsetParentEmptyArray && is_array($elem) && empty($elem)) {
  360. unset($keyСhain[$i]);
  361. $content = static::unsetInArray($content, implode('.', $keyСhain), false);
  362. }
  363. } else if (is_array($elem[$keyСhain[$i]])) {
  364. $elem = & $elem[$keyСhain[$i]];
  365. }
  366. }
  367. }
  368. }
  369. }
  370. return $content;
  371. }
  372. /**
  373. * Get class name from the file path
  374. *
  375. * @param string $filePath
  376. *
  377. * @return string
  378. */
  379. public static function getClassName($filePath)
  380. {
  381. $className = preg_replace('/\.php$/i', '', $filePath);
  382. $className = preg_replace('/^(application|custom)\//i', '', $className);
  383. $className = '\\'.static::toFormat($className, '\\');
  384. return $className;
  385. }
  386. /**
  387. * Return values of defined $key.
  388. *
  389. * @param array $array
  390. * @param mixed array|string $key Ex. of key is "entityDefs", "entityDefs.User"
  391. * @param mixed $default
  392. * @return mixed
  393. */
  394. public static function getValueByKey(array $array, $key = null, $default = null)
  395. {
  396. if (!isset($key) || empty($key)) {
  397. return $array;
  398. }
  399. if (is_array($key)) {
  400. $keys = $key;
  401. } else {
  402. $keys = explode('.', $key);
  403. }
  404. $lastItem = $array;
  405. foreach($keys as $keyName) {
  406. if (isset($lastItem[$keyName]) && is_array($lastItem)) {
  407. $lastItem = $lastItem[$keyName];
  408. } else {
  409. return $default;
  410. }
  411. }
  412. return $lastItem;
  413. }
  414. /**
  415. * Check if two variables are equals
  416. *
  417. * @param mixed $var1
  418. * @param mixed $var2
  419. * @return boolean
  420. */
  421. public static function isEquals($var1, $var2)
  422. {
  423. if (is_array($var1)) {
  424. static::ksortRecursive($var1);
  425. }
  426. if (is_array($var2)) {
  427. static::ksortRecursive($var2);
  428. }
  429. return ($var1 === $var2);
  430. }
  431. /**
  432. * Sort array recursively
  433. * @param array $array
  434. * @return bool
  435. */
  436. public static function ksortRecursive(&$array)
  437. {
  438. if (!is_array($array)) {
  439. return false;
  440. }
  441. ksort($array);
  442. foreach ($array as $key => $value) {
  443. static::ksortRecursive($array[$key]);
  444. }
  445. return true;
  446. }
  447. public static function isSingleArray(array $array)
  448. {
  449. foreach ($array as $key => $value) {
  450. if (!is_int($key)) {
  451. return false;
  452. }
  453. }
  454. return true;
  455. }
  456. public static function generateId()
  457. {
  458. return uniqid() . substr(md5(rand()), 0, 4);
  459. }
  460. public static function sanitizeFileName($fileName)
  461. {
  462. return preg_replace("/([^\w\s\d\-_~,;:\[\]\(\).])/u", '_', $fileName);
  463. }
  464. }