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

/helpers/class.string.php

https://github.com/robv/konnect
PHP | 283 lines | 237 code | 23 blank | 23 comment | 37 complexity | b78f10033c352470c05ac3c8d358b965 MD5 | raw file
  1. <?php
  2. class String
  3. {
  4. // Creates a friendly URL slug from a
  5. public static function clean($str, $replacer = '-')
  6. {
  7. $str = str_replace('%20', ' ', $str);
  8. $str = preg_replace('/[^a-z0-9 ' . $replacer . ']/i', ' ', $str);
  9. $str = strtolower(str_replace(' ', $replacer, trim($str)));
  10. $str = preg_replace('/\\' . $replacer . '+/', $replacer, $str);
  11. return $str;
  12. }
  13. public static function uc_slug($str, $replacer = '-', $original_seperator = '-')
  14. {
  15. $str = explode($original_seperator, $str);
  16. $str = array_map('ucwords', $str);
  17. return implode($replacer, $str);
  18. }
  19. // Formats a phone number as (xxx) xxx-xxxx or xxx-xxxx depending on the length.
  20. public static function format_phone($phone)
  21. {
  22. $phone = preg_replace("/[^0-9]/", '', $phone);
  23. if (strlen($phone) == 7)
  24. return preg_replace("/([0-9]{3})([0-9]{4})/", "$1-$2", $phone);
  25. elseif (strlen($phone) == 10)
  26. return preg_replace("/([0-9]{3})([0-9]{3})([0-9]{4})/", "($1) $2-$3", $phone);
  27. else
  28. return $phone;
  29. }
  30. // Converts a date/timestamp into the specified format
  31. public static function format_date($date = null, $format = null)
  32. {
  33. if (is_null($format))
  34. $format = 'Y-m-d H:i:s';
  35. if (is_null($date))
  36. $date = time();
  37. // if $date contains only numbers, treat it as a timestamp
  38. if (ctype_digit($date) === true)
  39. return date($format, $date);
  40. else
  41. return date($format, strtotime($date));
  42. }
  43. // Outputs a filesize in human readable format.
  44. public static function format_bytes($val, $round = 0)
  45. {
  46. $unit = array('','K','M','G','T','P','E','Z','Y');
  47. while ($val >= 1000)
  48. {
  49. $val /= 1024;
  50. array_shift($unit);
  51. }
  52. return round($val, $round) . array_shift($unit) . 'B';
  53. }
  54. // Ensures $str ends with a single /
  55. public static function slash($str)
  56. {
  57. return rtrim($str, '/') . '/';
  58. }
  59. // Ensures $str DOES NOT end with a /
  60. public static function unslash($str)
  61. {
  62. return rtrim($str, '/');
  63. }
  64. public static function strip_slashes($value)
  65. {
  66. return is_array($value) ? array_map(array('self', 'strip_slashes'), $value) : stripslashes($value);
  67. }
  68. public static function printr($var)
  69. {
  70. $output = print_r($var, true);
  71. $output = str_replace("\n", "<br>", $output);
  72. $output = str_replace(' ', '&nbsp;', $output);
  73. echo "<div style='font-family:courier;'>$output</div>";
  74. }
  75. /*
  76. usage:
  77. $a = array(array("id"=>10, "name"=>"joe"), array("id"=>11, "name"=>"bob"));
  78. $ids = array_pluck("id", $a); // == array(10,11)
  79. $names = array_pluck("name", $a); // == array("joe", "bob")
  80. works on non-keyed arrays also:
  81. $a = array(array(3,4), array(5,6));
  82. $col2 = array_pluck(1,$a); // == array(4,6) (grab 2nd column of data)
  83. */
  84. public static function array_pluck($key, $array)
  85. {
  86. if (is_array($key) || !is_array($array)) return array();
  87. $funct = create_function('$e', 'return is_array($e) && array_key_exists("'.$key.'",$e) ? $e["'. $key .'"] : null;');
  88. return array_map($funct, $array);
  89. }
  90. // Generates a random numerical / alpha string of the given length
  91. public static function random($length = 10)
  92. {
  93. $numbers = array(1,2,3,4,5,6,7,8,9,0);
  94. $alpha = 'q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m';
  95. $alphaup = strtoupper($alpha);
  96. $letters = explode(',',$alpha);
  97. $lettersup = explode(',',$alphaup);
  98. $characters = array_merge($numbers,$letters,$lettersup);
  99. $string = array_rand($characters,$length);
  100. $string = implode('',$string);
  101. return $string;
  102. }
  103. // Safely serialize and unserialize arrays, should be used in place of just serialize
  104. public static function safe_serialize($array)
  105. {
  106. return base64_encode(serialize($array));
  107. }
  108. public static function safe_unserialize($array)
  109. {
  110. return unserialize(base64_decode($array));
  111. }
  112. // Truncates a string to $max in length and add's $moretext to the end of it
  113. public static function truncate($string, $max, $more_text)
  114. {
  115. if (is_array($string))
  116. {
  117. return array_map(array($this, 'truncate'), $string);
  118. }
  119. else
  120. {
  121. if (strlen($string) > $max)
  122. {
  123. $max -= strlen($more_text);
  124. $new_string = strrev(strstr(strrev(substr($string,0,$max)), ' '));
  125. if ($new_string === '')
  126. $new_string = substr($string,0,$max);
  127. $new_string .= $more_text;
  128. $string = $new_string;
  129. }
  130. $string = String::balance_tags($string);
  131. return $string;
  132. }
  133. }
  134. // Useful when truncating, ensures html string does not leave tags open
  135. // Hideous but useful, TODO: Refactor balance tags function!
  136. public static function balance_tags($text) {
  137. $tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = '';
  138. # WP bug fix for comments - in case you REALLY meant to type '< !--'
  139. $text = str_replace('< !--', '< !--', $text);
  140. # WP bug fix for LOVE <3 (and other situations with '<' before a number)
  141. $text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
  142. while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex))
  143. {
  144. $newtext .= $tagqueue;
  145. $i = strpos($text,$regex[0]);
  146. $l = strlen($regex[0]);
  147. // clear the shifter
  148. $tagqueue = '';
  149. // Pop or Push
  150. if ($regex[1][0] == "/")
  151. { // End Tag
  152. $tag = strtolower(substr($regex[1],1));
  153. // if too many closing tags
  154. if ($stacksize <= 0)
  155. {
  156. $tag = '';
  157. //or close to be safe $tag = '/' . $tag;
  158. }
  159. // if stacktop value = tag close value then pop
  160. else if ($tagstack[$stacksize - 1] == $tag)
  161. { // found closing tag
  162. $tag = '</' . $tag . '>'; // Close Tag
  163. // Pop
  164. array_pop ($tagstack);
  165. $stacksize--;
  166. }
  167. else
  168. { // closing tag not at top, search for it
  169. for ($j=$stacksize-1;$j>=0;$j--)
  170. {
  171. if ($tagstack[$j] == $tag)
  172. {
  173. // add tag to tagqueue
  174. for ($k=$stacksize-1;$k>=$j;$k--)
  175. {
  176. $tagqueue .= '</' . array_pop ($tagstack) . '>';
  177. $stacksize--;
  178. }
  179. break;
  180. }
  181. }
  182. $tag = '';
  183. }
  184. }
  185. else
  186. {
  187. // Begin Tag
  188. $tag = strtolower($regex[1]);
  189. // Tag Cleaning
  190. // If self-closing or '', don't do anything.
  191. if ((substr($regex[2],-1) == '/') || ($tag == ''))
  192. {
  193. }
  194. // ElseIf it's a known single-entity tag but it doesn't close itself, do so
  195. elseif ($tag == 'br' || $tag == 'img' || $tag == 'hr' || $tag == 'input')
  196. {
  197. $regex[2] .= '/';
  198. }
  199. else
  200. { // Push the tag onto the stack
  201. // If the top of the stack is the same as the tag we want to push, close previous tag
  202. if (($stacksize > 0) && ($tag != 'div') && ($tagstack[$stacksize - 1] == $tag))
  203. {
  204. $tagqueue = '</' . array_pop ($tagstack) . '>';
  205. $stacksize--;
  206. }
  207. $stacksize = array_push ($tagstack, $tag);
  208. }
  209. // Attributes
  210. $attributes = $regex[2];
  211. if ($attributes)
  212. {
  213. $attributes = ' '.$attributes;
  214. }
  215. $tag = '<'.$tag.$attributes.'>';
  216. //If already queuing a close tag, then put this tag on, too
  217. if ($tagqueue)
  218. {
  219. $tagqueue .= $tag;
  220. $tag = '';
  221. }
  222. }
  223. $newtext .= substr($text,0,$i) . $tag;
  224. $text = substr($text,$i+$l);
  225. }
  226. // Clear Tag Queue
  227. $newtext .= $tagqueue;
  228. // Add Remaining text
  229. $newtext .= $text;
  230. // Empty Stack
  231. while ($x = array_pop($tagstack))
  232. {
  233. $newtext .= '</' . $x . '>'; // Add remaining tags to close
  234. }
  235. // WP fix for the bug with HTML comments
  236. $newtext = str_replace("< !--","<!--",$newtext);
  237. $newtext = str_replace("< !--","< !--",$newtext);
  238. return $newtext;
  239. }
  240. }