CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Team
    • Issues (Github)
    • YouTube Channel
    • Get Involved
    • Bakery
    • Featured Resources
    • Newsletter
    • Certification
    • My CakePHP
    • CakeFest
    • Facebook
    • Twitter
    • Help & Support
    • Forum
    • Stack Overflow
    • IRC
    • Slack
    • Paid Support
CakePHP

C CakePHP 3.7 Red Velvet API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.7
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Namespaces

  • Cake
    • Auth
      • Storage
    • Cache
      • Engine
    • Collection
      • Iterator
    • Command
    • Console
      • Exception
    • Controller
      • Component
      • Exception
    • Core
      • Configure
        • Engine
      • Exception
      • Retry
    • Database
      • Driver
      • Exception
      • Expression
      • Schema
      • Statement
      • Type
    • Datasource
      • Exception
    • Error
      • Middleware
    • Event
      • Decorator
    • Filesystem
    • Form
    • Http
      • Client
        • Adapter
        • Auth
      • Cookie
      • Exception
      • Middleware
      • Session
    • I18n
      • Formatter
      • Middleware
      • Parser
    • Log
      • Engine
    • Mailer
      • Exception
      • Transport
    • Network
      • Exception
    • ORM
      • Association
      • Behavior
        • Translate
      • Exception
      • Locator
      • Rule
    • Routing
      • Exception
      • Filter
      • Middleware
      • Route
    • Shell
      • Helper
      • Task
    • TestSuite
      • Fixture
      • Stub
    • Utility
      • Exception
    • Validation
    • View
      • Exception
      • Form
      • Helper
      • Widget
  • None

Classes

  • App
  • BasePlugin
  • ClassLoader
  • Configure
  • ObjectRegistry
  • Plugin
  • PluginCollection

Interfaces

  • ConsoleApplicationInterface
  • HttpApplicationInterface
  • PluginApplicationInterface
  • PluginInterface

Traits

  • ConventionsTrait
  • InstanceConfigTrait
  • StaticConfigTrait
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5:  *
  6:  * Licensed under The MIT License
  7:  * For full copyright and license information, please see the LICENSE.txt
  8:  * Redistributions of files must retain the above copyright notice.
  9:  *
 10:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 11:  * @link          https://cakephp.org CakePHP(tm) Project
 12:  * @since         3.0.0
 13:  * @license       https://opensource.org/licenses/mit-license.php MIT License
 14:  */
 15: namespace Cake\Core;
 16: 
 17: use ArrayIterator;
 18: use Cake\Event\EventDispatcherInterface;
 19: use Cake\Event\EventListenerInterface;
 20: use Countable;
 21: use IteratorAggregate;
 22: use RuntimeException;
 23: 
 24: /**
 25:  * Acts as a registry/factory for objects.
 26:  *
 27:  * Provides registry & factory functionality for object types. Used
 28:  * as a super class for various composition based re-use features in CakePHP.
 29:  *
 30:  * Each subclass needs to implement the various abstract methods to complete
 31:  * the template method load().
 32:  *
 33:  * The ObjectRegistry is EventManager aware, but each extending class will need to use
 34:  * \Cake\Event\EventDispatcherTrait to attach and detach on set and bind
 35:  *
 36:  * @see \Cake\Controller\ComponentRegistry
 37:  * @see \Cake\View\HelperRegistry
 38:  * @see \Cake\Console\TaskRegistry
 39:  */
 40: abstract class ObjectRegistry implements Countable, IteratorAggregate
 41: {
 42: 
 43:     /**
 44:      * Map of loaded objects.
 45:      *
 46:      * @var object[]
 47:      */
 48:     protected $_loaded = [];
 49: 
 50:     /**
 51:      * Loads/constructs an object instance.
 52:      *
 53:      * Will return the instance in the registry if it already exists.
 54:      * If a subclass provides event support, you can use `$config['enabled'] = false`
 55:      * to exclude constructed objects from being registered for events.
 56:      *
 57:      * Using Cake\Controller\Controller::$components as an example. You can alias
 58:      * an object by setting the 'className' key, i.e.,
 59:      *
 60:      * ```
 61:      * public $components = [
 62:      *   'Email' => [
 63:      *     'className' => '\App\Controller\Component\AliasedEmailComponent'
 64:      *   ];
 65:      * ];
 66:      * ```
 67:      *
 68:      * All calls to the `Email` component would use `AliasedEmail` instead.
 69:      *
 70:      * @param string $objectName The name/class of the object to load.
 71:      * @param array $config Additional settings to use when loading the object.
 72:      * @return mixed
 73:      * @throws \Exception If the class cannot be found.
 74:      */
 75:     public function load($objectName, $config = [])
 76:     {
 77:         if (is_array($config) && isset($config['className'])) {
 78:             $name = $objectName;
 79:             $objectName = $config['className'];
 80:         } else {
 81:             list(, $name) = pluginSplit($objectName);
 82:         }
 83: 
 84:         $loaded = isset($this->_loaded[$name]);
 85:         if ($loaded && !empty($config)) {
 86:             $this->_checkDuplicate($name, $config);
 87:         }
 88:         if ($loaded) {
 89:             return $this->_loaded[$name];
 90:         }
 91: 
 92:         $className = $this->_resolveClassName($objectName);
 93:         if (!$className || (is_string($className) && !class_exists($className))) {
 94:             list($plugin, $objectName) = pluginSplit($objectName);
 95:             $this->_throwMissingClassError($objectName, $plugin);
 96:         }
 97:         $instance = $this->_create($className, $name, $config);
 98:         $this->_loaded[$name] = $instance;
 99: 
100:         return $instance;
101:     }
102: 
103:     /**
104:      * Check for duplicate object loading.
105:      *
106:      * If a duplicate is being loaded and has different configuration, that is
107:      * bad and an exception will be raised.
108:      *
109:      * An exception is raised, as replacing the object will not update any
110:      * references other objects may have. Additionally, simply updating the runtime
111:      * configuration is not a good option as we may be missing important constructor
112:      * logic dependent on the configuration.
113:      *
114:      * @param string $name The name of the alias in the registry.
115:      * @param array $config The config data for the new instance.
116:      * @return void
117:      * @throws \RuntimeException When a duplicate is found.
118:      */
119:     protected function _checkDuplicate($name, $config)
120:     {
121:         /** @var \Cake\Core\InstanceConfigTrait $existing */
122:         $existing = $this->_loaded[$name];
123:         $msg = sprintf('The "%s" alias has already been loaded', $name);
124:         $hasConfig = method_exists($existing, 'config');
125:         if (!$hasConfig) {
126:             throw new RuntimeException($msg);
127:         }
128:         if (empty($config)) {
129:             return;
130:         }
131:         $existingConfig = $existing->getConfig();
132:         unset($config['enabled'], $existingConfig['enabled']);
133: 
134:         $fail = false;
135:         foreach ($config as $key => $value) {
136:             if (!array_key_exists($key, $existingConfig)) {
137:                 $fail = true;
138:                 break;
139:             }
140:             if (isset($existingConfig[$key]) && $existingConfig[$key] !== $value) {
141:                 $fail = true;
142:                 break;
143:             }
144:         }
145:         if ($fail) {
146:             $msg .= ' with the following config: ';
147:             $msg .= var_export($existingConfig, true);
148:             $msg .= ' which differs from ' . var_export($config, true);
149:             throw new RuntimeException($msg);
150:         }
151:     }
152: 
153:     /**
154:      * Should resolve the classname for a given object type.
155:      *
156:      * @param string $class The class to resolve.
157:      * @return string|bool The resolved name or false for failure.
158:      */
159:     abstract protected function _resolveClassName($class);
160: 
161:     /**
162:      * Throw an exception when the requested object name is missing.
163:      *
164:      * @param string $class The class that is missing.
165:      * @param string $plugin The plugin $class is missing from.
166:      * @return void
167:      * @throws \Exception
168:      */
169:     abstract protected function _throwMissingClassError($class, $plugin);
170: 
171:     /**
172:      * Create an instance of a given classname.
173:      *
174:      * This method should construct and do any other initialization logic
175:      * required.
176:      *
177:      * @param string $class The class to build.
178:      * @param string $alias The alias of the object.
179:      * @param array $config The Configuration settings for construction
180:      * @return mixed
181:      */
182:     abstract protected function _create($class, $alias, $config);
183: 
184:     /**
185:      * Get the list of loaded objects.
186:      *
187:      * @return string[] List of object names.
188:      */
189:     public function loaded()
190:     {
191:         return array_keys($this->_loaded);
192:     }
193: 
194:     /**
195:      * Check whether or not a given object is loaded.
196:      *
197:      * @param string $name The object name to check for.
198:      * @return bool True is object is loaded else false.
199:      */
200:     public function has($name)
201:     {
202:         return isset($this->_loaded[$name]);
203:     }
204: 
205:     /**
206:      * Get loaded object instance.
207:      *
208:      * @param string $name Name of object.
209:      * @return object|null Object instance if loaded else null.
210:      */
211:     public function get($name)
212:     {
213:         if (isset($this->_loaded[$name])) {
214:             return $this->_loaded[$name];
215:         }
216: 
217:         return null;
218:     }
219: 
220:     /**
221:      * Provide public read access to the loaded objects
222:      *
223:      * @param string $name Name of property to read
224:      * @return mixed
225:      */
226:     public function __get($name)
227:     {
228:         return $this->get($name);
229:     }
230: 
231:     /**
232:      * Provide isset access to _loaded
233:      *
234:      * @param string $name Name of object being checked.
235:      * @return bool
236:      */
237:     public function __isset($name)
238:     {
239:         return isset($this->_loaded[$name]);
240:     }
241: 
242:     /**
243:      * Sets an object.
244:      *
245:      * @param string $name Name of a property to set.
246:      * @param mixed $object Object to set.
247:      * @return void
248:      */
249:     public function __set($name, $object)
250:     {
251:         $this->set($name, $object);
252:     }
253: 
254:     /**
255:      * Unsets an object.
256:      *
257:      * @param string $name Name of a property to unset.
258:      * @return void
259:      */
260:     public function __unset($name)
261:     {
262:         $this->unload($name);
263:     }
264: 
265:     /**
266:      * Normalizes an object array, creates an array that makes lazy loading
267:      * easier
268:      *
269:      * @param array $objects Array of child objects to normalize.
270:      * @return array Array of normalized objects.
271:      */
272:     public function normalizeArray($objects)
273:     {
274:         $normal = [];
275:         foreach ($objects as $i => $objectName) {
276:             $config = [];
277:             if (!is_int($i)) {
278:                 $config = (array)$objectName;
279:                 $objectName = $i;
280:             }
281:             list(, $name) = pluginSplit($objectName);
282:             if (isset($config['class'])) {
283:                 $normal[$name] = $config;
284:             } else {
285:                 $normal[$name] = ['class' => $objectName, 'config' => $config];
286:             }
287:         }
288: 
289:         return $normal;
290:     }
291: 
292:     /**
293:      * Clear loaded instances in the registry.
294:      *
295:      * If the registry subclass has an event manager, the objects will be detached from events as well.
296:      *
297:      * @return $this
298:      */
299:     public function reset()
300:     {
301:         foreach (array_keys($this->_loaded) as $name) {
302:             $this->unload($name);
303:         }
304: 
305:         return $this;
306:     }
307: 
308:     /**
309:      * Set an object directly into the registry by name.
310:      *
311:      * If this collection implements events, the passed object will
312:      * be attached into the event manager
313:      *
314:      * @param string $objectName The name of the object to set in the registry.
315:      * @param object $object instance to store in the registry
316:      * @return $this
317:      */
318:     public function set($objectName, $object)
319:     {
320:         list(, $name) = pluginSplit($objectName);
321: 
322:         // Just call unload if the object was loaded before
323:         if (array_key_exists($objectName, $this->_loaded)) {
324:             $this->unload($objectName);
325:         }
326:         if ($this instanceof EventDispatcherInterface && $object instanceof EventListenerInterface) {
327:             $this->getEventManager()->on($object);
328:         }
329:         $this->_loaded[$name] = $object;
330: 
331:         return $this;
332:     }
333: 
334:     /**
335:      * Remove an object from the registry.
336:      *
337:      * If this registry has an event manager, the object will be detached from any events as well.
338:      *
339:      * @param string $objectName The name of the object to remove from the registry.
340:      * @return $this
341:      */
342:     public function unload($objectName)
343:     {
344:         if (empty($this->_loaded[$objectName])) {
345:             list($plugin, $objectName) = pluginSplit($objectName);
346:             $this->_throwMissingClassError($objectName, $plugin);
347:         }
348: 
349:         $object = $this->_loaded[$objectName];
350:         if ($this instanceof EventDispatcherInterface && $object instanceof EventListenerInterface) {
351:             $this->getEventManager()->off($object);
352:         }
353:         unset($this->_loaded[$objectName]);
354: 
355:         return $this;
356:     }
357: 
358:     /**
359:      * Returns an array iterator.
360:      *
361:      * @return \ArrayIterator
362:      */
363:     public function getIterator()
364:     {
365:         return new ArrayIterator($this->_loaded);
366:     }
367: 
368:     /**
369:      * Returns the number of loaded objects.
370:      *
371:      * @return int
372:      */
373:     public function count()
374:     {
375:         return count($this->_loaded);
376:     }
377: 
378:     /**
379:      * Debug friendly object properties.
380:      *
381:      * @return array
382:      */
383:     public function __debugInfo()
384:     {
385:         $properties = get_object_vars($this);
386:         if (isset($properties['_loaded'])) {
387:             $properties['_loaded'] = array_keys($properties['_loaded']);
388:         }
389: 
390:         return $properties;
391:     }
392: }
393: 
Follow @CakePHP
#IRC
OpenHub
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Logos & Trademarks
  • Community
  • Team
  • Issues (Github)
  • YouTube Channel
  • Get Involved
  • Bakery
  • Featured Resources
  • Newsletter
  • Certification
  • My CakePHP
  • CakeFest
  • Facebook
  • Twitter
  • Help & Support
  • Forum
  • Stack Overflow
  • IRC
  • Slack
  • Paid Support

Generated using CakePHP API Docs