diff options
Diffstat (limited to 'engine/classes/ElggPlugin.php')
| -rw-r--r-- | engine/classes/ElggPlugin.php | 312 |
1 files changed, 180 insertions, 132 deletions
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php index 18d97d23a..545b9a53c 100644 --- a/engine/classes/ElggPlugin.php +++ b/engine/classes/ElggPlugin.php @@ -9,11 +9,12 @@ * @subpackage Plugins.Settings */ class ElggPlugin extends ElggObject { - public $package; - public $manifest; + private $package; + private $manifest; private $path; private $pluginID; + private $errorMsg = ''; /** * Set subtype to 'plugin' @@ -29,15 +30,15 @@ class ElggPlugin extends ElggObject { $this->access_id = ACCESS_PUBLIC; } - /** * Loads the plugin by GUID or path. * * @warning Unlike other ElggEntity objects, you cannot null instantiate * ElggPlugin. You must point it to an actual plugin GUID or location. * - * @param mixed $plugin The GUID of the ElggPlugin object or the path of - * the plugin to load. + * @param mixed $plugin The GUID of the ElggPlugin object or the path of the plugin to load. + * + * @throws PluginException */ public function __construct($plugin) { if (!$plugin) { @@ -77,19 +78,9 @@ class ElggPlugin extends ElggObject { parent::__construct($existing_guid); } - // We have to let the entity load so we can manipulate it with the API. - // If the path is wrong or would cause an exception, catch it, - // disable the plugin, and emit an error. - try { - $this->package = new ElggPluginPackage($this->path, false); - $this->manifest = $this->package->getManifest(); - } catch (Exception $e) { - // we always have to allow the entity to load. - elgg_log("Failed to load $this->guid as a plugin. " . $e->getMessage(), 'WARNING'); - } + _elgg_cache_plugin_by_id($this); } - /** * Save the plugin object. Make sure required values exist. * @@ -128,6 +119,21 @@ class ElggPlugin extends ElggObject { } /** + * Returns the manifest's name if available, otherwise the ID. + * + * @return string + * @since 1.8.1 + */ + public function getFriendlyName() { + $manifest = $this->getManifest(); + if ($manifest) { + return $manifest->getName(); + } + + return $this->getID(); + } + + /** * Returns the plugin's full path with trailing slash. * * @return string @@ -136,17 +142,33 @@ class ElggPlugin extends ElggObject { return sanitise_filepath($this->path); } - /** * Sets the location of this plugin. * - * @param path $id The path to the plugin's dir. + * @param string $id The path to the plugin's dir. * @return bool */ public function setID($id) { return $this->attributes['title'] = $id; } + /** + * Returns an array of available markdown files for this plugin + * + * @return array + */ + public function getAvailableTextFiles() { + $filenames = $this->getPackage()->getTextFilenames(); + + $files = array(); + foreach ($filenames as $filename) { + if ($this->canReadFile($filename)) { + $files[$filename] = "$this->path/$filename"; + } + } + + return $files; + } // Load Priority @@ -160,7 +182,6 @@ class ElggPlugin extends ElggObject { return $this->$name; } - /** * Sets the priority of the plugin * @@ -177,8 +198,9 @@ class ElggPlugin extends ElggObject { $db_prefix = get_config('dbprefix'); $name = elgg_namespace_plugin_private_setting('internal', 'priority'); - // if no priority assume a priority of 0 + // if no priority assume a priority of 1 $old_priority = (int) $this->getPriority(); + $old_priority = (!$old_priority) ? 1 : $old_priority; $max_priority = elgg_get_max_plugin_priority(); // can't use switch here because it's not strict and @@ -194,15 +216,11 @@ class ElggPlugin extends ElggObject { } // should be a number by now - if ($priority) { + if ($priority > 0) { if (!is_numeric($priority)) { return false; } - if ($priority == $old_priority) { - return false; - } - // there's nothing above the max. if ($priority > $max_priority) { $priority = $max_priority; @@ -234,7 +252,6 @@ class ElggPlugin extends ElggObject { // set this priority if ($this->set($name, $priority)) { - //return elgg_plugins_reindex_priorities(); return true; } else { return false; @@ -250,8 +267,6 @@ class ElggPlugin extends ElggObject { /** * Returns a plugin setting * - * @todo These need to be namespaced - * * @param string $name The setting name * @return mixed */ @@ -284,27 +299,21 @@ class ElggPlugin extends ElggObject { $private_settings = get_data($q); - if ($private_settings) { - $return = array(); + $return = array(); + if ($private_settings) { foreach ($private_settings as $setting) { - $name = substr($setting->name, $ps_prefix_len); - $value = $setting->value; - - $return[$name] = $value; + $return[$setting->name] = $setting->value; } - - return $return; } - return false; + return $return; } /** * Set a plugin setting for the plugin * * @todo This will only work once the plugin has a GUID. - * @todo These need to be namespaced. * * @param string $name The name to set * @param string $value The value to set @@ -315,18 +324,10 @@ class ElggPlugin extends ElggObject { if (!$this->guid) { return false; } - // Hook to validate setting - $value = elgg_trigger_plugin_hook('plugin:setting', 'plugin', array( - 'plugin' => $this->pluginID, - 'plugin_object' => $this, - 'name' => $name, - 'value' => $value - ), $value); return $this->set($name, $value); } - /** * Removes a plugin setting name and value. * @@ -338,7 +339,6 @@ class ElggPlugin extends ElggObject { return remove_private_setting($this->guid, $name); } - /** * Removes all settings for this plugin. * @@ -348,11 +348,14 @@ class ElggPlugin extends ElggObject { */ public function unsetAllSettings() { $db_prefix = get_config('dbprefix'); - $ps_prefix = elgg_namespace_plugin_private_setting('setting', ''); + + $us_prefix = elgg_namespace_plugin_private_setting('user_setting', '', $this->getID()); + $is_prefix = elgg_namespace_plugin_private_setting('internal', '', $this->getID()); $q = "DELETE FROM {$db_prefix}private_settings WHERE entity_guid = $this->guid - AND name NOT LIKE '$ps_prefix%'"; + AND name NOT LIKE '$us_prefix%' + AND name NOT LIKE '$is_prefix%'"; return delete_data($q); } @@ -418,20 +421,18 @@ class ElggPlugin extends ElggObject { $private_settings = get_data($q); - if ($private_settings) { - $return = array(); + $return = array(); + if ($private_settings) { foreach ($private_settings as $setting) { $name = substr($setting->name, $ps_prefix_len); $value = $setting->value; $return[$name] = $value; } - - return $return; } - return false; + return $return; } /** @@ -457,10 +458,11 @@ class ElggPlugin extends ElggObject { } // Hook to validate setting - // note this doesn't pass the namespaced name! - $value = elgg_trigger_plugin_hook('plugin:usersetting', 'user', array( + // note: this doesn't pass the namespaced name + $value = elgg_trigger_plugin_hook('usersetting', 'plugin', array( 'user' => $user, - 'plugin' => $this->getID(), + 'plugin' => $this, + 'plugin_id' => $this->getID(), 'name' => $name, 'value' => $value ), $value); @@ -498,7 +500,6 @@ class ElggPlugin extends ElggObject { return remove_private_setting($user->guid, $name); } - /** * Removes all User Settings for this plugin * @@ -519,7 +520,6 @@ class ElggPlugin extends ElggObject { return delete_data($q); } - /** * Removes this plugin's user settings for all users. * @@ -545,27 +545,29 @@ class ElggPlugin extends ElggObject { * Returns if the plugin is complete, meaning has all required files * and Elgg can read them and they make sense. * - * @todo bad name? This could be confused with isValid() from ElggPackage. + * @todo bad name? This could be confused with isValid() from ElggPluginPackage. * * @return bool */ public function isValid() { if (!$this->getID()) { + $this->errorMsg = elgg_echo('ElggPlugin:NoId', array($this->guid)); return false; } - if (!$this->package instanceof ElggPluginPackage) { + if (!$this->getPackage() instanceof ElggPluginPackage) { + $this->errorMsg = elgg_echo('ElggPlugin:NoPluginPackagePackage', array($this->getID(), $this->guid)); return false; } - if (!$this->package->isValid()) { + if (!$this->getPackage()->isValid()) { + $this->errorMsg = $this->getPackage()->getError(); return false; } return true; } - /** * Is this plugin active? * @@ -590,17 +592,23 @@ class ElggPlugin extends ElggObject { return check_entity_relationship($this->guid, 'active_plugin', $site->guid); } - /** * Checks if this plugin can be activated on the current * Elgg installation. * + * @todo remove $site_guid param or implement it + * * @param mixed $site_guid Optional site guid * @return bool */ public function canActivate($site_guid = null) { - if ($this->package) { - return $this->package->isValid() && $this->package->checkDependencies(); + if ($this->getPackage()) { + $result = $this->getPackage()->isValid() && $this->getPackage()->checkDependencies(); + if (!$result) { + $this->errorMsg = $this->getPackage()->getError(); + } + + return $result; } return false; @@ -638,24 +646,14 @@ class ElggPlugin extends ElggObject { // if there are any on_enable functions, start the plugin now and run them // Note: this will not run re-run the init hooks! - $functions = $this->manifest->getOnActivate(); - if ($return && $functions) { - $flags = ELGG_PLUGIN_INCLUDE_START | ELGG_PLUGIN_REGISTER_CLASSES - | ELGG_PLUGIN_REGISTER_LANGUAGES | ELGG_PLUGIN_REGISTER_VIEWS; - - $this->start($flags); - foreach ($functions as $function) { - if (!is_callable($function)) { - $return = false; - } else { - $result = call_user_func($function); - // allow null to mean "I don't care" like other subsystems - $return = ($result === false) ? false: true; - } - - if ($return === false) { - break; - } + if ($return) { + if ($this->canReadFile('activate.php')) { + $flags = ELGG_PLUGIN_INCLUDE_START | ELGG_PLUGIN_REGISTER_CLASSES | + ELGG_PLUGIN_REGISTER_LANGUAGES | ELGG_PLUGIN_REGISTER_VIEWS; + + $this->start($flags); + + $return = $this->includeFile('activate.php'); } } @@ -669,7 +667,6 @@ class ElggPlugin extends ElggObject { return false; } - /** * Deactivates the plugin. * @@ -689,27 +686,10 @@ class ElggPlugin extends ElggObject { $return = elgg_trigger_event('deactivate', 'plugin', $params); - // run any deactivate functions - // check for the manifest in case we haven't fully loaded the plugin. - if ($this->manifest) { - $functions = $this->manifest->getOnDeactivate(); - } else { - $functions = array(); - } - - if ($return && $functions) { - foreach ($functions as $function) { - if (!is_callable($function)) { - $return = false; - } else { - $result = call_user_func($function); - // allow null to mean "I don't care" like other subsystems - $return = ($result === false) ? false : true; - } - - if ($return === false) { - break; - } + // run any deactivate code + if ($return) { + if ($this->canReadFile('deactivate.php')) { + $return = $this->includeFile('deactivate.php'); } } @@ -720,7 +700,6 @@ class ElggPlugin extends ElggObject { } } - /** * Start the plugin. * @@ -729,13 +708,18 @@ class ElggPlugin extends ElggObject { * @throws PluginException */ public function start($flags) { - if (!$this->canActivate()) { - return false; - } + //if (!$this->canActivate()) { + // return false; + //} + // include classes + if ($flags & ELGG_PLUGIN_REGISTER_CLASSES) { + $this->registerClasses(); + } + // include start file if ($flags & ELGG_PLUGIN_INCLUDE_START) { - $this->includeStart(); + $this->includeFile('start.php'); } // include views @@ -748,11 +732,6 @@ class ElggPlugin extends ElggObject { $this->registerLanguages(); } - // include classes - if ($flags & ELGG_PLUGIN_REGISTER_CLASSES) { - $this->registerClasses(); - } - return true; } @@ -760,24 +739,39 @@ class ElggPlugin extends ElggObject { // start helpers /** - * Includes the plugin's start file + * Includes one of the plugins files + * + * @param string $filename The name of the file * * @throws PluginException - * @return true + * @return mixed The return value of the included file (or 1 if there is none) */ - protected function includeStart() { + protected function includeFile($filename) { // This needs to be here to be backwards compatible for 1.0-1.7. // They expect the global config object to be available in start.php. - global $CONFIG; + if ($filename == 'start.php') { + global $CONFIG; + } - $start = "$this->path/start.php"; - if (!include($start)) { - $msg = elgg_echo('ElggPlugin:Exception:CannotIncludeStart', - array($this->getID(), $this->guid, $this->path)); + $filepath = "$this->path/$filename"; + + if (!$this->canReadFile($filename)) { + $msg = elgg_echo('ElggPlugin:Exception:CannotIncludeFile', + array($filename, $this->getID(), $this->guid, $this->path)); throw new PluginException($msg); } - return true; + return include $filepath; + } + + /** + * Checks whether a plugin file with the given name exists + * + * @param string $filename The name of the file + * @return bool + */ + protected function canReadFile($filename) { + return is_readable($this->path . '/' . $filename); } /** @@ -857,12 +851,7 @@ class ElggPlugin extends ElggObject { return true; } - // but need to have working ones. - if (!elgg_register_classes($classes_path)) { - $msg = elgg_echo('ElggPlugin:Exception:CannotRegisterClasses', - array($this->getID(), $this->guid, $classes_path)); - throw new PluginException($msg); - } + elgg_register_classes($classes_path); return true; } @@ -904,7 +893,9 @@ class ElggPlugin extends ElggObject { } /** - * Save a value to private settings. + * Save a value as private setting or attribute. + * + * Attributes include title and description. * * @param string $name Name * @param mixed $value Value @@ -922,6 +913,14 @@ class ElggPlugin extends ElggObject { return true; } else { + // Hook to validate setting + $value = elgg_trigger_plugin_hook('setting', 'plugin', array( + 'plugin_id' => $this->pluginID, + 'plugin' => $this, + 'name' => $name, + 'value' => $value + ), $value); + return $this->setPrivateSetting($name, $value); } } @@ -955,4 +954,53 @@ class ElggPlugin extends ElggObject { return remove_entity_relationship($this->guid, 'active_plugin', $site->guid); } } + + /** + * Returns the last error message registered. + * + * @return string|null + */ + public function getError() { + return $this->errorMsg; + } + + /** + * Returns this plugin's ElggPluginManifest object + * + * @return ElggPluginManifest + */ + public function getManifest() { + if ($this->manifest instanceof ElggPluginManifest) { + return $this->manifest; + } + + try { + $this->manifest = $this->getPackage()->getManifest(); + } catch (Exception $e) { + elgg_log("Failed to load manifest for plugin $this->guid. " . $e->getMessage(), 'WARNING'); + $this->errorMsg = $e->getmessage(); + } + + return $this->manifest; + } + + /** + * Returns this plugin's ElggPluginPackage object + * + * @return ElggPluginPackage + */ + public function getPackage() { + if ($this->package instanceof ElggPluginPackage) { + return $this->package; + } + + try { + $this->package = new ElggPluginPackage($this->path, false); + } catch (Exception $e) { + elgg_log("Failed to load package for $this->guid. " . $e->getMessage(), 'WARNING'); + $this->errorMsg = $e->getmessage(); + } + + return $this->package; + } } |
