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-2011, 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-2011, 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:
19: App::uses('ObjectCollection', 'Utility');
20: App::uses('Component', 'Controller');
21:
22: /**
23: * Components collection is used as a registry for loaded components and handles loading
24: * and constructing component class objects.
25: *
26: * @package Cake.Controller
27: */
28: class ComponentCollection extends ObjectCollection {
29:
30: /**
31: * The controller that this collection was initialized with.
32: *
33: * @var Controller
34: */
35: protected $_Controller = null;
36:
37: /**
38: * Initializes all the Components for a controller.
39: * Attaches a reference of each component to the Controller.
40: *
41: * @param Controller $Controller Controller to initialize components for.
42: * @return void
43: */
44: public function init(Controller $Controller) {
45: if (empty($Controller->components)) {
46: return;
47: }
48: $this->_Controller = $Controller;
49: $components = ComponentCollection::normalizeObjectArray($Controller->components);
50: foreach ($components as $name => $properties) {
51: $Controller->{$name} = $this->load($properties['class'], $properties['settings']);
52: }
53: }
54:
55: /**
56: * Get the controller associated with the collection.
57: *
58: * @return Controller.
59: */
60: public function getController() {
61: return $this->_Controller;
62: }
63:
64: /**
65: * Loads/constructs a component. Will return the instance in the registry if it already exists.
66: * You can use `$settings['enabled'] = false` to disable callbacks on a component when loading it.
67: * Callbacks default to on. Disabled component methods work as normal, only callbacks are disabled.
68: *
69: * You can alias your component as an existing component by setting the 'className' key, i.e.,
70: * {{{
71: * public $components = array(
72: * 'Email' => array(
73: * 'className' => 'AliasedEmail'
74: * );
75: * );
76: * }}}
77: * All calls to the `Email` component would use `AliasedEmail` instead.
78: *
79: * @param string $component Component name to load
80: * @param array $settings Settings for the component.
81: * @return Component A component object, Either the existing loaded component or a new one.
82: * @throws MissingComponentException when the component could not be found
83: */
84: public function load($component, $settings = array()) {
85: if (is_array($settings) && isset($settings['className'])) {
86: $alias = $component;
87: $component = $settings['className'];
88: }
89: list($plugin, $name) = pluginSplit($component, true);
90: if (!isset($alias)) {
91: $alias = $name;
92: }
93: if (isset($this->_loaded[$alias])) {
94: return $this->_loaded[$alias];
95: }
96: $componentClass = $name . 'Component';
97: App::uses($componentClass, $plugin . 'Controller/Component');
98: if (!class_exists($componentClass)) {
99: throw new MissingComponentException(array(
100: 'class' => $componentClass
101: ));
102: }
103: $this->_loaded[$alias] = new $componentClass($this, $settings);
104: $enable = isset($settings['enabled']) ? $settings['enabled'] : true;
105: if ($enable === true) {
106: $this->_enabled[] = $alias;
107: }
108: return $this->_loaded[$alias];
109: }
110:
111: }