PageRenderTime 35ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/Opl/Opt/Function.php

https://bitbucket.org/kandsten/hitta.sverok.se
PHP | 604 lines | 325 code | 44 blank | 235 comment | 54 complexity | c6e04621165d44f0656180fd1c7c39f5 MD5 | raw file
Possible License(s): GPL-3.0, MIT
  1. <?php
  2. /*
  3. * OPEN POWER LIBS <http://www.invenzzia.org>
  4. *
  5. * This file is subject to the new BSD license that is bundled
  6. * with this package in the file LICENSE. It is also available through
  7. * WWW at this URL: <http://www.invenzzia.org/license/new-bsd>
  8. *
  9. * Copyright (c) Invenzzia Group <http://www.invenzzia.org>
  10. * and other contributors. See website for details.
  11. *
  12. * $Id: Function.php 231 2009-09-19 07:13:14Z zyxist $
  13. */
  14. /**
  15. * A generic container for the template functions created for
  16. * the autoloader purporses only.
  17. */
  18. class Opt_Function
  19. {
  20. static private $_cycleIterator = 0;
  21. /**
  22. * The method allows to create aggregate functions that operate
  23. * on container. It calls the specified function for all the
  24. * container elements provided in the first function call
  25. * argument.
  26. *
  27. * @static
  28. * @param Callback $callback A valid function callback
  29. * @param Array $args The list of function arguments.
  30. * @return Container Processed container
  31. */
  32. static public function processContainer($callback, $args)
  33. {
  34. $result = array();
  35. foreach($args[0] as $idx => $value)
  36. {
  37. $args[0] = $value;
  38. $result[$idx] = call_user_func_array($callback, $args);
  39. }
  40. return $result;
  41. } // end processContainer();
  42. /**
  43. * Returns true, if the specified value is a valid OPT container.
  44. *
  45. * @static
  46. * @param Mixed $value The value to test.
  47. * @return Boolean True, if the value is really a container
  48. */
  49. static public function isContainer($value)
  50. {
  51. return is_array($value) || (is_object($value) && ($value instanceof Iterator || $value instanceof IteratorAggregate));
  52. } // end isContainer();
  53. /**
  54. * Returns the first non-empty argument.
  55. *
  56. * @static
  57. * @param mixed ... The arguments.
  58. * @return mixed The first non-empty argument
  59. */
  60. static public function firstof()
  61. {
  62. $args = func_get_args();
  63. $cnt = sizeof($args);
  64. for($i = 0; $i < $cnt; $i++)
  65. {
  66. if(!empty($args[$i]))
  67. {
  68. return $args[$i];
  69. }
  70. }
  71. } // end firstof();
  72. /**
  73. * Returns true, if the container contains the specified value.
  74. *
  75. * @static
  76. * @param string $item The container
  77. * @param mixed $value The value
  78. * @return True, if the value exists in the container.
  79. */
  80. static public function contains($item, $value)
  81. {
  82. if(is_array($item))
  83. {
  84. return in_array($value, $item);
  85. }
  86. elseif($item instanceof ArrayAccess && $item instanceof Traversable)
  87. {
  88. foreach($item as $r)
  89. {
  90. if($r === $value)
  91. {
  92. return true;
  93. }
  94. }
  95. }
  96. return false;
  97. } // end contains();
  98. /**
  99. * Returns true, if the container contains the specified key.
  100. *
  101. * @static
  102. * @param string $item The container
  103. * @param mixed $key The key
  104. * @return True, if the key exists in the container.
  105. */
  106. static public function containsKey($item, $key)
  107. {
  108. if(is_array($item) || $item instanceof ArrayAccess)
  109. {
  110. return isset($item[$key]);
  111. }
  112. return false;
  113. } // end containsKey();
  114. /**
  115. * Puts the specified string $delim between every two characters of $string.
  116. * By default, it puts spaces between the $string characters.
  117. *
  118. * @static
  119. * @param String|Container $string The string to be processed.
  120. * @param String $delim = ' ' Character delimiter.
  121. * @return String|Container The modified text.
  122. */
  123. static public function spacify($string, $delim = ' ')
  124. {
  125. if(self::isContainer($string))
  126. {
  127. return self::processContainer(array('Opt_Function', 'spacify'), array($string, $delim));
  128. }
  129. $ns = '';
  130. $len = strlen($string);
  131. $tpl = Opl_Registry::get('opt');
  132. for($i = 0; $i < $len; $i++)
  133. {
  134. if($tpl->charset == 'utf-8' && ord($string[$i]) > 127)
  135. {
  136. break;
  137. }
  138. $ns .= $string[$i];
  139. if($i + 1 < $len)
  140. {
  141. $ns .= $delim;
  142. }
  143. }
  144. return $ns;
  145. } // end spacify();
  146. /**
  147. * Makes an indentation to the specified string.
  148. *
  149. * @static
  150. * @param String|Container $string The source string or the container
  151. * @param Int $num The length of the indentation
  152. * @param String $with = ' ' The indent character
  153. * @return String|Container The modified string
  154. */
  155. static public function indent($string, $num, $with = ' ')
  156. {
  157. if(self::isContainer($string))
  158. {
  159. return self::processContainer(array('Opt_Function', 'indent'), array($string, $num, $with));
  160. }
  161. return preg_replace('/([\\r\\n]{1,2})/', '$1'.str_repeat($with, $num), $string);
  162. } // end indent();
  163. /**
  164. * Strips the groups of white characters in $string into a single space.
  165. *
  166. * @static
  167. * @param String|Container $string The source string or the container.
  168. * @return String|Container The modified string.
  169. */
  170. static public function strip($string)
  171. {
  172. if(self::isContainer($string))
  173. {
  174. return self::processContainer(array('Opt_Function', 'strip'), array($string));
  175. }
  176. return trim(preg_replace('/\s+/', ' ', $string));
  177. } // end strip();
  178. /**
  179. * Truncates the string or the container of strings to the specified length.
  180. * If the string was really shortened, appends the $etc to the end of it.
  181. * By default, the function can truncate a string in the middle of a word.
  182. * If you want to round the truncation to the whole words, change the default
  183. * value of the last argument to false.
  184. *
  185. * @static
  186. * @param String|Container $string The source string or the container of strings.
  187. * @param Int $length Truncate to the specified length.
  188. * @param String $etc = '' The extra string appended to the result, if it was really truncated.
  189. * @param Boolean $break = true Do we allow to break the words?
  190. * @return String|Container The modified string.
  191. */
  192. static public function truncate($string, $length, $etc = '', $break = true)
  193. {
  194. if(self::isContainer($string))
  195. {
  196. return self::processContainer(array('Opt_Function', 'truncate'), array($string, $length, $etc, $break));
  197. }
  198. if($length == 0)
  199. {
  200. return '';
  201. }
  202. $strlen = strlen($string);
  203. if($strlen > $length)
  204. {
  205. if(!$break)
  206. {
  207. $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length));
  208. }
  209. return substr($string, 0, $length).$etc;
  210. }
  211. return $string;
  212. } // end truncate();
  213. /**
  214. * Tries to break the string every specified number of characters.
  215. *
  216. * @param String $string The input string
  217. * @param Integer $width The width of a line
  218. * @param String $break The break string
  219. * @param Boolean $cut Whether to cut too long words
  220. * @return String
  221. */
  222. static public function wordwrap($string, $width, $break = '<br />', $cut = null)
  223. {
  224. if(!is_null($break))
  225. {
  226. $break = str_replace(array('\\n', '\\r', '\\t', '\\\\'), array("\n", "\r", "\t", '\\'), $break);
  227. }
  228. return wordwrap($string, $width, $break, $cut);
  229. } // end wordwrap();
  230. /**
  231. * Formats the input number to be a valid money amount string. The function is not available on
  232. * systems without strfmon capabilities (i.e. Microsoft Windows).
  233. *
  234. * @param Number $number The input number
  235. * @param String $format The format (if not specified, using locale settings)
  236. * @return String
  237. */
  238. static public function money($number, $format = null)
  239. {
  240. if(self::isContainer($number))
  241. {
  242. return self::processContainer(array('Opt_Function', 'money'), array($number, $format));
  243. }
  244. $opt = Opl_Registry::get('opt');
  245. $format = (is_null($format) ? $opt->moneyFormat : $format);
  246. return money_format($format, $number);
  247. } // end money();
  248. /**
  249. * Formats the input number to look nice in the text. If the extra arguments
  250. * are not present, they are taken from OPT configuration.
  251. *
  252. * @param Number $number The input number
  253. * @param Integer $d1 The number of decimals
  254. * @param String $d2 The decimal separator
  255. * @param String $d3 The thousand separator
  256. * @return String
  257. */
  258. static public function number($number, $d1 = null, $d2 = null, $d3 = null)
  259. {
  260. if(self::isContainer($number))
  261. {
  262. return self::processContainer(array('Opt_Function', 'number'), array($number, $d1, $d2, $d3));
  263. }
  264. $opt = Opl_Registry::get('opt');
  265. $d1 = (is_null($d1) ? $opt->numberDecimals : $d1);
  266. $d2 = (is_null($d2) ? $opt->numberDecPoint : $d2);
  267. $d3 = (is_null($d3) ? $opt->numberThousandSep : $d3);
  268. return number_format($number, $d1, $d2, $d3);
  269. } // end number();
  270. /**
  271. * Returns the absolute value of a number.
  272. *
  273. * @param Number|Container $items The input number of container of numbers
  274. * @return Number|Container
  275. */
  276. static public function absolute($items)
  277. {
  278. if(self::isContainer($items))
  279. {
  280. return self::processContainer('abs', array($items));
  281. }
  282. return abs($items);
  283. } // end absolute();
  284. /**
  285. * Sums all the numbers in the specified container.
  286. *
  287. * @param Container $items The container of numbers.
  288. * @return Number
  289. */
  290. static public function sum($items)
  291. {
  292. if(self::isContainer($items))
  293. {
  294. $sum = 0;
  295. foreach($items as $item)
  296. {
  297. if(!self::isContainer($item))
  298. {
  299. $sum += $item;
  300. }
  301. }
  302. return $sum;
  303. }
  304. return null;
  305. } // end sum();
  306. /**
  307. * Returns the average value of the numbers in a container.
  308. *
  309. * @param Container $items The container of numbers
  310. * @return Number
  311. */
  312. static public function average($items)
  313. {
  314. if(self::isContainer($items))
  315. {
  316. $sum = 0;
  317. $cnt = 0;
  318. foreach($items as $item)
  319. {
  320. if(!self::isContainer($item) && !is_null($item))
  321. {
  322. $sum += $item;
  323. $cnt++;
  324. }
  325. }
  326. if($cnt > 0)
  327. {
  328. return $sum / $cnt;
  329. }
  330. }
  331. return null;
  332. } // end average();
  333. /**
  334. * Returns the standard deviation of the numbers in a container.
  335. *
  336. * @param Container $items The container of numbers.
  337. * @return Number
  338. */
  339. static public function stddev($items)
  340. {
  341. $average = self::average($items);
  342. if(is_null($average))
  343. {
  344. return null;
  345. }
  346. $sum = 0;
  347. $cnt = 0;
  348. foreach($items as $item)
  349. {
  350. if(!self::isContainer($item) && !is_null($item))
  351. {
  352. $sum += pow($item - $average, 2);
  353. $cnt++;
  354. }
  355. }
  356. return sqrt(($sum / ($cnt - 1)));
  357. } // end stddev();
  358. /**
  359. * Replaces the lowercase characters in $item with the uppercase.
  360. *
  361. * @static
  362. * @param String|Container $item The string or the container.
  363. * @return String|Container The modified string
  364. */
  365. static public function upper($item)
  366. {
  367. if(self::isContainer($item))
  368. {
  369. return self::processContainer(array('Opt_Function', 'upper'), array($item));
  370. }
  371. return strtoupper($item);
  372. } // end upper();
  373. /**
  374. * Replaces the uppercase characters in $item with the lowercase.
  375. *
  376. * @static
  377. * @param String|Container $item The string or the container.
  378. * @return String|Container The modified string
  379. */
  380. static public function lower($item)
  381. {
  382. if(self::isContainer($item))
  383. {
  384. return self::processContainer(array('Opt_Function', 'lower'), array($item));
  385. }
  386. return strtolower($item);
  387. } // end lower();
  388. /**
  389. * Capitalizes the first character of $item.
  390. *
  391. * @static
  392. * @param String|Container $item The string or the container.
  393. * @return String|Container The modified string
  394. */
  395. static public function capitalize($item)
  396. {
  397. if(self::isContainer($item))
  398. {
  399. return self::processContainer(array('Opt_Function', 'capitalize'), array($item));
  400. }
  401. return ucfirst($item);
  402. } // end capitalize();
  403. /**
  404. * Changes the newline characters to the BR tag.
  405. *
  406. * @static
  407. * @param String|Container $item The string or the container.
  408. * @return String|Container The modified string
  409. */
  410. static public function nl2br($item)
  411. {
  412. if(self::isContainer($item))
  413. {
  414. return self::processContainer(array('Opt_Function', 'nl2br'), array($item));
  415. }
  416. return nl2br($item);
  417. } // end nl2br();
  418. /**
  419. * Removes the HTML tags from $item.
  420. *
  421. * @static
  422. * @param String|Container $item The string or the container.
  423. * @param String $what The list of allowable tags that must not be removed.
  424. * @return String|Container The modified string
  425. */
  426. static public function stripTags($item, $what = '')
  427. {
  428. if(self::isContainer($item))
  429. {
  430. return self::processContainer(array('Opt_Function', 'stripTags'), array($item, $what));
  431. }
  432. return strip_tags($item, $what);
  433. } // end stripTags();
  434. /**
  435. * Helps displaying a nice range between two numbers, if they are
  436. * not equal, i.e.: "5 - 10" or the number itself, if they are
  437. * equal. By default, the second number is evaluated as the current
  438. * year, which allows to create a range of years for the Copyright foot
  439. * at the bottom of the website.
  440. *
  441. * @static
  442. * @param Int $number1 Starting number
  443. * @param Int $number2=null Ending number
  444. * @return String The result string
  445. */
  446. static public function range($number1, $number2 = null)
  447. {
  448. if(is_null($number2))
  449. {
  450. $number2 = date('Y');
  451. }
  452. if($number2 == $number1)
  453. {
  454. return $number1;
  455. }
  456. return $number1.' - '.$number2;
  457. } // end range();
  458. /**
  459. * Returns true, if the specified string is a valid URL.
  460. *
  461. * @static
  462. * @param String $address The string to test.
  463. * @return Boolean True, if the specified string is a valid URL.
  464. */
  465. static public function isUrl($address)
  466. {
  467. return filter_var($address, FILTER_VALIDATE_URL) !== false;
  468. } // end isUrl();
  469. /**
  470. * Returns true, if the specified URL or file path points to the
  471. * image file. The recognition bases on the file extension and
  472. * currently recognizes JPG, PNG, GIF, SVG and BMP.
  473. *
  474. * @static
  475. * @param String $address The URL or filesystem path to test.
  476. * @return Boolean True, if the specified address points to an image.
  477. */
  478. static public function isImage($address)
  479. {
  480. $result = @parse_url($address);
  481. if(is_array($result))
  482. {
  483. if(isset($result['path']))
  484. {
  485. // Try to obtain the file extension
  486. if(($id = strrpos($result['path'], '.')) !== false)
  487. {
  488. if(in_array(substr($result['path'], $id+1, 3), array('jpg', 'png', 'gif', 'svg', 'bmp')))
  489. {
  490. return true;
  491. }
  492. }
  493. }
  494. }
  495. return false;
  496. } // end isImage();
  497. /**
  498. * Returns the next element of the specified list of items.
  499. *
  500. * @return Mixed
  501. */
  502. static public function cycle()
  503. {
  504. $items = func_get_args();
  505. if(is_array($items[0]))
  506. {
  507. $items = $items[0];
  508. }
  509. return ($items[(self::$_cycleIterator++) % sizeof($items) ]);
  510. } // end cycle();
  511. /**
  512. * Creates an entity for the specified string. If used with the 'u:' modifier,
  513. * it allows to display the entities in the output document.
  514. *
  515. * @static
  516. * @param String $name A valid entity name.
  517. * @return String
  518. */
  519. static public function entity($name)
  520. {
  521. if(!preg_match('/^(([a-zA-Z\_\:]{1}[a-zA-Z0-9\_\:\-\.]*)|(\#((x[a-fA-F0-9]+)|([0-9]+))))$/', $name))
  522. {
  523. throw new Opt_InvalidEntityName_Exception($name);
  524. }
  525. return '&'.$name.';';
  526. } // end entity();
  527. /**
  528. * Builds XML attributes from an array. The function allows to specify the
  529. * ignore list in either text- or array format.
  530. *
  531. * @param Array $attributes The list of attributes.
  532. * @param Mixed $ignoreList The list of ignored items.
  533. * @param String $prepend The string prepended to the attribute list.
  534. */
  535. static public function buildAttributes($attributes, $ignoreList = array(), $prepend = '')
  536. {
  537. if(is_string($ignoreList))
  538. {
  539. $ignoreList = explode(',', $ignoreList);
  540. array_walk($ignoreList, 'trim');
  541. }
  542. foreach($attributes as $name => $value)
  543. {
  544. if(!in_array($name, $ignoreList))
  545. {
  546. // Do not accept null values.
  547. if($value === null)
  548. {
  549. continue;
  550. }
  551. // If the name is correct...
  552. if(preg_match('/^([a-zA-Z0-9\.\_\-]+\:)?([a-zA-Z0-9\.\_\-]+)$/', $name))
  553. {
  554. $prepend .= ''.$name.'="'.htmlspecialchars($value).'" ';
  555. }
  556. }
  557. }
  558. return rtrim($prepend);
  559. } // end buildAttributes();
  560. } // end Opt_Function;