C_Component_Registry

A registry of registered products, modules, adapters, and utilities.

Defined (1)

The class is defined in the following location(s).

/pope/lib/class.component_registry.php  
  1. class C_Component_Registry 
  2. static $_instance = NULL; 
  3. var $_searched_paths = array(); 
  4. var $_blacklist = array(); 
  5. var $_meta_info = array(); 
  6. var $_default_path = NULL; 
  7. var $_modules = array(); 
  8. var $_products = array(); 
  9. var $_adapters = array(); 
  10. var $_utilities = array(); 
  11. var $_module_type_cache = array(); 
  12. var $_module_type_cache_count = 0; 
  13.  
  14.  
  15.  
  16. /** 
  17. * This is a singleton object 
  18. */ 
  19. private function __construct() 
  20. // Create an autoloader 
  21. spl_autoload_register(array($this, '_module_autoload'), TRUE); 
  22.  
  23.  
  24. /** 
  25. * Returns a singleton 
  26. * @return C_Component_Registry() 
  27. */ 
  28. static function &get_instance() 
  29. if (is_null(self::$_instance)) { 
  30. $klass = get_class(); 
  31. self::$_instance = new $klass(); 
  32. return self::$_instance; 
  33.  
  34. function require_module_file($module_file_abspath) 
  35. // We don't include (require) module files that have the same name. This 
  36. // avoids loading module.autoupdate.php from two products 
  37. static $already_required = array(); 
  38. $relpath = basename($module_file_abspath); 
  39. if (!in_array($relpath, $already_required)) { 
  40. @require_once($module_file_abspath); 
  41. $already_required[] = $relpath; 
  42.  
  43. function has_searched_path_before($abspath) 
  44. return in_array($abspath, $this->_searched_paths); 
  45.  
  46. function mark_as_searched_path($abspath) 
  47. $this->_searched_paths[] = $abspath; 
  48.  
  49.  
  50. /** 
  51. * Adds a path in the search paths for loading modules 
  52. * @param string $path 
  53. * @param bool $recurse - TRUE, FALSE, or the number of levels to recurse 
  54. * @param bool $load_all - loads all modules found in the path 
  55. */ 
  56. function add_module_path($path, $recurse = false, $load_all = false) 
  57. if (!$recurse || (!$this->has_searched_path_before($path))) { 
  58.  
  59. // If no default module path has been set, then set one now 
  60. if ($this->get_default_module_path() == null) { 
  61. $this->set_default_module_path($path); 
  62.  
  63. // We we've been passed a module file, then include it 
  64. if (@file_exists($path) && is_file($path)) { 
  65. $this->require_module_file($path); 
  66.  
  67. // Recursively find product and module files in this path 
  68. else foreach ($this->find_product_and_module_files($path, $recurse) as $file_abspath) { 
  69. $this->require_module_file($file_abspath); 
  70.  
  71. $this->mark_as_searched_path($path); 
  72.  
  73. if ($load_all) $this->load_all_modules(NULL, $path); 
  74.  
  75.  
  76. /** 
  77. * Retrieves the default module path (Note: this is just the generic root container path for modules) 
  78. * @return string 
  79. */ 
  80. function get_default_module_path() 
  81. return $this->_default_path; 
  82.  
  83.  
  84. /** 
  85. * Sets the default module path (Note: this is just the generic root container path for modules) 
  86. * @param string $path 
  87. */ 
  88. function set_default_module_path($path) 
  89. $this->_default_path = $path; 
  90.  
  91.  
  92. /** 
  93. * Retrieves the module path 
  94. * @param string $module_id 
  95. * @return string 
  96. */ 
  97. function get_module_path($module_id) 
  98. if (isset($this->_meta_info[$module_id])) { 
  99. $info = $this->_meta_info[$module_id]; 
  100.  
  101. if (isset($info['path'])) { 
  102. return $info['path']; 
  103.  
  104. return null; 
  105.  
  106.  
  107. /** 
  108. * Retrieves the module installation directory 
  109. * @param string $module_id 
  110. * @return string 
  111. */ 
  112. function get_module_dir($module_id) 
  113. $path = $this->get_module_path($module_id); 
  114.  
  115. if ($path != null) { 
  116. return dirname($path); 
  117.  
  118. return null; 
  119.  
  120.  
  121. function is_module_loaded($module_id) 
  122. return (isset($this->_meta_info[$module_id]) && isset($this->_meta_info[$module_id]['loaded']) && $this->_meta_info[$module_id]['loaded']); 
  123.  
  124. /** 
  125. * Loads a module's code according to its dependency list 
  126. * @param string $module_id 
  127. */ 
  128. function load_module($module_id) 
  129. $retval = FALSE; 
  130.  
  131. if (($module = $this->get_module($module_id)) && !$this->is_module_loaded($module_id) && !$this->is_blacklisted($module_id)) { 
  132. $module->load(); 
  133. $retval = $this->_meta_info[$module_id]['loaded'] = TRUE; 
  134.  
  135.  
  136. return $retval; 
  137.  
  138. function load_all_modules($type=NULL, $dir=NULL) 
  139. $modules = $this->get_known_module_list(); 
  140. $ret = true; 
  141.  
  142. foreach ($modules as $module_id) 
  143. if ($type == null || $this->get_module_meta($module_id, 'type') == $type) { 
  144. if ($dir == NULL || strpos($this->get_module_dir($module_id), $dir) !== FALSE) 
  145. $ret = $this->load_module($module_id) && $ret; 
  146.  
  147. return $ret; 
  148.  
  149.  
  150. /** 
  151. * Initializes a previously loaded module 
  152. * @param string $module_id 
  153. */ 
  154. function initialize_module($module_id) 
  155. $retval = FALSE; 
  156.  
  157. if (isset($this->_modules[$module_id])) { 
  158. $module = $this->_modules[$module_id]; 
  159.  
  160. if ($this->is_module_loaded($module_id) && !$module->initialized) { 
  161. if (method_exists($module, 'initialize')) 
  162. $module->initialize(); 
  163.  
  164. $module->initialized = true; 
  165. $retval = TRUE; 
  166. return $retval; 
  167.  
  168.  
  169. /** 
  170. * Initializes an already loaded product 
  171. * @param string $product_id 
  172. * @return bool 
  173. */ 
  174. function initialize_product($product_id) 
  175. return $this->initialize_module($product_id); 
  176.  
  177.  
  178. /** 
  179. * Initializes all previously loaded modules 
  180. */ 
  181. function initialize_all_modules() 
  182. $module_list = $this->get_loaded_module_list(); 
  183.  
  184. foreach ($module_list as $module_id) 
  185. $this->initialize_module($module_id); 
  186.  
  187.  
  188. /** 
  189. * Adds an already loaded module to the registry 
  190. * @param string $module_id 
  191. * @param C_Base_Module $module_object 
  192. */ 
  193. function add_module($module_id, $module_object) 
  194. if (!isset($this->_modules[$module_id])) { 
  195. $this->_modules[$module_id] = $module_object; 
  196.  
  197. if (!isset($this->_meta_info[$module_id])) { 
  198. $klass = new ReflectionClass($module_object); 
  199.  
  200. $this->_meta_info[$module_id] = array( 
  201. 'path' => $klass->getFileName(),  
  202. 'type' => $klass->isSubclassOf('C_Base_Product') ? 'product' : 'module',  
  203. 'loaded' => FALSE 
  204. ); 
  205.  
  206.  
  207. /** 
  208. * Deletes an already loaded module from the registry 
  209. * @param string $module_id 
  210. */ 
  211. function del_module($module_id) 
  212. if (isset($this->_modules[$module_id])) { 
  213. unset($this->_modules[$module_id]); 
  214.  
  215.  
  216. /** 
  217. * Retrieves the instance of the registered module. Note: it's the instance of the module object, so the module needs to be loaded or this function won't return anything. For module info returned by scanning (with add_module_path), look at get_module_meta 
  218. * @param string $module_id 
  219. * @return C_Base_Module 
  220. */ 
  221. function get_module($module_id) 
  222. if (isset($this->_modules[$module_id])) { 
  223. return $this->_modules[$module_id]; 
  224.  
  225. return null; 
  226.  
  227. function get_module_meta($module_id, $meta_name) 
  228. $meta = $this->get_module_meta_list($module_id); 
  229.  
  230. if (isset($meta[$meta_name])) { 
  231. return $meta[$meta_name]; 
  232.  
  233. return null; 
  234.  
  235. function get_module_meta_list($module_id) 
  236. if (isset($this->_meta_info[$module_id])) { 
  237. return $this->_meta_info[$module_id]; 
  238.  
  239. return null; 
  240.  
  241. /** 
  242. * Retrieves a list of instantiated module ids, in their "loaded" order as defined by a product 
  243. * @return array 
  244. */ 
  245. function get_module_list($for_product_id=FALSE) 
  246. $retval = $module_list = array(); 
  247. // As of May 1, 2015, there's a new standard. A product will provide get_provided_modules() and get_modules_to_load(). 
  248.  
  249. // As of Feb 10, 2015, there's no standard way across Pope products to an "ordered" list of modules 
  250. // that the product provides. 
  251. // 
  252. // The "standard" going forward will insist that all Product classes will provide either: 
  253. // A) a static property called "modules" 
  254. // B) an instance method called "define_modules", which returns a list of modules, and as well, sets 
  255. // a static property called "modules'. 
  256. // 
  257. // IMPORTANT! 
  258. // The Photocrati Theme, as of version 4.1.8, doesn't follow this standard. But both NextGEN Pro and Plus do. 
  259.  
  260. // Following the standard above, collect all modules provided by a product 
  261. $problematic_product_id = FALSE; 
  262. foreach ($this->get_product_list() as $product_id) { 
  263. $modules = array(); 
  264.  
  265. // Try getting the list of modules using the "standard" described above 
  266. $obj = $this->get_product($product_id); 
  267. try{ 
  268. $klass = new ReflectionClass($obj); 
  269. if ($klass->hasMethod('get_modules_to_load')) { 
  270. $modules = $obj->get_modules_provided(); 
  271. elseif ($klass->hasProperty('modules')) { 
  272. $modules = $klass->getStaticPropertyValue('modules'); 
  273.  
  274. if (!$modules && $klass->hasMethod('define_modules')) { 
  275. $modules = $obj->define_modules(); 
  276. if ($klass->hasProperty('modules')) { 
  277. $modules = $klass->getStaticPropertyValue('modules'); 
  278.  
  279. // We've encountered a product that doesn't follow the standard. For these exceptions, we'll have to 
  280. // make an educated guess - if the module path is in the product's default module path, we know that 
  281. // it belongs to the product 
  282. catch (ReflectionException $ex) { 
  283. $modules = array(); 
  284.  
  285. if (!$modules) { 
  286. $product_path = $this->get_product_module_path($product_id); 
  287. foreach ($this->_modules as $module_id => $module) { 
  288. if (strpos($this->get_module_path($module_id), $product_path) !== FALSE) { 
  289. $modules[] = $module_id; 
  290. if (!$modules) $problematic_product_id = $product_id; 
  291.  
  292. $module_list[$product_id] = $modules; 
  293.  
  294. // If we have a problematic product, that is, one that we can't find it's ordered list of modules 
  295. // that it provides, then we have one last fallback: get a list of modules that Pope is aware of, but hasn't 
  296. // added to $module_list[$product_id] yet 
  297. if ($problematic_product_id) { 
  298. $modules = array(); 
  299. foreach (array_keys($this->_modules) as $module_id) { 
  300. $assigned = FALSE; 
  301. foreach (array_keys($module_list) as $product_id) { 
  302. if (in_array($module_id, $module_list[$product_id])) { 
  303. $assigned =TRUE; 
  304. break; 
  305. if (!$assigned) $modules[] = $module_id; 
  306. $module_list[$problematic_product_id] = $modules; 
  307.  
  308. // Now that we know which products provide which modules, we can serve the request. 
  309. if (!$for_product_id) { 
  310. foreach (array_values($module_list) as $modules) { 
  311. $retval = array_merge($retval, $modules); 
  312. else $retval = $module_list[$for_product_id]; 
  313.  
  314. // Final fallback...if all else fails, just return the list of all modules 
  315. // that Pope is aware of 
  316. if (!$retval) $retval = array_keys($this->_modules); 
  317.  
  318.  
  319. return $retval; 
  320.  
  321. function get_loaded_module_list() 
  322. $retval = array(); 
  323.  
  324. foreach ($this->get_module_list() as $module_id) { 
  325. if ($this->is_module_loaded($module_id)) $retval[] = $module_id; 
  326.  
  327. return $retval; 
  328.  
  329. /** 
  330. * Retrieves a list of registered module ids, including those that aren't loaded (i.e. get_module() call with those unloaded ids will fail) 
  331. * @return array 
  332. */ 
  333. function get_known_module_list() 
  334. return array_keys($this->_meta_info); 
  335.  
  336.  
  337. function load_product($product_id) 
  338. return $this->load_module($product_id); 
  339.  
  340. function load_all_products() 
  341. return $this->load_all_modules('product'); 
  342.  
  343. /** 
  344. * Adds an already loaded product in the registry 
  345. * @param string $product_id 
  346. * @param C_Base_Module $product_object 
  347. */ 
  348. function add_product($product_id, $product_object) 
  349. if (!isset($this->_products[$product_id])) { 
  350. $this->_products[$product_id] = $product_object; 
  351.  
  352.  
  353. /** 
  354. * Deletes an already loaded product from the registry 
  355. * @param string $product_id 
  356. */ 
  357. function del_product($product_id) 
  358. if (isset($this->_products[$product_id])) { 
  359. unset($this->_products[$product_id]); 
  360.  
  361.  
  362. /** 
  363. * Retrieves the instance of the registered product 
  364. * @param string $product_id 
  365. * @return C_Base_Module 
  366. */ 
  367. function get_product($product_id) 
  368. if (isset($this->_products[$product_id])) { 
  369. return $this->_products[$product_id]; 
  370.  
  371. return null; 
  372.  
  373. function get_product_meta($product_id, $meta_name) 
  374. $meta = $this->get_product_meta_list($product_id); 
  375.  
  376. if (isset($meta[$meta_name])) { 
  377. return $meta[$meta_name]; 
  378.  
  379. return null; 
  380.  
  381. function get_product_meta_list($product_id) 
  382. if (isset($this->_meta_info[$product_id]) && $this->_meta_info[$product_id]['type'] == 'product') { 
  383. return $this->_meta_info[$product_id]; 
  384.  
  385. return null; 
  386.  
  387.  
  388. /** 
  389. * Retrieves the module installation path for a specific product (Note: this is just the generic root container path for modules of this product) 
  390. * @param string $product_id 
  391. * @return string 
  392. */ 
  393. function get_product_module_path($product_id) 
  394. if (isset($this->_meta_info[$product_id])) { 
  395. $info = $this->_meta_info[$product_id]; 
  396.  
  397. if (isset($info['product-module-path'])) { 
  398. return $info['product-module-path']; 
  399.  
  400. return null; 
  401.  
  402. function blacklist_module_file($relpath) 
  403. if (!in_array($relpath, $this->_blacklist)) $this->_blacklist[] = $relpath; 
  404.  
  405. function is_blacklisted($filename) 
  406. return in_array($filename, $this->_blacklist); 
  407.  
  408. /** 
  409. * Sets the module installation path for a specific product (Note: this is just the generic root container path for modules of this product) 
  410. * @param string $product_id 
  411. * @param string $module_path 
  412. */ 
  413. function set_product_module_path($product_id, $module_path) 
  414. if (isset($this->_meta_info[$product_id])) { 
  415. $this->_meta_info[$product_id]['product-module-path'] = $module_path; 
  416.  
  417.  
  418. /** 
  419. * Retrieves a list of instantiated product ids 
  420. * @return array 
  421. */ 
  422. function get_product_list() 
  423. return array_keys($this->_products); 
  424.  
  425. /** 
  426. * Retrieves a list of registered product ids, including those that aren't loaded (i.e. get_product() call with those unloaded ids will fail) 
  427. * @return array 
  428. */ 
  429. function get_known_product_list() 
  430. $list = array_keys($this->_meta_info); 
  431. $return = array(); 
  432.  
  433. foreach ($list as $module_id) 
  434. if ($this->get_product_meta_list($module_id) != null) 
  435. $return[] = $module_id; 
  436.  
  437. return $return; 
  438.  
  439.  
  440. /** 
  441. * Registers an adapter for an interface with specific contexts 
  442. * @param string $interface 
  443. * @param string $class 
  444. * @param array $contexts 
  445. */ 
  446. function add_adapter($interface, $class, $contexts=FALSE) 
  447. // If no specific contexts are given, then we assume 
  448. // that the adapter is to be applied in ALL contexts 
  449. if (!$contexts) $contexts = array('all'); 
  450. if (!is_array($contexts)) $contexts = array($contexts); 
  451.  
  452. if (!isset($this->_adapters[$interface])) { 
  453. $this->_adapters[$interface] = array(); 
  454.  
  455. // Iterate through each specific context 
  456. foreach ($contexts as $context) { 
  457. if (!isset($this->_adapters[$interface][$context])) { 
  458. $this->_adapters[$interface][$context] = array(); 
  459. $this->_adapters[$interface][$context][] = $class; 
  460.  
  461.  
  462. /** 
  463. * Removes an adapter for an interface. May optionally specifify what 
  464. * contexts to remove the adapter from, leaving the rest intact 
  465. * @param string $interface 
  466. * @param string $class 
  467. * @param array $contexts 
  468. */ 
  469. function del_adapter($interface, $class, $contexts=FALSE) 
  470. // Ensure that contexts is an array of contexts 
  471. if (!$contexts) $contexts = array('all'); 
  472. if (!is_array($contexts)) $contexts = array($contexts); 
  473.  
  474. // Iterate through each context for an adapter 
  475. foreach ($this->_adapters[$interface] as $context => $classes) { 
  476. if (!$context OR in_array($context, $contexts)) { 
  477. $index = array_search($class, $classes); 
  478. unset($this->_adapters[$interface][$context][$index]); 
  479.  
  480.  
  481.  
  482.  
  483. /** 
  484. * Apply adapters registered for the component 
  485. * @param C_Component $component 
  486. * @return C_Component 
  487. */ 
  488. function &apply_adapters(C_Component &$component) 
  489. // Iterate through each adapted interface. If the component implements 
  490. // the interface, then apply the adapters 
  491. foreach ($this->_adapters as $interface => $contexts) { 
  492. if ($component->implements_interface($interface)) { 
  493.  
  494.  
  495. // Determine what context apply to the current component 
  496. $applied_contexts = array('all'); 
  497. if ($component->context) { 
  498. $applied_contexts[] = $component->context; 
  499. $applied_contexts = $this->_flatten_array($applied_contexts); 
  500.  
  501. // Iterate through each of the components contexts and apply the 
  502. // registered adapters 
  503. foreach ($applied_contexts as $context) { 
  504. if (isset($contexts[$context])) { 
  505. foreach ($contexts[$context] as $adapter) { 
  506. $component->add_mixin($adapter, FALSE); 
  507.  
  508.  
  509. return $component; 
  510.  
  511.  
  512. /** 
  513. * Adds a utility for an interface, to be used in particular contexts 
  514. * @param string $interface 
  515. * @param string $class 
  516. * @param array $contexts 
  517. */ 
  518. function add_utility($interface, $class, $contexts=FALSE) 
  519. // If no specific contexts are given, then we assume 
  520. // that the utility is for ALL contexts 
  521. if (!$contexts) $contexts = array('all'); 
  522. if (!is_array($contexts)) $contexts = array($contexts); 
  523.  
  524. if (!isset($this->_utilities[$interface])) { 
  525. $this->_utilities[$interface] = array(); 
  526.  
  527. // Add the utility for each appropriate context 
  528. foreach ($contexts as $context) { 
  529. $this->_utilities[$interface][$context] = $class; 
  530.  
  531.  
  532. /** 
  533. * Deletes a registered utility for a particular interface. 
  534. * @param string $interface 
  535. * @param array $contexts 
  536. */ 
  537. function del_utility($interface, $contexts=FALSE) 
  538. if (!$contexts) $contexts = array('all'); 
  539. if (!is_array($contexts)) $contexts = array($contexts); 
  540.  
  541. // Iterate through each context for an interface 
  542. foreach ($this->_utilities[$interface] as $context => $class) { 
  543. if (!$context OR in_array($context, $contexts)) { 
  544. unset($this->_utilities[$interface][$context]); 
  545.  
  546. /** 
  547. * Gets the class name of the component providing a utility implementation 
  548. * @param string $interface 
  549. * @param string|array $context 
  550. * @return string 
  551. */ 
  552. function get_utility_class_name($interface, $context=FALSE) 
  553. return $this->_retrieve_utility_class($interface, $context); 
  554.  
  555.  
  556. /** 
  557. * Retrieves an instantiates the registered utility for the provided instance. 
  558. * The instance is a singleton and must provide the get_instance() method 
  559. * @param string $interface 
  560. * @param string $context 
  561. * @return C_Component 
  562. */ 
  563. function get_utility($interface, $context=FALSE) 
  564. if (!$context) $context='all'; 
  565. $class = $this->_retrieve_utility_class($interface, $context); 
  566. return call_user_func("{$class}::get_instance", $context); 
  567.  
  568.  
  569. /** 
  570. * Flattens an array of arrays to a single array 
  571. * @param array $array 
  572. * @param array $parent (optional) 
  573. * @param bool $exclude_duplicates (optional - defaults to TRUE) 
  574. * @return array 
  575. */ 
  576. function _flatten_array($array, $parent=NULL, $exclude_duplicates=TRUE) 
  577. if (is_array($array)) { 
  578.  
  579. // We're to add each element to the parent array 
  580. if ($parent) { 
  581. foreach ($array as $index => $element) { 
  582. foreach ($this->_flatten_array($array) as $sub_element) { 
  583. if ($exclude_duplicates) { 
  584. if (!in_array($sub_element, $parent)) { 
  585. $parent[] = $sub_element; 
  586. else $parent[] = $sub_element; 
  587. $array = $parent; 
  588.  
  589. // We're starting the process.. 
  590. else { 
  591. $index = 0; 
  592. while (isset($array[$index])) { 
  593. $element = $array[$index]; 
  594. if (is_array($element)) { 
  595. $array = $this->_flatten_array($element, $array); 
  596. unset($array[$index]); 
  597. $index += 1; 
  598. $array = array_values($array); 
  599. else { 
  600. $array = array($array); 
  601.  
  602. return $array; 
  603.  
  604. function find_product_and_module_files($abspath, $recursive=FALSE) 
  605. $retval = array(); 
  606. static $recursive_level = 0; 
  607. static $exclusions = array('..', '.', 'error_log', 'README', 'CHANGELOG', 'readme.txt', 'changelog.txt'); 
  608. $recursive_level++; 
  609.  
  610. $abspath = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $abspath); 
  611. if (!in_array($abspath, $exclusions)) { 
  612. $contents = @scandir($abspath); 
  613. if ($contents) foreach ($contents as $filename) { 
  614. if (in_array($filename, $exclusions)) continue; 
  615. $filename_abspath = $abspath.DIRECTORY_SEPARATOR.$filename; 
  616.  
  617. // Is this a subdirectory? 
  618. // We don't use is_dir(), as it's less efficient than just checking for a 'dot' in the filename. 
  619. // The problem is that we're assuming that our directories won't contain a 'dot'. 
  620. if ($recursive && strpos($filename, '.') === FALSE) { 
  621.  
  622. // The recursive parameter can either be set to TRUE or the number of levels to navigate 
  623. // If we reach the max number of recursive levels we're supported to navigate, then we try 
  624. // to guess if there's a module or product file under the directory with the same name as 
  625. // the directory 
  626. if ($recursive === TRUE || (is_int($recursive) && $recursive_level <= $recursive)) { 
  627. $retval = array_merge($retval, $this->find_product_and_module_files($filename_abspath, $recursive)); 
  628.  
  629. elseif (@file_exists(($module_abspath = $filename_abspath.DIRECTORY_SEPARATOR.'module.'.$filename.'.php'))) { 
  630. $filename = 'module.'.$filename.'.php'; 
  631. $filename_abspath = $module_abspath; 
  632. elseif (@file_exists(($product_abspath = $filename_abspath.DIRECTORY_SEPARATOR.'product.'.$filename.'.php'))) { 
  633. $filename = 'product.'.$filename.'.php'; 
  634. $filename_abspath = $module_abspath; 
  635.  
  636.  
  637. if ((strpos($filename, 'module.') === 0 OR strpos($filename, 'product.') === 0) AND !$this->is_blacklisted($filename)) { 
  638. $retval[] = $filename_abspath; 
  639.  
  640. $this->mark_as_searched_path($abspath); 
  641.  
  642. $recursive_level--; 
  643.  
  644. return $retval; 
  645.  
  646.  
  647. /** 
  648. * Private API method. Retrieves the class which currently provides the utility 
  649. * @param string $interface 
  650. * @param string $context 
  651. */ 
  652. function _retrieve_utility_class($interface, $context='all') 
  653. $class = FALSE; 
  654.  
  655. if (!$context) $context = 'all'; 
  656. if (isset($this->_utilities[$interface])) { 
  657. if (isset($this->_utilities[$interface][$context])) { 
  658. $class = $this->_utilities[$interface][$context]; 
  659.  
  660. // No utility defined for the specified interface 
  661. else { 
  662. if ($context == 'all') $context = 'default'; 
  663. $class = $this->_retrieve_utility_class($interface, FALSE); 
  664. if (!$class) 
  665. throw new Exception("No utility registered for `{$interface}` with the `{$context}` context."); 
  666.  
  667. else throw new Exception("No utilities registered for `{$interface}`"); 
  668.  
  669. return $class; 
  670. /** 
  671. * Autoloads any classes, interfaces, or adapters needed by this module 
  672. */ 
  673. function _module_autoload($name) 
  674. // Pope classes are always prefixed 
  675. if (strpos($name, 'C_') !== 0 && strpos($name, 'A_') !== 0 && strpos($name, 'Mixin_') !== 0) { 
  676. return; 
  677.  
  678. if ($this->_module_type_cache == null || count($this->_modules) > $this->_module_type_cache_count) 
  679. $this->_module_type_cache_count = count($this->_modules); 
  680. $modules = $this->_modules; 
  681.  
  682. $keys = array(); 
  683. foreach ($modules as $mod => $properties) $keys[$mod] = $properties->module_version; 
  684. if (!($this->_module_type_cache = C_Pope_Cache::get($keys, array()))) { 
  685. foreach ($modules as $module_id => $module) 
  686. $dir = $this->get_module_dir($module_id); 
  687. $type_list = $module->get_type_list(); 
  688.  
  689. foreach ($type_list as $type => $filename) 
  690. $this->_module_type_cache[strtolower($type)] = $dir . DIRECTORY_SEPARATOR . $filename; 
  691. C_Pope_Cache::set($keys, $this->_module_type_cache); 
  692. elseif (is_object($this->_module_type_cache)) $this->_module_type_cache = get_object_vars($this->_module_type_cache); 
  693.  
  694. $name = strtolower($name); 
  695.  
  696. if (isset($this->_module_type_cache[$name])) 
  697. $module_filename = $this->_module_type_cache[$name]; 
  698.  
  699. if (file_exists($module_filename)) 
  700. require_once($module_filename);