1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
19:
20: 21: 22: 23: 24: 25:
26: class String {
27:
28: 29: 30: 31: 32: 33:
34: public static function uuid() {
35: $node = env('SERVER_ADDR');
36:
37: if (strpos($node, ':') !== false) {
38: if (substr_count($node, '::')) {
39: $node = str_replace(
40: '::', str_repeat(':0000', 8 - substr_count($node, ':')) . ':', $node
41: );
42: }
43: $node = explode(':', $node) ;
44: $ipv6 = '' ;
45:
46: foreach ($node as $id) {
47: $ipv6 .= str_pad(base_convert($id, 16, 2), 16, 0, STR_PAD_LEFT);
48: }
49: $node = base_convert($ipv6, 2, 10);
50:
51: if (strlen($node) < 38) {
52: $node = null;
53: } else {
54: $node = crc32($node);
55: }
56: } elseif (empty($node)) {
57: $host = env('HOSTNAME');
58:
59: if (empty($host)) {
60: $host = env('HOST');
61: }
62:
63: if (!empty($host)) {
64: $ip = gethostbyname($host);
65:
66: if ($ip === $host) {
67: $node = crc32($host);
68: } else {
69: $node = ip2long($ip);
70: }
71: }
72: } elseif ($node !== '127.0.0.1') {
73: $node = ip2long($node);
74: } else {
75: $node = null;
76: }
77:
78: if (empty($node)) {
79: $node = crc32(Configure::read('Security.salt'));
80: }
81:
82: if (function_exists('zend_thread_id')) {
83: $pid = zend_thread_id();
84: } else {
85: $pid = getmypid();
86: }
87:
88: if (!$pid || $pid > 65535) {
89: $pid = mt_rand(0, 0xfff) | 0x4000;
90: }
91:
92: list($timeMid, $timeLow) = explode(' ', microtime());
93: $uuid = sprintf(
94: "%08x-%04x-%04x-%02x%02x-%04x%08x", (int)$timeLow, (int)substr($timeMid, 2) & 0xffff,
95: mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3f) | 0x80, mt_rand(0, 0xff), $pid, $node
96: );
97:
98: return $uuid;
99: }
100:
101: 102: 103: 104: 105: 106: 107: 108: 109: 110:
111: public static function tokenize($data, $separator = ',', $leftBound = '(', $rightBound = ')') {
112: if (empty($data) || is_array($data)) {
113: return $data;
114: }
115:
116: $depth = 0;
117: $offset = 0;
118: $buffer = '';
119: $results = array();
120: $length = strlen($data);
121: $open = false;
122:
123: while ($offset <= $length) {
124: $tmpOffset = -1;
125: $offsets = array(
126: strpos($data, $separator, $offset),
127: strpos($data, $leftBound, $offset),
128: strpos($data, $rightBound, $offset)
129: );
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:
171: if (!empty($results)) {
172: $data = array_map('trim', $results);
173: } else {
174: $data = array();
175: }
176: return $data;
177: }
178:
179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199:
200: public static function insert($str, $data, $options = array()) {
201: $defaults = array(
202: 'before' => ':', 'after' => null, 'escape' => '\\', 'format' => null, 'clean' => false
203: );
204: $options += $defaults;
205: $format = $options['format'];
206: $data = (array)$data;
207: if (empty($data)) {
208: return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
209: }
210:
211: if (!isset($format)) {
212: $format = sprintf(
213: '/(?<!%s)%s%%s%s/',
214: preg_quote($options['escape'], '/'),
215: str_replace('%', '%%', preg_quote($options['before'], '/')),
216: str_replace('%', '%%', preg_quote($options['after'], '/'))
217: );
218: }
219:
220: if (strpos($str, '?') !== false && is_numeric(key($data))) {
221: $offset = 0;
222: while (($pos = strpos($str, '?', $offset)) !== false) {
223: $val = array_shift($data);
224: $offset = $pos + strlen($val);
225: $str = substr_replace($str, $val, $pos, 1);
226: }
227: return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
228: } else {
229: asort($data);
230:
231: $hashKeys = array();
232: foreach ($data as $key => $value) {
233: $hashKeys[] = crc32($key);
234: }
235:
236: $tempData = array_combine(array_keys($data), array_values($hashKeys));
237: krsort($tempData);
238: foreach ($tempData as $key => $hashVal) {
239: $key = sprintf($format, preg_quote($key, '/'));
240: $str = preg_replace($key, $hashVal, $str);
241: }
242: $dataReplacements = array_combine($hashKeys, array_values($data));
243: foreach ($dataReplacements as $tmpHash => $tmpValue) {
244: $tmpValue = (is_array($tmpValue)) ? '' : $tmpValue;
245: $str = str_replace($tmpHash, $tmpValue, $str);
246: }
247: }
248:
249: if (!isset($options['format']) && isset($options['before'])) {
250: $str = str_replace($options['escape'] . $options['before'], $options['before'], $str);
251: }
252: return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
253: }
254:
255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265:
266: public static function cleanInsert($str, $options) {
267: $clean = $options['clean'];
268: if (!$clean) {
269: return $str;
270: }
271: if ($clean === true) {
272: $clean = array('method' => 'text');
273: }
274: if (!is_array($clean)) {
275: $clean = array('method' => $options['clean']);
276: }
277: switch ($clean['method']) {
278: case 'html':
279: $clean = array_merge(array(
280: 'word' => '[\w,.]+',
281: 'andText' => true,
282: 'replacement' => '',
283: ), $clean);
284: $kleenex = sprintf(
285: '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i',
286: preg_quote($options['before'], '/'),
287: $clean['word'],
288: preg_quote($options['after'], '/')
289: );
290: $str = preg_replace($kleenex, $clean['replacement'], $str);
291: if ($clean['andText']) {
292: $options['clean'] = array('method' => 'text');
293: $str = String::cleanInsert($str, $options);
294: }
295: break;
296: case 'text':
297: $clean = array_merge(array(
298: 'word' => '[\w,.]+',
299: 'gap' => '[\s]*(?:(?:and|or)[\s]*)?',
300: 'replacement' => '',
301: ), $clean);
302:
303: $kleenex = sprintf(
304: '/(%s%s%s%s|%s%s%s%s)/',
305: preg_quote($options['before'], '/'),
306: $clean['word'],
307: preg_quote($options['after'], '/'),
308: $clean['gap'],
309: $clean['gap'],
310: preg_quote($options['before'], '/'),
311: $clean['word'],
312: preg_quote($options['after'], '/')
313: );
314: $str = preg_replace($kleenex, $clean['replacement'], $str);
315: break;
316: }
317: return $str;
318: }
319:
320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333:
334: public static function wrap($text, $options = array()) {
335: if (is_numeric($options)) {
336: $options = array('width' => $options);
337: }
338: $options += array('width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0);
339: if ($options['wordWrap']) {
340: $wrapped = wordwrap($text, $options['width'], "\n");
341: } else {
342: $wrapped = trim(chunk_split($text, $options['width'] - 1, "\n"));
343: }
344: if (!empty($options['indent'])) {
345: $chunks = explode("\n", $wrapped);
346: for ($i = $options['indentAt'], $len = count($chunks); $i < $len; $i++) {
347: $chunks[$i] = $options['indent'] . $chunks[$i];
348: }
349: $wrapped = implode("\n", $chunks);
350: }
351: return $wrapped;
352: }
353: }
354: