PageRenderTime 28ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/php/utilities.class.php

https://bitbucket.org/chamilo/chamilo-dev/
PHP | 967 lines | 705 code | 89 blank | 173 comment | 41 complexity | 34b602238575e209fa10886bb48e78b9 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. namespace common\libraries;
  3. use user\UserDataManager;
  4. use repository\RepositoryDataManager;
  5. use repository\ContentObject;
  6. use XML_Unserializer;
  7. use PEAR;
  8. use Exception;
  9. /**
  10. * @package common
  11. *
  12. * This class provides some common methods that are used throughout the
  13. * platform.
  14. *
  15. * @author Tim De Pauw
  16. * @author Hans De Bisschop
  17. * @author Dieter De Neef
  18. */
  19. class Utilities
  20. {
  21. const TOOLBAR_DISPLAY_ICON = 1;
  22. const TOOLBAR_DISPLAY_LABEL = 2;
  23. const TOOLBAR_DISPLAY_ICON_AND_LABEL = 3;
  24. const COMMON_LIBRARIES = __NAMESPACE__;
  25. private static $us_camel_map = array();
  26. private static $us_camel_map_with_spaces = array();
  27. private static $camel_us_map = array();
  28. private static $camel_us_map_with_spaces = array();
  29. /**
  30. * Splits a Google-style search query. For example, the query
  31. * /"chamilo repository" utilities/ would be parsed into
  32. * array('chamilo repository', 'utilities').
  33. * @param $pattern The query.
  34. * @return array The query's parts.
  35. */
  36. static function split_query($pattern)
  37. {
  38. $matches = array();
  39. preg_match_all('/(?:"([^"]+)"|""|(\S+))/', $pattern, $matches);
  40. $parts = array();
  41. for($i = 1; $i <= 2; $i ++)
  42. {
  43. foreach ($matches[$i] as $m)
  44. {
  45. if (! is_null($m) && strlen($m) > 0)
  46. $parts[] = $m;
  47. }
  48. }
  49. return (count($parts) ? $parts : null);
  50. }
  51. /**
  52. * Transforms a search string (given by an end user in a search form) to a
  53. * Condition, which can be used to retrieve learning objects from the
  54. * repository.
  55. * @param string $query The query as given by the end user.
  56. * @param mixed $properties The learning object properties which should be
  57. * taken into account for the condition. For
  58. * example, array('title','type') will yield a
  59. * Condition which can be used to search for
  60. * learning objects on the properties 'title' or
  61. * 'type'. By default the properties are 'title'
  62. * and 'description'. If the condition should
  63. * apply to a single property, you can pass a
  64. * string instead of an array.
  65. * @return Condition The condition.
  66. * @deprecated Use the function get_conditions() in action_bar_renderer to access the search property.
  67. * This function uses this method to create the conditions.
  68. */
  69. static function query_to_condition($query, $properties = array(ContentObject :: PROPERTY_TITLE, ContentObject :: PROPERTY_DESCRIPTION))
  70. {
  71. if (! is_array($properties))
  72. {
  73. $properties = array($properties);
  74. }
  75. $queries = self :: split_query($query);
  76. if (is_null($queries))
  77. {
  78. return null;
  79. }
  80. $cond = array();
  81. foreach ($queries as $q)
  82. {
  83. $q = '*' . $q . '*';
  84. $pattern_conditions = array();
  85. foreach ($properties as $index => $property)
  86. {
  87. // reset storage properties when new cycle begins
  88. $is_alias = false;
  89. $storage_unit = null;
  90. // fill storage properties if we get the correct property instance
  91. if ($property instanceof ConditionProperty)
  92. {
  93. $is_alias = $property->get_is_alias_storage_unit();
  94. $storage_unit = $property->get_storage_unit();
  95. $property = $property->get_property();
  96. }
  97. $pattern_conditions[] = new PatternMatchCondition($property, $q, $storage_unit, $is_alias);
  98. }
  99. if (count($pattern_conditions) > 1)
  100. {
  101. $cond[] = new OrCondition($pattern_conditions);
  102. }
  103. else
  104. {
  105. $cond[] = $pattern_conditions[0];
  106. }
  107. }
  108. $result = new AndCondition($cond);
  109. return $result;
  110. }
  111. /**
  112. * Converts a date/time value retrieved from a FormValidator datepicker
  113. * element to the corresponding UNIX itmestamp.
  114. * @param string $string The date/time value.
  115. * @return int The UNIX timestamp.
  116. */
  117. static function time_from_datepicker($string)
  118. {
  119. list($date, $time) = split(' ', $string);
  120. list($year, $month, $day) = split('-', $date);
  121. list($hours, $minutes, $seconds) = split(':', $time);
  122. return mktime($hours, $minutes, $seconds, $month, $day, $year);
  123. }
  124. /**
  125. * Converts a date/time value retrieved from a FormValidator datepicker without timepicker
  126. * element to the corresponding UNIX itmestamp.
  127. * @param string $string The date/time value.
  128. * @return int The UNIX timestamp.
  129. */
  130. static function time_from_datepicker_without_timepicker($string, $h = 0, $m = 0, $s = 0)
  131. {
  132. list($year, $month, $day) = split('-', $string);
  133. return mktime($h, $m, $s, $month, $day, $year);
  134. }
  135. /**
  136. * Orders the given learning objects by their title. Note that the
  137. * ordering happens in-place; there is no return value.
  138. * @param array $objects The learning objects to order.
  139. */
  140. static function order_content_objects_by_title($objects)
  141. {
  142. usort($objects, array(get_class(), 'by_title'));
  143. }
  144. static function order_content_objects_by_id_desc($objects)
  145. {
  146. usort($objects, array(get_class(), 'by_id_desc'));
  147. }
  148. /**
  149. * Prepares the given learning objects for use as a value for the
  150. * element_finder QuickForm element.
  151. * @param array $objects The learning objects.
  152. * @return array The value.
  153. */
  154. static function content_objects_for_element_finder($objects)
  155. {
  156. $return = array();
  157. foreach ($objects as $object)
  158. {
  159. $id = $object->get_id();
  160. $return[$id] = self :: content_object_for_element_finder($object);
  161. }
  162. return $return;
  163. }
  164. /**
  165. * Prepares the given learning object for use as a value for the
  166. * element_finder QuickForm element's value array.
  167. * @param ContentObject $object The learning object.
  168. * @return array The value.
  169. */
  170. static function content_object_for_element_finder($object)
  171. {
  172. $type = $object->get_type();
  173. // TODO: i18n
  174. $date = date('r', $object->get_modification_date());
  175. $return = array();
  176. $return['id'] = 'lo_' . $object->get_id();
  177. $return['classes'] = 'type type_' . $type;
  178. $return['title'] = $object->get_title();
  179. $return['description'] = Translation :: get('TypeName', array(), ContentObject :: get_content_object_type_namespace($type)) . ' (' . $date . ')';
  180. return $return;
  181. }
  182. /**
  183. * Converts the given under_score string to CamelCase notation.
  184. * @param string $string The string in under_score notation.
  185. * @return string The string in CamelCase notation.
  186. */
  187. static function underscores_to_camelcase($string)
  188. {
  189. if (! isset(self :: $us_camel_map[$string]))
  190. {
  191. self :: $us_camel_map[$string] = ucfirst(preg_replace('/_([a-z])/e', 'strtoupper("\1")', $string));
  192. }
  193. return self :: $us_camel_map[$string];
  194. }
  195. static function underscores_to_camelcase_with_spaces($string)
  196. {
  197. if (! isset(self :: $us_camel_map_with_spaces[$string]))
  198. {
  199. self :: $us_camel_map_with_spaces[$string] = ucfirst(preg_replace('/_([a-z])/e', '" " . strtoupper("\1")', $string));
  200. }
  201. return self :: $us_camel_map_with_spaces[$string];
  202. }
  203. /**
  204. * Converts the given CamelCase string to under_score notation.
  205. * @param string $string The string in CamelCase notation.
  206. * @return string The string in under_score notation.
  207. */
  208. static function camelcase_to_underscores($string)
  209. {
  210. if (! isset(self :: $camel_us_map[$string]))
  211. {
  212. self :: $camel_us_map[$string] = preg_replace(array('/^([A-Z])/e', '/([A-Z])/e'), array('strtolower("\1")',
  213. '"_".strtolower("\1")'), $string);
  214. }
  215. return self :: $camel_us_map[$string];
  216. }
  217. /**
  218. * Compares learning objects by title.
  219. * @param ContentObject $content_object_1
  220. * @param ContentObject $content_object_2
  221. * @return int
  222. */
  223. static function by_title($content_object_1, $content_object_2)
  224. {
  225. return strcasecmp($content_object_1->get_title(), $content_object_2->get_title());
  226. }
  227. private static function by_id_desc($content_object_1, $content_object_2)
  228. {
  229. return ($content_object_1->get_id() < $content_object_2->get_id() ? 1 : - 1);
  230. }
  231. /**
  232. * Checks if a file is an HTML document.
  233. */
  234. // TODO: SCARA - MOVED / FROM: document_form_class / TO: Utilities or some other relevant class.
  235. static function is_html_document($path)
  236. {
  237. return (preg_match('/\.x?html?$/', $path) === 1);
  238. }
  239. static function build_uses($publication_attr)
  240. {
  241. $rdm = RepositoryDataManager :: get_instance();
  242. $udm = UserDataManager :: get_instance();
  243. $html = array();
  244. $html[] = '<ul class="publications_list">';
  245. foreach ($publication_attr as $info)
  246. {
  247. $publisher = $udm->retrieve_user($info->get_publisher_user_id());
  248. $object = $rdm->retrieve_content_object($info->get_publication_object_id());
  249. $html[] = '<li>';
  250. // TODO: i18n
  251. // TODO: SCARA - Find cleaner solution to display Learning Object title + url
  252. if ($info->get_url())
  253. {
  254. $html[] = '<a href="' . $info->get_url() . '">' . $info->get_application() . ': ' . $info->get_location() . '</a>';
  255. }
  256. else
  257. {
  258. $html[] = $info->get_application() . ': ' . $info->get_location();
  259. }
  260. $html[] = ' > <a href="' . $object->get_view_url() . '">' . $object->get_title() . '</a> (' . $publisher->get_firstname() . ' ' . $publisher->get_lastname() . ', ' . date('r', $info->get_publication_date()) . ')';
  261. $html[] = '</li>';
  262. }
  263. $html[] = '</ul>';
  264. return implode($html);
  265. }
  266. static function add_block_hider()
  267. {
  268. $html = array();
  269. $html[] = '<script type="text/javascript">';
  270. $html[] .= 'function showElement(item)';
  271. $html[] .= '{';
  272. $html[] .= ' if (document.getElementById(item).style.display == \'block\')';
  273. $html[] .= ' {';
  274. $html[] .= ' document.getElementById(item).style.display = \'none\';';
  275. $html[] .= ' document.getElementById(\'plus-\'+item).style.display = \'inline\';';
  276. $html[] .= ' document.getElementById(\'minus-\'+item).style.display = \'none\';';
  277. $html[] .= ' }';
  278. $html[] .= ' else';
  279. $html[] .= ' {';
  280. $html[] .= ' document.getElementById(item).style.display = \'block\';';
  281. $html[] .= ' document.getElementById(\'plus-\'+item).style.display = \'none\';';
  282. $html[] .= ' document.getElementById(\'minus-\'+item).style.display = \'inline\';';
  283. $html[] .= ' document.getElementById(item).value = \'Version comments here ...\';';
  284. $html[] .= ' }';
  285. $html[] .= '}';
  286. $html[] .= '</script>';
  287. return implode("\n", $html);
  288. }
  289. static function build_block_hider($id = null, $message = null, $display_block = false)
  290. {
  291. $html = array();
  292. if (isset($id))
  293. {
  294. if (! isset($message))
  295. {
  296. $message = self :: underscores_to_camelcase($id);
  297. }
  298. $show_message = 'Show' . $message;
  299. $hide_message = 'Hide' . $message;
  300. $html[] = '<div id="plus-' . $id . '"><a href="javascript:showElement(\'' . $id . '\')">' . Translation :: get('Show' . $message) . '</a></div>';
  301. $html[] = '<div id="minus-' . $id . '" style="display: none;"><a href="javascript:showElement(\'' . $id . '\')">' . Translation :: get('Hide' . $message) . '</a></div>';
  302. $html[] = '<div id="' . $id . '" style="display: ' . ($display_block ? 'block' : 'none') . ';">';
  303. }
  304. else
  305. {
  306. $html[] = '</div>';
  307. }
  308. return implode("\n", $html);
  309. }
  310. // 2 simple functions to display an array, a bit prettier as print_r
  311. // for testing purposes only!
  312. // @author Dieter De Neef
  313. static function DisplayArray($array)
  314. {
  315. $depth = 0;
  316. if (is_array($array))
  317. {
  318. echo "Array (<br />";
  319. for($i = 0; $i < count($array); $i ++)
  320. {
  321. if (is_array($array[$i]))
  322. {
  323. DisplayInlineArray($array[$i], $depth + 1, $i);
  324. }
  325. else
  326. {
  327. echo "[" . $i . "] => " . $array[$i];
  328. echo "<br />";
  329. $depth = 0;
  330. }
  331. }
  332. echo ")<br />";
  333. }
  334. else
  335. {
  336. echo "Variabele is geen array";
  337. }
  338. }
  339. static function DisplayInlineArray($inlinearray, $depth, $element)
  340. {
  341. $spaces = null;
  342. for($j = 0; $j < $depth - 1; $j ++)
  343. {
  344. $spaces .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
  345. }
  346. echo $spaces . "[" . $element . "]" . "Array (<br />";
  347. $spaces .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
  348. for($i = 0; $i < count($inlinearray); $i ++)
  349. {
  350. $key = key($inlinearray);
  351. if (is_array($inlinearray[$i]))
  352. {
  353. DisplayInlineArray($inlinearray[$i], $depth + 1, $i);
  354. }
  355. else
  356. {
  357. echo $spaces . "[" . $key . "] => " . $inlinearray[$key];
  358. echo "<br />";
  359. }
  360. next($inlinearray);
  361. }
  362. echo $spaces . ")<br />";
  363. }
  364. static function format_seconds_to_hours($seconds)
  365. {
  366. $hours = floor($seconds / 3600);
  367. $rest = $seconds % 3600;
  368. $minutes = floor($rest / 60);
  369. $seconds = $rest % 60;
  370. if ($minutes < 10)
  371. {
  372. $minutes = '0' . $minutes;
  373. }
  374. if ($seconds < 10)
  375. {
  376. $seconds = '0' . $seconds;
  377. }
  378. return $hours . ':' . $minutes . ':' . $seconds;
  379. }
  380. static function format_seconds_to_minutes($seconds)
  381. {
  382. $minutes = floor($seconds / 60);
  383. $seconds = $seconds % 60;
  384. if ($minutes < 10)
  385. {
  386. $minutes = '0' . $minutes;
  387. }
  388. if ($seconds < 10)
  389. {
  390. $seconds = '0' . $seconds;
  391. }
  392. return $minutes . ':' . $seconds;
  393. }
  394. /**
  395. * Strips the tags on request, and truncates if necessary a given string to the given length in characters.
  396. * Adds a character at the end (either specified or default ...) when the string is truncated.
  397. * Boolean $strip to indicate if the tags within the string have to be stripped
  398. * @param string $string The input string, UTF-8 encoded.
  399. * @param int $length The limit of the resulting length in characters.
  400. * @param boolean $strip Indicates if the tags within the string have to be stripped.
  401. * @param string $char A UTF-8 encoded character put at the end of the result string indicating truncation,
  402. * by default it is the horizontal ellipsis (\u2026)
  403. * @return string The result string, html-entities (if any) are converted to normal UTF-8 characters.
  404. */
  405. static function truncate_string($string, $length = 200, $strip = true, $char = "\xE2\x80\xA6")
  406. {
  407. if ($strip)
  408. {
  409. $string = strip_tags($string);
  410. }
  411. $string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');
  412. if (mb_strlen($string, 'UTF-8') > $length)
  413. {
  414. $string = mb_substr($string, 0, $length - mb_strlen($char, 'UTF-8'), 'UTF-8') . $char;
  415. }
  416. return $string;
  417. }
  418. static function extract_xml_file($file, $extra_options = array())
  419. {
  420. require_once 'XML/Unserializer.php';
  421. if (file_exists($file))
  422. {
  423. $unserializer = new XML_Unserializer();
  424. $unserializer->setOption(XML_UNSERIALIZER_OPTION_COMPLEXTYPE, 'array');
  425. $unserializer->setOption(XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE, true);
  426. $unserializer->setOption(XML_UNSERIALIZER_OPTION_RETURN_RESULT, true);
  427. $unserializer->setOption(XML_UNSERIALIZER_OPTION_GUESS_TYPES, true);
  428. foreach ($extra_options as $op => $value)
  429. $unserializer->setOption($op, $value);
  430. // userialize the document
  431. $status = $unserializer->unserialize($file, true);
  432. if (PEAR :: isError($status))
  433. {
  434. return false;
  435. }
  436. else
  437. {
  438. $data = $unserializer->getUnserializedData();
  439. return $data;
  440. }
  441. }
  442. else
  443. {
  444. return null;
  445. }
  446. }
  447. /**
  448. * @param string $application
  449. */
  450. static function set_application($application)
  451. {
  452. Translation :: set_application($application);
  453. Theme :: set_application($application);
  454. }
  455. /**
  456. * @param mixed $value
  457. * @return string
  458. */
  459. static function display_true_false_icon($value)
  460. {
  461. if ($value)
  462. {
  463. $icon = 'action_setting_true.png';
  464. }
  465. else
  466. {
  467. $icon = 'action_setting_false.png';
  468. }
  469. return '<img src="' . Theme :: get_common_image_path() . $icon . '">';
  470. }
  471. /**
  472. * @param string $string
  473. */
  474. static function htmlentities($string)
  475. {
  476. return htmlentities($string, ENT_COMPAT, 'UTF-8');
  477. }
  478. /**
  479. * @return int
  480. */
  481. static function get_usable_memory()
  482. {
  483. $val = trim(@ini_get('memory_limit'));
  484. if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
  485. {
  486. $memory_limit = (int) $regs[1];
  487. switch ($regs[2])
  488. {
  489. case 'k' :
  490. case 'K' :
  491. $memory_limit *= 1024;
  492. break;
  493. case 'm' :
  494. case 'M' :
  495. $memory_limit *= 1048576;
  496. break;
  497. case 'g' :
  498. case 'G' :
  499. $memory_limit *= 1073741824;
  500. break;
  501. }
  502. // how much memory PHP requires at the start of export (it is really a little less)
  503. if ($memory_limit > 6100000)
  504. {
  505. $memory_limit -= 6100000;
  506. }
  507. // allow us to consume half of the total memory available
  508. $memory_limit /= 2;
  509. }
  510. else
  511. {
  512. // set the buffer to 1M if we have no clue how much memory PHP will give us :P
  513. $memory_limit = 1048576;
  514. }
  515. return $memory_limit;
  516. }
  517. /**
  518. * @param string $mimetype
  519. * @return string The image html
  520. */
  521. static function mimetype_to_image($mimetype)
  522. {
  523. $mimetype_image = str_replace('/', '_', $mimetype);
  524. return Theme :: get_common_image('mimetype/' . $mimetype_image, 'png', $mimetype, '', ToolbarItem :: DISPLAY_ICON);
  525. }
  526. static function register_autoload()
  527. {
  528. spl_autoload_register('common\libraries\Utilities::autoload');
  529. }
  530. /**
  531. * @param string $classname
  532. * @return boolean
  533. */
  534. static function autoload($classname)
  535. {
  536. $classname_parts = explode('\\', $classname);
  537. if (count($classname_parts) == 1 || $classname == 'Doctrine\Common\ClassLoader')
  538. {
  539. // Non-namespaced class, should be a plugin
  540. return self :: autoload_plugin($classname);
  541. }
  542. $unqualified_class_name = $classname_parts[count($classname_parts) - 1];
  543. array_pop($classname_parts);
  544. $autoloader_path = Path :: get(SYS_PATH) . implode('/', $classname_parts) . '/' . 'php/autoloader.class.php';
  545. if (file_exists($autoloader_path))
  546. {
  547. require_once $autoloader_path;
  548. $autoloader_class = implode('\\', $classname_parts) . '\\Autoloader';
  549. if ($autoloader_class :: load($unqualified_class_name))
  550. {
  551. return true;
  552. }
  553. }
  554. //standard fall back
  555. $class_filename = self :: camelcase_to_underscores($unqualified_class_name) . '.class.php';
  556. $class_path = dirname($autoloader_path) . '/' . $class_filename;
  557. if (file_exists($class_path))
  558. {
  559. require_once $class_path;
  560. return class_exists($classname);
  561. }
  562. }
  563. static function autoload_plugin($classname)
  564. {
  565. // Zend or Google
  566. $classes = array('Zend_Loader' => 'Zend/Loader.php', 'phpCAS' => 'CAS.php', 'MDB2' => 'MDB2.php',
  567. 'MDB2_Driver_Common' => 'MDB2.php', 'MDB2_Driver_Manager_Common' => 'MDB2/Driver/Manager/Common.php',
  568. 'MDB2_Module_Common' => 'MDB2.php', 'MDB2_Extended' => 'MDB2/Extended.php', 'PEAR' => 'PEAR.php',
  569. 'Contact_Vcard_Build' => 'File/Contact_Vcard_Build.php',
  570. 'Contact_Vcard_Parse' => 'File/Contact_Vcard_Parse.php', 'HTTP_Request' => 'HTTP/Request.php',
  571. 'Net_LDAP2' => 'Net/LDAP2.php', 'Net_LDAP2_Filter' => 'Net/LDAP2/Filter.php',
  572. 'Pager' => 'Pager/Pager.php', 'Pager_Sliding' => 'Pager/Sliding.php',
  573. 'XML_Unserializer' => 'XML/Unserializer.php', 'XML_Serializer' => 'XML/Serializer.php',
  574. 'HTML_Table' => 'HTML/Table.php', 'HTML_QuickForm' => 'HTML/QuickForm.php',
  575. 'HTML_Menu' => 'HTML/Menu.php', 'HTML_Menu_ArrayRenderer' => 'HTML/Menu/ArrayRenderer.php',
  576. 'HTML_Menu_DirectTreeRenderer' => 'HTML/Menu/DirectTreeRenderer.php',
  577. 'HTML_QuickForm_Controller' => 'HTML/QuickForm/Controller.php',
  578. 'HTML_QuickForm_Rule' => 'HTML/QuickForm/Rule.php', 'HTML_QuickForm_Page' => 'HTML/QuickForm/Page.php',
  579. 'HTML_QuickForm_Action' => 'HTML/QuickForm/Action.php',
  580. 'HTML_QuickForm_RuleRegistry' => 'HTML/QuickForm/RuleRegistry.php',
  581. 'HTML_QuickForm_Action_Display' => 'HTML/QuickForm/Action/Display.php',
  582. 'HTML_QuickForm_Rule_Compare' => 'HTML/QuickForm/Rule/Compare.php',
  583. 'HTML_QuickForm_advmultiselect' => 'HTML/QuickForm/advmultiselect.php',
  584. 'HTML_QuickForm_button' => 'HTML/QuickForm/button.php',
  585. 'HTML_QuickForm_checkbox' => 'HTML/QuickForm/checkbox.php',
  586. 'HTML_QuickForm_date' => 'HTML/QuickForm/date.php',
  587. 'HTML_QuickForm_element' => 'HTML/QuickForm/element.php',
  588. 'HTML_QuickForm_file' => 'HTML/QuickForm/file.php', 'HTML_QuickForm_group' => 'HTML/QuickForm/group.php',
  589. 'HTML_QuickForm_hidden' => 'HTML/QuickForm/hidden.php',
  590. 'HTML_QuickForm_html' => 'HTML/QuickForm/html.php', 'HTML_QuickForm_radio' => 'HTML/QuickForm/radio.php',
  591. 'HTML_QuickForm_select' => 'HTML/QuickForm/select.php',
  592. 'HTML_QuickForm_text' => 'HTML/QuickForm/text.php',
  593. 'HTML_QuickForm_textarea' => 'HTML/QuickForm/textarea.php');
  594. if (array_key_exists($classname, $classes))
  595. {
  596. require_once $classes[$classname];
  597. return class_exists($classname);
  598. }
  599. $other_plugin_classes = array('RestResult' => 'webservices/rest/client/rest_result.class.php',
  600. 'Doctrine\Common\ClassLoader' => 'doctrine/Common/ClassLoader.php',
  601. 'LastRss' => 'lastrss/lastrss.class.php');
  602. if (array_key_exists($classname, $other_plugin_classes))
  603. {
  604. require_once Path :: get_plugin_path() . '/' . $other_plugin_classes[$classname];
  605. return class_exists($classname);
  606. }
  607. //Fallback strategy => Pear naming convention : replace _ by /
  608. $classfile = str_replace("_", "/", $classname) . ".php";
  609. if (file_exists($classfile))
  610. {
  611. require_once $classfile;
  612. return class_exists($classname);
  613. }
  614. return false;
  615. }
  616. /**
  617. * Render a complete backtrace for the currently executing script
  618. * @return string The backtrace
  619. */
  620. static function get_backtrace()
  621. {
  622. $html = array();
  623. $backtraces = debug_backtrace();
  624. foreach ($backtraces as $backtrace)
  625. {
  626. $html[] = implode(' ', $backtrace);
  627. }
  628. return implode('<br/>', $html);
  629. }
  630. /**
  631. * Get the class name from a fully qualified namespaced class name
  632. * if and only if it's in the given namespace
  633. *
  634. * @param string $namespace
  635. * @param string $classname
  636. * @return string|boolean The class name or false
  637. */
  638. static function get_namespace_classname($namespace, $classname)
  639. {
  640. $classname_parts = explode('\\', $classname);
  641. if (count($classname_parts) == 1)
  642. {
  643. return false;
  644. }
  645. else
  646. {
  647. $class_name = $classname_parts[count($classname_parts) - 1];
  648. array_pop($classname_parts);
  649. if (implode('\\', $classname_parts) != $namespace)
  650. {
  651. return false;
  652. }
  653. else
  654. {
  655. return $class_name;
  656. }
  657. }
  658. }
  659. /**
  660. * @param Object $object
  661. * @param booleean $convert_to_underscores
  662. * @return string The class name
  663. */
  664. static function get_classname_from_object($object, $convert_to_underscores = false)
  665. {
  666. return self :: get_classname_from_namespace(get_class($object), $convert_to_underscores);
  667. }
  668. /**
  669. * @param Object $object
  670. * @return string The namespace
  671. */
  672. static function get_namespace_from_object($object)
  673. {
  674. return self :: get_namespace_from_classname(get_class($object));
  675. }
  676. /**
  677. * @param string $classname
  678. * @param boolean $convert_to_underscores
  679. * @return string The class name
  680. */
  681. static function get_classname_from_namespace($classname, $convert_to_underscores = false)
  682. {
  683. $classname = array_pop(explode('\\', $classname));
  684. if ($convert_to_underscores)
  685. {
  686. $classname = self :: camelcase_to_underscores($classname);
  687. }
  688. return $classname;
  689. }
  690. /**
  691. * @param string $namespace
  692. * @return string The namespace
  693. */
  694. static function get_namespace_from_classname($namespace)
  695. {
  696. $namespace_parts = explode('\\', $namespace);
  697. array_pop($namespace_parts);
  698. return implode('\\', $namespace_parts);
  699. }
  700. static function get_package_name_from_namespace($namespace, $convert_to_camelcase = false)
  701. {
  702. $package_name = array_pop(explode('\\', $namespace));
  703. if ($convert_to_camelcase)
  704. {
  705. $package_name = self :: underscores_to_camelcase($package_name);
  706. }
  707. return $package_name;
  708. }
  709. /**
  710. * Returns the package name for a given object
  711. *
  712. * @param Object $object
  713. * @param Boolean $convert_to_camelcase
  714. *
  715. * @return String
  716. */
  717. static function get_package_name_from_object($object, $convert_to_camelcase = false)
  718. {
  719. return self :: get_package_name_from_namespace(self :: get_namespace_from_object($object),
  720. $convert_to_camelcase);
  721. }
  722. static function load_custom_class($path_hash, $class_name, $prefix_path)
  723. {
  724. $lower_case = self :: camelcase_to_underscores($class_name);
  725. if (key_exists($lower_case, $path_hash))
  726. {
  727. $url = $path_hash[$lower_case];
  728. require_once $prefix_path . $url;
  729. return true;
  730. }
  731. return false;
  732. }
  733. static function clone_array($items)
  734. {
  735. $result = array();
  736. foreach ($items as $key => $value)
  737. {
  738. $result[$key] = is_object($value) ? clone ($value) : $value;
  739. }
  740. return $result;
  741. }
  742. static function handle_exception($exception)
  743. {
  744. $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  745. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  746. <head>
  747. <title>Uncaught exception</title>
  748. <link rel="stylesheet" href="common/libraries/resources/css/aqua/aqua.css" type="text/css"/>
  749. </head>
  750. <body dir="ltr">
  751. <div id="outerframe">
  752. <div id="header">
  753. <div id="header1">
  754. <div class="banner"><span class="logo"></span><span class="text">Chamilo</span></div>
  755. <div class="clear">&nbsp;</div>
  756. </div>
  757. <div class="clear">&nbsp;</div>
  758. </div>
  759. <div id="trailbox">
  760. <ul id="breadcrumbtrail">
  761. <li><a href="#">Uncaught exception</a></li>
  762. </ul>
  763. </div>
  764. <div id="main" style="min-height: 300px;">
  765. <div class="error-message">' . $exception->getMessage() . '</div><br /><br />
  766. </div>
  767. <div id="footer">
  768. <div id="copyright">
  769. <div class="logo">
  770. <a href="http://www.chamilo.org"><img src="common/libraries/resources/images/aqua/logo_footer.png" alt="footer"/></a>
  771. </div>
  772. <div class="links">
  773. <a href="http://www.chamilo.org">http://www.chamilo.org</a>&nbsp;|&nbsp;&copy;&nbsp;' . @date('Y') . '
  774. </div>
  775. <div class="clear"></div>
  776. </div>
  777. </div>
  778. </div>
  779. </body>
  780. </html>';
  781. echo $html;
  782. }
  783. /**
  784. * Error handling function
  785. */
  786. static function handle_error($errno, $errstr, $errfile, $errline)
  787. {
  788. switch ($errno)
  789. {
  790. case E_USER_ERROR :
  791. self :: write_error('PHP Fatal error', $errstr, $errfile, $errline);
  792. break;
  793. case E_USER_WARNING :
  794. self :: write_error('PHP Warning', $errstr, $errfile, $errline);
  795. break;
  796. case E_USER_NOTICE :
  797. self :: write_error('PHP Notice', $errstr, $errfile, $errline);
  798. default :
  799. /*
  800. if(!strpos($errfile, 'plugin') && !strpos($errstr, 'MDB2') && strpos($errstr, 'Non-static')===false
  801. && strpos($errstr, 'Declaration of')===false)
  802. echo $errstr, $errfile, $errline, '<br/>';
  803. */
  804. }
  805. return true;
  806. }
  807. static function write_error($errno, $errstr, $errfile, $errline)
  808. {
  809. $path = Path :: get(SYS_FILE_PATH) . 'logs';
  810. $file = $path . '/error_log_' . date('Ymd') . '.txt';
  811. $fh = fopen($file, 'a');
  812. $message = date('[H:i:s] ', time()) . $errno . ' File: ' . $errfile . ' - Line: ' . $errline . ' - Message: ' . $errstr;
  813. fwrite($fh, $message . "\n");
  814. fclose($fh);
  815. }
  816. static function get_global_error_message()
  817. {
  818. $error_message = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  819. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  820. <head>
  821. <title>Chamilo isn\'t installed ?!</title>
  822. <link rel="stylesheet" href="common/libraries/resources/css/aqua/aqua.css" type="text/css"/>
  823. </head>
  824. <body dir="ltr">
  825. <div id="outerframe">
  826. <div id="header">
  827. <div id="header1">
  828. <div class="banner"><span class="logo"></span><span class="text">Chamilo</span></div>
  829. <div class="clear">&nbsp;</div>
  830. </div>
  831. <div class="clear">&nbsp;</div>
  832. </div>
  833. <div id="main" style="min-height: 300px;">' . "\n";
  834. $version = phpversion();
  835. if ($version >= 5.3)
  836. {
  837. $error_message .= ' <div class="normal-message" style="margin-bottom: 39px; margin-top: 30px;">From the looks of it, Chamilo is currently not installed on your system.<br /><br />Please check your database and/or configuration files if you are certain the platform was installed correctly.<br /><br />If you\'re starting Chamilo for the first time, you may want to install the platform first by clicking the button below. Alternatively, you can read the installation guide, visit chamilo.org for more information or go to the community forum if you need support.
  838. </div>
  839. <div class="clear">&nbsp;</div>
  840. <div style="text-align: center;"><a class="button positive_button" href="install/">Install Chamilo </a><a class="button normal_button read_button" href="documentation/install.txt" target="_blank">Read the installation guide</a><a class="button normal_button surf_button" href="http://www.chamilo.org/" target="_blank">Visit chamilo.org</a><a class="button normal_button help_button" href="http://www.chamilo.org/forum/" target="_blank">Get support</a></div>' . "\n";
  841. }
  842. else
  843. {
  844. $error_message .= ' <div class="error-message">Your version of PHP is not recent enough to use the Chamilo software.
  845. <br /><a href="http://www.php.net">Please upgrade to PHP version 5.3 or higher</a></div><br /><br />' . "\n";
  846. }
  847. $error_message .= ' </div>
  848. <div id="footer">
  849. <div id="copyright">
  850. <div class="logo">
  851. <a href="http://www.chamilo.org"><img src="common/libraries/resources/images/aqua/logo_footer.png" /></a>
  852. </div>
  853. <div class="links">
  854. <a href="http://www.chamilo.org">http://www.chamilo.org</a>&nbsp;|&nbsp;&copy;&nbsp;2009
  855. </div>
  856. <div class="clear"></div>
  857. </div>
  858. </div>
  859. </div>
  860. </body>
  861. </html>';
  862. return $error_message;
  863. }
  864. }
  865. ?>