aboutsummaryrefslogtreecommitdiff
path: root/engine/lib/plugins.php
diff options
context:
space:
mode:
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2011-01-02 23:00:23 +0000
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2011-01-02 23:00:23 +0000
commitfc21edb0785f2cac11dc592278fad97fffeeb082 (patch)
tree24047873840c5931766abaa5b15a73c0692e7565 /engine/lib/plugins.php
parenta826bea54e8934c19b2ada619d966cc7d9628b42 (diff)
downloadelgg-fc21edb0785f2cac11dc592278fad97fffeeb082.tar.gz
elgg-fc21edb0785f2cac11dc592278fad97fffeeb082.tar.bz2
Fixes #1986, #2170, #2225, #2759. Integrated ElggPluginPackage and ElggPluginManifest with ElggPlugin. System now uses ElggPlugin objects to determin plugins. Order is stored in private settings. This absolutely requires running upgrade.php.
git-svn-id: http://code.elgg.org/elgg/trunk@7817 36083f99-b078-4883-b0ff-0f9b5a30f544
Diffstat (limited to 'engine/lib/plugins.php')
-rw-r--r--engine/lib/plugins.php1134
1 files changed, 681 insertions, 453 deletions
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index 29f55926c..cd74353de 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -7,202 +7,296 @@
* @subpackage Plugins
*/
-/// Cache enabled plugins per page
-$ENABLED_PLUGINS_CACHE = NULL;
+/**
+ * Tells ElggPlugin::start() to include the start.php file.
+ */
+define('ELGG_PLUGIN_INCLUDE_START', 1);
/**
- * Returns a list of plugins to load, in the order that they should be loaded.
+ * Tells ElggPlugin::start() to automatically register the plugin's views.
+ */
+define('ELGG_PLUGIN_REGISTER_VIEWS', 2);
+
+/**
+ * Tells ElggPlugin::start() to automatically register the plugin's languages.
+ */
+define('ELGG_PLUGIN_REGISTER_LANGUAGES', 4);
+
+/**
+ * Tells ElggPlugin::start() to automatically register the plugin's classes.
+ */
+define('ELGG_PLUGIN_REGISTER_CLASSES', 8);
+
+/**
+ * Prefix for plugin setting names
*
- * @return array List of plugins
+ * @todo Can't namespace these because many plugins directly call
+ * private settings via $entity->$name.
*/
-function get_plugin_list() {
- global $CONFIG;
+//define('ELGG_PLUGIN_SETTING_PREFIX', 'plugin:setting:');
- if (!empty($CONFIG->pluginlistcache)) {
- return $CONFIG->pluginlistcache;
- }
+/**
+ * Prefix for plugin user setting names
+ */
+define('ELGG_PLUGIN_USER_SETTING_PREFIX', 'plugin:user_setting:');
- if ($site = get_entity($CONFIG->site_guid)) {
- $pluginorder = $site->pluginorder;
- if (!empty($pluginorder)) {
- $plugins = unserialize($pluginorder);
+/**
+ * Internal settings prefix
+ *
+ * @todo This could be resolved by promoting ElggPlugin to a 5th type.
+ */
+define('ELGG_PLUGIN_INTERNAL_PREFIX', 'elgg:internal:');
- $CONFIG->pluginlistcache = $plugins;
- return $plugins;
- } else {
- // this only runs on install, otherwise uses serialized plugin order
- $plugins = array();
-
- if ($handle = opendir($CONFIG->pluginspath)) {
- while ($mod = readdir($handle)) {
- // must be directory and not begin with a .
- if (substr($mod, 0, 1) !== '.' && is_dir($CONFIG->pluginspath . "/" . $mod)) {
- $plugins[] = $mod;
- }
- }
- }
- sort($plugins);
+/**
+ * Returns a list of plugin IDs (dir names) from a dir.
+ *
+ * @param string $dir A dir to scan for plugins. Defaults to config's plugins_path.
+ *
+ * @return array
+ */
+function elgg_get_plugin_ids_in_dir($dir = null) {
+ if (!$dir) {
+ $dir = elgg_get_plugin_path();
+ }
+
+ $plugin_idss = array();
+ $handle = opendir($dir);
- $CONFIG->pluginlistcache = $plugins;
- return $plugins;
+ if ($handle) {
+ while ($plugin_id = readdir($handle)) {
+ // must be directory and not begin with a .
+ if (substr($plugin_id, 0, 1) !== '.' && is_dir($dir . $plugin_id)) {
+ $plugin_ids[] = $plugin_id;
+ }
}
}
- return false;
+ sort($plugin_ids);
+
+ return $plugin_ids;
}
/**
- * Regenerates the list of known plugins and saves it to the current site
- *
- * Important: You should regenerate simplecache and the viewpath cache after executing this function
- * otherwise you may experience view display artifacts. Do this with the following code:
+ * Discovers plugins in the plugins_path setting and creates ElggPlugin
+ * entities for them if they don't exist. If there are plugins with entities
+ * but not actual files, will disable the ElggPlugin entities and mark as inactive.
+ * The ElggPlugin object holds config data, so don't delete.
*
- * elgg_view_regenerate_simplecache();
- * elgg_filepath_cache_reset();
- *
- * @param array $pluginorder Optionally, a list of existing plugins and their orders
- *
- * @return array The new list of plugins and their orders
+ * @todo Crappy name?
+ * @return bool
*/
-function regenerate_plugin_list($pluginorder = FALSE) {
- global $CONFIG;
-
- $CONFIG->pluginlistcache = NULL;
+function elgg_generate_plugin_entities() {
+ $site = get_config('site');
+ $dir = elgg_get_plugin_path();
+
+ $options = array(
+ 'type' => 'object',
+ 'subtype' => 'plugin',
+ 'limit' => ELGG_ENTITIES_NO_VALUE
+ );
+
+ $old_ia = elgg_set_ignore_access(true);
+ $old_access = access_get_show_hidden_status();
+ access_show_hidden_entities(true);
+ $known_plugins = elgg_get_entities_from_relationship($options);
+
+ if (!$known_plugins) {
+ $known_plugins = array();
+ }
- if ($site = get_entity($CONFIG->site_guid)) {
- if (empty($pluginorder)) {
- $pluginorder = $site->pluginorder;
- $pluginorder = unserialize($pluginorder);
- } else {
- ksort($pluginorder);
+ // map paths to indexes
+ $id_map = array();
+ foreach ($known_plugins as $i => $plugin) {
+ // if the ID is wrong, delete the plugin because we can never load it.
+ $id = $plugin->getID();
+ if (!$id) {
+ $plugin->delete();
+ unset($known_plugins[$i]);
+ continue;
}
+ $id_map[$plugin->getID()] = $i;
+ }
- if (empty($pluginorder)) {
- $pluginorder = array();
- }
+ $physical_plugins = elgg_get_plugin_ids_in_dir($dir);
- $max = 0;
- if (sizeof($pluginorder)) {
- foreach ($pluginorder as $key => $plugin) {
- if (is_dir($CONFIG->pluginspath . "/" . $plugin)) {
- if ($key > $max) {
- $max = $key;
- }
- } else {
- unset($pluginorder[$key]);
- }
- }
- }
- // Add new plugins to the end
- if ($handle = opendir($CONFIG->pluginspath)) {
- while ($mod = readdir($handle)) {
- // must be directory and not begin with a .
- if (substr($mod, 0, 1) !== '.' && is_dir($CONFIG->pluginspath . "/" . $mod)) {
- if (!in_array($mod, $pluginorder)) {
- $max = $max + 10;
- $pluginorder[$max] = $mod;
- }
- }
+ if (!$physical_plugins) {
+ return false;
+ }
+
+ $new_plugin_priority = elgg_get_max_plugin_priority() + 1;
+
+ // check real plugins against known ones
+ foreach ($physical_plugins as $plugin_id) {
+ // is this already in the db?
+ if (array_key_exists($plugin_id, $id_map)) {
+ $index = $id_map[$plugin_id];
+ $plugin = $known_plugins[$index];
+ // was this plugin deleted and its entity disabled?
+ if ($plugin->enabled != 'yes') {
+ $plugin->enable();
+ $plugin->deactivate();
}
- }
- ksort($pluginorder);
+ // remove from the list of plugins to disable
+ unset($known_plugins[$index]);
+ } else {
+ // add new plugins
+ $plugin = new ElggPlugin($plugin_id);
+ $plugin->save();
+ $plugin->setPriority($new_plugin_priority);
- // Now reorder the keys ..
- $key = 10;
- $plugins = array();
- if (sizeof($pluginorder)) {
- foreach ($pluginorder as $plugin) {
- $plugins[$key] = $plugin;
- $key = $key + 10;
- }
+ $new_plugin_priority++;
}
+ }
- $plugins = serialize($plugins);
+ // everything remaining in $known_plugins needs to be disabled
+ // because they are entities, but their dirs were removed.
+ // don't delete the entities because they hold settings.
+ foreach ($known_plugins as $plugin) {
+ $plugin->deactivate();
+ $plugin->disable();
+ }
+
+ access_show_hidden_entities($old_access);
+ elgg_set_ignore_access($old_ia);
- $site->pluginorder = $plugins;
+ return true;
+}
- return $plugins;
+/**
+ * Returns an ElggPlugin object with the path $path.
+ *
+ * @param string $id The id (dir name) of the plugin. NOT the guid.
+ * @return mixed ElggPlugin or false.
+ */
+function elgg_get_plugin_from_id($id) {
+ $id = sanitize_string($id);
+ $db_prefix = get_config('dbprefix');
+
+ $options = array(
+ 'type' => 'object',
+ 'subtype' => 'plugin',
+ 'joins' => array("JOIN {$db_prefix}objects_entity oe on oe.guid = e.guid"),
+ 'wheres' => array("oe.title = '$id'"),
+ 'limit' => 1
+ );
+
+ $plugins = elgg_get_entities($options);
+
+ if ($plugins) {
+ return $plugins[0];
}
- return FALSE;
+ return false;
+}
+
+/**
+ * Returns if a plugin exists in the system.
+ *
+ * @warning This checks only plugins that are registered in the system!
+ * If the plugin cache is outdated, be sure to regenerate it with
+ * {@link elgg_generate_plugin_objects()} first.
+ *
+ * @param string $id The plugin ID.
+ * @return bool
+ */
+function elgg_plugin_exists($id) {
+ $plugin = elgg_get_plugin_from_id($id);
+
+ return ($plugin) ? true : false;
}
+/**
+ * Returns the highest priority of the plugins
+ *
+ * @return int
+ */
+function elgg_get_max_plugin_priority() {
+ $db_prefix = get_config('dbprefix');
+ $priority = elgg_namespace_plugin_private_setting('internal', 'priority');
+ $plugin_subtype = get_subtype_id('object', 'plugin');
+
+ $q = "SELECT MAX(CAST(ps.value AS unsigned)) as max
+ FROM {$db_prefix}entities e, {$db_prefix}private_settings ps
+ WHERE ps.name = '$priority'
+ AND ps.entity_guid = e.guid
+ AND e.type = 'object' and e.subtype = $plugin_subtype";
+
+ $data = get_data($q);
+ if ($data) {
+ return $data[0]->max;
+ }
+
+ // can't have a priority of 0.
+ return 1;
+}
/**
- * For now, loads plugins directly
+ * Loads all active plugins in the order specified in the tool admin panel.
*
- * @todo Add proper plugin handler that launches plugins in an
- * admin-defined order and activates them on admin request
+ * @note This is called on every page load and includes additional checking that plugins
+ * are fit to be loaded. If a plugin is active and problematic, it will be disabled
+ * and a visible error emitted.
*
- * @return void
+ * @return bool
*/
-function load_plugins() {
+function elgg_load_plugins() {
global $CONFIG;
- if (empty($CONFIG->pluginspath)) {
- return;
+ $plugins_path = elgg_get_plugin_path();
+ $start_flags = ELGG_PLUGIN_INCLUDE_START
+ | ELGG_PLUGIN_REGISTER_VIEWS
+ | ELGG_PLUGIN_REGISTER_LANGUAGES
+ | ELGG_PLUGIN_REGISTER_CLASSES;
+
+ if (!$plugins_path) {
+ return false;
}
// temporary disable all plugins if there is a file called 'disabled' in the plugin dir
- if (file_exists($CONFIG->pluginspath . "disabled")) {
- return;
+ if (file_exists("$plugins_path/disabled")) {
+ return false;
}
-
- // See if we have cached values for things
+
+ // Load view caches if available
$cached_view_paths = elgg_filepath_cache_load('views');
$cached_view_types = elgg_filepath_cache_load('view_types');
$cached_view_info = is_string($cached_view_paths) && is_string($cached_view_types);
+
if ($cached_view_info) {
$CONFIG->views = unserialize($cached_view_paths);
$CONFIG->view_types = unserialize($cached_view_types);
+
+ // don't need to register views
+ $start_flags = $start_flags & ~ELGG_PLUGIN_REGISTER_VIEWS;
}
- $plugins = get_plugin_list();
-
- if (sizeof($plugins)) {
- foreach ($plugins as $mod) {
- if (is_plugin_enabled($mod)) {
- if (file_exists($CONFIG->pluginspath . $mod)) {
- if (!include($CONFIG->pluginspath . $mod . "/start.php")) {
- // automatically disable the bad plugin
- disable_plugin($mod);
-
- // register error rather than rendering the site unusable with exception
- register_error(sprintf(elgg_echo('PluginException:MisconfiguredPlugin'), $mod));
-
- // continue loading remaining plugins
- continue;
- }
-
- if (!$cached_view_info) {
- $view_dir = $CONFIG->pluginspath . $mod . '/views/';
-
- if (is_dir($view_dir) && ($handle = opendir($view_dir))) {
- while (FALSE !== ($view_type = readdir($handle))) {
- $view_type_dir = $view_dir . $view_type;
-
- if ('.' !== substr($view_type, 0, 1) && is_dir($view_type_dir)) {
- if (autoregister_views('', $view_type_dir, $view_dir, $view_type)) {
- // add the valid view type.
- if (!in_array($view_type, $CONFIG->view_types)) {
- $CONFIG->view_types[] = $view_type;
- }
- }
- }
- }
- }
- }
-
- if (is_dir($CONFIG->pluginspath . "$mod/classes")) {
- elgg_register_classes($CONFIG->pluginspath . "$mod/classes");
- }
-
- if (is_dir($CONFIG->pluginspath . $mod . "/languages")) {
- register_translations($CONFIG->pluginspath . $mod . "/languages/");
- }
- }
+ $return = true;
+ $plugins = elgg_get_plugins('active');
+ if ($plugins) {
+ foreach ($plugins as $plugin) {
+ // check if plugin can be started and try to start it.
+ // if anything is bad, disable it and emit a message.
+ if (!$plugin->isValid()) {
+ $plugin->deactivate();
+ $msg = elgg_echo('PluginException:MisconfiguredPlugin', array($plugin->getID(), $plugin->guid));
+ register_error($msg);
+ $return = false;
+
+ continue;
+ }
+
+ try {
+ $plugin->start($start_flags);
+ } catch (Exception $e) {
+ $plugin->deactivate();
+ $msg = elgg_echo('PluginException:CannotStart',
+ array($plugin->getID(), $plugin->guid, $e->getMessage()));
+ register_error($msg);
+ $return = false;
+
+ continue;
}
}
}
@@ -212,21 +306,257 @@ function load_plugins() {
elgg_filepath_cache_save('views', serialize($CONFIG->views));
elgg_filepath_cache_save('view_types', serialize($CONFIG->view_types));
}
+
+ return $return;
+}
+
+/**
+ * Returns an ordered list of plugins
+ *
+ * @param string $status The status of the plugins. active, inactive, or all.
+ * @param bool $include_deleted Include physically deleted (and so inactive and disabled) plugins?
+ * @param mixed $site_guid Optional site guid
+ * @return array
+ */
+function elgg_get_plugins($status = 'active', $include_deleted = false, $site_guid = NULL) {
+ $db_prefix = get_config('dbprefix');
+ $priority = elgg_namespace_plugin_private_setting('internal', 'priority');
+
+ if (!$site_guid) {
+ $site = get_config('site');
+ $site_guid = $site->guid;
+ }
+
+ // grab plugins
+ $options = array(
+ 'type' => 'object',
+ 'subtype' => 'plugin',
+ 'limit' => ELGG_ENTITIES_NO_VALUE,
+ 'joins' => array("JOIN {$db_prefix}private_settings ps on ps.entity_guid = e.guid"),
+ 'wheres' => array("ps.name = '$priority'"),
+ 'order_by' => "CAST(ps.value as unsigned), e.guid"
+ );
+
+ switch ($status) {
+ case 'active':
+ $options['relationship'] = 'active_plugin';
+ $options['relationship_guid'] = $site_guid;
+ $options['inverse_relationship'] = true;
+ break;
+
+ case 'inactive':
+ $options['wheres'][] = "NOT EXISTS (
+ SELECT 1 FROM {$db_prefix}entity_relationships active_er
+ WHERE active_er.guid_one = e.guid
+ AND active_er.relationship = 'active_plugin'
+ AND active_er.guid_two = $site_guid)";
+ break;
+
+ case 'all':
+ default:
+ break;
+ }
+
+ if ($include_deleted) {
+ $old_id = elgg_set_ignore_access(true);
+ }
+
+ $plugins = elgg_get_entities_from_relationship($options);
+
+ if ($include_deleted) {
+ elgg_set_ignore_access($old_ia);
+ }
+
+ return $plugins;
+}
+
+/**
+ * Reorder plugins to an order specified by the array.
+ * Plugins not included in this array will be appended to the end.
+ *
+ * @note This doesn't use the ElggPlugin->setPriority() method because
+ * all plugins are being changed and we don't want it to automatically
+ * reorder plugins.
+ *
+ * @param array $order An array of plugin ids in the order to set them
+ * @return bool
+ */
+function elgg_set_plugin_priorities(array $order) {
+ $name = elgg_namespace_plugin_private_setting('internal', 'priority');
+
+ $plugins = elgg_get_plugins('any', true);
+ if (!$plugins) {
+ return false;
+ }
+
+ $return = true;
+
+ // reindex to get standard counting. no need to increment by 10.
+ // though we do start with 1
+ $order = array_values($order);
+
+ foreach ($plugins as $plugin) {
+ $plugin_id = $plugin->getID();
+
+ if (!in_array($plugin_id, $order)) {
+ $missing_plugins[] = $plugin;
+ continue;
+ }
+
+ $priority = array_search($plugin_id, $order) + 1;
+
+ if (!$plugin->set($name, $priority)) {
+ $return = false;
+ break;
+ }
+ }
+
+ // set the missing plugins priorities
+ if ($return && $missing_plugins) {
+ if (!$priority) {
+ $priority = 0;
+ }
+ foreach ($missing_plugins as $plugin) {
+ $priority++;
+ if (!$plugin->set($name, $priority)) {
+ $return = false;
+ break;
+ }
+ }
+ }
+
+ return $return;
+}
+
+/**
+ * Reindexes all plugin priorities starting at 1.
+ *
+ * @todo Can this be done in a single sql command?
+ * @return bool
+ */
+function elgg_plugins_reindex_priorities() {
+ return elgg_set_plugin_priorities(array());
+}
+
+/**
+ * Returns a list of plugins to load, in the order that they should be loaded.
+ *
+ * @deprecated 1.8
+ *
+ * @return array List of plugins
+ */
+function get_plugin_list() {
+ elgg_deprecated_notice('get_plugin_list() is deprecated by elgg_get_plugin_ids_in_dir() or elgg_get_plugins()', 1.8);
+
+ $plugins = elgg_get_plugins('any');
+
+ $list = array();
+ if ($plugins) {
+ foreach ($plugins as $i => $plugin) {
+ // in <=1.7 this returned indexed by multiples of 10.
+ // uh...sure...why not.
+ $index = ($i + 1) * 10;
+ $list[$index] = $plugin->getID();
+ }
+ }
+
+ return $list;
+}
+
+/**
+ * Regenerates the list of known plugins and saves it to the current site
+ *
+ * Important: You should regenerate simplecache and the viewpath cache after executing this function
+ * otherwise you may experience view display artifacts. Do this with the following code:
+ *
+ * elgg_view_regenerate_simplecache();
+ * elgg_filepath_cache_reset();
+ *
+ * @deprecated 1.8
+ *
+ * @param array $pluginorder Optionally, a list of existing plugins and their orders
+ *
+ * @return array The new list of plugins and their orders
+ */
+function regenerate_plugin_list($pluginorder = FALSE) {
+ $msg = 'regenerate_plugin_list() is (sorta) deprecated by elgg_generate_plugin_entities() and'
+ . ' elgg_set_plugin_priorities().';
+ elgg_deprecated_notice($msg, 1.8);
+
+ // they're probably trying to set it?
+ if ($pluginorder) {
+ if (elgg_generate_plugin_entities()) {
+ // sort the plugins by the index numerically since we used
+ // weird indexes in the old system.
+ ksort($pluginorder, SORT_NUMERIC);
+ return elgg_set_plugin_priorities($pluginorder);
+ }
+ return false;
+ } else {
+ // they're probably trying to regenerate from disk?
+ return elgg_generate_plugin_entities();
+ }
+}
+
+
+/**
+ * Loads plugins
+ *
+ * @deprecate 1.8
+ *
+ * @return bool
+ */
+function load_plugins() {
+ elgg_deprecated_notice('load_plugins() is deprecated by elgg_load_plugins()', 1.8);
+
+ return elgg_load_plugins();
+}
+
+
+/**
+ * Namespaces a string to be used as a private setting for a plugin.
+ *
+ * @param string $type The type of value: user_setting or internal.
+ * @param string $name The name to namespace.
+ * @param string $id The plugin's ID to namespace with. Required for user_setting.
+ * @return string
+ */
+function elgg_namespace_plugin_private_setting($type, $name, $id = null) {
+ switch ($type) {
+// case 'setting':
+// $name = ELGG_PLUGIN_SETTING_PREFIX . $name;
+// break;
+
+ case 'user_setting':
+ if (!$id) {
+ $id = elgg_get_calling_plugin_id();
+ }
+ $name = ELGG_PLUGIN_USER_SETTING_PREFIX . "$id:$name";
+ break;
+
+ case 'internal':
+ $name = ELGG_PLUGIN_INTERNAL_PREFIX . $name;
+ break;
+ }
+
+ return $name;
}
/**
* Get the name of the most recent plugin to be called in the
* call stack (or the plugin that owns the current page, if any).
*
- * i.e., if the last plugin was in /mod/foobar/, get_plugin_name would return foo_bar.
+ * i.e., if the last plugin was in /mod/foobar/, this would return foo_bar.
*
* @param boolean $mainfilename If set to true, this will instead determine the
* context from the main script filename called by
* the browser. Default = false.
*
+ * @since 1.8
+ *
* @return string|false Plugin name, or false if no plugin name was called
*/
-function get_plugin_name($mainfilename = false) {
+function elgg_get_calling_plugin_id($mainfilename = false) {
if (!$mainfilename) {
if ($backtrace = debug_backtrace()) {
foreach ($backtrace as $step) {
@@ -254,31 +584,38 @@ function get_plugin_name($mainfilename = false) {
}
/**
- * Load and parse a plugin manifest from a plugin XML file.
+ * Get the name of the most recent plugin to be called in the
+ * call stack (or the plugin that owns the current page, if any).
*
- * Example file:
+ * i.e., if the last plugin was in /mod/foobar/, get_plugin_name would return foo_bar.
*
- * <plugin_manifest>
- * <!-- Basic information -->
- * <field key="name" value="My Plugin" />
- * <field key="description" value="My Plugin's concise description" />
- * <field key="version" value="1.0" />
- * <field key="category" value="theme" />
- * <field key="category" value="bundled" />
- * <field key="screenshot" value="path/relative/to/my_plugin.jpg" />
- * <field key="screenshot" value="path/relative/to/my_plugin_2.jpg" />
+ * @deprecated 1.8
*
- * <field key="author" value="Curverider Ltd" />
- * <field key="website" value="http://www.elgg.org/" />
- * <field key="copyright" value="(C) Curverider 2008-2010" />
- * <field key="licence" value="GNU Public License version 2" />
- * </plugin_manifest>
+ * @param boolean $mainfilename If set to true, this will instead determine the
+ * context from the main script filename called by
+ * the browser. Default = false.
*
- * @param string $plugin Plugin name.
+ * @return string|false Plugin name, or false if no plugin name was called
+ */
+function get_plugin_name($mainfilename = false) {
+ elgg_deprecated_notice('get_plugin_name() is deprecated by elgg_get_calling_plugin_id()', 1.8);
+
+ return elgg_get_calling_plugin_id($mainfilename);
+}
+
+/**
+ * Load and parse a plugin manifest from a plugin XML file.
+ *
+ * @example plugins/manifest.xml Example 1.8-style manifest file.
+ *
+ * @deprecated 1.8
*
+ * @param string $plugin Plugin name.
* @return array of values
*/
function load_plugin_manifest($plugin) {
+ elgg_deprecated_notice('load_plugin_manifest() is deprecated by ElggPlugin->getManifest()', 1.8);
+
$xml_file = elgg_get_plugin_path() . "$plugin/manifest.xml";
try {
@@ -294,11 +631,14 @@ function load_plugin_manifest($plugin) {
* This function checks a plugin manifest 'elgg_version' value against the current install
* returning TRUE if the elgg_version is >= the current install's version.
*
- * @param string $manifest_elgg_version_string The build version (eg 2009010201).
+ * @deprecated 1.8
*
+ * @param string $manifest_elgg_version_string The build version (eg 2009010201).
* @return bool
*/
function check_plugin_compatibility($manifest_elgg_version_string) {
+ elgg_deprecated_notice('check_plugin_compatibility() is deprecated by ElggPlugin->canActivate()', 1.8);
+
$version = get_version();
if (strpos($manifest_elgg_version_string, '.') === false) {
@@ -327,6 +667,7 @@ function check_plugin_compatibility($manifest_elgg_version_string) {
* @param string $name A specific provided name to return. Requires $provide_type.
*
* @return array
+ * @since 1.8
*/
function elgg_get_plugins_provides($type = null, $name = null) {
static $provides = null;
@@ -377,6 +718,7 @@ function elgg_get_plugins_provides($type = null, $name = null) {
* @param string $comparison The comparison operator to use in version_compare()
*
* @return bool
+ * @since 1.8
*/
function elgg_check_plugins_provides($type, $name, $version = null, $comparison = 'ge') {
if (!$provided = elgg_get_plugins_provides($type, $name)) {
@@ -395,25 +737,33 @@ function elgg_check_plugins_provides($type, $name, $version = null, $comparison
/**
* Shorthand function for finding the plugin settings.
*
- * @param string $plugin_name Optional plugin name, if not specified
- * then it is detected from where you are calling from.
+ * @deprecated 1.8
+ *
+ * @param string $plugin_id Optional plugin id, if not specified
+ * then it is detected from where you are calling.
*
* @return mixed
*/
-function find_plugin_settings($plugin_name = "") {
- $options = array('type' => 'object', 'subtype' => 'plugin', 'limit' => 9999);
- $plugins = elgg_get_entities($options);
- $plugin_name = sanitise_string($plugin_name);
- if (!$plugin_name) {
- $plugin_name = get_plugin_name();
+function find_plugin_settings($plugin_id = null) {
+ elgg_deprecated_notice('find_plugin_setting() is deprecated by elgg_get_calling_plugin_entity() or elgg_get_plugin_from_id()', 1.8);
+ if ($plugin_id) {
+ return elgg_get_plugin_from_id($plugin_id);
+ } else {
+ return elgg_get_calling_plugin_entity();
}
+}
- if ($plugins) {
- foreach ($plugins as $plugin) {
- if (strcmp($plugin->title, $plugin_name) == 0) {
- return $plugin;
- }
- }
+/**
+ * Returns the ElggPlugin entity of the last plugin called.
+ *
+ * @return mixed ElggPlugin or false
+ * @since 1.8
+ */
+function elgg_get_calling_plugin_entity() {
+ $plugin_id = elgg_get_calling_plugin_id();
+
+ if ($plugin_id) {
+ return elgg_get_plugin_from_id($plugin_id);
}
return false;
@@ -422,34 +772,41 @@ function find_plugin_settings($plugin_name = "") {
/**
* Find the plugin settings for a user.
*
- * @param string $plugin_name Plugin name.
- * @param int $user_guid The guid who's settings to retrieve.
+ * @param string $plugin_id Plugin name.
+ * @param int $user_guid The guid who's settings to retrieve.
*
* @return array of settings in an associative array minus prefix.
*/
-function find_plugin_usersettings($plugin_name = "", $user_guid = 0) {
- $plugin_name = sanitise_string($plugin_name);
+function find_plugin_usersettings($plugin_id = null, $user_guid = 0) {
+ $plugin_id = sanitise_string($plugin_id);
$user_guid = (int)$user_guid;
+ $db_prefix = get_config('db_prefix');
+ $ps_prefix = elgg_namespace_plugin_private_setting('user_setting', "$plugin_id:");
+ $ps_prefix_len = strlen($ps_prefix);
- if (!$plugin_name) {
- $plugin_name = get_plugin_name();
+ if (!$plugin_id) {
+ $plugin_id = elgg_get_calling_plugin_id();
}
if ($user_guid == 0) {
$user_guid = get_loggedin_userid();
}
- // Get metadata for user
- $all_metadata = get_all_private_settings($user_guid); //get_metadata_for_entity($user_guid);
- if ($all_metadata) {
- $prefix = "plugin:settings:$plugin_name:";
+ // Get private settings for user
+ $q = "SELECT * FROM {$db_prefix}private_settings
+ WHERE entity_guid = $user_guid
+ AND name LIKE '$ps_prefix$plugin_id'";
+
+ $private_settings = get_data($q);
+ if ($private_settings) {
$return = new stdClass;
- foreach ($all_metadata as $key => $meta) {
- $name = substr($key, strlen($prefix));
- $value = $meta;
+ foreach ($private_settings as $setting) {
+ $name = substr($setting->name, $ps_prefix_len);
+ $value = $setting->value;
- if (strpos($key, $prefix) === 0) {
+ // @todo why?
+ if (strpos($key, $ps_prefix) === 0) {
$return->$name = $value;
}
}
@@ -463,21 +820,21 @@ function find_plugin_usersettings($plugin_name = "", $user_guid = 0) {
/**
* Set a user specific setting for a plugin.
*
- * @param string $name The name - note, can't be "title".
- * @param mixed $value The value.
- * @param int $user_guid Optional user.
- * @param string $plugin_name Optional plugin name, if not specified then it
- * is detected from where you are calling from.
+ * @param string $name The name - note, can't be "title".
+ * @param mixed $value The value.
+ * @param int $user_guid Optional user.
+ * @param string $plugin_id Optional plugin name, if not specified then it
+ * is detected from where you are calling from.
*
* @return bool
*/
-function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_name = "") {
- $plugin_name = sanitise_string($plugin_name);
+function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_id = "") {
+ $plugin_id = sanitise_string($plugin_id);
$user_guid = (int)$user_guid;
$name = sanitise_string($name);
- if (!$plugin_name) {
- $plugin_name = get_plugin_name();
+ if (!$plugin_id) {
+ $plugin_id = elgg_get_calling_plugin_id();
}
$user = get_entity($user_guid);
@@ -486,19 +843,17 @@ function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_name = ""
}
if (($user) && ($user instanceof ElggUser)) {
- $prefix = "plugin:settings:$plugin_name:$name";
- //$user->$prefix = $value;
- //$user->save();
+ $name = elgg_namespace_plugin_private_setting('user_setting', "$plugin_id:$name");
// Hook to validate setting
$value = elgg_trigger_plugin_hook('plugin:usersetting', 'user', array(
'user' => $user,
- 'plugin' => $plugin_name,
+ 'plugin' => $plugin_id,
'name' => $name,
'value' => $value
), $value);
- return set_private_setting($user->guid, $prefix, $value);
+ return set_private_setting($user->guid, $name, $value);
}
return false;
@@ -507,18 +862,18 @@ function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_name = ""
/**
* Clears a user-specific plugin setting
*
- * @param str $name Name of the plugin setting
- * @param int $user_guid Defaults to logged in user
- * @param str $plugin_name Defaults to contextual plugin name
+ * @param str $name Name of the plugin setting
+ * @param int $user_guid Defaults to logged in user
+ * @param str $plugin_id Defaults to contextual plugin name
*
* @return bool Success
*/
-function clear_plugin_usersetting($name, $user_guid = 0, $plugin_name = '') {
- $plugin_name = sanitise_string($plugin_name);
+function clear_plugin_usersetting($name, $user_guid = 0, $plugin_id = '') {
+ $plugin_id = sanitise_string($plugin_id);
$name = sanitise_string($name);
- if (!$plugin_name) {
- $plugin_name = get_plugin_name();
+ if (!$plugin_id) {
+ $plugin_id = elgg_get_calling_plugin_id();
}
$user = get_entity((int) $user_guid);
@@ -527,7 +882,7 @@ function clear_plugin_usersetting($name, $user_guid = 0, $plugin_name = '') {
}
if (($user) && ($user instanceof ElggUser)) {
- $prefix = "plugin:settings:$plugin_name:$name";
+ $prefix = elgg_namespace_plugin_private_setting('user_setting', "$plugin_id:$name");
return remove_private_setting($user->getGUID(), $prefix);
}
@@ -538,20 +893,20 @@ function clear_plugin_usersetting($name, $user_guid = 0, $plugin_name = '') {
/**
* Get a user specific setting for a plugin.
*
- * @param string $name The name.
- * @param int $user_guid Guid of owning user
- * @param string $plugin_name Optional plugin name, if not specified
+ * @param string $name The name.
+ * @param int $user_guid Guid of owning user
+ * @param string $plugin_id Optional plugin name, if not specified
* then it is detected from where you are calling from.
*
* @return mixed
*/
-function get_plugin_usersetting($name, $user_guid = 0, $plugin_name = "") {
- $plugin_name = sanitise_string($plugin_name);
+function get_plugin_usersetting($name, $user_guid = 0, $plugin_id = "") {
+ $plugin_id = sanitise_string($plugin_id);
$user_guid = (int)$user_guid;
$name = sanitise_string($name);
- if (!$plugin_name) {
- $plugin_name = get_plugin_name();
+ if (!$plugin_id) {
+ $plugin_id = elgg_get_calling_plugin_id();
}
$user = get_entity($user_guid);
@@ -560,8 +915,8 @@ function get_plugin_usersetting($name, $user_guid = 0, $plugin_name = "") {
}
if (($user) && ($user instanceof ElggUser)) {
- $prefix = "plugin:settings:$plugin_name:$name";
- return get_private_setting($user->guid, $prefix);
+ $name = elgg_namespace_plugin_private_setting('user_setting', "$plugin_id:$name");
+ return get_private_setting($user->guid, $name);
}
return false;
@@ -570,143 +925,126 @@ function get_plugin_usersetting($name, $user_guid = 0, $plugin_name = "") {
/**
* Set a setting for a plugin.
*
- * @param string $name The name - note, can't be "title".
- * @param mixed $value The value.
- * @param string $plugin_name Optional plugin name, if not specified
- * then it is detected from where you are calling from.
+ * @param string $name The name - note, can't be "title".
+ * @param mixed $value The value.
+ * @param string $plugin_id Optional plugin name, if not specified
+ * then it is detected from where you are calling from.
*
* @return int|false
*/
-function set_plugin_setting($name, $value, $plugin_name = "") {
- if (!$plugin_name) {
- $plugin_name = get_plugin_name();
+function set_plugin_setting($name, $value, $plugin_id = null) {
+ if ($plugin_id) {
+ $plugin = elgg_get_plugin_from_id($plugin_id);
+ } else {
+ $plugin = elgg_get_calling_plugin_entity();
}
- $plugin = find_plugin_settings($plugin_name);
if (!$plugin) {
- $plugin = new ElggPlugin();
- }
-
- if ($name != 'title') {
- // Hook to validate setting
- $value = elgg_trigger_plugin_hook('plugin:setting', 'plugin', array(
- 'plugin' => $plugin_name,
- 'name' => $name,
- 'value' => $value
- ), $value);
-
- $plugin->title = $plugin_name;
- $plugin->access_id = ACCESS_PUBLIC;
- $plugin->save();
- $plugin->$name = $value;
-
- return $plugin->getGUID();
+ return false;
}
- return false;
+ return $plugin->setSetting($name, $value);
}
/**
* Get setting for a plugin.
*
- * @param string $name The name.
- * @param string $plugin_name Optional plugin name, if not specified
- * then it is detected from where you are calling from.
+ * @param string $name The name.
+ * @param string $plugin_id Optional plugin name, if not specified
+ * then it is detected from where you are calling from.
*
* @return mixed
*/
-function get_plugin_setting($name, $plugin_name = "") {
- $plugin = find_plugin_settings($plugin_name);
+function get_plugin_setting($name, $plugin_id = "") {
+ if ($plugin_id) {
+ $plugin = elgg_get_plugin_from_id($plugin_id);
+ } else {
+ $plugin = elgg_get_calling_plugin_entity();
+ }
- if ($plugin) {
- return $plugin->$name;
+ if (!$plugin) {
+ return false;
}
- return false;
+ return $plugin->getSetting($name);
}
/**
* Clear a plugin setting.
*
- * @param string $name The name.
- * @param string $plugin_name Optional plugin name, if not specified
- * then it is detected from where you are calling from.
+ * @param string $name The name.
+ * @param string $plugin_id Optional plugin name, if not specified
+ * then it is detected from where you are calling from.
*
* @return bool
*/
-function clear_plugin_setting($name, $plugin_name = "") {
- $plugin = find_plugin_settings($plugin_name);
+function clear_plugin_setting($name, $plugin_id = "") {
+ if ($plugin_id) {
+ $plugin = elgg_get_plugin_from_id($plugin_id);
+ } else {
+ $plugin = elgg_get_calling_plugin_entity();
+ }
- if ($plugin) {
- return remove_private_setting($plugin->guid, $name);
+ if (!$plugin) {
+ return false;
}
- return FALSE;
+ return $plugin->removeSetting($name);
}
/**
* Clear all plugin settings.
*
- * @param string $plugin_name Optional plugin name, if not specified
- * then it is detected from where you are calling from.
+ * @param string $plugin_id Optional plugin name, if not specified
+ * then it is detected from where you are calling from.
*
* @return bool
* @since 1.7.0
*/
-function clear_all_plugin_settings($plugin_name = "") {
- $plugin = find_plugin_settings($plugin_name);
+function clear_all_plugin_settings($plugin_id = "") {
+ if ($plugin_id) {
+ $plugin = elgg_get_plugin_from_id($plugin_id);
+ } else {
+ $plugin = elgg_get_calling_plugin_entity();
+ }
if ($plugin) {
- return remove_all_private_settings($plugin->guid);
+ $plugin->removeAllSettings();
}
- return FALSE;
+ return false;
}
/**
* Return an array of installed plugins.
*
+ * @deprecated 1.8
+ *
* @param string $status any|enabled|disabled
* @return array
*/
-function get_installed_plugins($status = 'any') {
+function get_installed_plugins($status = 'all') {
global $CONFIG;
- $installed_plugins = array();
+ elgg_deprecated_notice('get_installed_plugins() was deprecated by elgg_get_plugins()', 1.8);
- if (!empty($CONFIG->pluginspath)) {
- $plugins = get_plugin_list();
+ $plugins = elgg_get_plugins($status);
- foreach ($plugins as $mod) {
- // require manifest.
- if (!$manifest = load_plugin_manifest($mod)) {
- continue;
- }
-
- $enabled = is_plugin_enabled($mod);
-
- switch ($status) {
- case 'enabled':
- if ($enabled != true) {
- continue 2;
- }
- break;
-
- case 'disabled':
- if ($enabled == true) {
- continue 2;
- }
- break;
+ if (!$plugins) {
+ return array();
+ }
- case 'any':
- default:
- break;
- }
+ $installed_plugins = array();
- $installed_plugins[$mod] = array();
- $installed_plugins[$mod]['active'] = $enabled;
- $installed_plugins[$mod]['manifest'] = $manifest;
+ foreach ($plugins as $plugin) {
+ if (!$plugin->isValid()) {
+ continue;
}
+
+ $installed_plugins[$plugin->getID()] = array(
+ 'active' => $plugin->isActive(),
+ 'manifest' => $plugin->manifest->getManifest()
+ );
}
return $installed_plugins;
@@ -721,82 +1059,36 @@ function get_installed_plugins($status = 'any') {
* elgg_view_regenerate_simplecache();
* elgg_filepath_cache_reset();
*
+ * @deprecated 1.8
+ *
* @param string $plugin The plugin name.
* @param int $site_guid The site id, if not specified then this is detected.
*
* @return array
* @throws InvalidClassException
*/
-function enable_plugin($plugin, $site_guid = 0) {
- global $CONFIG, $ENABLED_PLUGINS_CACHE;
+function enable_plugin($plugin, $site_guid = null) {
+ elgg_deprecated_notice('enable_plugin() was deprecated by ElggPlugin->activate()', 1.8);
$plugin = sanitise_string($plugin);
- $site_guid = (int) $site_guid;
- if ($site_guid == 0) {
- $site_guid = $CONFIG->site_guid;
- }
- $site = get_entity($site_guid);
- if (!($site instanceof ElggSite)) {
- $msg = elgg_echo('InvalidClassException:NotValidElggStar', array($site_guid, "ElggSite"));
- throw new InvalidClassException($msg);
- }
-
- if (!$plugin_info = load_plugin_manifest($plugin)) {
- return FALSE;
+ $site_guid = (int) $site_guid;
+ if (!$site_guid) {
+ $site = get_config('site');
+ $site_guid = $site->guid;
}
- // getMetadata() doesn't return an array if only one plugin is enabled
- if ($enabled = $site->enabled_plugins) {
- if (!is_array($enabled)) {
- $enabled = array($enabled);
- }
- } else {
- $enabled = array();
+ try {
+ $plugin = new ElggPlugin($plugin);
+ } catch(Exception $e) {
+ return false;
}
- $enabled[] = $plugin;
- $enabled = array_unique($enabled);
-
- if ($return = $site->setMetaData('enabled_plugins', $enabled)) {
-
- // for other plugins that want to hook into this.
- $params = array('plugin' => $plugin, 'manifest' => $plugin_info);
- if ($return && !elgg_trigger_event('enable', 'plugin', $params)) {
- $return = FALSE;
- }
-
- // for this plugin's on_enable
- if ($return && isset($plugin_info['on_enable'])) {
- // pull in the actual plugin's start so the on_enable function is callable
- // NB: this will not run re-run the init hooks!
- $start = "{$CONFIG->pluginspath}$plugin/start.php";
- if (!file_exists($start) || !include($start)) {
- $return = FALSE;
- }
-
- // need language files for the messages
- $translations = "{$CONFIG->pluginspath}$plugin/languages/";
- register_translations($translations);
- if (!is_callable($plugin_info['on_enable'])) {
- $return = FALSE;
- } else {
- $on_enable = call_user_func($plugin_info['on_enable']);
- // allow null to mean "I don't care" like other subsystems
- $return = ($on_disable === FALSE) ? FALSE : TRUE;
- }
- }
-
- // disable the plugin if the on_enable or trigger results failed
- if (!$return) {
- array_pop($enabled);
- $site->setMetaData('enabled_plugins', $enabled);
- }
-
- $ENABLED_PLUGINS_CACHE = $enabled;
+ if (!$plugin->canActivate($site_guid)) {
+ return false;
}
- return $return;
+ return $plugin->activate($site_guid);
}
/**
@@ -808,6 +1100,8 @@ function enable_plugin($plugin, $site_guid = 0) {
* elgg_view_regenerate_simplecache();
* elgg_filepath_cache_reset();
*
+ * @deprecated 1.8
+ *
* @param string $plugin The plugin name.
* @param int $site_guid The site id, if not specified then this is detected.
*
@@ -815,118 +1109,53 @@ function enable_plugin($plugin, $site_guid = 0) {
* @throws InvalidClassException
*/
function disable_plugin($plugin, $site_guid = 0) {
- global $CONFIG, $ENABLED_PLUGINS_CACHE;
+ elgg_deprecated_notice('disable_plugin() was deprecated by ElggPlugin->deactivate()', 1.8);
$plugin = sanitise_string($plugin);
- $site_guid = (int) $site_guid;
- if ($site_guid == 0) {
- $site_guid = $CONFIG->site_guid;
- }
-
- $site = get_entity($site_guid);
- if (!($site instanceof ElggSite)) {
- $msg = elgg_echo('InvalidClassException:NotValidElggStar', array($site_guid, "ElggSite"));
- throw new InvalidClassException();
- }
- if (!$plugin_info = load_plugin_manifest($plugin)) {
- return FALSE;
- }
-
- // getMetadata() doesn't return an array if only one plugin is enabled
- if ($enabled = $site->enabled_plugins) {
- if (!is_array($enabled)) {
- $enabled = array($enabled);
- }
- } else {
- $enabled = array();
- }
-
- $old_enabled = $enabled;
-
- // remove the disabled plugin from the array
- if (FALSE !== $i = array_search($plugin, $enabled)) {
- unset($enabled[$i]);
+ $site_guid = (int) $site_guid;
+ if (!$site_guid) {
+ $site = get_config('site');
+ $site_guid = $site->guid;
}
- // if we're unsetting all the plugins, this will return an empty array.
- // it will fail with FALSE, though.
- $return = (FALSE === $site->enabled_plugins = $enabled) ? FALSE : TRUE;
-
- if ($return) {
- // for other plugins that want to hook into this.
- $params = array('plugin' => $plugin, 'manifest' => $plugin_info);
- if ($return && !elgg_trigger_event('disable', 'plugin', $params)) {
- $return = FALSE;
- }
-
- // for this plugin's on_disable
- if ($return && isset($plugin_info['on_disable'])) {
- if (!is_callable($plugin_info['on_disable'])) {
- $return = FALSE;
- } else {
- $on_disable = call_user_func($plugin_info['on_disable']);
- // allow null to mean "I don't care" like other subsystems
- $return = ($on_disable === FALSE) ? FALSE : TRUE;
- }
- }
-
- // disable the plugin if the on_enable or trigger results failed
- if (!$return) {
- $site->enabled_plugins = $old_enabled;
- $ENABLED_PLUGINS_CACHE = $old_enabled;
- } else {
- $ENABLED_PLUGINS_CACHE = $enabled;
- }
+ try {
+ $plugin = new ElggPlugin($plugin);
+ } catch(Exception $e) {
+ return false;
}
- return $return;
+ return $plugin->deactivate($site_guid);
}
/**
* Return whether a plugin is enabled or not.
*
+ * @deprecated 1.8
+ *
* @param string $plugin The plugin name.
* @param int $site_guid The site id, if not specified then this is detected.
*
* @return bool
- * @throws InvalidClassException
*/
function is_plugin_enabled($plugin, $site_guid = 0) {
- global $CONFIG, $ENABLED_PLUGINS_CACHE;
+ elgg_deprecated_notice('is_plugin_enabled() was deprecated by ElggPlugin->isActive()', 1.8);
- if (!file_exists($CONFIG->pluginspath . $plugin)) {
- return false;
- }
+ $plugin = sanitise_string($plugin);
$site_guid = (int) $site_guid;
- if ($site_guid == 0) {
- $site_guid = $CONFIG->site_guid;
+ if (!$site_guid) {
+ $site = get_config('site');
+ $site_guid = $site->guid;
}
- if (!$ENABLED_PLUGINS_CACHE) {
- $site = get_entity($site_guid);
- if (!($site instanceof ElggSite)) {
- $msg = elgg_echo('InvalidClassException:NotValidElggStar', array($site_guid, "ElggSite"));
- throw new InvalidClassException($msg);
- }
-
- $enabled_plugins = $site->enabled_plugins;
- if ($enabled_plugins && !is_array($enabled_plugins)) {
- $enabled_plugins = array($enabled_plugins);
- }
- $ENABLED_PLUGINS_CACHE = $enabled_plugins;
- }
-
- if (is_array($ENABLED_PLUGINS_CACHE)) {
- foreach ($ENABLED_PLUGINS_CACHE as $e) {
- if ($e == $plugin) {
- return true;
- }
- }
+ try {
+ $plugin = new ElggPlugin($plugin);
+ } catch(Exception $e) {
+ return false;
}
- return false;
+ return $plugin->isActive($site_guid);
}
/**
@@ -935,7 +1164,6 @@ function is_plugin_enabled($plugin, $site_guid = 0) {
* @return void
*/
function plugin_run_once() {
- // Register a class
add_subtype("object", "plugin", "ElggPlugin");
}
@@ -978,4 +1206,4 @@ function plugin_init() {
elgg_register_action('admin/plugins/reorder', '', 'admin');
}
-elgg_register_event_handler('init', 'system', 'plugin_init');
+elgg_register_event_handler('init', 'system', 'plugin_init'); \ No newline at end of file