ComponentCollection.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. /**
  3. * Components collection is used as a registry for loaded components and handles loading
  4. * and constructing component class objects.
  5. *
  6. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  7. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  8. *
  9. * Licensed under The MIT License
  10. * Redistributions of files must retain the above copyright notice.
  11. *
  12. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://cakephp.org CakePHP(tm) Project
  14. * @package Cake.Controller
  15. * @since CakePHP(tm) v 2.0
  16. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  17. */
  18. App::uses('ObjectCollection', 'Utility');
  19. App::uses('Component', 'Controller');
  20. App::uses('CakeEventListener', 'Event');
  21. /**
  22. * Components collection is used as a registry for loaded components and handles loading
  23. * and constructing component class objects.
  24. *
  25. * @package Cake.Controller
  26. */
  27. class ComponentCollection extends ObjectCollection implements CakeEventListener {
  28. /**
  29. * The controller that this collection was initialized with.
  30. *
  31. * @var Controller
  32. */
  33. protected $_Controller = null;
  34. /**
  35. * Initializes all the Components for a controller.
  36. * Attaches a reference of each component to the Controller.
  37. *
  38. * @param Controller $Controller Controller to initialize components for.
  39. * @return void
  40. */
  41. public function init(Controller $Controller) {
  42. if (empty($Controller->components)) {
  43. return;
  44. }
  45. $this->_Controller = $Controller;
  46. $components = ComponentCollection::normalizeObjectArray($Controller->components);
  47. foreach ($components as $name => $properties) {
  48. $Controller->{$name} = $this->load($properties['class'], $properties['settings']);
  49. }
  50. }
  51. /**
  52. * Get the controller associated with the collection.
  53. *
  54. * @return Controller Controller instance
  55. */
  56. public function getController() {
  57. return $this->_Controller;
  58. }
  59. /**
  60. * Loads/constructs a component. Will return the instance in the registry if it already exists.
  61. * You can use `$settings['enabled'] = false` to disable callbacks on a component when loading it.
  62. * Callbacks default to on. Disabled component methods work as normal, only callbacks are disabled.
  63. *
  64. * You can alias your component as an existing component by setting the 'className' key, i.e.,
  65. * {{{
  66. * public $components = array(
  67. * 'Email' => array(
  68. * 'className' => 'AliasedEmail'
  69. * );
  70. * );
  71. * }}}
  72. * All calls to the `Email` component would use `AliasedEmail` instead.
  73. *
  74. * @param string $component Component name to load
  75. * @param array $settings Settings for the component.
  76. * @return Component A component object, Either the existing loaded component or a new one.
  77. * @throws MissingComponentException when the component could not be found
  78. */
  79. public function load($component, $settings = array()) {
  80. if (is_array($settings) && isset($settings['className'])) {
  81. $alias = $component;
  82. $component = $settings['className'];
  83. }
  84. list($plugin, $name) = pluginSplit($component, true);
  85. if (!isset($alias)) {
  86. $alias = $name;
  87. }
  88. if (isset($this->_loaded[$alias])) {
  89. return $this->_loaded[$alias];
  90. }
  91. $componentClass = $name . 'Component';
  92. App::uses($componentClass, $plugin . 'Controller/Component');
  93. if (!class_exists($componentClass)) {
  94. throw new MissingComponentException(array(
  95. 'class' => $componentClass,
  96. 'plugin' => substr($plugin, 0, -1)
  97. ));
  98. }
  99. $this->_loaded[$alias] = new $componentClass($this, $settings);
  100. $enable = isset($settings['enabled']) ? $settings['enabled'] : true;
  101. if ($enable) {
  102. $this->enable($alias);
  103. }
  104. return $this->_loaded[$alias];
  105. }
  106. /**
  107. * Returns the implemented events that will get routed to the trigger function
  108. * in order to dispatch them separately on each component
  109. *
  110. * @return array
  111. */
  112. public function implementedEvents() {
  113. return array(
  114. 'Controller.initialize' => array('callable' => 'trigger'),
  115. 'Controller.startup' => array('callable' => 'trigger'),
  116. 'Controller.beforeRender' => array('callable' => 'trigger'),
  117. 'Controller.beforeRedirect' => array('callable' => 'trigger'),
  118. 'Controller.shutdown' => array('callable' => 'trigger'),
  119. );
  120. }
  121. }