sfToolkit.class.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  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 14169 2008-12-18 10:13:51Z FabianLange $
  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. $ignore = array(T_COMMENT => true, T_DOC_COMMENT => true);
  167. $output = '';
  168. foreach (token_get_all($source) as $token) {
  169. // array
  170. if (isset($token[1])) {
  171. // no action on comments
  172. if (!isset($ignore[$token[0]])) {
  173. // anything else -> output "as is"
  174. $output .= $token[1];
  175. }
  176. } else {
  177. // simple 1-character token
  178. $output .= $token;
  179. }
  180. }
  181. return $output;
  182. }
  183. /**
  184. * Strip slashes recursively from array
  185. *
  186. * @param array $value the value to strip
  187. *
  188. * @return array clean value with slashes stripped
  189. */
  190. public static function stripslashesDeep($value)
  191. {
  192. return is_array($value) ? array_map(array('sfToolkit', 'stripslashesDeep'), $value) : stripslashes($value);
  193. }
  194. // code from php at moechofe dot com (array_merge comment on php.net)
  195. /*
  196. * array arrayDeepMerge ( array array1 [, array array2 [, array ...]] )
  197. *
  198. * Like array_merge
  199. *
  200. * arrayDeepMerge() merges the elements of one or more arrays together so
  201. * that the values of one are appended to the end of the previous one. It
  202. * returns the resulting array.
  203. * If the input arrays have the same string keys, then the later value for
  204. * that key will overwrite the previous one. If, however, the arrays contain
  205. * numeric keys, the later value will not overwrite the original value, but
  206. * will be appended.
  207. * If only one array is given and the array is numerically indexed, the keys
  208. * get reindexed in a continuous way.
  209. *
  210. * Different from array_merge
  211. * If string keys have arrays for values, these arrays will merge recursively.
  212. */
  213. public static function arrayDeepMerge()
  214. {
  215. switch (func_num_args())
  216. {
  217. case 0:
  218. return false;
  219. case 1:
  220. return func_get_arg(0);
  221. case 2:
  222. $args = func_get_args();
  223. $args[2] = array();
  224. if (is_array($args[0]) && is_array($args[1]))
  225. {
  226. foreach (array_unique(array_merge(array_keys($args[0]),array_keys($args[1]))) as $key)
  227. {
  228. $isKey0 = array_key_exists($key, $args[0]);
  229. $isKey1 = array_key_exists($key, $args[1]);
  230. if ($isKey0 && $isKey1 && is_array($args[0][$key]) && is_array($args[1][$key]))
  231. {
  232. $args[2][$key] = self::arrayDeepMerge($args[0][$key], $args[1][$key]);
  233. }
  234. else if ($isKey0 && $isKey1)
  235. {
  236. $args[2][$key] = $args[1][$key];
  237. }
  238. else if (!$isKey1)
  239. {
  240. $args[2][$key] = $args[0][$key];
  241. }
  242. else if (!$isKey0)
  243. {
  244. $args[2][$key] = $args[1][$key];
  245. }
  246. }
  247. return $args[2];
  248. }
  249. else
  250. {
  251. return $args[1];
  252. }
  253. default :
  254. $args = func_get_args();
  255. $args[1] = sfToolkit::arrayDeepMerge($args[0], $args[1]);
  256. array_shift($args);
  257. return call_user_func_array(array('sfToolkit', 'arrayDeepMerge'), $args);
  258. break;
  259. }
  260. }
  261. /**
  262. * Converts string to array
  263. *
  264. * @param string $string the value to convert to array
  265. *
  266. * @return array
  267. */
  268. public static function stringToArray($string)
  269. {
  270. preg_match_all('/
  271. \s*(\w+) # key \\1
  272. \s*=\s* # =
  273. (\'|")? # values may be included in \' or " \\2
  274. (.*?) # value \\3
  275. (?(2) \\2) # matching \' or " if needed \\4
  276. \s*(?:
  277. (?=\w+\s*=) | \s*$ # followed by another key= or the end of the string
  278. )
  279. /x', $string, $matches, PREG_SET_ORDER);
  280. $attributes = array();
  281. foreach ($matches as $val)
  282. {
  283. $attributes[$val[1]] = self::literalize($val[3]);
  284. }
  285. return $attributes;
  286. }
  287. /**
  288. * Finds the type of the passed value, returns the value as the new type.
  289. *
  290. * @param string $value
  291. * @param bool $quoted Quote?
  292. *
  293. * @return mixed
  294. */
  295. public static function literalize($value, $quoted = false)
  296. {
  297. // lowercase our value for comparison
  298. $value = trim($value);
  299. $lvalue = strtolower($value);
  300. if (in_array($lvalue, array('null', '~', '')))
  301. {
  302. $value = null;
  303. }
  304. else if (in_array($lvalue, array('true', 'on', '+', 'yes')))
  305. {
  306. $value = true;
  307. }
  308. else if (in_array($lvalue, array('false', 'off', '-', 'no')))
  309. {
  310. $value = false;
  311. }
  312. else if (ctype_digit($value))
  313. {
  314. $value = (int) $value;
  315. }
  316. else if (is_numeric($value))
  317. {
  318. $value = (float) $value;
  319. }
  320. else
  321. {
  322. $value = self::replaceConstants($value);
  323. if ($quoted)
  324. {
  325. $value = '\''.str_replace('\'', '\\\'', $value).'\'';
  326. }
  327. }
  328. return $value;
  329. }
  330. /**
  331. * Replaces constant identifiers in a scalar value.
  332. *
  333. * @param string $value the value to perform the replacement on
  334. *
  335. * @return string the value with substitutions made
  336. */
  337. public static function replaceConstants($value)
  338. {
  339. 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;
  340. }
  341. /**
  342. * Returns subject replaced with regular expression matchs
  343. *
  344. * @param mixed $search subject to search
  345. * @param array $replacePairs array of search => replace pairs
  346. */
  347. public static function pregtr($search, $replacePairs)
  348. {
  349. return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search);
  350. }
  351. /**
  352. * Checks if array values are empty
  353. *
  354. * @param array $array the array to check
  355. * @return boolean true if empty, otherwise false
  356. */
  357. public static function isArrayValuesEmpty($array)
  358. {
  359. static $isEmpty = true;
  360. foreach ($array as $value)
  361. {
  362. $isEmpty = (is_array($value)) ? self::isArrayValuesEmpty($value) : (strlen($value) == 0);
  363. if (!$isEmpty)
  364. {
  365. break;
  366. }
  367. }
  368. return $isEmpty;
  369. }
  370. /**
  371. * Checks if a string is an utf8.
  372. *
  373. * Yi Stone Li<yili@yahoo-inc.com>
  374. * Copyright (c) 2007 Yahoo! Inc. All rights reserved.
  375. * Licensed under the BSD open source license
  376. *
  377. * @param string
  378. *
  379. * @return bool true if $string is valid UTF-8 and false otherwise.
  380. */
  381. public static function isUTF8($string)
  382. {
  383. for ($idx = 0, $strlen = strlen($string); $idx < $strlen; $idx++)
  384. {
  385. $byte = ord($string[$idx]);
  386. if ($byte & 0x80)
  387. {
  388. if (($byte & 0xE0) == 0xC0)
  389. {
  390. // 2 byte char
  391. $bytes_remaining = 1;
  392. }
  393. else if (($byte & 0xF0) == 0xE0)
  394. {
  395. // 3 byte char
  396. $bytes_remaining = 2;
  397. }
  398. else if (($byte & 0xF8) == 0xF0)
  399. {
  400. // 4 byte char
  401. $bytes_remaining = 3;
  402. }
  403. else
  404. {
  405. return false;
  406. }
  407. if ($idx + $bytes_remaining >= $strlen)
  408. {
  409. return false;
  410. }
  411. while ($bytes_remaining--)
  412. {
  413. if ((ord($string[++$idx]) & 0xC0) != 0x80)
  414. {
  415. return false;
  416. }
  417. }
  418. }
  419. }
  420. return true;
  421. }
  422. /**
  423. * Returns a reference to an array value for a path.
  424. *
  425. * @param array $values The values to search
  426. * @param string $name The token name
  427. * @param array $default Default if not found
  428. *
  429. * @return array reference
  430. */
  431. public static function &getArrayValueForPathByRef(&$values, $name, $default = null)
  432. {
  433. if (false === $offset = strpos($name, '['))
  434. {
  435. $return = $default;
  436. if (isset($values[$name]))
  437. {
  438. $return = &$values[$name];
  439. }
  440. return $return;
  441. }
  442. if (!isset($values[substr($name, 0, $offset)]))
  443. {
  444. return $default;
  445. }
  446. $array = &$values[substr($name, 0, $offset)];
  447. while (false !== $pos = strpos($name, '[', $offset))
  448. {
  449. $end = strpos($name, ']', $pos);
  450. if ($end == $pos + 1)
  451. {
  452. // reached a []
  453. if (!is_array($array))
  454. {
  455. return $default;
  456. }
  457. break;
  458. }
  459. else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
  460. {
  461. return $default;
  462. }
  463. else if (is_array($array))
  464. {
  465. $array = &$array[substr($name, $pos + 1, $end - $pos - 1)];
  466. $offset = $end;
  467. }
  468. else
  469. {
  470. return $default;
  471. }
  472. }
  473. return $array;
  474. }
  475. /**
  476. * Returns an array value for a path.
  477. *
  478. * @param array $values The values to search
  479. * @param string $name The token name
  480. * @param array $default Default if not found
  481. *
  482. * @return array
  483. */
  484. public static function getArrayValueForPath($values, $name, $default = null)
  485. {
  486. if (false === $offset = strpos($name, '['))
  487. {
  488. return isset($values[$name]) ? $values[$name] : $default;
  489. }
  490. if (!isset($values[substr($name, 0, $offset)]))
  491. {
  492. return $default;
  493. }
  494. $array = $values[substr($name, 0, $offset)];
  495. while (false !== $pos = strpos($name, '[', $offset))
  496. {
  497. $end = strpos($name, ']', $pos);
  498. if ($end == $pos + 1)
  499. {
  500. // reached a []
  501. if (!is_array($array))
  502. {
  503. return $default;
  504. }
  505. break;
  506. }
  507. else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
  508. {
  509. return $default;
  510. }
  511. else if (is_array($array))
  512. {
  513. $array = $array[substr($name, $pos + 1, $end - $pos - 1)];
  514. $offset = $end;
  515. }
  516. else
  517. {
  518. return $default;
  519. }
  520. }
  521. return $array;
  522. }
  523. /**
  524. * Returns true if the a path exists for the given array.
  525. *
  526. * @param array $values The values to search
  527. * @param string $name The token name
  528. *
  529. * @return bool
  530. */
  531. public static function hasArrayValueForPath($values, $name)
  532. {
  533. if (false === $offset = strpos($name, '['))
  534. {
  535. return array_key_exists($name, $values);
  536. }
  537. if (!isset($values[substr($name, 0, $offset)]))
  538. {
  539. return false;
  540. }
  541. $array = $values[substr($name, 0, $offset)];
  542. while (false !== $pos = strpos($name, '[', $offset))
  543. {
  544. $end = strpos($name, ']', $pos);
  545. if ($end == $pos + 1)
  546. {
  547. // reached a []
  548. return is_array($array);
  549. }
  550. else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
  551. {
  552. return false;
  553. }
  554. else if (is_array($array))
  555. {
  556. $array = $array[substr($name, $pos + 1, $end - $pos - 1)];
  557. $offset = $end;
  558. }
  559. else
  560. {
  561. return false;
  562. }
  563. }
  564. return true;
  565. }
  566. /**
  567. * Removes a path for the given array.
  568. *
  569. * @param array $values The values to search
  570. * @param string $name The token name
  571. * @param mixed $default The default value to return if the name does not exist
  572. */
  573. public static function removeArrayValueForPath(&$values, $name, $default = null)
  574. {
  575. if (false === $offset = strpos($name, '['))
  576. {
  577. if (isset($values[$name]))
  578. {
  579. $value = $values[$name];
  580. unset($values[$name]);
  581. return $value;
  582. }
  583. else
  584. {
  585. return $default;
  586. }
  587. }
  588. if (!isset($values[substr($name, 0, $offset)]))
  589. {
  590. return $default;
  591. }
  592. $value = &$values[substr($name, 0, $offset)];
  593. while (false !== $pos = strpos($name, '[', $offset))
  594. {
  595. $end = strpos($name, ']', $pos);
  596. if ($end == $pos + 1)
  597. {
  598. // reached a []
  599. if (!is_array($value))
  600. {
  601. return $default;
  602. }
  603. break;
  604. }
  605. else if (!isset($value[substr($name, $pos + 1, $end - $pos - 1)]))
  606. {
  607. return $default;
  608. }
  609. else if (is_array($value))
  610. {
  611. $parent = &$value;
  612. $key = substr($name, $pos + 1, $end - $pos - 1);
  613. $value = &$value[$key];
  614. $offset = $end;
  615. }
  616. else
  617. {
  618. return $default;
  619. }
  620. }
  621. if ($key)
  622. {
  623. unset($parent[$key]);
  624. }
  625. return $value;
  626. }
  627. /**
  628. * Get path to php cli.
  629. *
  630. * @throws sfException If no php cli found
  631. * @return string
  632. */
  633. public static function getPhpCli()
  634. {
  635. $path = getenv('PATH') ? getenv('PATH') : getenv('Path');
  636. $suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe', '.bat', '.cmd', '.com')) : array('');
  637. foreach (array('php5', 'php') as $phpCli)
  638. {
  639. foreach ($suffixes as $suffix)
  640. {
  641. foreach (explode(PATH_SEPARATOR, $path) as $dir)
  642. {
  643. $file = $dir.DIRECTORY_SEPARATOR.$phpCli.$suffix;
  644. if (is_executable($file))
  645. {
  646. return $file;
  647. }
  648. }
  649. }
  650. }
  651. throw new sfException('Unable to find PHP executable.');
  652. }
  653. /**
  654. * From PEAR System.php
  655. *
  656. * LICENSE: This source file is subject to version 3.0 of the PHP license
  657. * that is available through the world-wide-web at the following URI:
  658. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  659. * the PHP License and are unable to obtain it through the web, please
  660. * send a note to license@php.net so we can mail you a copy immediately.
  661. *
  662. * @author Tomas V.V.Cox <cox@idecnet.com>
  663. * @copyright 1997-2006 The PHP Group
  664. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  665. */
  666. public static function getTmpDir()
  667. {
  668. if (DIRECTORY_SEPARATOR == '\\')
  669. {
  670. if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP'))
  671. {
  672. return $var;
  673. }
  674. if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP'))
  675. {
  676. return $var;
  677. }
  678. if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir'))
  679. {
  680. return $var;
  681. }
  682. return getenv('SystemRoot').'\temp';
  683. }
  684. if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR'))
  685. {
  686. return $var;
  687. }
  688. return '/tmp';
  689. }
  690. /**
  691. * Converts strings to UTF-8 via iconv. NB, the result may not by UTF-8 if the conversion failed.
  692. *
  693. * This file comes from Prado (BSD License)
  694. *
  695. * @param string $string string to convert to UTF-8
  696. * @param string $from current encoding
  697. *
  698. * @return string UTF-8 encoded string, original string if iconv failed.
  699. */
  700. static public function I18N_toUTF8($string, $from)
  701. {
  702. $from = strtoupper($from);
  703. if ($from != 'UTF-8')
  704. {
  705. $s = iconv($from,'UTF-8',$string); // to UTF-8
  706. return $s !== false ? $s : $string; // it could return false
  707. }
  708. return $string;
  709. }
  710. /**
  711. * Converts UTF-8 strings to a different encoding. NB. The result may not have been encoded if iconv fails.
  712. *
  713. * This file comes from Prado (BSD License)
  714. *
  715. * @param string $string the UTF-8 string for conversion
  716. * @param string $to new encoding
  717. *
  718. * @return string encoded string.
  719. */
  720. static public function I18N_toEncoding($string, $to)
  721. {
  722. $to = strtoupper($to);
  723. if ($to != 'UTF-8')
  724. {
  725. $s = iconv('UTF-8', $to, $string);
  726. return $s !== false ? $s : $string;
  727. }
  728. return $string;
  729. }
  730. /**
  731. * Adds a path to the PHP include_path setting.
  732. *
  733. * @param mixed $path Single string path or an array of paths
  734. * @param string $position Either 'front' or 'back'
  735. *
  736. * @return string The old include path
  737. */
  738. static public function addIncludePath($path, $position = 'front')
  739. {
  740. if (is_array($path))
  741. {
  742. foreach ('front' == $position ? array_reverse($path) : $path as $p)
  743. {
  744. self::addIncludePath($p, $position);
  745. }
  746. return;
  747. }
  748. $paths = explode(PATH_SEPARATOR, get_include_path());
  749. // remove what's already in the include_path
  750. if (false !== $key = array_search(realpath($path), array_map('realpath', $paths)))
  751. {
  752. unset($paths[$key]);
  753. }
  754. switch ($position)
  755. {
  756. case 'front':
  757. array_unshift($paths, $path);
  758. break;
  759. case 'back':
  760. $paths[] = $path;
  761. break;
  762. default:
  763. throw new InvalidArgumentException(sprintf('Unrecognized position: "%s"', $position));
  764. }
  765. return set_include_path(join(PATH_SEPARATOR, $paths));
  766. }
  767. }