/**
* 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.
*
* @todo Crappy name?
* @return bool
* @since 1.8.0
* @access private
*/
function elgg_generate_plugin_entities()
{
// @todo $site unused, can remove?
$site = get_config('site');
$dir = elgg_get_plugins_path();
$db_prefix = elgg_get_config('dbprefix');
$options = array('type' => 'object', 'subtype' => 'plugin', 'selects' => array('plugin_oe.*'), 'joins' => array("JOIN {$db_prefix}objects_entity plugin_oe on plugin_oe.guid = e.guid"), '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);
/* @var ElggPlugin[] $known_plugins */
if (!$known_plugins) {
$known_plugins = array();
}
// 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;
}
$physical_plugins = elgg_get_plugin_ids_in_dir($dir);
if (!$physical_plugins) {
return false;
}
// 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->isEnabled()) {
$plugin->enable();
$plugin->deactivate();
$plugin->setPriority('last');
}
// remove from the list of plugins to disable
unset($known_plugins[$index]);
} else {
// add new plugins
// priority is force to last in save() if not set.
$plugin = new ElggPlugin($plugin_id);
$plugin->save();
}
}
// 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) {
if ($plugin->isActive()) {
$plugin->deactivate();
}
// remove the priority.
$name = elgg_namespace_plugin_private_setting('internal', 'priority');
remove_private_setting($plugin->guid, $name);
$plugin->disable();
}
access_show_hidden_entities($old_access);
elgg_set_ignore_access($old_ia);
elgg_reindex_plugin_priorities();
return true;
}