PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/oiclient/data/symfony/util/sfToolkit.class.php

http://openirudi.googlecode.com/
PHP | 816 lines | 535 code | 73 blank | 208 comment | 114 complexity | 3d1430cdd191f07a13cce6c9537536c9 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. * (c) 2004-2006 Sean Kerr <sean@code-box.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * sfToolkit provides basic utility methods.
  12. *
  13. * @package symfony
  14. * @subpackage util
  15. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  16. * @author Sean Kerr <sean@code-box.org>
  17. * @version SVN: $Id: sfToolkit.class.php 10833 2008-08-13 11:33:13Z fabien $
  18. */
  19. class sfToolkit
  20. {
  21. /**
  22. * Extract the class or interface name from filename.
  23. *
  24. * @param string $filename A filename.
  25. *
  26. * @return string A class or interface name, if one can be extracted, otherwise null.
  27. */
  28. public static function extractClassName($filename)
  29. {
  30. $retval = null;
  31. if (self::isPathAbsolute($filename))
  32. {
  33. $filename = basename($filename);
  34. }
  35. $pattern = '/(.*?)\.(class|interface)\.php/i';
  36. if (preg_match($pattern, $filename, $match))
  37. {
  38. $retval = $match[1];
  39. }
  40. return $retval;
  41. }
  42. /**
  43. * Clear all files in a given directory.
  44. *
  45. * @param string $directory An absolute filesystem path to a directory.
  46. */
  47. public static function clearDirectory($directory)
  48. {
  49. if (!is_dir($directory))
  50. {
  51. return;
  52. }
  53. // open a file point to the cache dir
  54. $fp = opendir($directory);
  55. // ignore names
  56. $ignore = array('.', '..', 'CVS', '.svn');
  57. while (($file = readdir($fp)) !== false)
  58. {
  59. if (!in_array($file, $ignore))
  60. {
  61. if (is_link($directory.'/'.$file))
  62. {
  63. // delete symlink
  64. unlink($directory.'/'.$file);
  65. }
  66. else if (is_dir($directory.'/'.$file))
  67. {
  68. // recurse through directory
  69. self::clearDirectory($directory.'/'.$file);
  70. // delete the directory
  71. rmdir($directory.'/'.$file);
  72. }
  73. else
  74. {
  75. // delete the file
  76. unlink($directory.'/'.$file);
  77. }
  78. }
  79. }
  80. // close file pointer
  81. closedir($fp);
  82. }
  83. /**
  84. * Clear all files and directories corresponding to a glob pattern.
  85. *
  86. * @param string $pattern An absolute filesystem pattern.
  87. */
  88. public static function clearGlob($pattern)
  89. {
  90. $files = glob($pattern);
  91. // order is important when removing directories
  92. sort($files);
  93. foreach ($files as $file)
  94. {
  95. if (is_dir($file))
  96. {
  97. // delete directory
  98. self::clearDirectory($file);
  99. }
  100. else
  101. {
  102. // delete file
  103. unlink($file);
  104. }
  105. }
  106. }
  107. /**
  108. * Determine if a filesystem path is absolute.
  109. *
  110. * @param path $path A filesystem path.
  111. *
  112. * @return bool true, if the path is absolute, otherwise false.
  113. */
  114. public static function isPathAbsolute($path)
  115. {
  116. if ($path[0] == '/' || $path[0] == '\\' ||
  117. (strlen($path) > 3 && ctype_alpha($path[0]) &&
  118. $path[1] == ':' &&
  119. ($path[2] == '\\' || $path[2] == '/')
  120. )
  121. )
  122. {
  123. return true;
  124. }
  125. return false;
  126. }
  127. /**
  128. * Determine if a lock file is present.
  129. *
  130. * @param string $lockFile Name of the lock file.
  131. * @param integer $maxLockFileLifeTime A max amount of life time for the lock file.
  132. *
  133. * @return bool true, if the lock file is present, otherwise false.
  134. */
  135. public static function hasLockFile($lockFile, $maxLockFileLifeTime = 0)
  136. {
  137. $isLocked = false;
  138. if (is_readable($lockFile) && ($last_access = fileatime($lockFile)))
  139. {
  140. $now = time();
  141. $timeDiff = $now - $last_access;
  142. if (!$maxLockFileLifeTime || $timeDiff < $maxLockFileLifeTime)
  143. {
  144. $isLocked = true;
  145. }
  146. else
  147. {
  148. $isLocked = @unlink($lockFile) ? false : true;
  149. }
  150. }
  151. return $isLocked;
  152. }
  153. /**
  154. * Strips comments from php source code
  155. *
  156. * @param string $source PHP source code.
  157. *
  158. * @return string Comment free source code.
  159. */
  160. public static function stripComments($source)
  161. {
  162. if (!sfConfig::get('sf_strip_comments', true) || !function_exists('token_get_all'))
  163. {
  164. return $source;
  165. }
  166. $output = '';
  167. $tokens = token_get_all($source);
  168. foreach ($tokens as $token)
  169. {
  170. if (is_string($token))
  171. {
  172. // simple 1-character token
  173. $output .= $token;
  174. }
  175. else
  176. {
  177. // token array
  178. list($id, $text) = $token;
  179. switch ($id)
  180. {
  181. case T_COMMENT:
  182. case T_DOC_COMMENT:
  183. // no action on comments
  184. break;
  185. default:
  186. // anything else -> output "as is"
  187. $output .= $text;
  188. break;
  189. }
  190. }
  191. }
  192. return $output;
  193. }
  194. /**
  195. * Strip slashes recursively from array
  196. *
  197. * @param array $value the value to strip
  198. *
  199. * @return array clean value with slashes stripped
  200. */
  201. public static function stripslashesDeep($value)
  202. {
  203. return is_array($value) ? array_map(array('sfToolkit', 'stripslashesDeep'), $value) : stripslashes($value);
  204. }
  205. // code from php at moechofe dot com (array_merge comment on php.net)
  206. /*
  207. * array arrayDeepMerge ( array array1 [, array array2 [, array ...]] )
  208. *
  209. * Like array_merge
  210. *
  211. * arrayDeepMerge() merges the elements of one or more arrays together so
  212. * that the values of one are appended to the end of the previous one. It
  213. * returns the resulting array.
  214. * If the input arrays have the same string keys, then the later value for
  215. * that key will overwrite the previous one. If, however, the arrays contain
  216. * numeric keys, the later value will not overwrite the original value, but
  217. * will be appended.
  218. * If only one array is given and the array is numerically indexed, the keys
  219. * get reindexed in a continuous way.
  220. *
  221. * Different from array_merge
  222. * If string keys have arrays for values, these arrays will merge recursively.
  223. */
  224. public static function arrayDeepMerge()
  225. {
  226. switch (func_num_args())
  227. {
  228. case 0:
  229. return false;
  230. case 1:
  231. return func_get_arg(0);
  232. case 2:
  233. $args = func_get_args();
  234. $args[2] = array();
  235. if (is_array($args[0]) && is_array($args[1]))
  236. {
  237. foreach (array_unique(array_merge(array_keys($args[0]),array_keys($args[1]))) as $key)
  238. {
  239. $isKey0 = array_key_exists($key, $args[0]);
  240. $isKey1 = array_key_exists($key, $args[1]);
  241. if ($isKey0 && $isKey1 && is_array($args[0][$key]) && is_array($args[1][$key]))
  242. {
  243. $args[2][$key] = self::arrayDeepMerge($args[0][$key], $args[1][$key]);
  244. }
  245. else if ($isKey0 && $isKey1)
  246. {
  247. $args[2][$key] = $args[1][$key];
  248. }
  249. else if (!$isKey1)
  250. {
  251. $args[2][$key] = $args[0][$key];
  252. }
  253. else if (!$isKey0)
  254. {
  255. $args[2][$key] = $args[1][$key];
  256. }
  257. }
  258. return $args[2];
  259. }
  260. else
  261. {
  262. return $args[1];
  263. }
  264. default :
  265. $args = func_get_args();
  266. $args[1] = sfToolkit::arrayDeepMerge($args[0], $args[1]);
  267. array_shift($args);
  268. return call_user_func_array(array('sfToolkit', 'arrayDeepMerge'), $args);
  269. break;
  270. }
  271. }
  272. /**
  273. * Converts string to array
  274. *
  275. * @param string $string the value to convert to array
  276. *
  277. * @return array
  278. */
  279. public static function stringToArray($string)
  280. {
  281. preg_match_all('/
  282. \s*(\w+) # key \\1
  283. \s*=\s* # =
  284. (\'|")? # values may be included in \' or " \\2
  285. (.*?) # value \\3
  286. (?(2) \\2) # matching \' or " if needed \\4
  287. \s*(?:
  288. (?=\w+\s*=) | \s*$ # followed by another key= or the end of the string
  289. )
  290. /x', $string, $matches, PREG_SET_ORDER);
  291. $attributes = array();
  292. foreach ($matches as $val)
  293. {
  294. $attributes[$val[1]] = self::literalize($val[3]);
  295. }
  296. return $attributes;
  297. }
  298. /**
  299. * Finds the type of the passed value, returns the value as the new type.
  300. *
  301. * @param string $value
  302. * @param bool $quoted Quote?
  303. *
  304. * @return mixed
  305. */
  306. public static function literalize($value, $quoted = false)
  307. {
  308. // lowercase our value for comparison
  309. $value = trim($value);
  310. $lvalue = strtolower($value);
  311. if (in_array($lvalue, array('null', '~', '')))
  312. {
  313. $value = null;
  314. }
  315. else if (in_array($lvalue, array('true', 'on', '+', 'yes')))
  316. {
  317. $value = true;
  318. }
  319. else if (in_array($lvalue, array('false', 'off', '-', 'no')))
  320. {
  321. $value = false;
  322. }
  323. else if (ctype_digit($value))
  324. {
  325. $value = (int) $value;
  326. }
  327. else if (is_numeric($value))
  328. {
  329. $value = (float) $value;
  330. }
  331. else
  332. {
  333. $value = self::replaceConstants($value);
  334. if ($quoted)
  335. {
  336. $value = '\''.str_replace('\'', '\\\'', $value).'\'';
  337. }
  338. }
  339. return $value;
  340. }
  341. /**
  342. * Replaces constant identifiers in a scalar value.
  343. *
  344. * @param string $value the value to perform the replacement on
  345. *
  346. * @return string the value with substitutions made
  347. */
  348. public static function replaceConstants($value)
  349. {
  350. return is_string($value) ? preg_replace_callback('/%(.+?)%/', create_function('$v', 'return sfConfig::has(strtolower($v[1])) ? sfConfig::get(strtolower($v[1])) : "%{$v[1]}%";'), $value) : $value;
  351. }
  352. /**
  353. * Returns subject replaced with regular expression matchs
  354. *
  355. * @param mixed $search subject to search
  356. * @param array $replacePairs array of search => replace pairs
  357. */
  358. public static function pregtr($search, $replacePairs)
  359. {
  360. return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search);
  361. }
  362. /**
  363. * Checks if array values are empty
  364. *
  365. * @param array $array the array to check
  366. * @return boolean true if empty, otherwise false
  367. */
  368. public static function isArrayValuesEmpty($array)
  369. {
  370. static $isEmpty = true;
  371. foreach ($array as $value)
  372. {
  373. $isEmpty = (is_array($value)) ? self::isArrayValuesEmpty($value) : (strlen($value) == 0);
  374. if (!$isEmpty)
  375. {
  376. break;
  377. }
  378. }
  379. return $isEmpty;
  380. }
  381. /**
  382. * Checks if a string is an utf8.
  383. *
  384. * Yi Stone Li<yili@yahoo-inc.com>
  385. * Copyright (c) 2007 Yahoo! Inc. All rights reserved.
  386. * Licensed under the BSD open source license
  387. *
  388. * @param string
  389. *
  390. * @return bool true if $string is valid UTF-8 and false otherwise.
  391. */
  392. public static function isUTF8($string)
  393. {
  394. for ($idx = 0, $strlen = strlen($string); $idx < $strlen; $idx++)
  395. {
  396. $byte = ord($string[$idx]);
  397. if ($byte & 0x80)
  398. {
  399. if (($byte & 0xE0) == 0xC0)
  400. {
  401. // 2 byte char
  402. $bytes_remaining = 1;
  403. }
  404. else if (($byte & 0xF0) == 0xE0)
  405. {
  406. // 3 byte char
  407. $bytes_remaining = 2;
  408. }
  409. else if (($byte & 0xF8) == 0xF0)
  410. {
  411. // 4 byte char
  412. $bytes_remaining = 3;
  413. }
  414. else
  415. {
  416. return false;
  417. }
  418. if ($idx + $bytes_remaining >= $strlen)
  419. {
  420. return false;
  421. }
  422. while ($bytes_remaining--)
  423. {
  424. if ((ord($string[++$idx]) & 0xC0) != 0x80)
  425. {
  426. return false;
  427. }
  428. }
  429. }
  430. }
  431. return true;
  432. }
  433. /**
  434. * Returns a reference to an array value for a path.
  435. *
  436. * @param array $values The values to search
  437. * @param string $name The token name
  438. * @param array $default Default if not found
  439. *
  440. * @return array reference
  441. */
  442. public static function &getArrayValueForPathByRef(&$values, $name, $default = null)
  443. {
  444. if (false === $offset = strpos($name, '['))
  445. {
  446. $return = $default;
  447. if (isset($values[$name]))
  448. {
  449. $return = &$values[$name];
  450. }
  451. return $return;
  452. }
  453. if (!isset($values[substr($name, 0, $offset)]))
  454. {
  455. return $default;
  456. }
  457. $array = &$values[substr($name, 0, $offset)];
  458. while (false !== $pos = strpos($name, '[', $offset))
  459. {
  460. $end = strpos($name, ']', $pos);
  461. if ($end == $pos + 1)
  462. {
  463. // reached a []
  464. if (!is_array($array))
  465. {
  466. return $default;
  467. }
  468. break;
  469. }
  470. else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
  471. {
  472. return $default;
  473. }
  474. else if (is_array($array))
  475. {
  476. $array = &$array[substr($name, $pos + 1, $end - $pos - 1)];
  477. $offset = $end;
  478. }
  479. else
  480. {
  481. return $default;
  482. }
  483. }
  484. return $array;
  485. }
  486. /**
  487. * Returns an array value for a path.
  488. *
  489. * @param array $values The values to search
  490. * @param string $name The token name
  491. * @param array $default Default if not found
  492. *
  493. * @return array
  494. */
  495. public static function getArrayValueForPath($values, $name, $default = null)
  496. {
  497. if (false === $offset = strpos($name, '['))
  498. {
  499. return isset($values[$name]) ? $values[$name] : $default;
  500. }
  501. if (!isset($values[substr($name, 0, $offset)]))
  502. {
  503. return $default;
  504. }
  505. $array = $values[substr($name, 0, $offset)];
  506. while (false !== $pos = strpos($name, '[', $offset))
  507. {
  508. $end = strpos($name, ']', $pos);
  509. if ($end == $pos + 1)
  510. {
  511. // reached a []
  512. if (!is_array($array))
  513. {
  514. return $default;
  515. }
  516. break;
  517. }
  518. else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
  519. {
  520. return $default;
  521. }
  522. else if (is_array($array))
  523. {
  524. $array = $array[substr($name, $pos + 1, $end - $pos - 1)];
  525. $offset = $end;
  526. }
  527. else
  528. {
  529. return $default;
  530. }
  531. }
  532. return $array;
  533. }
  534. /**
  535. * Returns true if the a path exists for the given array.
  536. *
  537. * @param array $values The values to search
  538. * @param string $name The token name
  539. *
  540. * @return bool
  541. */
  542. public static function hasArrayValueForPath($values, $name)
  543. {
  544. if (false === $offset = strpos($name, '['))
  545. {
  546. return array_key_exists($name, $values);
  547. }
  548. if (!isset($values[substr($name, 0, $offset)]))
  549. {
  550. return false;
  551. }
  552. $array = $values[substr($name, 0, $offset)];
  553. while (false !== $pos = strpos($name, '[', $offset))
  554. {
  555. $end = strpos($name, ']', $pos);
  556. if ($end == $pos + 1)
  557. {
  558. // reached a []
  559. return is_array($array);
  560. }
  561. else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
  562. {
  563. return false;
  564. }
  565. else if (is_array($array))
  566. {
  567. $array = $array[substr($name, $pos + 1, $end - $pos - 1)];
  568. $offset = $end;
  569. }
  570. else
  571. {
  572. return false;
  573. }
  574. }
  575. return true;
  576. }
  577. /**
  578. * Removes a path for the given array.
  579. *
  580. * @param array $values The values to search
  581. * @param string $name The token name
  582. * @param mixed $default The default value to return if the name does not exist
  583. */
  584. public static function removeArrayValueForPath(&$values, $name, $default = null)
  585. {
  586. if (false === $offset = strpos($name, '['))
  587. {
  588. if (isset($values[$name]))
  589. {
  590. $value = $values[$name];
  591. unset($values[$name]);
  592. return $value;
  593. }
  594. else
  595. {
  596. return $default;
  597. }
  598. }
  599. if (!isset($values[substr($name, 0, $offset)]))
  600. {
  601. return $default;
  602. }
  603. $value = &$values[substr($name, 0, $offset)];
  604. while (false !== $pos = strpos($name, '[', $offset))
  605. {
  606. $end = strpos($name, ']', $pos);
  607. if ($end == $pos + 1)
  608. {
  609. // reached a []
  610. if (!is_array($value))
  611. {
  612. return $default;
  613. }
  614. break;
  615. }
  616. else if (!isset($value[substr($name, $pos + 1, $end - $pos - 1)]))
  617. {
  618. return $default;
  619. }
  620. else if (is_array($value))
  621. {
  622. $parent = &$value;
  623. $key = substr($name, $pos + 1, $end - $pos - 1);
  624. $value = &$value[$key];
  625. $offset = $end;
  626. }
  627. else
  628. {
  629. return $default;
  630. }
  631. }
  632. if ($key)
  633. {
  634. unset($parent[$key]);
  635. }
  636. return $value;
  637. }
  638. /**
  639. * Get path to php cli.
  640. *
  641. * @throws sfException If no php cli found
  642. * @return string
  643. */
  644. public static function getPhpCli()
  645. {
  646. $path = getenv('PATH') ? getenv('PATH') : getenv('Path');
  647. $suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe', '.bat', '.cmd', '.com')) : array('');
  648. foreach (array('php5', 'php') as $phpCli)
  649. {
  650. foreach ($suffixes as $suffix)
  651. {
  652. foreach (explode(PATH_SEPARATOR, $path) as $dir)
  653. {
  654. $file = $dir.DIRECTORY_SEPARATOR.$phpCli.$suffix;
  655. if (is_executable($file))
  656. {
  657. return $file;
  658. }
  659. }
  660. }
  661. }
  662. throw new sfException('Unable to find PHP executable.');
  663. }
  664. /**
  665. * From PEAR System.php
  666. *
  667. * LICENSE: This source file is subject to version 3.0 of the PHP license
  668. * that is available through the world-wide-web at the following URI:
  669. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  670. * the PHP License and are unable to obtain it through the web, please
  671. * send a note to license@php.net so we can mail you a copy immediately.
  672. *
  673. * @author Tomas V.V.Cox <cox@idecnet.com>
  674. * @copyright 1997-2006 The PHP Group
  675. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  676. */
  677. public static function getTmpDir()
  678. {
  679. if (DIRECTORY_SEPARATOR == '\\')
  680. {
  681. if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP'))
  682. {
  683. return $var;
  684. }
  685. if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP'))
  686. {
  687. return $var;
  688. }
  689. if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir'))
  690. {
  691. return $var;
  692. }
  693. return getenv('SystemRoot').'\temp';
  694. }
  695. if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR'))
  696. {
  697. return $var;
  698. }
  699. return '/tmp';
  700. }
  701. /**
  702. * Converts strings to UTF-8 via iconv. NB, the result may not by UTF-8 if the conversion failed.
  703. *
  704. * This file comes from Prado (BSD License)
  705. *
  706. * @param string $string string to convert to UTF-8
  707. * @param string $from current encoding
  708. *
  709. * @return string UTF-8 encoded string, original string if iconv failed.
  710. */
  711. static public function I18N_toUTF8($string, $from)
  712. {
  713. $from = strtoupper($from);
  714. if ($from != 'UTF-8')
  715. {
  716. $s = iconv($from,'UTF-8',$string); // to UTF-8
  717. return $s !== false ? $s : $string; // it could return false
  718. }
  719. return $string;
  720. }
  721. /**
  722. * Converts UTF-8 strings to a different encoding. NB. The result may not have been encoded if iconv fails.
  723. *
  724. * This file comes from Prado (BSD License)
  725. *
  726. * @param string $string the UTF-8 string for conversion
  727. * @param string $to new encoding
  728. *
  729. * @return string encoded string.
  730. */
  731. static public function I18N_toEncoding($string, $to)
  732. {
  733. $to = strtoupper($to);
  734. if ($to != 'UTF-8')
  735. {
  736. $s = iconv('UTF-8', $to, $string);
  737. return $s !== false ? $s : $string;
  738. }
  739. return $string;
  740. }
  741. }