X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCore%2FAddon.php;h=511364b8acb0cff9bb6180e97d6dd8441bea288b;hb=dd94fb124229bf84f84992781c8c455c7653af74;hp=a06982820e11530dd8e605789b3150d48bb3f42c;hpb=14fde5dc9b1915392601fb94efc6224c01f2b216;p=friendica.git diff --git a/src/Core/Addon.php b/src/Core/Addon.php index a06982820e..511364b8ac 100644 --- a/src/Core/Addon.php +++ b/src/Core/Addon.php @@ -1,19 +1,41 @@ . + * */ + namespace Friendica\Core; -use Friendica\App; -use Friendica\BaseObject; -use Friendica\Core\Logger; use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Util\Strings; /** * Some functions to handle addons */ -class Addon extends BaseObject +class Addon { + /** + * The addon sub-directory + * @var string + */ + const DIRECTORY = 'addon'; + /** * List of the names of enabled addons * @@ -22,7 +44,62 @@ class Addon extends BaseObject private static $addons = []; /** - * @brief Synchronize addons: + * Returns the list of available addons with their current status and info. + * This list is made from scanning the addon/ folder. + * Unsupported addons are excluded unless they already are enabled or system.show_unsupported_addon is set. + * + * @return array + * @throws \Exception + */ + public static function getAvailableList() + { + $addons = []; + $files = glob('addon/*/'); + if (is_array($files)) { + foreach ($files as $file) { + if (is_dir($file)) { + list($tmp, $addon) = array_map('trim', explode('/', $file)); + $info = self::getInfo($addon); + + if (DI::config()->get('system', 'show_unsupported_addons') + || strtolower($info['status']) != 'unsupported' + || self::isEnabled($addon) + ) { + $addons[] = [$addon, (self::isEnabled($addon) ? 'on' : 'off'), $info]; + } + } + } + } + + return $addons; + } + + /** + * Returns a list of addons that can be configured at the node level. + * The list is formatted for display in the admin panel aside. + * + * @return array + * @throws \Exception + */ + public static function getAdminList() + { + $addons_admin = []; + $addonsAdminStmt = DBA::select('addon', ['name'], ['plugin_admin' => 1], ['order' => ['name']]); + while ($addon = DBA::fetch($addonsAdminStmt)) { + $addons_admin[$addon['name']] = [ + 'url' => 'admin/addons/' . $addon['name'], + 'name' => $addon['name'], + 'class' => 'addon' + ]; + } + DBA::close($addonsAdminStmt); + + return $addons_admin; + } + + + /** + * Synchronize addons: * * system.addon contains a comma-separated list of names * of addons which are used on this system. @@ -35,48 +112,22 @@ class Addon extends BaseObject */ public static function loadAddons() { - $installed_addons = []; - - $r = DBA::select('addon', [], ['installed' => 1]); - if (DBA::isResult($r)) { - $installed_addons = DBA::toArray($r); - } - - $addons = Config::get('system', 'addon'); - $addons_arr = []; - - if ($addons) { - $addons_arr = explode(',', str_replace(' ', '', $addons)); - } - - self::$addons = $addons_arr; - - $installed_arr = []; - - foreach ($installed_addons as $addon) { - if (!self::isEnabled($addon['name'])) { - self::uninstall($addon['name']); - } else { - $installed_arr[] = $addon['name']; - } - } - - foreach (self::$addons as $p) { - if (!in_array($p, $installed_arr)) { - self::install($p); - } - } + $installed_addons = DBA::selectToArray('addon', ['name'], ['installed' => true]); + self::$addons = array_column($installed_addons, 'name'); } /** - * @brief uninstalls an addon. + * uninstalls an addon. * * @param string $addon name of the addon - * @return boolean + * @return void + * @throws \Exception */ public static function uninstall($addon) { - Logger::log("Addons: uninstalling " . $addon); + $addon = Strings::sanitizeFilePathItem($addon); + + Logger::notice("Addon {addon}: {action}", ['action' => 'uninstall', 'addon' => $addon]); DBA::delete('addon', ['name' => $addon]); @include_once('addon/' . $addon . '/' . $addon . '.php'); @@ -85,50 +136,48 @@ class Addon extends BaseObject $func(); } + Hook::delete(['file' => 'addon/' . $addon . '/' . $addon . '.php']); + unset(self::$addons[array_search($addon, self::$addons)]); } /** - * @brief installs an addon. + * installs an addon. * * @param string $addon name of the addon * @return bool + * @throws \Exception */ public static function install($addon) { - // silently fail if addon was removed + $addon = Strings::sanitizeFilePathItem($addon); + // silently fail if addon was removed of if $addon is funky if (!file_exists('addon/' . $addon . '/' . $addon . '.php')) { return false; } - Logger::log("Addons: installing " . $addon); + + Logger::notice("Addon {addon}: {action}", ['action' => 'install', 'addon' => $addon]); $t = @filemtime('addon/' . $addon . '/' . $addon . '.php'); @include_once('addon/' . $addon . '/' . $addon . '.php'); if (function_exists($addon . '_install')) { $func = $addon . '_install'; - $func(); - - $addon_admin = (function_exists($addon . "_addon_admin") ? 1 : 0); - - DBA::insert('addon', ['name' => $addon, 'installed' => true, - 'timestamp' => $t, 'plugin_admin' => $addon_admin]); - - // we can add the following with the previous SQL - // once most site tables have been updated. - // This way the system won't fall over dead during the update. - - if (file_exists('addon/' . $addon . '/.hidden')) { - DBA::update('addon', ['hidden' => true], ['name' => $addon]); - } + $func(DI::app()); + } - if (!self::isEnabled($addon)) { - self::$addons[] = $addon; - } - return true; - } else { - Logger::log("Addons: FAILED installing " . $addon); - return false; + DBA::insert('addon', [ + 'name' => $addon, + 'installed' => true, + 'timestamp' => $t, + 'plugin_admin' => function_exists($addon . '_addon_admin'), + 'hidden' => file_exists('addon/' . $addon . '/.hidden') + ]); + + if (!self::isEnabled($addon)) { + self::$addons[] = $addon; } + + return true; } /** @@ -136,48 +185,25 @@ class Addon extends BaseObject */ public static function reload() { - $addons = Config::get('system', 'addon'); - if (strlen($addons)) { - $r = DBA::select('addon', [], ['installed' => 1]); - if (DBA::isResult($r)) { - $installed = DBA::toArray($r); - } else { - $installed = []; + $addons = DBA::selectToArray('addon', [], ['installed' => true]); + + foreach ($addons as $addon) { + $addonname = Strings::sanitizeFilePathItem(trim($addon['name'])); + $fname = 'addon/' . $addonname . '/' . $addonname . '.php'; + $t = @filemtime($fname); + if (!file_exists($fname) || ($addon['timestamp'] == $t)) { + continue; } - $addon_list = explode(',', $addons); - - if (count($addon_list)) { - foreach ($addon_list as $addon) { - $addon = trim($addon); - $fname = 'addon/' . $addon . '/' . $addon . '.php'; - - if (file_exists($fname)) { - $t = @filemtime($fname); - foreach ($installed as $i) { - if (($i['name'] == $addon) && ($i['timestamp'] != $t)) { - Logger::log('Reloading addon: ' . $i['name']); - @include_once($fname); - - if (function_exists($addon . '_uninstall')) { - $func = $addon . '_uninstall'; - $func(); - } - if (function_exists($addon . '_install')) { - $func = $addon . '_install'; - $func(); - } - DBA::update('addon', ['timestamp' => $t], ['id' => $i['id']]); - } - } - } - } - } + Logger::notice("Addon {addon}: {action}", ['action' => 'reload', 'addon' => $addon['name']]); + + self::uninstall($fname); + self::install($fname); } } /** - * @brief Parse addon comment in search of addon infos. + * Parse addon comment in search of addon infos. * * like * \code @@ -191,10 +217,11 @@ class Addon extends BaseObject * *\endcode * @param string $addon the name of the addon * @return array with the addon information + * @throws \Exception */ public static function getInfo($addon) { - $a = self::getApp(); + $addon = Strings::sanitizeFilePathItem($addon); $info = [ 'name' => $addon, @@ -211,7 +238,7 @@ class Addon extends BaseObject $stamp1 = microtime(true); $f = file_get_contents("addon/$addon/$addon.php"); - $a->saveTimestamp($stamp1, "file"); + DI::profiler()->saveTimestamp($stamp1, "file"); $r = preg_match("|/\*.*\*/|msU", $f, $m); @@ -266,20 +293,11 @@ class Addon extends BaseObject return self::$addons; } - /** - * Saves the current enabled addon list in the system.addon config key - * - * @return boolean - */ - public static function saveEnabledList() - { - return Config::set("system", "addon", implode(", ", self::$addons)); - } - /** * Returns the list of non-hidden enabled addon names * * @return array + * @throws \Exception */ public static function getVisibleList() { @@ -297,13 +315,14 @@ class Addon extends BaseObject /** * Shim of Hook::register left for backward compatibility purpose. * - * @see Hook::register + * @see Hook::register * @deprecated since version 2018.12 * @param string $hook the name of the hook * @param string $file the name of the file that hooks into * @param string $function the name of the function that the hook will call * @param int $priority A priority (defaults to 0) * @return mixed|bool + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function registerHook($hook, $file, $function, $priority = 0) { @@ -313,12 +332,13 @@ class Addon extends BaseObject /** * Shim of Hook::unregister left for backward compatibility purpose. * - * @see Hook::unregister + * @see Hook::unregister * @deprecated since version 2018.12 * @param string $hook the name of the hook * @param string $file the name of the file that hooks into * @param string $function the name of the function that the hook called * @return boolean + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function unregisterHook($hook, $file, $function) { @@ -328,10 +348,11 @@ class Addon extends BaseObject /** * Shim of Hook::callAll left for backward-compatibility purpose. * - * @see Hook::callAll + * @see Hook::callAll * @deprecated since version 2018.12 - * @param string $name of the hook to call + * @param string $name of the hook to call * @param string|array &$data to transmit to the callback handler + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function callHooks($name, &$data = null) {