/** * This method is used internally by {@link nutshell\core\loader\Loader} to * create/return instances of plugins. This almost always happens when * something attempts to access the plugin via a plugin shortcut since these * always point to the Loader's plugin container. * * @internal * @access public * @static * @param Array $args - Args to be passed to the plugin constructor. * @throws Exception - If one of the base behaviours is not implemented. * @return nutshell\core\plugin\Plugin */ public static function getInstance(array $args = array()) { $className = get_called_class(); //If $instance is set, then it is definately a singleton. if (!isset($GLOBALS['NUTSHELL_PLUGIN_SINGLETON'][$className])) { $instance = new static(); self::applyBehaviours($instance); $GLOBALS['NUTSHELL_PLUGIN_SINGLETON'][$className] = $instance; $namespace = ObjectHelper::getNamespace($className); list(, , $plugin) = explode('\\', $namespace); if (is_dir(NS_HOME . 'plugin' . _DS_ . $plugin . _DS_)) { $dir = NS_HOME . 'plugin' . _DS_ . $plugin . _DS_; } else { if (is_dir(APP_HOME . 'plugin' . _DS_ . $plugin . _DS_)) { $dir = APP_HOME . 'plugin' . _DS_ . $plugin . _DS_; } else { throw new PluginException(PluginException::LIBRARY_NOT_FOUND, NS_HOME . 'plugin' . _DS_ . $plugin . _DS_, APP_HOME . 'plugin' . _DS_ . $plugin . _DS_); } } /** * Of note, the plugin which instaciates */ foreach (new DirectoryIterator($dir) as $iteration) { //We don't load folders or files from within folders. if ($iteration->isFile() && !(substr($iteration->getBasename(), 0, 1) == '.')) { require_once $iteration->getPathname(); } } $instance->init(); } //It must be a singleton. Return the instance. return $GLOBALS['NUTSHELL_PLUGIN_SINGLETON'][$className]; }
public static function registerBehaviours() { static::registerBehaviour(get_called_class(), 'NamedSession', function ($classInstance) { $session = Nutshell::getInstance()->plugin->Session; if (!isset($session->{ObjectHelper::getBaseClassName($classInstance)})) { $session->{ObjectHelper::getBaseClassName($classInstance)} = new stdClass(); } $classInstance->session = $session->{ObjectHelper::getBaseClassName($classInstance)}; }); }
/** * This is a helper method for loading a child class. * * This method is usually used when a component implements * the {link:register}() method. * * @param Array $files - An array of file paths to load. * @static * @access public * @return void; */ public static function load($files) { $directory = ObjectHelper::getClassPath(get_called_class()); if (!is_array($files)) { $files = array($files); } for ($i = 0, $j = count($files); $i < $j; $i++) { $file = $directory . $files[$i]; require $file; } }
private function getParentPlugin() { $NS = ObjectHelper::getNamespace($this); $NSParts = explode('\\', $NS); if ($NSParts[1] == 'plugin') { if (isset($NSParts[2])) { $NSParts[2] = ucwords($NSParts[2]); } else { throw new PluginException(PluginException::NO_PARENT_PLUGIN, 'Unable to find parent plugin.'); } return $NSParts[0] . '\\' . $NSParts[1] . '\\' . $NSParts[2]; } else { throw new PluginException(PluginException::INCORRECT_CONTEXT, 'Attempted to use PluginExtension outside of plugin context.'); } }
public function buildDescriptor() { $descriptor = array(); foreach ($this->config->{$this->ref}->providers as $providerName => $provider) { if ($provider->type == 'polling') { $thisProvider = array('type' => $provider->type, 'url' => $this->plugin->Url->makeURL(strtolower(ObjectHelper::getBaseClassName($this->controller)) . '/' . $providerName), 'interval' => isset($provider->interval) ? $provider->interval : self::DEFAULT_INTERVAL); } else { if ($provider->type == 'remoting') { $thisProvider = array('type' => $provider->type, 'url' => $this->plugin->Url->makeURL(strtolower(ObjectHelper::getBaseClassName($this->controller)) . '/' . $providerName), 'namespace' => $this->nsPrefix . '.' . $providerName, 'actions' => array()); foreach ($provider->modules as $moduleName => $module) { for ($i = 0, $j = count($module); $i < $j; $i++) { $thisProvider['actions'][$moduleName][] = array('name' => $module[$i]->name, 'len' => $module[$i]->args); } } } else { throw new DirectException(DirectException::INVALID_PROVIDER_TYPE, $provider->type); } } $descriptor[] = $thisProvider; } header('Content-type:application/json;'); print json_encode($descriptor); }
public static function autoload($className) { $namespace = ObjectHelper::getNamespace($className); $className = ObjectHelper::getBaseClassName($className); //Check for an application plugin's library class. // if (strstr($namespace,'plugin\\')) // { // $namespaceParts =explode('\\',$namespace); // $where =array_shift($namespaceParts); // $filePath =false; // if ($where==='nutshell') // { // $filePath=NS_HOME.implode(_DS_,$namespaceParts)._DS_.$className.'.php'; // } // else if ($where==='application') // { // $filePath=APP_HOME.implode(_DS_,$namespaceParts)._DS_.$className.'.php'; // } // if (is_file($filePath)) // { // //Invoke the plugin. // require_once($filePath); // } // else // { // throw new ('Unable to autoload class "'.$namespace.'\\'.$className.'".'); // } // } // //Check for a plugin behaviour. // else if (strstr($namespace, 'behaviour\\')) { list(, , $plugin) = explode('\\', $namespace); $pathSuffix = 'plugin' . _DS_ . $plugin . _DS_ . 'behaviour' . _DS_ . $className . '.php'; if (is_file($file = NS_HOME . $pathSuffix)) { //Invoke the plugin. Nutshell::getInstance()->plugin->{ucfirst($plugin)}; } else { if (is_file($file = APP_HOME . $pathSuffix)) { Nutshell::getInstance()->plugin->{ucfirst($plugin)}; } else { throw new LoaderException(LoaderException::CANNOT_AUTOLOAD_CLASS, 'Unable to autoload class "' . $namespace . $className . '".'); } } } else { $namespaceParts = explode('\\', $namespace); $where = array_shift($namespaceParts); $filePath = false; if ($where === 'nutshell') { $filePath = NS_HOME . implode(_DS_, $namespaceParts) . _DS_ . $className . '.php'; } else { if ($where === 'application') { $filePath = APP_HOME . implode(_DS_, $namespaceParts) . _DS_ . $className . '.php'; } } if (is_file($filePath)) { //Invoke the plugin. require $filePath; } else { throw new LoaderException(LoaderException::CANNOT_AUTOLOAD_CLASS, 'Unable to autoload class "' . $namespace . '\\' . $className . '"', '"' . $filePath . '" does not exist'); } } }
/** * Register's a custom behavior with attached functionality. * * You would usually attach a closure to this method as the callback and embed * functionality which performs the specific "behaviour". * * The closure must accept a single parameter "$classInstance" which is the instance * of the class which has implemented the custom behaviour. * * @access protected * @static * @param Mixed $plugin - Either the plugin name or an instance of the plugin. * @param String $behaviourName - The name of the behaviour to register. * @param Mixed $callback - A function reference or Closure. * @return Void * @throws Exception */ protected static function registerBehaviour($plugin, $behaviourName, $callback) { $pluginName = lcfirst(ObjectHelper::getBaseClassName($plugin)); $behaviour = 'nutshell\\behaviour\\' . $pluginName . '\\' . $behaviourName; if (!isset(self::$behaviours[$behaviour])) { self::$behaviours[$behaviour] = $callback; } else { throw new Exception('Plugin ".$pluginName." tried to define the behaviour "' . $behaviourName . '". But this behaviour has already been defined.'); } }