callbacks as $callback) { $callback($this); } /* * Load plugin components */ $pluginManager = PluginManager::instance(); $plugins = $pluginManager->getPlugins(); foreach ($plugins as $plugin) { $components = $plugin->registerComponents(); if (!is_array($components)) continue; foreach ($components as $className => $code) { $this->registerComponent($className, $code, $plugin); } } } /** * Manually registers a widget for consideration. * Usage: *
     *   ComponentManager::registerComponents(function($manager){
     *       $manager->registerComponent('October\Demo\Components\Test', 'testComponent');
     *   });
     * 
* * @return array Array values are class names. */ public function registerComponents(callable $definitions) { $this->callbacks[] = $definitions; } /** * Registers a single component. */ public function registerComponent($className, $code = null, $plugin = null) { if (!$this->classMap) $this->classMap = []; if (!$this->codeMap) $this->codeMap = []; if (!$code) $code = Str::getClassId($className); $className = Str::normalizeClassName($className); $this->codeMap[$code] = $className; $this->classMap[$className] = $code; if ($plugin !== null) $this->pluginMap[$className] = $plugin; } /** * Returns a list of registered components. * @return array Array keys are codes, values are class names. */ public function listComponents() { if ($this->codeMap === null) $this->loadComponents(); return $this->codeMap; } /** * Returns an array of all component detail definitions. * @return array Array keys are component codes, values are the details defined in the component. */ public function listComponentDetails() { if ($this->detailsCache !== null) return $this->detailsCache; $details = []; foreach ($this->listComponents() as $componentAlias => $componentClass) { $details[$componentAlias] = $this->makeComponent($componentClass)->componentDetails(); } return $this->detailsCache = $details; } /** * Returns a class name from a component code * Normalizes a class name or converts an code to it's class name. * @return string The class name resolved, or null. */ public function resolve($name) { $codes = $this->listComponents(); if (isset($codes[$name])) return $codes[$name]; $name = Str::normalizeClassName($name); if (isset($this->classMap[$name])) return $name; return null; } /** * Checks to see if a component has been registered. * @param string $name A component class name or code. * @return bool Returns true if the component is registered, otherwise false. */ public function hasComponent($name) { $className = $this->resolve($name); if (!$className) return false; return isset($this->classMap[$className]); } /** * Makes a component object with properties set. * @param $name A component class name or code. * @param CmsObject $cmsObject The Cms object that spawned this component. * @param array $properties The properties set by the Page or Layout. * @return ComponentBase The component object. */ public function makeComponent($name, $cmsObject = null, $properties = []) { $className = $this->resolve($name); if (!$className) return null; if (!class_exists($className)) throw new \Exception('Component class not found '.$className); $component = new $className($cmsObject, $properties); $component->name = $name; return $component; } /** * Returns a parent plugin for a specific component object. * @param mixed $component A component to find the plugin for. * @return mixed Returns the plugin object or null. */ public function findComponentPlugin($component) { $className = Str::normalizeClassName(get_class($component)); if (isset($this->pluginMap[$className])) return $this->pluginMap[$className]; return null; } }