1 <?php
  2 
  3   4   5   6   7   8   9  10 
 11 
 12 namespace ICanBoogie;
 13 
 14  15  16  17  18  19  20  21  22  23  24  25 
 26 function escape($str, $charset=CHARSET)
 27 {
 28     return htmlspecialchars($str, ENT_COMPAT, $charset);
 29 }
 30 
 31  32  33  34  35  36  37  38  39  40  41 
 42 function escape_all($str, $charset=CHARSET)
 43 {
 44     return htmlentities($str, ENT_COMPAT, $charset);
 45 }
 46 
 47 if (!function_exists(__NAMESPACE__ . '\downcase'))
 48 {
 49      50  51  52  53  54  55 
 56     function downcase($str)
 57     {
 58         return mb_strtolower($str);
 59     }
 60 }
 61 
 62 if (!function_exists(__NAMESPACE__ . '\upcase'))
 63 {
 64      65  66  67  68  69  70 
 71     function upcase($str)
 72     {
 73         return mb_strtoupper($str);
 74     }
 75 }
 76 
 77 if (!function_exists(__NAMESPACE__ . '\capitalize'))
 78 {
 79      80  81  82  83  84 
 85     function capitalize($str)
 86     {
 87         return upcase(mb_substr($str, 0, 1)) . downcase(mb_substr($str, 1));
 88     }
 89 }
 90 
 91  92  93  94  95  96  97  98  99 100 
101 function shorten($str, $length=32, $position=.75, &$shortened=null)
102 {
103     $l = mb_strlen($str);
104 
105     if ($l <= $length)
106     {
107         return $str;
108     }
109 
110     $length--;
111     $position = (int) ($position * $length);
112 
113     if ($position == 0)
114     {
115         $str = '…' . mb_substr($str, $l - $length);
116     }
117     else if ($position == $length)
118     {
119         $str = mb_substr($str, 0, $length) . '…';
120     }
121     else
122     {
123         $str = mb_substr($str, 0, $position) . '…' . mb_substr($str, $l - ($length - $position));
124     }
125 
126     $shortened = true;
127 
128     return $str;
129 }
130 
131 132 133 134 135 136 137 138 
139 function remove_accents($str, $charset=CHARSET)
140 {
141     $str = htmlentities($str, ENT_NOQUOTES, $charset);
142 
143     $str = preg_replace('#&([A-za-z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
144     $str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); 
145     $str = preg_replace('#&[^;]+;#', '', $str); 
146 
147     return $str;
148 }
149 
150 151 152 153 154 155 156 157 158 159 
160 function unaccent_compare($a, $b)
161 {
162     return strcmp(remove_accents($a), remove_accents($b));
163 }
164 
165 166 167 168 169 170 171 172 173 174 
175 function unaccent_compare_ci($a, $b)
176 {
177     return strcasecmp(remove_accents($a), remove_accents($b));
178 }
179 
180 181 182 183 184 185 186 187 188 189 190 191 
192 function normalize($str, $separator='-', $charset=CHARSET)
193 {
194     $str = str_replace('\'', '', $str);
195     $str = remove_accents($str, $charset);
196     $str = strtolower($str);
197     $str = preg_replace('#[^a-z0-9]+#', $separator, $str);
198     $str = trim($str, $separator);
199 
200     return $str;
201 }
202 
203 204 205 206 207 208 209 210 211 212 
213 function dump($value)
214 {
215     if (function_exists('xdebug_var_dump'))
216     {
217         ob_start();
218 
219         xdebug_var_dump($value);
220 
221         $value = ob_get_clean();
222     }
223     else
224     {
225         $value = '<pre>' . escape(print_r($value, true)) . '</pre>';
226     }
227 
228     return $value;
229 }
230 
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 
248 function format($str, array $args=array())
249 {
250     static $quotation_start;
251     static $quotation_end;
252 
253     if ($quotation_start === null)
254     {
255         if (PHP_SAPI == 'cli')
256         {
257             $quotation_start = '"';
258             $quotation_end = '"';
259         }
260         else
261         {
262             $quotation_start = '<q>';
263             $quotation_end = '</q>';
264         }
265     }
266 
267     if (!$args)
268     {
269         return $str;
270     }
271 
272     $holders = array();
273     $i = 0;
274 
275     foreach ($args as $key => $value)
276     {
277         if (is_object($value) && method_exists($value, '__toString'))
278         {
279             $value = (string) $value;
280         }
281 
282         if (is_array($value) || is_object($value))
283         {
284             $value = dump($value);
285         }
286         else if (is_bool($value))
287         {
288             $value = $value ? '<em>true</em>' : '<em>false</em>';
289         }
290         else if (is_null($value))
291         {
292             $value = '<em>null</em>';
293         }
294 
295         if (is_string($key))
296         {
297             switch ($key{0})
298             {
299                 case ':': break;
300                 case '!': $value = escape($value); break;
301                 case '%': $value = $quotation_start . escape($value) . $quotation_end; break;
302 
303                 default:
304                 {
305                     $escaped_value = escape($value);
306 
307                     $holders['!' . $key] = $escaped_value;
308                     $holders['%' . $key] = $quotation_start . $escaped_value . $quotation_end;
309 
310                     $key = ':' . $key;
311                 }
312             }
313         }
314 
315         $holders[$key] = $value;
316         $holders['\\' . $i] = $value;
317         $holders['{' . $i . '}'] = $value;
318 
319         $i++;
320     }
321 
322     return strtr($str, $holders);
323 }
324 
325 326 327 328 329 330 331 332 333 334 335 336 
337 function stable_sort(&$array, $picker=null)
338 {
339     static $transform, $restore;
340 
341     $i = 0;
342 
343     if (!$transform)
344     {
345         $transform = function(&$v, $k) use (&$i)
346         {
347             $v = array($v, ++$i, $k, $v);
348         };
349 
350         $restore = function(&$v, $k)
351         {
352             $v = $v[3];
353         };
354     }
355 
356     if ($picker)
357     {
358         array_walk
359         (
360             $array, function(&$v, $k) use (&$i, $picker)
361             {
362                 $v = array($picker($v, $k), ++$i, $k, $v);
363             }
364         );
365     }
366     else
367     {
368         array_walk($array, $transform);
369     }
370 
371     asort($array);
372 
373     array_walk($array, $restore);
374 }
375 
376 377 378 379 380 381 382 383 384 385 386 387 
388 function sort_by_weight(array $array, $weight_picker)
389 {
390     if (!$array)
391     {
392         return $array;
393     }
394 
395     $order = array();
396 
397     foreach ($array as $k => $v)
398     {
399         $order[$k] = $weight_picker($v, $k);
400     }
401 
402     $n = count($order);
403     $top = min($order) - $n;
404     $bottom = max($order) + $n;
405 
406     foreach ($order as &$weight)
407     {
408         if ($weight === 'top')
409         {
410             $weight = --$top;
411         }
412         else if ($weight === 'bottom')
413         {
414             $weight = ++$bottom;
415         }
416     }
417 
418     foreach ($order as $k => &$weight)
419     {
420         if (strpos($weight, 'before:') === 0)
421         {
422             $target = substr($weight, 7);
423 
424             if (isset($order[$target]))
425             {
426                 $order = array_insert($order, $target, $order[$target], $k);
427             }
428             else
429             {
430                 $weight = 0;
431             }
432         }
433         else if (strpos($weight, 'after:') === 0)
434         {
435             $target = substr($weight, 6);
436 
437             if (isset($order[$target]))
438             {
439                 $order = array_insert($order, $target, $order[$target], $k, true);
440             }
441             else
442             {
443                 $weight = 0;
444             }
445         }
446     }
447 
448     stable_sort($order);
449 
450     array_walk($order, function(&$v, $k) use($array) {
451 
452         $v = $array[$k];
453 
454     });
455 
456     return $order;
457 }
458 
459 460 461 462 463 464 465 466 467 468 469 470 471 
472 function array_insert($array, $relative, $value, $key=null, $after=false)
473 {
474     if ($key)
475     {
476         unset($array[$key]);
477     }
478 
479     $keys = array_keys($array);
480     $pos = array_search($relative, $keys, true);
481 
482     if ($after)
483     {
484         $pos++;
485     }
486 
487     $spliced = array_splice($array, $pos);
488 
489     if ($key !== null)
490     {
491         $array = array_merge($array, array($key => $value));
492     }
493     else
494     {
495         array_unshift($spliced, $value);
496     }
497 
498     return array_merge($array, $spliced);
499 }
500 
501 502 503 504 505 506 507 508 509 
510 function array_flatten($array, $separator='.', $depth=0)
511 {
512     $rc = array();
513 
514     if (is_array($separator))
515     {
516         foreach ($array as $key => $value)
517         {
518             if (!is_array($value))
519             {
520                 $rc[$key . ($depth ? $separator[1] : '')] = $value;
521 
522                 continue;
523             }
524 
525             $values = array_flatten($value, $separator, $depth + 1);
526 
527             foreach ($values as $vkey => $value)
528             {
529                 $rc[$key . ($depth ? $separator[1] : '') . $separator[0] . $vkey] = $value;
530             }
531         }
532     }
533     else
534     {
535         foreach ($array as $key => $value)
536         {
537             if (!is_array($value))
538             {
539                 $rc[$key] = $value;
540 
541                 continue;
542             }
543 
544             $values = array_flatten($value, $separator);
545 
546             foreach ($values as $vkey => $value)
547             {
548                 $rc[$key . $separator . $vkey] = $value;
549             }
550         }
551     }
552 
553     return $rc;
554 }
555 
556 557 558 559 560 561 562 563 
564 function array_merge_recursive(array $array1, array $array2=array())
565 {
566     $arrays = func_get_args();
567 
568     $merge = array_shift($arrays);
569 
570     foreach ($arrays as $array)
571     {
572         foreach ($array as $key => $val)
573         {
574             
575             
576             
577             
578 
579             if (is_array($val) && array_key_exists($key, $merge))
580             {
581                 $val = array_merge_recursive((array) $merge[$key], $val);
582             }
583 
584             
585             
586             
587             
588 
589             if (is_numeric($key))
590             {
591                 $merge[] = $val;
592             }
593             else
594             {
595                 $merge[$key] = $val;
596             }
597         }
598     }
599 
600     return $merge;
601 }
602 
603 function exact_array_merge_recursive(array $array1, array $array2=array())
604 {
605     $arrays = func_get_args();
606 
607     $merge = array_shift($arrays);
608 
609     foreach ($arrays as $array)
610     {
611         foreach ($array as $key => $val)
612         {
613             
614             
615             
616             
617 
618             if (is_array($val) && array_key_exists($key, $merge))
619             {
620                 $val = exact_array_merge_recursive((array) $merge[$key], $val);
621             }
622 
623             $merge[$key] = $val;
624         }
625     }
626 
627     return $merge;
628 }
629 
630 631 632 633 634 635 636 637 638 
639 function normalize_url_path($path)
640 {
641     static $cache = array();
642 
643     if (isset($cache[$path]))
644     {
645         return $cache[$path];
646     }
647 
648     $normalized = preg_replace('#\/index\.(html|php)$#', '/', $path);
649     $normalized = rtrim($normalized, '/');
650 
651     if (!preg_match('#\.[a-z]+$#', $normalized))
652     {
653         $normalized .= '/';
654     }
655 
656     $cache[$path] = $normalized;
657 
658     return $normalized;
659 }
660 
661 662 663 664 665 666 667 
668 function generate_v4_uuid()
669 {
670     $data = openssl_random_pseudo_bytes(16);
671     $data[6] = chr(ord($data[6]) & 0x0f | 0x40); 
672     $data[8] = chr(ord($data[8]) & 0x3f | 0x80); 
673     return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
674 }