Merge pull request #14770 from Art4/new-addonproxy

New AddonHelper
This commit is contained in:
Hypolite Petovan 2025-02-10 07:53:24 -05:00 committed by GitHub
commit 17207dbb67
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 909 additions and 330 deletions

View file

@ -11,7 +11,6 @@ use Friendica\Content\Nav;
use Friendica\Content\Pager; use Friendica\Content\Pager;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Core\ACL; use Friendica\Core\ACL;
use Friendica\Core\Addon;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\System; use Friendica\Core\System;
@ -1067,6 +1066,7 @@ function photos_content()
$cmnt_tpl = Renderer::getMarkupTemplate('comment_item.tpl'); $cmnt_tpl = Renderer::getMarkupTemplate('comment_item.tpl');
$tpl = Renderer::getMarkupTemplate('photo_item.tpl'); $tpl = Renderer::getMarkupTemplate('photo_item.tpl');
$return_path = DI::args()->getCommand(); $return_path = DI::args()->getCommand();
$addonHelper = DI::addonHelper();
if (!DBA::isResult($items)) { if (!DBA::isResult($items)) {
if (($can_post || Security::canWriteToUserWall($owner_uid))) { if (($can_post || Security::canWriteToUserWall($owner_uid))) {
@ -1075,7 +1075,7 @@ function photos_content()
* This should be better if done by a hook * This should be better if done by a hook
*/ */
$qcomment = null; $qcomment = null;
if (Addon::isEnabled('qcomment')) { if ($addonHelper->isAddonEnabled('qcomment')) {
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words'); $words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
$qcomment = $words ? explode("\n", $words) : []; $qcomment = $words ? explode("\n", $words) : [];
} }
@ -1131,7 +1131,7 @@ function photos_content()
* This should be better if done by a hook * This should be better if done by a hook
*/ */
$qcomment = null; $qcomment = null;
if (Addon::isEnabled('qcomment')) { if ($addonHelper->isAddonEnabled('qcomment')) {
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words'); $words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
$qcomment = $words ? explode("\n", $words) : []; $qcomment = $words ? explode("\n", $words) : [];
} }
@ -1211,7 +1211,7 @@ function photos_content()
* This should be better if done by a hook * This should be better if done by a hook
*/ */
$qcomment = null; $qcomment = null;
if (Addon::isEnabled('qcomment')) { if ($addonHelper->isAddonEnabled('qcomment')) {
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words'); $words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
$qcomment = $words ? explode("\n", $words) : []; $qcomment = $words ? explode("\n", $words) : [];
} }

View file

@ -17,6 +17,7 @@ use Friendica\App\Router;
use Friendica\Capabilities\ICanCreateResponses; use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Capabilities\ICanHandleRequests; use Friendica\Capabilities\ICanHandleRequests;
use Friendica\Content\Nav; use Friendica\Content\Nav;
use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Addon\Capability\ICanLoadAddons; use Friendica\Core\Addon\Capability\ICanLoadAddons;
use Friendica\Core\Config\Factory\Config; use Friendica\Core\Config\Factory\Config;
use Friendica\Core\Container; use Friendica\Core\Container;
@ -171,6 +172,8 @@ class App
$this->session = $this->container->create(IHandleUserSessions::class); $this->session = $this->container->create(IHandleUserSessions::class);
$this->appHelper = $this->container->create(AppHelper::class); $this->appHelper = $this->container->create(AppHelper::class);
$addonHelper = $this->container->create(AddonHelper::class);
$this->load( $this->load(
$request->getServerParams(), $request->getServerParams(),
$this->container->create(DbaDefinition::class), $this->container->create(DbaDefinition::class),
@ -180,6 +183,7 @@ class App
$this->profiler, $this->profiler,
$this->container->create(EventDispatcherInterface::class), $this->container->create(EventDispatcherInterface::class),
$this->appHelper, $this->appHelper,
$addonHelper,
); );
$this->registerTemplateEngine(); $this->registerTemplateEngine();
@ -189,6 +193,7 @@ class App
$this->container->create(IManagePersonalConfigValues::class), $this->container->create(IManagePersonalConfigValues::class),
$this->container->create(Page::class), $this->container->create(Page::class),
$this->container->create(Nav::class), $this->container->create(Nav::class),
$addonHelper,
$this->container->create(ModuleHTTPException::class), $this->container->create(ModuleHTTPException::class),
$start_time, $start_time,
$request $request
@ -221,6 +226,7 @@ class App
$this->container->create(Profiler::class), $this->container->create(Profiler::class),
$this->container->create(EventDispatcherInterface::class), $this->container->create(EventDispatcherInterface::class),
$this->container->create(AppHelper::class), $this->container->create(AppHelper::class),
$this->container->create(AddonHelper::class),
); );
$this->registerTemplateEngine(); $this->registerTemplateEngine();
@ -252,6 +258,7 @@ class App
$this->container->create(Profiler::class), $this->container->create(Profiler::class),
$this->container->create(EventDispatcherInterface::class), $this->container->create(EventDispatcherInterface::class),
$this->container->create(AppHelper::class), $this->container->create(AppHelper::class),
$this->container->create(AddonHelper::class),
); );
/** @var BasePath */ /** @var BasePath */
@ -341,7 +348,8 @@ class App
IManageConfigValues $config, IManageConfigValues $config,
Profiler $profiler, Profiler $profiler,
EventDispatcherInterface $eventDispatcher, EventDispatcherInterface $eventDispatcher,
AppHelper $appHelper AppHelper $appHelper,
AddonHelper $addonHelper
): void { ): void {
if ($config->get('system', 'ini_max_execution_time') !== false) { if ($config->get('system', 'ini_max_execution_time') !== false) {
set_time_limit((int) $config->get('system', 'ini_max_execution_time')); set_time_limit((int) $config->get('system', 'ini_max_execution_time'));
@ -363,7 +371,7 @@ class App
if ($mode->has(Mode::DBAVAILABLE)) { if ($mode->has(Mode::DBAVAILABLE)) {
Core\Hook::loadHooks(); Core\Hook::loadHooks();
$loader = (new Config())->createConfigFileManager($appHelper->getBasePath(), $serverParams); $loader = (new Config())->createConfigFileManager($appHelper->getBasePath(), $addonHelper->getAddonPath(), $serverParams);
$eventDispatcher->dispatch(new ConfigLoadedEvent(ConfigLoadedEvent::CONFIG_LOADED, $loader)); $eventDispatcher->dispatch(new ConfigLoadedEvent(ConfigLoadedEvent::CONFIG_LOADED, $loader));
@ -415,6 +423,7 @@ class App
IManagePersonalConfigValues $pconfig, IManagePersonalConfigValues $pconfig,
Page $page, Page $page,
Nav $nav, Nav $nav,
AddonHelper $addonHelper,
ModuleHTTPException $httpException, ModuleHTTPException $httpException,
float $start_time, float $start_time,
ServerRequestInterface $request ServerRequestInterface $request
@ -503,12 +512,12 @@ class App
// but we need "view" module for stylesheet // but we need "view" module for stylesheet
if ($this->mode->isInstall() && $moduleName !== 'install') { if ($this->mode->isInstall() && $moduleName !== 'install') {
$this->baseURL->redirect('install'); $this->baseURL->redirect('install');
} else {
Core\Update::check($this->appHelper->getBasePath(), false);
Core\Addon::loadAddons();
Core\Hook::loadHooks();
} }
Core\Update::check($this->appHelper->getBasePath(), false);
$addonHelper->loadAddons();
Core\Hook::loadHooks();
// Compatibility with Hubzilla // Compatibility with Hubzilla
if ($moduleName == 'rpost') { if ($moduleName == 'rpost') {
$this->baseURL->redirect('compose'); $this->baseURL->redirect('compose');

View file

@ -7,13 +7,11 @@
namespace Friendica\App; namespace Friendica\App;
use Dice\Dice;
use FastRoute\DataGenerator\GroupCountBased; use FastRoute\DataGenerator\GroupCountBased;
use FastRoute\Dispatcher; use FastRoute\Dispatcher;
use FastRoute\RouteCollector; use FastRoute\RouteCollector;
use FastRoute\RouteParser\Std; use FastRoute\RouteParser\Std;
use Friendica\Capabilities\ICanHandleRequests; use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Addon;
use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Cache\Capability\ICanCache; use Friendica\Core\Cache\Capability\ICanCache;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
@ -86,6 +84,8 @@ class Router
/** @var LoggerInterface */ /** @var LoggerInterface */
private $logger; private $logger;
private AddonHelper $addonHelper;
/** @var bool */ /** @var bool */
private $isLocalUser; private $isLocalUser;
@ -110,7 +110,7 @@ class Router
* @param IHandleUserSessions $userSession * @param IHandleUserSessions $userSession
* @param RouteCollector|null $routeCollector * @param RouteCollector|null $routeCollector
*/ */
public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, IHandleUserSessions $userSession, RouteCollector $routeCollector = null) public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, AddonHelper $addonHelper, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
{ {
$this->baseRoutesFilepath = $baseRoutesFilepath; $this->baseRoutesFilepath = $baseRoutesFilepath;
$this->l10n = $l10n; $this->l10n = $l10n;
@ -120,6 +120,7 @@ class Router
$this->config = $config; $this->config = $config;
$this->server = $server; $this->server = $server;
$this->logger = $logger; $this->logger = $logger;
$this->addonHelper = $addonHelper;
$this->isLocalUser = !empty($userSession->getLocalUserId()); $this->isLocalUser = !empty($userSession->getLocalUserId());
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased()); $this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
@ -282,7 +283,7 @@ class Router
if ($routeInfo[0] === Dispatcher::FOUND) { if ($routeInfo[0] === Dispatcher::FOUND) {
$this->moduleClass = $routeInfo[1]; $this->moduleClass = $routeInfo[1];
$this->parameters[] = $routeInfo[2]; $this->parameters[] = $routeInfo[2];
} else if ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) { } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
throw new HTTPException\MethodNotAllowedException($this->l10n->t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1]))); throw new HTTPException\MethodNotAllowedException($this->l10n->t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1])));
} else { } else {
throw new HTTPException\NotFoundException($this->l10n->t('Page not found.')); throw new HTTPException\NotFoundException($this->l10n->t('Page not found.'));
@ -293,7 +294,7 @@ class Router
} catch (NotFoundException $e) { } catch (NotFoundException $e) {
$moduleName = $this->args->getModuleName(); $moduleName = $this->args->getModuleName();
// Then we try addon-provided modules that we wrap in the LegacyModule class // Then we try addon-provided modules that we wrap in the LegacyModule class
if (Addon::isEnabled($moduleName) && file_exists("addon/{$moduleName}/{$moduleName}.php")) { if ($this->addonHelper->isAddonEnabled($moduleName) && file_exists("addon/{$moduleName}/{$moduleName}.php")) {
//Check if module is an app and if public access to apps is allowed or not //Check if module is an app and if public access to apps is allowed or not
$privateapps = $this->config->get('config', 'private_addons', false); $privateapps = $this->config->get('config', 'private_addons', false);
if (!$this->isLocalUser && Hook::isAddonApp($moduleName) && $privateapps) { if (!$this->isLocalUser && Hook::isAddonApp($moduleName) && $privateapps) {

View file

@ -10,7 +10,7 @@ namespace Friendica\Console;
use Console_Table; use Console_Table;
use Friendica\App\Mode; use Friendica\App\Mode;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Addon as AddonCore; use Friendica\Core\Addon\AddonHelper;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Util\Strings; use Friendica\Util\Strings;
use RuntimeException; use RuntimeException;
@ -34,6 +34,7 @@ class Addon extends \Asika\SimpleConsole\Console
* @var Database * @var Database
*/ */
private $dba; private $dba;
private AddonHelper $addonHelper;
protected function getHelp() protected function getHelp()
{ {
@ -56,15 +57,16 @@ HELP;
return $help; return $help;
} }
public function __construct(Mode $appMode, L10n $l10n, Database $dba, array $argv = null) public function __construct(Mode $appMode, L10n $l10n, Database $dba, AddonHelper $addonHelper, array $argv = null)
{ {
parent::__construct($argv); parent::__construct($argv);
$this->appMode = $appMode; $this->appMode = $appMode;
$this->l10n = $l10n; $this->l10n = $l10n;
$this->dba = $dba; $this->dba = $dba;
$this->addonHelper = $addonHelper;
AddonCore::loadAddons(); $this->addonHelper->loadAddons();
} }
protected function doExecute(): int protected function doExecute(): int
@ -122,23 +124,22 @@ HELP;
return false; return false;
} }
foreach (AddonCore::getAvailableList() as $addon) { foreach ($this->addonHelper->getAvailableAddons() as $addonId) {
$addon_name = $addon[0]; $enabled = $this->addonHelper->isAddonEnabled($addonId);
$enabled = AddonCore::isEnabled($addon_name);
if ($subCmd === 'all') { if ($subCmd === 'all') {
$table->addRow([$addon_name, $enabled ? 'enabled' : 'disabled']); $table->addRow([$addonId, $enabled ? 'enabled' : 'disabled']);
continue; continue;
} }
if ($subCmd === 'enabled' && $enabled === true) { if ($subCmd === 'enabled' && $enabled === true) {
$table->addRow([$addon_name]); $table->addRow([$addonId]);
continue; continue;
} }
if ($subCmd === 'disabled' && $enabled === false) { if ($subCmd === 'disabled' && $enabled === false) {
$table->addRow([$addon_name]); $table->addRow([$addonId]);
continue; continue;
} }
} }
@ -163,11 +164,11 @@ HELP;
throw new RuntimeException($this->l10n->t('Addon not found')); throw new RuntimeException($this->l10n->t('Addon not found'));
} }
if (AddonCore::isEnabled($addon)) { if ($this->addonHelper->isAddonEnabled($addon)) {
throw new RuntimeException($this->l10n->t('Addon already enabled')); throw new RuntimeException($this->l10n->t('Addon already enabled'));
} }
AddonCore::install($addon); $this->addonHelper->installAddon($addon);
return 0; return 0;
} }
@ -187,11 +188,11 @@ HELP;
throw new RuntimeException($this->l10n->t('Addon not found')); throw new RuntimeException($this->l10n->t('Addon not found'));
} }
if (!AddonCore::isEnabled($addon)) { if (!$this->addonHelper->isAddonEnabled($addon)) {
throw new RuntimeException($this->l10n->t('Addon already disabled')); throw new RuntimeException($this->l10n->t('Addon already disabled'));
} }
AddonCore::uninstall($addon); $this->addonHelper->uninstallAddon($addon);
return 0; return 0;
} }

View file

@ -11,7 +11,7 @@ namespace Friendica\Console;
use Asika\SimpleConsole\Console; use Asika\SimpleConsole\Console;
use Friendica\App\Mode; use Friendica\App\Mode;
use Friendica\Core\Addon; use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
@ -29,6 +29,7 @@ final class JetstreamDaemon extends Console
private IManageKeyValuePairs $keyValue; private IManageKeyValuePairs $keyValue;
private SysDaemon $daemon; private SysDaemon $daemon;
private Jetstream $jetstream; private Jetstream $jetstream;
private AddonHelper $addonHelper;
/** /**
* @param Mode $mode * @param Mode $mode
@ -38,7 +39,7 @@ final class JetstreamDaemon extends Console
* @param Jetstream $jetstream * @param Jetstream $jetstream
* @param array|null $argv * @param array|null $argv
*/ */
public function __construct(Mode $mode, IManageConfigValues $config, IManageKeyValuePairs $keyValue, SysDaemon $daemon, Jetstream $jetstream, array $argv = null) public function __construct(Mode $mode, IManageConfigValues $config, IManageKeyValuePairs $keyValue, SysDaemon $daemon, Jetstream $jetstream, AddonHelper $addonHelper, array $argv = null)
{ {
parent::__construct($argv); parent::__construct($argv);
@ -47,6 +48,7 @@ final class JetstreamDaemon extends Console
$this->keyValue = $keyValue; $this->keyValue = $keyValue;
$this->jetstream = $jetstream; $this->jetstream = $jetstream;
$this->daemon = $daemon; $this->daemon = $daemon;
$this->addonHelper = $addonHelper;
} }
protected function getHelp(): string protected function getHelp(): string
@ -95,10 +97,10 @@ HELP;
); );
} }
Addon::loadAddons(); $this->addonHelper->loadAddons();
Hook::loadHooks(); Hook::loadHooks();
if (!Addon::isEnabled('bluesky')) { if (!$this->addonHelper->isAddonEnabled('bluesky')) {
throw new RuntimeException("Bluesky has to be enabled.\n"); throw new RuntimeException("Bluesky has to be enabled.\n");
} }

View file

@ -207,7 +207,7 @@ class Conversation
if ($total === 0) { if ($total === 0) {
throw new InternalServerErrorException(sprintf('There has to be at least one Liker for verb "%s"', $verb)); throw new InternalServerErrorException(sprintf('There has to be at least one Liker for verb "%s"', $verb));
} else if ($total === 1) { } elseif ($total === 1) {
$likerString = $likers[0]; $likerString = $likers[0];
} else { } else {
if ($total < $this->config->get('system', 'max_likers')) { if ($total < $this->config->get('system', 'max_likers')) {
@ -1501,7 +1501,7 @@ class Conversation
$body_html = ItemModel::prepareBody($item, true, $preview); $body_html = ItemModel::prepareBody($item, true, $preview);
[$categories, $folders] = $this->item->determineCategoriesTerms($item, $this->session->getLocalUserId()); list($categories, $folders) = $this->item->determineCategoriesTerms($item, $this->session->getLocalUserId());
if (!empty($item['featured'])) { if (!empty($item['featured'])) {
$pinned = $this->l10n->t('Pinned item'); $pinned = $this->l10n->t('Pinned item');

View file

@ -7,7 +7,6 @@
namespace Friendica\Content; namespace Friendica\Content;
use Friendica\Core\Addon;
use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
@ -33,13 +32,13 @@ class Widget
*/ */
public static function follow(string $value = ''): string public static function follow(string $value = ''): string
{ {
return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), array( return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), [
'$connect' => DI::l10n()->t('Add New Contact'), '$connect' => DI::l10n()->t('Add New Contact'),
'$desc' => DI::l10n()->t('Enter address or web location'), '$desc' => DI::l10n()->t('Enter address or web location'),
'$hint' => DI::l10n()->t('Example: bob@example.com, http://example.com/barbara'), '$hint' => DI::l10n()->t('Example: bob@example.com, http://example.com/barbara'),
'$value' => $value, '$value' => $value,
'$follow' => DI::l10n()->t('Connect') '$follow' => DI::l10n()->t('Connect')
)); ]);
} }
/** /**
@ -87,19 +86,21 @@ class Widget
*/ */
public static function unavailableNetworks(): array public static function unavailableNetworks(): array
{ {
$addonHelper = DI::addonHelper();
// Always hide content from these networks // Always hide content from these networks
$networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::TWITTER, Protocol::ZOT, Protocol::OSTATUS, Protocol::STATUSNET]; $networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::TWITTER, Protocol::ZOT, Protocol::OSTATUS, Protocol::STATUSNET];
Addon::loadAddons(); $addonHelper->loadAddons();
if (!Addon::isEnabled('discourse')) { if (!$addonHelper->isAddonEnabled('discourse')) {
$networks[] = Protocol::DISCOURSE; $networks[] = Protocol::DISCOURSE;
} }
if (!Addon::isEnabled('pumpio')) { if (!$addonHelper->isAddonEnabled('pumpio')) {
$networks[] = Protocol::PUMPIO; $networks[] = Protocol::PUMPIO;
} }
if (!Addon::isEnabled('tumblr')) { if (!$addonHelper->isAddonEnabled('tumblr')) {
$networks[] = Protocol::TUMBLR; $networks[] = Protocol::TUMBLR;
} }
@ -107,7 +108,7 @@ class Widget
$networks[] = Protocol::DIASPORA; $networks[] = Protocol::DIASPORA;
} }
if (!Addon::isEnabled('pnut')) { if (!$addonHelper->isAddonEnabled('pnut')) {
$networks[] = Protocol::PNUT; $networks[] = Protocol::PNUT;
} }
return $networks; return $networks;
@ -120,18 +121,20 @@ class Widget
*/ */
public static function availableNetworks(): array public static function availableNetworks(): array
{ {
$networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED]; $addonHelper = DI::addonHelper();
Addon::loadAddons();
if (Addon::isEnabled('discourse')) { $networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED];
$addonHelper->loadAddons();
if ($addonHelper->isAddonEnabled('discourse')) {
$networks[] = Protocol::DISCOURSE; $networks[] = Protocol::DISCOURSE;
} }
if (Addon::isEnabled('pumpio')) { if ($addonHelper->isAddonEnabled('pumpio')) {
$networks[] = Protocol::PUMPIO; $networks[] = Protocol::PUMPIO;
} }
if (Addon::isEnabled('tumblr')) { if ($addonHelper->isAddonEnabled('tumblr')) {
$networks[] = Protocol::TUMBLR; $networks[] = Protocol::TUMBLR;
} }
@ -143,7 +146,7 @@ class Widget
$networks[] = Protocol::MAIL; $networks[] = Protocol::MAIL;
} }
if (Addon::isEnabled('pnut')) { if ($addonHelper->isAddonEnabled('pnut')) {
$networks[] = Protocol::PNUT; $networks[] = Protocol::PNUT;
} }
return $networks; return $networks;

View file

@ -18,6 +18,9 @@ class Addon
{ {
/** /**
* The addon sub-directory * The addon sub-directory
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAddonPath()` instead
*
* @var string * @var string
*/ */
const DIRECTORY = 'addon'; const DIRECTORY = 'addon';
@ -34,6 +37,8 @@ class Addon
* This list is made from scanning the addon/ folder. * 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. * Unsupported addons are excluded unless they already are enabled or system.show_unsupported_addon is set.
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAvailableAddons()` instead
*
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
@ -64,6 +69,8 @@ class Addon
* Returns a list of addons that can be configured at the node level. * Returns a list of addons that can be configured at the node level.
* The list is formatted for display in the admin panel aside. * The list is formatted for display in the admin panel aside.
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getEnabledAddonsWithAdminSettings()` instead
*
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */
@ -88,7 +95,6 @@ class Addon
return $addons_admin; return $addons_admin;
} }
/** /**
* Synchronize addons: * Synchronize addons:
* *
@ -100,6 +106,7 @@ class Addon
* Then go through the config list and if we have a addon that isn't installed, * Then go through the config list and if we have a addon that isn't installed,
* call the install procedure and add it to the database. * call the install procedure and add it to the database.
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::loadAddons()` instead
*/ */
public static function loadAddons() public static function loadAddons()
{ {
@ -109,6 +116,8 @@ class Addon
/** /**
* uninstalls an addon. * uninstalls an addon.
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::uninstallAddon()` instead
*
* @param string $addon name of the addon * @param string $addon name of the addon
* @return void * @return void
* @throws \Exception * @throws \Exception
@ -135,6 +144,8 @@ class Addon
/** /**
* installs an addon. * installs an addon.
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::installAddon()` instead
*
* @param string $addon name of the addon * @param string $addon name of the addon
* @return bool * @return bool
* @throws \Exception * @throws \Exception
@ -173,6 +184,8 @@ class Addon
/** /**
* reload all updated addons * reload all updated addons
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::reloadAddons()` instead
*
* @return void * @return void
* @throws \Exception * @throws \Exception
* *
@ -209,6 +222,9 @@ class Addon
* * Maintainer: Jess <email> * * Maintainer: Jess <email>
* * * *
* *\endcode * *\endcode
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAddonInfo()` instead
*
* @param string $addon the name of the addon * @param string $addon the name of the addon
* @return array with the addon information * @return array with the addon information
* @throws \Exception * @throws \Exception
@ -275,6 +291,8 @@ class Addon
/** /**
* Checks if the provided addon is enabled * Checks if the provided addon is enabled
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::isAddonEnabled()` instead
*
* @param string $addon * @param string $addon
* @return boolean * @return boolean
*/ */
@ -286,6 +304,8 @@ class Addon
/** /**
* Returns a list of the enabled addon names * Returns a list of the enabled addon names
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getEnabledAddons()` instead
*
* @return array * @return array
*/ */
public static function getEnabledList(): array public static function getEnabledList(): array
@ -296,6 +316,8 @@ class Addon
/** /**
* Returns the list of non-hidden enabled addon names * Returns the list of non-hidden enabled addon names
* *
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getVisibleEnabledAddons()` instead
*
* @return array * @return array
* @throws \Exception * @throws \Exception
*/ */

View file

@ -0,0 +1,92 @@
<?php
// Copyright (C) 2010-2024, the Friendica project
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
//
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
namespace Friendica\Core\Addon;
/**
* Some functions to handle addons
*/
interface AddonHelper
{
/**
* Returns the absolute path to the addon folder
*
* e.g. `/var/www/html/addon`
*/
public function getAddonPath(): string;
/**
* Returns the list of available addons.
*
* 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 string[]
*/
public function getAvailableAddons(): array;
/**
* Installs an addon.
*
* @param string $addonId name of the addon
*
* @return bool true on success or false on failure
*/
public function installAddon(string $addonId): bool;
/**
* Uninstalls an addon.
*
* @param string $addonId name of the addon
*/
public function uninstallAddon(string $addonId): void;
/**
* Load addons.
*
* @internal
*/
public function loadAddons(): void;
/**
* Reload (uninstall and install) all updated addons.
*/
public function reloadAddons(): void;
/**
* Get the comment block of an addon as value object.
*/
public function getAddonInfo(string $addonId): AddonInfo;
/**
* Checks if the provided addon is enabled
*/
public function isAddonEnabled(string $addonId): bool;
/**
* Returns a list with the IDs of the enabled addons
*
* @return string[]
*/
public function getEnabledAddons(): array;
/**
* Returns a list with the IDs of the non-hidden enabled addons
*
* @return string[]
*/
public function getVisibleEnabledAddons(): array;
/**
* Returns a list with the IDs of the enabled addons that provides admin settings.
*
* @return string[]
*/
public function getEnabledAddonsWithAdminSettings(): array;
}

View file

@ -0,0 +1,140 @@
<?php
// Copyright (C) 2010-2024, the Friendica project
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
//
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
namespace Friendica\Core\Addon;
/**
* Information about an addon
*/
final class AddonInfo
{
/**
* @internal Never create this object by yourself, use `Friendica\Core\Addon\AddonHelper::getAddonInfo()` instead.
*
* @see Friendica\Core\Addon\AddonHelper::getAddonInfo()
*/
public static function fromArray(array $info): self
{
$id = array_key_exists('id', $info) ? (string) $info['id'] : '';
$name = array_key_exists('name', $info) ? (string) $info['name'] : '';
$description = array_key_exists('description', $info) ? (string) $info['description'] : '';
$authors = array_key_exists('authors', $info) ? self::parseContributors($info['authors']) : [];
$maintainers = array_key_exists('maintainers', $info) ? self::parseContributors($info['maintainers']) : [];
$version = array_key_exists('version', $info) ? (string) $info['version'] : '';
$status = array_key_exists('status', $info) ? (string) $info['status'] : '';
return new self(
$id,
$name,
$description,
$authors,
$maintainers,
$version,
$status
);
}
private static function parseContributors($entries): array
{
if (!is_array($entries)) {
return [];
}
$contributors = [];
foreach ($entries as $entry) {
if (!is_array($entry)) {
continue;
}
if (!array_key_exists('name', $entry)) {
continue;
}
$contributor = [
'name' => (string) $entry['name'],
];
if (array_key_exists('link', $entry)) {
$contributor['link'] = (string) $entry['link'];
}
$contributors[] = $contributor;
}
return $contributors;
}
private string $id = '';
private string $name = '';
private string $description = '';
private array $authors = [];
private array $maintainers = [];
private string $version = '';
private string $status = '';
private function __construct(
string $id,
string $name,
string $description,
array $authors,
array $maintainers,
string $version,
string $status
) {
$this->id = $id;
$this->name = $name;
$this->description = $description;
$this->authors = $authors;
$this->maintainers = $maintainers;
$this->version = $version;
$this->status = $status;
}
public function getId(): string
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function getDescription(): string
{
return $this->description;
}
public function getAuthors(): array
{
return $this->authors;
}
public function getMaintainers(): array
{
return $this->maintainers;
}
public function getVersion(): string
{
return $this->version;
}
public function getStatus(): string
{
return $this->status;
}
}

View file

@ -0,0 +1,154 @@
<?php
// Copyright (C) 2010-2024, the Friendica project
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
//
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
namespace Friendica\Core\Addon;
use Friendica\Core\Addon;
/**
* Proxy to the Addon class
*
* @internal
*/
final class AddonProxy implements AddonHelper
{
private string $addonPath;
public function __construct(string $addonPath)
{
$this->addonPath = $addonPath;
}
/**
* Returns the absolute path to the addon folder
*
* e.g. `/var/www/html/addon`
*/
public function getAddonPath(): string
{
return $this->addonPath;
}
/**
* Returns the list of available addons.
*
* 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 string[]
*/
public function getAvailableAddons(): array
{
return array_map(
function (array $item) {
return $item[0];
},
Addon::getAvailableList()
);
}
/**
* Installs an addon.
*
* @param string $addonId name of the addon
*
* @return bool true on success or false on failure
*/
public function installAddon(string $addonId): bool
{
return Addon::install($addonId);
}
/**
* Uninstalls an addon.
*
* @param string $addonId name of the addon
*/
public function uninstallAddon(string $addonId): void
{
Addon::uninstall($addonId);
}
/**
* Load addons.
*
* @internal
*/
public function loadAddons(): void
{
Addon::loadAddons();
}
/**
* Reload (uninstall and install) all updated addons.
*/
public function reloadAddons(): void
{
Addon::reload();
}
/**
* Get the comment block of an addon as value object.
*/
public function getAddonInfo(string $addonId): AddonInfo
{
$data = Addon::getInfo($addonId);
// add addon ID
$data['id'] = $addonId;
// rename author to authors
$data['authors'] = $data['author'];
unset($data['author']);
// rename maintainer to maintainers
$data['maintainers'] = $data['maintainer'];
unset($data['maintainer']);
return AddonInfo::fromArray($data);
}
/**
* Checks if the provided addon is enabled
*/
public function isAddonEnabled(string $addonId): bool
{
return Addon::isEnabled($addonId);
}
/**
* Returns a list with the IDs of the enabled addons
*
* @return string[]
*/
public function getEnabledAddons(): array
{
return Addon::getEnabledList();
}
/**
* Returns a list with the IDs of the non-hidden enabled addons
*
* @return string[]
*/
public function getVisibleEnabledAddons(): array
{
return Addon::getVisibleList();
}
/**
* Returns a list with the IDs of the enabled addons that provides admin settings.
*
* @return string[]
*/
public function getEnabledAddonsWithAdminSettings(): array
{
return array_keys(Addon::getAdminList());
}
}

View file

@ -42,7 +42,7 @@ class Config
* *
* @return Util\ConfigFileManager * @return Util\ConfigFileManager
*/ */
public function createConfigFileManager(string $basePath, array $server = []): Util\ConfigFileManager public function createConfigFileManager(string $basePath, string $addonPath, array $server = []): Util\ConfigFileManager
{ {
if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) { if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
$configDir = $server[self::CONFIG_DIR_ENV]; $configDir = $server[self::CONFIG_DIR_ENV];
@ -51,7 +51,7 @@ class Config
} }
$staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR; $staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
return new Util\ConfigFileManager($basePath, $configDir, $staticDir, $server); return new Util\ConfigFileManager($basePath, $addonPath, $configDir, $staticDir, $server);
} }
/** /**

View file

@ -7,7 +7,6 @@
namespace Friendica\Core\Config\Util; namespace Friendica\Core\Config\Util;
use Friendica\Core\Addon;
use Friendica\Core\Config\Exception\ConfigFileException; use Friendica\Core\Config\Exception\ConfigFileException;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
@ -46,6 +45,7 @@ class ConfigFileManager
* @var string * @var string
*/ */
private $baseDir; private $baseDir;
private string $addonDir;
/** /**
* @var string * @var string
*/ */
@ -65,9 +65,10 @@ class ConfigFileManager
* @param string $configDir * @param string $configDir
* @param string $staticDir * @param string $staticDir
*/ */
public function __construct(string $baseDir, string $configDir, string $staticDir, array $server = []) public function __construct(string $baseDir, string $addonDir, string $configDir, string $staticDir, array $server = [])
{ {
$this->baseDir = $baseDir; $this->baseDir = $baseDir;
$this->addonDir = $addonDir;
$this->configDir = $configDir; $this->configDir = $configDir;
$this->staticDir = $staticDir; $this->staticDir = $staticDir;
$this->server = $server; $this->server = $server;
@ -122,7 +123,7 @@ class ConfigFileManager
if (file_exists($configName)) { if (file_exists($configName)) {
return $this->loadConfigFile($configName); return $this->loadConfigFile($configName);
} else if (file_exists($iniName)) { } elseif (file_exists($iniName)) {
return $this->loadINIConfigFile($iniName); return $this->loadINIConfigFile($iniName);
} else { } else {
return []; return [];
@ -160,17 +161,16 @@ class ConfigFileManager
*/ */
public function loadAddonConfig(string $name): array public function loadAddonConfig(string $name): array
{ {
$filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/ $filepath = $this->addonDir . DIRECTORY_SEPARATOR . // /var/www/html/addon/
Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
$name . DIRECTORY_SEPARATOR . // openstreetmap/ $name . DIRECTORY_SEPARATOR . // openstreetmap/
'config' . DIRECTORY_SEPARATOR . // config/ 'config' . DIRECTORY_SEPARATOR . // config/
$name . ".config.php"; // openstreetmap.config.php $name . ".config.php"; // openstreetmap.config.php
if (file_exists($filepath)) { if (!file_exists($filepath)) {
return $this->loadConfigFile($filepath);
} else {
return []; return [];
} }
return $this->loadConfigFile($filepath);
} }
/** /**

View file

@ -8,7 +8,6 @@
namespace Friendica\Core\Storage\Repository; namespace Friendica\Core\Storage\Repository;
use Exception; use Exception;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\L10n; use Friendica\Core\L10n;
@ -20,6 +19,7 @@ use Friendica\Core\Storage\Capability\ICanConfigureStorage;
use Friendica\Core\Storage\Capability\ICanWriteToStorage; use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Core\Storage\Type; use Friendica\Core\Storage\Type;
use Friendica\DI;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\InternalServerErrorException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -84,7 +84,7 @@ class StorageManager
/// @fixme Loading the addons & hooks here is really bad practice, but solves https://github.com/friendica/friendica/issues/11178 /// @fixme Loading the addons & hooks here is really bad practice, but solves https://github.com/friendica/friendica/issues/11178
/// clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore /// clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore
if ($includeAddon) { if ($includeAddon) {
Addon::loadAddons(); DI::addonHelper()->loadAddons();
Hook::loadHooks(); Hook::loadHooks();
} }
@ -228,11 +228,13 @@ class StorageManager
*/ */
public function isValidBackend(string $name = null, array $validBackends = null): bool public function isValidBackend(string $name = null, array $validBackends = null): bool
{ {
$validBackends = $validBackends ?? array_merge($this->validBackends, $validBackends = $validBackends ?? array_merge(
$this->validBackends,
[ [
Type\SystemResource::getName(), Type\SystemResource::getName(),
Type\ExternalResource::getName(), Type\ExternalResource::getName(),
]); ]
);
return in_array($name, $validBackends); return in_array($name, $validBackends);
} }

View file

@ -8,6 +8,7 @@
namespace Friendica; namespace Friendica;
use Dice\Dice; use Dice\Dice;
use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Logger\Capability\ICheckLoggerSettings; use Friendica\Core\Logger\Capability\ICheckLoggerSettings;
use Friendica\Core\Logger\LoggerManager; use Friendica\Core\Logger\LoggerManager;
use Friendica\Core\Logger\Util\LoggerSettingsCheck; use Friendica\Core\Logger\Util\LoggerSettingsCheck;
@ -280,6 +281,11 @@ abstract class DI
return self::$dice->create(Core\Storage\Repository\StorageManager::class); return self::$dice->create(Core\Storage\Repository\StorageManager::class);
} }
public static function addonHelper(): AddonHelper
{
return self::$dice->create(AddonHelper::class);
}
/** /**
* @return \Friendica\Core\System * @return \Friendica\Core\System
*/ */

View file

@ -8,7 +8,6 @@
namespace Friendica\Module\Admin\Addons; namespace Friendica\Module\Admin\Addons;
use Friendica\Content\Text\Markdown; use Friendica\Content\Text\Markdown;
use Friendica\Core\Addon;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\BaseAdmin; use Friendica\Module\BaseAdmin;
@ -42,12 +41,12 @@ class Details extends BaseAdmin
{ {
parent::content(); parent::content();
$addons_admin = Addon::getAdminList(); $addonHelper = DI::addonHelper();
$addon = Strings::sanitizeFilePathItem($this->parameters['addon']); $addon = Strings::sanitizeFilePathItem($this->parameters['addon']);
if (!is_file("addon/$addon/$addon.php")) { if (!is_file("addon/$addon/$addon.php")) {
DI::sysmsg()->addNotice(DI::l10n()->t('Addon not found.')); DI::sysmsg()->addNotice(DI::l10n()->t('Addon not found.'));
Addon::uninstall($addon); $addonHelper->uninstallAddon($addon);
DI::baseUrl()->redirect('admin/addons'); DI::baseUrl()->redirect('admin/addons');
} }
@ -55,11 +54,11 @@ class Details extends BaseAdmin
self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons_details', 't'); self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons_details', 't');
// Toggle addon status // Toggle addon status
if (Addon::isEnabled($addon)) { if ($addonHelper->isAddonEnabled($addon)) {
Addon::uninstall($addon); $addonHelper->uninstallAddon($addon);
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon)); DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon));
} else { } else {
Addon::install($addon); $addonHelper->installAddon($addon);
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon)); DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon));
} }
@ -67,7 +66,7 @@ class Details extends BaseAdmin
} }
// display addon details // display addon details
if (Addon::isEnabled($addon)) { if ($addonHelper->isAddonEnabled($addon)) {
$status = 'on'; $status = 'on';
$action = DI::l10n()->t('Disable'); $action = DI::l10n()->t('Disable');
} else { } else {
@ -82,13 +81,17 @@ class Details extends BaseAdmin
$readme = '<pre>' . file_get_contents("addon/$addon/README") . '</pre>'; $readme = '<pre>' . file_get_contents("addon/$addon/README") . '</pre>';
} }
$addons_admin = $addonHelper->getEnabledAddonsWithAdminSettings();
$admin_form = ''; $admin_form = '';
if (array_key_exists($addon, $addons_admin)) { if (in_array($addon, $addons_admin)) {
require_once "addon/$addon/$addon.php"; require_once "addon/$addon/$addon.php";
$func = $addon . '_addon_admin'; $func = $addon . '_addon_admin';
$func($admin_form); $func($admin_form);
} }
$addonInfo = $addonHelper->getAddonInfo($addon);
$t = Renderer::getMarkupTemplate('admin/addons/details.tpl'); $t = Renderer::getMarkupTemplate('admin/addons/details.tpl');
return Renderer::replaceMacros($t, [ return Renderer::replaceMacros($t, [
@ -100,7 +103,13 @@ class Details extends BaseAdmin
'$addon' => $addon, '$addon' => $addon,
'$status' => $status, '$status' => $status,
'$action' => $action, '$action' => $action,
'$info' => Addon::getInfo($addon), '$info' => [
'name' => $addonInfo->getName(),
'version' => $addonInfo->getVersion(),
'description' => $addonInfo->getDescription(),
'author' => $addonInfo->getAuthors(),
'maintainer' => $addonInfo->getMaintainers(),
],
'$str_author' => DI::l10n()->t('Author: '), '$str_author' => DI::l10n()->t('Author: '),
'$str_maintainer' => DI::l10n()->t('Maintainer: '), '$str_maintainer' => DI::l10n()->t('Maintainer: '),

View file

@ -7,7 +7,6 @@
namespace Friendica\Module\Admin\Addons; namespace Friendica\Module\Admin\Addons;
use Friendica\Core\Addon;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\BaseAdmin; use Friendica\Module\BaseAdmin;
@ -24,22 +23,25 @@ class Index extends BaseAdmin
{ {
parent::content(); parent::content();
$addonHelper = DI::addonHelper();
// reload active themes // reload active themes
if (!empty($_GET['action'])) { if (!empty($_GET['action'])) {
self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons', 't'); self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons', 't');
switch ($_GET['action']) { switch ($_GET['action']) {
case 'reload': case 'reload':
Addon::reload(); $addonHelper->reloadAddons();
DI::sysmsg()->addInfo(DI::l10n()->t('Addons reloaded')); DI::sysmsg()->addInfo(DI::l10n()->t('Addons reloaded'));
break; break;
case 'toggle' : case 'toggle':
$addon = $_GET['addon'] ?? ''; $addon = $_GET['addon'] ?? '';
if (Addon::isEnabled($addon)) {
Addon::uninstall($addon); if ($addonHelper->isAddonEnabled($addon)) {
$addonHelper->uninstallAddon($addon);
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon)); DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon));
} elseif (Addon::install($addon)) { } elseif ($addonHelper->installAddon($addon)) {
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon)); DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon));
} else { } else {
DI::sysmsg()->addNotice(DI::l10n()->t('Addon %s failed to install.', $addon)); DI::sysmsg()->addNotice(DI::l10n()->t('Addon %s failed to install.', $addon));
@ -52,7 +54,23 @@ class Index extends BaseAdmin
DI::baseUrl()->redirect('admin/addons'); DI::baseUrl()->redirect('admin/addons');
} }
$addons = Addon::getAvailableList(); $addons = [];
foreach ($addonHelper->getAvailableAddons() as $addonId) {
$addonInfo = $addonHelper->getAddonInfo($addonId);
$info = [
'name' => $addonInfo->getName(),
'description' => $addonInfo->getDescription(),
'version' => $addonInfo->getVersion(),
];
$addons[] = [
$addonId,
($addonHelper->isAddonEnabled($addonId) ? 'on' : 'off'),
$info,
];
}
$t = Renderer::getMarkupTemplate('admin/addons/index.tpl'); $t = Renderer::getMarkupTemplate('admin/addons/index.tpl');
return Renderer::replaceMacros($t, [ return Renderer::replaceMacros($t, [

View file

@ -8,7 +8,6 @@
namespace Friendica\Module\Admin; namespace Friendica\Module\Admin;
use Friendica\App; use Friendica\App;
use Friendica\Core\Addon;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Update; use Friendica\Core\Update;
@ -28,6 +27,7 @@ class Summary extends BaseAdmin
parent::content(); parent::content();
$basePath = DI::appHelper()->getBasePath(); $basePath = DI::appHelper()->getBasePath();
$addonPath = DI::addonHelper()->getAddonPath();
// are there MyISAM tables in the DB? If so, trigger a warning message // are there MyISAM tables in the DB? If so, trigger a warning message
$warningtext = []; $warningtext = [];
@ -101,8 +101,12 @@ class Summary extends BaseAdmin
// Check server vitality // Check server vitality
if (!self::checkSelfHostMeta()) { if (!self::checkSelfHostMeta()) {
$well_known = DI::baseUrl() . Probe::HOST_META; $well_known = DI::baseUrl() . Probe::HOST_META;
$warningtext[] = DI::l10n()->t('<a href="%s">%s</a> is not reachable on your system. This is a severe configuration issue that prevents server to server communication. See <a href="%s">the installation page</a> for help.', $warningtext[] = DI::l10n()->t(
$well_known, $well_known, DI::baseUrl() . '/help/Install'); '<a href="%s">%s</a> is not reachable on your system. This is a severe configuration issue that prevents server to server communication. See <a href="%s">the installation page</a> for help.',
$well_known,
$well_known,
DI::baseUrl() . '/help/Install'
);
} }
// Check logfile permission // Check logfile permission
@ -114,7 +118,7 @@ class Summary extends BaseAdmin
} }
// check legacy basepath settings // check legacy basepath settings
$configLoader = (new Config())->createConfigFileManager($basePath, $_SERVER); $configLoader = (new Config())->createConfigFileManager($basePath, $addonPath, $_SERVER);
$configCache = new Cache(); $configCache = new Cache();
$configLoader->setupCache($configCache); $configLoader->setupCache($configCache);
$confBasepath = $configCache->get('system', 'basepath'); $confBasepath = $configCache->get('system', 'basepath');
@ -125,25 +129,31 @@ class Summary extends BaseAdmin
'from' => $currBasepath, 'from' => $currBasepath,
'to' => $confBasepath, 'to' => $confBasepath,
]); ]);
$warningtext[] = DI::l10n()->t('Friendica\'s system.basepath was updated from \'%s\' to \'%s\'. Please remove the system.basepath from your db to avoid differences.', $warningtext[] = DI::l10n()->t(
'Friendica\'s system.basepath was updated from \'%s\' to \'%s\'. Please remove the system.basepath from your db to avoid differences.',
$currBasepath, $currBasepath,
$confBasepath); $confBasepath
);
} elseif (!is_dir($currBasepath)) { } elseif (!is_dir($currBasepath)) {
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [ DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
'from' => $currBasepath, 'from' => $currBasepath,
'to' => $confBasepath, 'to' => $confBasepath,
]); ]);
$warningtext[] = DI::l10n()->t('Friendica\'s current system.basepath \'%s\' is wrong and the config file \'%s\' isn\'t used.', $warningtext[] = DI::l10n()->t(
'Friendica\'s current system.basepath \'%s\' is wrong and the config file \'%s\' isn\'t used.',
$currBasepath, $currBasepath,
$confBasepath); $confBasepath
);
} else { } else {
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [ DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
'from' => $currBasepath, 'from' => $currBasepath,
'to' => $confBasepath, 'to' => $confBasepath,
]); ]);
$warningtext[] = DI::l10n()->t('Friendica\'s current system.basepath \'%s\' is not equal to the config file \'%s\'. Please fix your configuration.', $warningtext[] = DI::l10n()->t(
'Friendica\'s current system.basepath \'%s\' is not equal to the config file \'%s\'. Please fix your configuration.',
$currBasepath, $currBasepath,
$confBasepath); $confBasepath
);
} }
} }
@ -177,7 +187,7 @@ class Summary extends BaseAdmin
'$platform' => App::PLATFORM, '$platform' => App::PLATFORM,
'$codename' => App::CODENAME, '$codename' => App::CODENAME,
'$build' => DI::config()->get('system', 'build'), '$build' => DI::config()->get('system', 'build'),
'$addons' => [DI::l10n()->t('Active addons'), Addon::getEnabledList()], '$addons' => [DI::l10n()->t('Active addons'), DI::addonHelper()->getEnabledAddons()],
'$serversettings' => $server_settings, '$serversettings' => $server_settings,
'$warningtext' => $warningtext, '$warningtext' => $warningtext,
]); ]);

View file

@ -8,7 +8,6 @@
namespace Friendica\Module; namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\Addon;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
@ -98,9 +97,19 @@ abstract class BaseAdmin extends BaseModule
]], ]],
]; ];
$addons_admin = [];
foreach (DI::addonHelper()->getEnabledAddonsWithAdminSettings() as $addonId) {
$addons_admin[$addonId] = [
'url' => 'admin/addons/' . $addonId,
'name' => $addonId,
'class' => 'addon',
];
}
$t = Renderer::getMarkupTemplate('admin/aside.tpl'); $t = Renderer::getMarkupTemplate('admin/aside.tpl');
DI::page()['aside'] .= Renderer::replaceMacros($t, [ DI::page()['aside'] .= Renderer::replaceMacros($t, [
'$admin' => ['addons_admin' => Addon::getAdminList()], '$admin' => ['addons_admin' => $addons_admin],
'$subpages' => $aside_sub, '$subpages' => $aside_sub,
'$admtxt' => DI::l10n()->t('Admin'), '$admtxt' => DI::l10n()->t('Admin'),
'$plugadmtxt' => DI::l10n()->t('Addon Features'), '$plugadmtxt' => DI::l10n()->t('Addon Features'),

View file

@ -11,7 +11,7 @@ use Friendica\App;
use Friendica\App\Arguments; use Friendica\App\Arguments;
use Friendica\App\BaseURL; use Friendica\App\BaseURL;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\Addon; use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
@ -31,6 +31,7 @@ use Psr\Log\LoggerInterface;
*/ */
class Friendica extends BaseModule class Friendica extends BaseModule
{ {
private AddonHelper $addonHelper;
/** @var IManageConfigValues */ /** @var IManageConfigValues */
private $config; private $config;
/** @var IManageKeyValuePairs */ /** @var IManageKeyValuePairs */
@ -38,18 +39,19 @@ class Friendica extends BaseModule
/** @var IHandleUserSessions */ /** @var IHandleUserSessions */
private $session; private $session;
public function __construct(IHandleUserSessions $session, IManageKeyValuePairs $keyValue, IManageConfigValues $config, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) public function __construct(AddonHelper $addonHelper, IHandleUserSessions $session, IManageKeyValuePairs $keyValue, IManageConfigValues $config, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{ {
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->config = $config; $this->config = $config;
$this->keyValue = $keyValue; $this->keyValue = $keyValue;
$this->session = $session; $this->session = $session;
$this->addonHelper = $addonHelper;
} }
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
$visibleAddonList = Addon::getVisibleList(); $visibleAddonList = $this->addonHelper->getVisibleEnabledAddons();
if (!empty($visibleAddonList)) { if (!empty($visibleAddonList)) {
$sorted = $visibleAddonList; $sorted = $visibleAddonList;
@ -102,11 +104,13 @@ class Friendica extends BaseModule
$tpl = Renderer::getMarkupTemplate('friendica.tpl'); $tpl = Renderer::getMarkupTemplate('friendica.tpl');
return Renderer::replaceMacros($tpl, [ return Renderer::replaceMacros($tpl, [
'about' => $this->t('This is Friendica, version %s that is running at the web location %s. The database version is %s, the post update version is %s.', 'about' => $this->t(
'This is Friendica, version %s that is running at the web location %s. The database version is %s, the post update version is %s.',
'<strong>' . App::VERSION . '</strong>', '<strong>' . App::VERSION . '</strong>',
$this->baseUrl, $this->baseUrl,
'<strong>' . $this->config->get('system', 'build') . '/' . DB_UPDATE_VERSION . '</strong>', '<strong>' . $this->config->get('system', 'build') . '/' . DB_UPDATE_VERSION . '</strong>',
'<strong>' . $this->keyValue->get('post_update_version') . '/' . PostUpdate::VERSION . '</strong>'), '<strong>' . $this->keyValue->get('post_update_version') . '/' . PostUpdate::VERSION . '</strong>'
),
'friendica' => $this->t('Please visit <a href="https://friendi.ca">Friendi.ca</a> to learn more about the Friendica project.'), 'friendica' => $this->t('Please visit <a href="https://friendi.ca">Friendi.ca</a> to learn more about the Friendica project.'),
'bugs' => $this->t('Bug reports and issues: please visit') . ' ' . '<a href="https://github.com/friendica/friendica/issues?state=open">' . $this->t('the bugtracker at github') . '</a>', 'bugs' => $this->t('Bug reports and issues: please visit') . ' ' . '<a href="https://github.com/friendica/friendica/issues?state=open">' . $this->t('the bugtracker at github') . '</a>',
'info' => $this->t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'), 'info' => $this->t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'),
@ -157,7 +161,7 @@ class Friendica extends BaseModule
]; ];
} }
$visible_addons = Addon::getVisibleList(); $visible_addons = $this->addonHelper->getVisibleEnabledAddons();
$this->config->reload(); $this->config->reload();
$locked_features = []; $locked_features = [];

View file

@ -8,7 +8,6 @@
namespace Friendica\Protocol; namespace Friendica\Protocol;
use Friendica\App; use Friendica\App;
use Friendica\Core\Addon;
use Friendica\DI; use Friendica\DI;
use Friendica\Module; use Friendica\Module;
use Friendica\Module\Register; use Friendica\Module\Register;
@ -43,6 +42,11 @@ class ZOT
*/ */
public static function getSiteInfo(): array public static function getSiteInfo(): array
{ {
$baseUrl = (string) DI::baseUrl();
$keyValue = DI::keyValue();
$addonHelper = DI::addonHelper();
$config = DI::config();
$policies = [ $policies = [
Module\Register::OPEN => 'open', Module\Register::OPEN => 'open',
Module\Register::APPROVE => 'approve', Module\Register::APPROVE => 'approve',
@ -50,14 +54,14 @@ class ZOT
]; ];
return [ return [
'url' => (string)DI::baseUrl(), 'url' => $baseUrl,
'openWebAuth' => (string)DI::baseUrl() . '/owa', 'openWebAuth' => $baseUrl . '/owa',
'authRedirect' => (string)DI::baseUrl() . '/magic', 'authRedirect' => $baseUrl . '/magic',
'register_policy' => $policies[Register::getPolicy()], 'register_policy' => $policies[Register::getPolicy()],
'accounts' => DI::keyValue()->get('nodeinfo_total_users'), 'accounts' => $keyValue->get('nodeinfo_total_users'),
'plugins' => Addon::getVisibleList(), 'plugins' => $addonHelper->getVisibleEnabledAddons(),
'sitename' => DI::config()->get('config', 'sitename'), 'sitename' => $config->get('config', 'sitename'),
'about' => DI::config()->get('config', 'info'), 'about' => $config->get('config', 'info'),
'project' => App::PLATFORM, 'project' => App::PLATFORM,
'version' => App::VERSION, 'version' => App::VERSION,
]; ];

View file

@ -7,7 +7,6 @@
namespace Friendica\Worker; namespace Friendica\Worker;
use Friendica\Core\Addon;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBA; use Friendica\Database\DBA;
@ -145,7 +144,7 @@ class Cron
// Update "blocked" status of servers // Update "blocked" status of servers
Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers'); Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers');
Addon::reload(); DI::addonHelper()->reloadAddons();
DI::keyValue()->set('last_cron_daily', time()); DI::keyValue()->set('last_cron_daily', time());
} }

View file

@ -42,6 +42,12 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
[Dice::INSTANCE => Dice::SELF], [Dice::INSTANCE => Dice::SELF],
], ],
], ],
\Friendica\Core\Addon\AddonHelper::class => [
'instanceOf' => \Friendica\Core\Addon\AddonProxy::class,
'constructParams' => [
$basepath . '/addon',
],
],
\Friendica\Util\BasePath::class => [ \Friendica\Util\BasePath::class => [
'constructParams' => [ 'constructParams' => [
$basepath, $basepath,
@ -81,6 +87,7 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
'call' => [ 'call' => [
['createConfigFileManager', [ ['createConfigFileManager', [
$basepath, $basepath,
$basepath . '/addon',
$serverVars, $serverVars,
], Dice::CHAIN_CALL], ], Dice::CHAIN_CALL],
], ],

View file

@ -8,7 +8,7 @@
namespace Friendica\Test; namespace Friendica\Test;
use Friendica\Capabilities\ICanCreateResponses; use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon; use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\DI; use Friendica\DI;
@ -201,7 +201,7 @@ abstract class ApiTestCase extends FixtureTestCase
'plugin_admin' => function_exists($addon . '_addon_admin'), 'plugin_admin' => function_exists($addon . '_addon_admin'),
]); ]);
Addon::loadAddons(); $this->dice->create(AddonHelper::class)->loadAddons();
Hook::loadHooks(); Hook::loadHooks();
} }
} }

View file

@ -44,7 +44,7 @@ trait FixtureTestTrait
->addRules(include __DIR__ . '/../static/dependencies.config.php') ->addRules(include __DIR__ . '/../static/dependencies.config.php')
->addRule(ConfigFileManager::class, [ ->addRule(ConfigFileManager::class, [
'instanceOf' => Config::class, 'instanceOf' => Config::class,
'call' => [['createConfigFileManager', [$this->root->url(), $server,], Dice::CHAIN_CALL]]]) 'call' => [['createConfigFileManager', [$this->root->url(), $this->root->url() . '/addon', $server,], Dice::CHAIN_CALL]]])
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true]) ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null]) ->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null])
->addRule(Arguments::class, [ ->addRule(Arguments::class, [

View file

@ -0,0 +1,55 @@
<?php
// Copyright (C) 2010-2024, the Friendica project
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
//
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
namespace Friendica\Test\Unit\Core\Addon;
use Friendica\Core\Addon\AddonInfo;
use PHPUnit\Framework\TestCase;
class AddonInfoTest extends TestCase
{
public function testFromArrayCreatesObject(): void
{
$data = [
'id' => '',
'name' => '',
'description' => '',
'authors' => [],
'maintainers' => [],
'version' => '',
'status' => '',
];
$this->assertInstanceOf(AddonInfo::class, AddonInfo::fromArray($data));
}
public function testGetterReturningCorrectValues(): void
{
$data = [
'id' => 'test',
'name' => 'Test-Addon',
'description' => 'This is an addon for tests',
'authors' => [['name' => 'Sam']],
'maintainers' => [['name' => 'Sam', 'link' => 'https://example.com']],
'version' => '0.1',
'status' => 'In Development',
];
$info = AddonInfo::fromArray($data);
$this->assertSame($data['id'], $info->getId());
$this->assertSame($data['name'], $info->getName());
$this->assertSame($data['description'], $info->getDescription());
$this->assertSame($data['description'], $info->getDescription());
$this->assertSame($data['authors'], $info->getAuthors());
$this->assertSame($data['maintainers'], $info->getMaintainers());
$this->assertSame($data['version'], $info->getVersion());
$this->assertSame($data['status'], $info->getStatus());
}
}

View file

@ -15,8 +15,6 @@ use Friendica\Database\Definition\DbaDefinition;
use Friendica\Database\Definition\ViewDefinition; use Friendica\Database\Definition\ViewDefinition;
use Friendica\Test\DatabaseTestTrait; use Friendica\Test\DatabaseTestTrait;
use Friendica\Test\Util\Database\StaticDatabase; use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Util\Profiler;
use Psr\Log\NullLogger;
trait CreateDatabaseTrait trait CreateDatabaseTrait
{ {
@ -32,7 +30,12 @@ trait CreateDatabaseTrait
return $this->dba; return $this->dba;
} }
$configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/'); $configFileManager = new ConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
$this->root->url() . '/config',
$this->root->url() . '/static'
);
$config = new ReadOnlyFileConfig(new Cache([ $config = new ReadOnlyFileConfig(new Cache([
'database' => [ 'database' => [
'disable_pdo' => true 'disable_pdo' => true

View file

@ -34,6 +34,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -61,6 +62,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -90,6 +92,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -127,6 +130,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -163,6 +167,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -217,6 +222,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -254,6 +260,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -288,6 +295,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -322,6 +330,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager( $configFileLoader = new ConfigFileManager(
$this->root->url(), $this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR, $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
); );
@ -341,7 +350,11 @@ class ConfigFileManagerTest extends MockedTestCase
{ {
$this->delConfigFile('local.config.php'); $this->delConfigFile('local.config.php');
$configFileManager = (new Config())->createConfigFileManager($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']); $configFileManager = (new Config())->createConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/'],
);
$configCache = new Cache(); $configCache = new Cache();
$configFileManager->setupCache($configCache); $configFileManager->setupCache($configCache);
@ -367,10 +380,11 @@ class ConfigFileManagerTest extends MockedTestCase
->at($this->root->getChild('config2')) ->at($this->root->getChild('config2'))
->setContent(file_get_contents($fileDir . 'B.config.php')); ->setContent(file_get_contents($fileDir . 'B.config.php'));
$configFileManager = (new Config())->createConfigFileManager($this->root->url(), $configFileManager = (new Config())->createConfigFileManager(
[ $this->root->url(),
'FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url(), $this->root->url() . '/addon',
]); ['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()],
);
$configCache = new Cache(); $configCache = new Cache();
$configFileManager->setupCache($configCache); $configFileManager->setupCache($configCache);
@ -389,11 +403,12 @@ class ConfigFileManagerTest extends MockedTestCase
->at($this->root->getChild('config')) ->at($this->root->getChild('config'))
->setContent(''); ->setContent('');
$configFileManager = (new Config())->createConfigFileManager($this->root->url()); $configFileManager = (new Config())->createConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
);
$configCache = new Cache(); $configCache = new Cache();
$configFileManager->setupCache($configCache); $configFileManager->setupCache($configCache);
self::assertEquals(1,1);
} }
} }

View file

@ -16,7 +16,6 @@ use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Test\DatabaseTestCase; use Friendica\Test\DatabaseTestCase;
use Friendica\Test\Util\CreateDatabaseTrait; use Friendica\Test\Util\CreateDatabaseTrait;
use Friendica\Test\Util\VFSTrait; use Friendica\Test\Util\VFSTrait;
use org\bovigo\vfs\vfsStream;
class ConfigTest extends DatabaseTestCase class ConfigTest extends DatabaseTestCase
{ {
@ -56,7 +55,12 @@ class ConfigTest extends DatabaseTestCase
parent::setUp(); parent::setUp();
$this->configCache = new Cache(); $this->configCache = new Cache();
$this->configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/'); $this->configFileManager = new ConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
$this->root->url() . '/config',
$this->root->url() . '/static'
);
} }
/** /**
@ -173,7 +177,7 @@ class ConfigTest extends DatabaseTestCase
*/ */
public function testSetUp(array $data) public function testSetUp(array $data)
{ {
$this->loadDirectFixture($this->configToDbArray($data) , $this->getDbInstance()); $this->loadDirectFixture($this->configToDbArray($data), $this->getDbInstance());
$this->testedConfig = $this->getInstance(); $this->testedConfig = $this->getInstance();
self::assertInstanceOf(Cache::class, $this->testedConfig->getCache()); self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
@ -608,7 +612,13 @@ class ConfigTest extends DatabaseTestCase
$this->setConfigFile('static' . DIRECTORY_SEPARATOR . 'env.config.php', true); $this->setConfigFile('static' . DIRECTORY_SEPARATOR . 'env.config.php', true);
$this->loadDirectFixture($this->configToDbArray($data), $this->getDbInstance()); $this->loadDirectFixture($this->configToDbArray($data), $this->getDbInstance());
$configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/', $server); $configFileManager = new ConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
$this->root->url() . '/config',
$this->root->url() . '/static',
$server
);
$configFileManager->setupCache($this->configCache); $configFileManager->setupCache($this->configCache);
$config = new DatabaseConfig($this->getDbInstance(), $this->configCache); $config = new DatabaseConfig($this->getDbInstance(), $this->configCache);

View file

@ -9,16 +9,11 @@ namespace Friendica\Test\src\Core\Config;
use Friendica\Core\Config\Capability\ISetConfigValuesTransactionally; use Friendica\Core\Config\Capability\ISetConfigValuesTransactionally;
use Friendica\Core\Config\Model\DatabaseConfig; use Friendica\Core\Config\Model\DatabaseConfig;
use Friendica\Core\Config\Model\ReadOnlyFileConfig;
use Friendica\Core\Config\Model\ConfigTransaction; use Friendica\Core\Config\Model\ConfigTransaction;
use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Test\DatabaseTestCase;
use Friendica\Test\FixtureTestCase; use Friendica\Test\FixtureTestCase;
use Friendica\Test\MockedTest;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Test\Util\VFSTrait;
use Mockery\Exception\InvalidCountException; use Mockery\Exception\InvalidCountException;
class ConfigTransactionTest extends FixtureTestCase class ConfigTransactionTest extends FixtureTestCase
@ -30,7 +25,12 @@ class ConfigTransactionTest extends FixtureTestCase
{ {
parent::setUp(); parent::setUp();
$this->configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/'); $this->configFileManager = new ConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
$this->root->url() . '/config',
$this->root->url() . '/static'
);
} }
public function dataTests(): array public function dataTests(): array

View file

@ -21,16 +21,12 @@ use Friendica\Core\Storage\Repository\StorageManager;
use Friendica\Core\Storage\Type\Filesystem; use Friendica\Core\Storage\Type\Filesystem;
use Friendica\Core\Storage\Type\SystemResource; use Friendica\Core\Storage\Type\SystemResource;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Database\Definition\DbaDefinition;
use Friendica\Database\Definition\ViewDefinition;
use Friendica\DI; use Friendica\DI;
use Friendica\Core\Config\Factory\Config; use Friendica\Core\Config\Factory\Config;
use Friendica\Core\Storage\Type; use Friendica\Core\Storage\Type;
use Friendica\Test\DatabaseTestCase; use Friendica\Test\DatabaseTestCase;
use Friendica\Test\Util\CreateDatabaseTrait; use Friendica\Test\Util\CreateDatabaseTrait;
use Friendica\Test\Util\Database\StaticDatabase; use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Test\Util\VFSTrait;
use Friendica\Util\Profiler;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger; use Psr\Log\NullLogger;
@ -64,7 +60,10 @@ class StorageManagerTest extends DatabaseTestCase
$this->database = $this->getDbInstance(); $this->database = $this->getDbInstance();
$configFactory = new Config(); $configFactory = new Config();
$configFileManager = $configFactory->createConfigFileManager($this->root->url()); $configFileManager = $configFactory->createConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
);
$configCache = $configFactory->createCache($configFileManager); $configCache = $configFactory->createCache($configFileManager);
$this->config = new \Friendica\Core\Config\Model\DatabaseConfig($this->database, $configCache); $this->config = new \Friendica\Core\Config\Model\DatabaseConfig($this->database, $configCache);

View file

@ -32,7 +32,12 @@ class DatabaseTest extends FixtureTestCase
parent::setUp(); parent::setUp();
$this->configCache = new Cache(); $this->configCache = new Cache();
$this->configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/'); $this->configFileManager = new ConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
$this->root->url() . '/config',
$this->root->url() . '/static'
);
} }
/** /**