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); } if ($code == 'viewBag' && $className != 'Cms\Classes\ViewBag') { throw new SystemException(sprintf( 'The component code viewBag is reserved. Please use another code for the component class %s.', $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) { throw new SystemException(sprintf( 'Class name is not registered for the component %s. Check the component plugin.', $name )); } if (!class_exists($className)) { throw new SystemException(sprintf( 'Component class not found %s.Check the component plugin.', $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; } }