PageRenderTime 25ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/app/code/core/Mage/Core/Helper/String.php

https://gitlab.com/axeltizon/magentoV1.9-demopoweraccess
PHP | 479 lines | 266 code | 33 blank | 180 comment | 49 complexity | 8a9238669924b1640b4a93200ddaa401 MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Core
  23. * @copyright Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Core data helper
  28. *
  29. * @author Magento Core Team <core@magentocommerce.com>
  30. */
  31. class Mage_Core_Helper_String extends Mage_Core_Helper_Abstract
  32. {
  33. const ICONV_CHARSET = 'UTF-8';
  34. /**
  35. * @var Mage_Core_Helper_Array
  36. */
  37. protected $_arrayHelper;
  38. /**
  39. * Truncate a string to a certain length if necessary, appending the $etc string.
  40. * $remainder will contain the string that has been replaced with $etc.
  41. *
  42. * @param string $string
  43. * @param int $length
  44. * @param string $etc
  45. * @param string &$remainder
  46. * @param bool $breakWords
  47. * @return string
  48. */
  49. public function truncate($string, $length = 80, $etc = '...', &$remainder = '', $breakWords = true)
  50. {
  51. $remainder = '';
  52. if (0 == $length) {
  53. return '';
  54. }
  55. $originalLength = $this->strlen($string);
  56. if ($originalLength > $length) {
  57. $length -= $this->strlen($etc);
  58. if ($length <= 0) {
  59. return '';
  60. }
  61. $preparedString = $string;
  62. $preparedlength = $length;
  63. if (!$breakWords) {
  64. $preparedString = preg_replace('/\s+?(\S+)?$/u', '', $this->substr($string, 0, $length + 1));
  65. $preparedlength = $this->strlen($preparedString);
  66. }
  67. $remainder = $this->substr($string, $preparedlength, $originalLength);
  68. return $this->substr($preparedString, 0, $length) . $etc;
  69. }
  70. return $string;
  71. }
  72. /**
  73. * Retrieve string length using default charset
  74. *
  75. * @param string $string
  76. * @return int
  77. */
  78. public function strlen($string)
  79. {
  80. return iconv_strlen($string, self::ICONV_CHARSET);
  81. }
  82. /**
  83. * Passthrough to iconv_substr()
  84. *
  85. * @param string $string
  86. * @param int $offset
  87. * @param int $length
  88. * @return string
  89. */
  90. public function substr($string, $offset, $length = null)
  91. {
  92. $string = $this->cleanString($string);
  93. if (is_null($length)) {
  94. $length = $this->strlen($string) - $offset;
  95. }
  96. return iconv_substr($string, $offset, $length, self::ICONV_CHARSET);
  97. }
  98. /**
  99. * Split string and appending $insert string after $needle
  100. *
  101. * @param string $str
  102. * @param integer $length
  103. * @param string $needle
  104. * @param string $insert
  105. * @return string
  106. */
  107. public function splitInjection($str, $length = 50, $needle = '-', $insert = ' ')
  108. {
  109. $str = $this->str_split($str, $length);
  110. $newStr = '';
  111. foreach ($str as $part) {
  112. if ($this->strlen($part) >= $length) {
  113. $lastDelimetr = $this->strpos($this->strrev($part), $needle);
  114. $tmpNewStr = '';
  115. $tmpNewStr = $this->substr($this->strrev($part), 0, $lastDelimetr)
  116. . $insert . $this->substr($this->strrev($part), $lastDelimetr);
  117. $newStr .= $this->strrev($tmpNewStr);
  118. } else {
  119. $newStr .= $part;
  120. }
  121. }
  122. return $newStr;
  123. }
  124. /**
  125. * Binary-safe strrev()
  126. *
  127. * @param string $str
  128. * @return string
  129. */
  130. public function strrev($str)
  131. {
  132. $result = '';
  133. $strlen = $this->strlen($str);
  134. if (!$strlen) {
  135. return $result;
  136. }
  137. for ($i = $strlen-1; $i >= 0; $i--) {
  138. $result .= $this->substr($str, $i, 1);
  139. }
  140. return $result;
  141. }
  142. /**
  143. * Binary-safe variant of str_split()
  144. * + option not to break words
  145. * + option to trim spaces (between each word)
  146. * + option to set character(s) (pcre pattern) to be considered as words separator
  147. *
  148. * @param string $str
  149. * @param int $length
  150. * @param bool $keepWords
  151. * @param bool $trim
  152. * @param string $wordSeparatorRegex
  153. * @return array
  154. */
  155. public function str_split($str, $length = 1, $keepWords = false, $trim = false, $wordSeparatorRegex = '\s')
  156. {
  157. $result = array();
  158. $strlen = $this->strlen($str);
  159. if ((!$strlen) || (!is_int($length)) || ($length <= 0)) {
  160. return $result;
  161. }
  162. // trim
  163. if ($trim) {
  164. $str = trim(preg_replace('/\s{2,}/siu', ' ', $str));
  165. }
  166. // do a usual str_split, but safe for our encoding
  167. if ((!$keepWords) || ($length < 2)) {
  168. for ($offset = 0; $offset < $strlen; $offset += $length) {
  169. $result[] = $this->substr($str, $offset, $length);
  170. }
  171. }
  172. // split smartly, keeping words
  173. else {
  174. $split = preg_split('/(' . $wordSeparatorRegex . '+)/siu', $str, null, PREG_SPLIT_DELIM_CAPTURE);
  175. $i = 0;
  176. $space = '';
  177. $spaceLen = 0;
  178. foreach ($split as $key => $part) {
  179. if ($trim) {
  180. // ignore spaces (even keys)
  181. if ($key % 2) {
  182. continue;
  183. }
  184. $space = ' ';
  185. $spaceLen = 1;
  186. }
  187. if (empty($result[$i])) {
  188. $currentLength = 0;
  189. $result[$i] = '';
  190. $space = '';
  191. $spaceLen = 0;
  192. }
  193. else {
  194. $currentLength = $this->strlen($result[$i]);
  195. }
  196. $partLength = $this->strlen($part);
  197. // add part to current last element
  198. if (($currentLength + $spaceLen + $partLength) <= $length) {
  199. $result[$i] .= $space . $part;
  200. }
  201. // add part to new element
  202. elseif ($partLength <= $length) {
  203. $i++;
  204. $result[$i] = $part;
  205. }
  206. // break too long part recursively
  207. else {
  208. foreach ($this->str_split($part, $length, false, $trim, $wordSeparatorRegex) as $subpart) {
  209. $i++;
  210. $result[$i] = $subpart;
  211. }
  212. }
  213. }
  214. }
  215. // remove last element, if empty
  216. if ($count = count($result)) {
  217. if ($result[$count - 1] === '') {
  218. unset($result[$count - 1]);
  219. }
  220. }
  221. // remove first element, if empty
  222. if (isset($result[0]) && $result[0] === '') {
  223. array_shift($result);
  224. }
  225. return $result;
  226. }
  227. /**
  228. * Split words
  229. *
  230. * @param string $str The source string
  231. * @param bool $uniqueOnly Unique words only
  232. * @param int $maxWordLength Limit words count
  233. * @param string $wordSeparatorRegexp
  234. * @return array
  235. */
  236. function splitWords($str, $uniqueOnly = false, $maxWordLength = 0, $wordSeparatorRegexp = '\s')
  237. {
  238. $result = array();
  239. $split = preg_split('#' . $wordSeparatorRegexp . '#siu', $str, null, PREG_SPLIT_NO_EMPTY);
  240. foreach ($split as $word) {
  241. if ($uniqueOnly) {
  242. $result[$word] = $word;
  243. }
  244. else {
  245. $result[] = $word;
  246. }
  247. }
  248. if ($maxWordLength && count($result) > $maxWordLength) {
  249. $result = array_slice($result, 0, $maxWordLength);
  250. }
  251. return $result;
  252. }
  253. /**
  254. * Clean non UTF-8 characters
  255. *
  256. * @param string $string
  257. * @return string
  258. */
  259. public function cleanString($string)
  260. {
  261. return '"libiconv"' == ICONV_IMPL ?
  262. iconv(self::ICONV_CHARSET, self::ICONV_CHARSET . '//IGNORE', $string) : $string;
  263. }
  264. /**
  265. * Find position of first occurrence of a string
  266. *
  267. * @param string $haystack
  268. * @param string $needle
  269. * @param int $offset
  270. * @return int|false
  271. */
  272. public function strpos($haystack, $needle, $offset = null)
  273. {
  274. return iconv_strpos($haystack, $needle, $offset, self::ICONV_CHARSET);
  275. }
  276. /**
  277. * Sorts array with multibyte string keys
  278. *
  279. * @param array $sort
  280. * @return array
  281. */
  282. public function ksortMultibyte(array &$sort)
  283. {
  284. if (empty($sort)) {
  285. return false;
  286. }
  287. $oldLocale = setlocale(LC_COLLATE, "0");
  288. $localeCode = Mage::app()->getLocale()->getLocaleCode();
  289. // use fallback locale if $localeCode is not available
  290. setlocale(LC_COLLATE, $localeCode . '.UTF8', 'C.UTF-8', 'en_US.utf8');
  291. ksort($sort, SORT_LOCALE_STRING);
  292. setlocale(LC_COLLATE, $oldLocale);
  293. return $sort;
  294. }
  295. /**
  296. * Parse query string to array
  297. *
  298. * @param string $str
  299. * @return array
  300. */
  301. public function parseQueryStr($str)
  302. {
  303. $argSeparator = '&';
  304. $result = array();
  305. $partsQueryStr = explode($argSeparator, $str);
  306. foreach ($partsQueryStr as $partQueryStr) {
  307. if ($this->_validateQueryStr($partQueryStr)) {
  308. $param = $this->_explodeAndDecodeParam($partQueryStr);
  309. $param = $this->_handleRecursiveParamForQueryStr($param);
  310. $result = $this->_appendParam($result, $param);
  311. }
  312. }
  313. return $result;
  314. }
  315. /**
  316. * Validate query pair string
  317. *
  318. * @param string $str
  319. * @return bool
  320. */
  321. protected function _validateQueryStr($str)
  322. {
  323. if (!$str || (strpos($str, '=') === false)) {
  324. return false;
  325. }
  326. return true;
  327. }
  328. /**
  329. * Prepare param
  330. *
  331. * @param string $str
  332. * @return array
  333. */
  334. protected function _explodeAndDecodeParam($str)
  335. {
  336. $preparedParam = array();
  337. $param = explode('=', $str);
  338. $preparedParam['key'] = urldecode(array_shift($param));
  339. $preparedParam['value'] = urldecode(array_shift($param));
  340. return $preparedParam;
  341. }
  342. /**
  343. * Append param to general result
  344. *
  345. * @param array $result
  346. * @param array $param
  347. * @return array
  348. */
  349. protected function _appendParam(array $result, array $param)
  350. {
  351. $key = $param['key'];
  352. $value = $param['value'];
  353. if ($key) {
  354. if (is_array($value) && array_key_exists($key, $result)) {
  355. $helper = $this->getArrayHelper();
  356. $result[$key] = $helper->mergeRecursiveWithoutOverwriteNumKeys($result[$key], $value);
  357. } else {
  358. $result[$key] = $value;
  359. }
  360. }
  361. return $result;
  362. }
  363. /**
  364. * Handle param recursively
  365. *
  366. * @param array $param
  367. * @return array
  368. */
  369. protected function _handleRecursiveParamForQueryStr(array $param)
  370. {
  371. $value = $param['value'];
  372. $key = $param['key'];
  373. $subKeyBrackets = $this->_getLastSubkey($key);
  374. $subKey = $this->_getLastSubkey($key, false);
  375. if ($subKeyBrackets) {
  376. if ($subKey) {
  377. $param['value'] = array($subKey => $value);
  378. } else {
  379. $param['value'] = array($value);
  380. }
  381. $param['key'] = $this->_removeSubkeyPartFromKey($key, $subKeyBrackets);
  382. $param = $this->_handleRecursiveParamForQueryStr($param);
  383. }
  384. return $param;
  385. }
  386. /**
  387. * Remove subkey part from key
  388. *
  389. * @param string $key
  390. * @param string $subKeyBrackets
  391. * @return string
  392. */
  393. protected function _removeSubkeyPartFromKey($key, $subKeyBrackets)
  394. {
  395. return substr($key, 0, strrpos($key, $subKeyBrackets));
  396. }
  397. /**
  398. * Get last part key from query array
  399. *
  400. * @param string $key
  401. * @param bool $withBrackets
  402. * @return string
  403. */
  404. protected function _getLastSubkey($key, $withBrackets = true)
  405. {
  406. $subKey = '';
  407. $leftBracketSymbol = '[';
  408. $rightBracketSymbol = ']';
  409. $firstPos = strrpos($key, $leftBracketSymbol);
  410. $lastPos = strrpos($key, $rightBracketSymbol);
  411. if (($firstPos !== false || $lastPos !== false)
  412. && $firstPos < $lastPos
  413. ) {
  414. $keyLenght = $lastPos - $firstPos + 1;
  415. $subKey = substr($key, $firstPos, $keyLenght);
  416. if (!$withBrackets) {
  417. $subKey = ltrim($subKey, $leftBracketSymbol);
  418. $subKey = rtrim($subKey, $rightBracketSymbol);
  419. }
  420. }
  421. return $subKey;
  422. }
  423. /**
  424. * Set array helper
  425. *
  426. * @param Mage_Core_Helper_Abstract $helper
  427. * @return Mage_Core_Helper_String
  428. */
  429. public function setArrayHelper(Mage_Core_Helper_Abstract $helper)
  430. {
  431. $this->_arrayHelper = $helper;
  432. return $this;
  433. }
  434. /**
  435. * Get Array Helper
  436. *
  437. * @return Mage_Core_Helper_Array
  438. */
  439. public function getArrayHelper()
  440. {
  441. if (!$this->_arrayHelper) {
  442. $this->_arrayHelper = Mage::helper('core/array');
  443. }
  444. return $this->_arrayHelper;
  445. }
  446. }