PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/cake/libs/string.php

https://bitbucket.org/unsl/listop
PHP | 327 lines | 236 code | 15 blank | 76 comment | 45 complexity | 61db24dc6389b57404e0bf77cd6fe5bc MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /* SVN FILE: $Id: string.php,v 1.1 2010-03-19 15:40:48 diegoq Exp $ */
  3. /**
  4. * String handling methods.
  5. *
  6. *
  7. * PHP versions 4 and 5
  8. *
  9. * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
  10. * Copyright 2005-2010, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  11. *
  12. * Licensed under The MIT License
  13. * Redistributions of files must retain the above copyright notice.
  14. *
  15. * @filesource
  16. * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  17. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
  18. * @package cake
  19. * @subpackage cake.cake.libs
  20. * @since CakePHP(tm) v 1.2.0.5551
  21. * @version $Revision: 1.1 $
  22. * @modifiedby $LastChangedBy$
  23. * @lastmodified $Date: 2010-03-19 15:40:48 $
  24. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  25. */
  26. /**
  27. * String handling methods.
  28. *
  29. *
  30. * @package cake
  31. * @subpackage cake.cake.libs
  32. */
  33. class String extends Object {
  34. /**
  35. * Gets a reference to the String object instance
  36. *
  37. * @return object String instance
  38. * @access public
  39. * @static
  40. */
  41. function &getInstance() {
  42. static $instance = array();
  43. if (!$instance) {
  44. $instance[0] =& new String();
  45. }
  46. return $instance[0];
  47. }
  48. /**
  49. * Generate a random UUID
  50. *
  51. * @see http://www.ietf.org/rfc/rfc4122.txt
  52. * @return RFC 4122 UUID
  53. * @static
  54. */
  55. function uuid() {
  56. $node = env('SERVER_ADDR');
  57. $pid = null;
  58. if (strpos($node, ':') !== false) {
  59. if (substr_count($node, '::')) {
  60. $node = str_replace('::', str_repeat(':0000', 8 - substr_count($node, ':')) . ':', $node);
  61. }
  62. $node = explode(':', $node) ;
  63. $ipv6 = '' ;
  64. foreach ($node as $id) {
  65. $ipv6 .= str_pad(base_convert($id, 16, 2), 16, 0, STR_PAD_LEFT);
  66. }
  67. $node = base_convert($ipv6, 2, 10);
  68. if (strlen($node) < 38) {
  69. $node = null;
  70. } else {
  71. $node = crc32($node);
  72. }
  73. } elseif (empty($node)) {
  74. $host = env('HOSTNAME');
  75. if (empty($host)) {
  76. $host = env('HOST');
  77. }
  78. if (!empty($host)) {
  79. $ip = gethostbyname($host);
  80. if ($ip === $host) {
  81. $node = crc32($host);
  82. } else {
  83. $node = ip2long($ip);
  84. }
  85. }
  86. } elseif ($node !== '127.0.0.1') {
  87. $node = ip2long($node);
  88. } else {
  89. $node = null;
  90. }
  91. if (empty($node)) {
  92. $node = crc32(Configure::read('Security.salt'));
  93. }
  94. if (function_exists('zend_thread_id')) {
  95. $pid = zend_thread_id();
  96. } else {
  97. $pid = getmypid();
  98. }
  99. if (!$pid || $pid > 65535) {
  100. $pid = mt_rand(0, 0xfff) | 0x4000;
  101. }
  102. list($timeMid, $timeLow) = explode(' ', microtime());
  103. $uuid = sprintf("%08x-%04x-%04x-%02x%02x-%04x%08x", (int)$timeLow, (int)substr($timeMid, 2) & 0xffff,
  104. mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3f) | 0x80, mt_rand(0, 0xff), $pid, $node);
  105. return $uuid;
  106. }
  107. /**
  108. * Tokenizes a string using $separator, ignoring any instance of $separator that appears between $leftBound
  109. * and $rightBound
  110. *
  111. * @param string $data The data to tokenize
  112. * @param string $separator The token to split the data on
  113. * @return array
  114. * @access public
  115. * @static
  116. */
  117. function tokenize($data, $separator = ',', $leftBound = '(', $rightBound = ')') {
  118. if (empty($data) || is_array($data)) {
  119. return $data;
  120. }
  121. $depth = 0;
  122. $offset = 0;
  123. $buffer = '';
  124. $results = array();
  125. $length = strlen($data);
  126. $open = false;
  127. while ($offset <= $length) {
  128. $tmpOffset = -1;
  129. $offsets = array(strpos($data, $separator, $offset), strpos($data, $leftBound, $offset), strpos($data, $rightBound, $offset));
  130. for ($i = 0; $i < 3; $i++) {
  131. if ($offsets[$i] !== false && ($offsets[$i] < $tmpOffset || $tmpOffset == -1)) {
  132. $tmpOffset = $offsets[$i];
  133. }
  134. }
  135. if ($tmpOffset !== -1) {
  136. $buffer .= substr($data, $offset, ($tmpOffset - $offset));
  137. if ($data{$tmpOffset} == $separator && $depth == 0) {
  138. $results[] = $buffer;
  139. $buffer = '';
  140. } else {
  141. $buffer .= $data{$tmpOffset};
  142. }
  143. if ($leftBound != $rightBound) {
  144. if ($data{$tmpOffset} == $leftBound) {
  145. $depth++;
  146. }
  147. if ($data{$tmpOffset} == $rightBound) {
  148. $depth--;
  149. }
  150. } else {
  151. if ($data{$tmpOffset} == $leftBound) {
  152. if (!$open) {
  153. $depth++;
  154. $open = true;
  155. } else {
  156. $depth--;
  157. $open = false;
  158. }
  159. }
  160. }
  161. $offset = ++$tmpOffset;
  162. } else {
  163. $results[] = $buffer . substr($data, $offset);
  164. $offset = $length + 1;
  165. }
  166. }
  167. if (empty($results) && !empty($buffer)) {
  168. $results[] = $buffer;
  169. }
  170. if (!empty($results)) {
  171. $data = array_map('trim', $results);
  172. } else {
  173. $data = array();
  174. }
  175. return $data;
  176. }
  177. /**
  178. * Replaces variable placeholders inside a $str with any given $data. Each key in the $data array corresponds to a variable
  179. * placeholder name in $str. Example:
  180. *
  181. * Sample: String::insert('My name is :name and I am :age years old.', array('name' => 'Bob', '65'));
  182. * Returns: My name is Bob and I am 65 years old.
  183. *
  184. * Available $options are:
  185. * before: The character or string in front of the name of the variable placeholder (Defaults to ':')
  186. * after: The character or string after the name of the variable placeholder (Defaults to null)
  187. * escape: The character or string used to escape the before character / string (Defaults to '\')
  188. * format: A regex to use for matching variable placeholders. Default is: '/(?<!\\)\:%s/' (Overwrites before, after, breaks escape / clean)
  189. * clean: A boolean or array with instructions for String::cleanInsert
  190. *
  191. * @param string $str A string containing variable placeholders
  192. * @param string $data A key => val array where each key stands for a placeholder variable name to be replaced with val
  193. * @param string $options An array of options, see description above
  194. * @return string
  195. * @access public
  196. * @static
  197. */
  198. function insert($str, $data, $options = array()) {
  199. $defaults = array(
  200. 'before' => ':', 'after' => null, 'escape' => '\\', 'format' => null, 'clean' => false
  201. );
  202. $options += $defaults;
  203. $format = $options['format'];
  204. if (!isset($format)) {
  205. $format = sprintf(
  206. '/(?<!%s)%s%%s%s/',
  207. preg_quote($options['escape'], '/'),
  208. str_replace('%', '%%', preg_quote($options['before'], '/')),
  209. str_replace('%', '%%', preg_quote($options['after'], '/'))
  210. );
  211. }
  212. if (!is_array($data)) {
  213. $data = array($data);
  214. }
  215. if (array_keys($data) === array_keys(array_values($data))) {
  216. $offset = 0;
  217. while (($pos = strpos($str, '?', $offset)) !== false) {
  218. $val = array_shift($data);
  219. $offset = $pos + strlen($val);
  220. $str = substr_replace($str, $val, $pos, 1);
  221. }
  222. } else {
  223. asort($data);
  224. $hashKeys = array_map('md5', array_keys($data));
  225. $tempData = array_combine(array_keys($data), array_values($hashKeys));
  226. foreach ($tempData as $key => $hashVal) {
  227. $key = sprintf($format, preg_quote($key, '/'));
  228. $str = preg_replace($key, $hashVal, $str);
  229. }
  230. $dataReplacements = array_combine($hashKeys, array_values($data));
  231. foreach ($dataReplacements as $tmpHash => $data) {
  232. $str = str_replace($tmpHash, $data, $str);
  233. }
  234. }
  235. if (!isset($options['format']) && isset($options['before'])) {
  236. $str = str_replace($options['escape'].$options['before'], $options['before'], $str);
  237. }
  238. if (!$options['clean']) {
  239. return $str;
  240. }
  241. return String::cleanInsert($str, $options);
  242. }
  243. /**
  244. * Cleans up a Set::insert formated string with given $options depending on the 'clean' key in $options. The default method used is
  245. * text but html is also available. The goal of this function is to replace all whitespace and uneeded markup around placeholders
  246. * that did not get replaced by Set::insert.
  247. *
  248. * @param string $str
  249. * @param string $options
  250. * @return string
  251. * @access public
  252. * @static
  253. */
  254. function cleanInsert($str, $options) {
  255. $clean = $options['clean'];
  256. if (!$clean) {
  257. return $str;
  258. }
  259. if ($clean === true) {
  260. $clean = array('method' => 'text');
  261. }
  262. if (!is_array($clean)) {
  263. $clean = array('method' => $options['clean']);
  264. }
  265. switch ($clean['method']) {
  266. case 'html':
  267. $clean = array_merge(array(
  268. 'word' => '[\w,.]+',
  269. 'andText' => true,
  270. 'replacement' => '',
  271. ), $clean);
  272. $kleenex = sprintf(
  273. '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i',
  274. preg_quote($options['before'], '/'),
  275. $clean['word'],
  276. preg_quote($options['after'], '/')
  277. );
  278. $str = preg_replace($kleenex, $clean['replacement'], $str);
  279. if ($clean['andText']) {
  280. $options['clean'] = array('method' => 'text');
  281. $str = String::cleanInsert($str, $options);
  282. }
  283. break;
  284. case 'text':
  285. $clean = array_merge(array(
  286. 'word' => '[\w,.]+',
  287. 'gap' => '[\s]*(?:(?:and|or)[\s]*)?',
  288. 'replacement' => '',
  289. ), $clean);
  290. $kleenex = sprintf(
  291. '/(%s%s%s%s|%s%s%s%s)/',
  292. preg_quote($options['before'], '/'),
  293. $clean['word'],
  294. preg_quote($options['after'], '/'),
  295. $clean['gap'],
  296. $clean['gap'],
  297. preg_quote($options['before'], '/'),
  298. $clean['word'],
  299. preg_quote($options['after'], '/')
  300. );
  301. $str = preg_replace($kleenex, $clean['replacement'], $str);
  302. break;
  303. }
  304. return $str;
  305. }
  306. }
  307. ?>