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

View file

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

View file

@ -7,13 +7,11 @@
namespace Friendica\App;
use Dice\Dice;
use FastRoute\DataGenerator\GroupCountBased;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use FastRoute\RouteParser\Std;
use Friendica\Capabilities\ICanHandleRequests;
use Friendica\Core\Addon;
use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Cache\Capability\ICanCache;
use Friendica\Core\Config\Capability\IManageConfigValues;
@ -86,6 +84,8 @@ class Router
/** @var LoggerInterface */
private $logger;
private AddonHelper $addonHelper;
/** @var bool */
private $isLocalUser;
@ -110,17 +110,18 @@ class Router
* @param IHandleUserSessions $userSession
* @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->l10n = $l10n;
$this->cache = $cache;
$this->lock = $lock;
$this->args = $args;
$this->config = $config;
$this->server = $server;
$this->logger = $logger;
$this->isLocalUser = !empty($userSession->getLocalUserId());
$this->baseRoutesFilepath = $baseRoutesFilepath;
$this->l10n = $l10n;
$this->cache = $cache;
$this->lock = $lock;
$this->args = $args;
$this->config = $config;
$this->server = $server;
$this->logger = $logger;
$this->addonHelper = $addonHelper;
$this->isLocalUser = !empty($userSession->getLocalUserId());
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
@ -275,14 +276,14 @@ class Router
try {
// Check if the HTTP method is OPTIONS and return the special Options Module with the possible HTTP methods
if ($this->args->getMethod() === static::OPTIONS) {
$this->moduleClass = Options::class;
$this->moduleClass = Options::class;
$this->parameters[] = ['AllowedMethods' => $dispatcher->getOptions($cmd)];
} else {
$routeInfo = $dispatcher->dispatch($this->args->getMethod(), $cmd);
if ($routeInfo[0] === Dispatcher::FOUND) {
$this->moduleClass = $routeInfo[1];
$this->moduleClass = $routeInfo[1];
$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])));
} else {
throw new HTTPException\NotFoundException($this->l10n->t('Page not found.'));
@ -293,7 +294,7 @@ class Router
} catch (NotFoundException $e) {
$moduleName = $this->args->getModuleName();
// 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
$privateapps = $this->config->get('config', 'private_addons', false);
if (!$this->isLocalUser && Hook::isAddonApp($moduleName) && $privateapps) {

View file

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

View file

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

View file

@ -207,7 +207,7 @@ class Conversation
if ($total === 0) {
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];
} else {
if ($total < $this->config->get('system', 'max_likers')) {
@ -976,8 +976,8 @@ class Conversation
}
foreach ($items as $key => $row) {
$items[$key]['emojis'] = $emojis[$key] ?? [];
$items[$key]['counts'] = $counts[$key] ?? 0;
$items[$key]['emojis'] = $emojis[$key] ?? [];
$items[$key]['counts'] = $counts[$key] ?? 0;
$items[$key]['quoteshares'] = $quoteshares[$key] ?? [];
$always_display = in_array($mode, [self::MODE_CONTACTS, self::MODE_CONTACT_POSTS]);
@ -1431,7 +1431,7 @@ class Conversation
public function getContextLessThreadList(array $items, string $mode, bool $preview, bool $pagedrop, string $formSecurityToken): array
{
$threads = [];
$uriids = [];
$uriids = [];
foreach ($items as $item) {
if (in_array($item['uri-id'], $uriids)) {
@ -1456,7 +1456,7 @@ class Conversation
$tags = Tag::populateFromItem($item);
$author = [
$author = [
'uid' => 0,
'id' => $item['author-id'],
'network' => $item['author-network'],
@ -1501,7 +1501,7 @@ class Conversation
$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'])) {
$pinned = $this->l10n->t('Pinned item');

View file

@ -7,7 +7,6 @@
namespace Friendica\Content;
use Friendica\Core\Addon;
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
@ -33,13 +32,13 @@ class Widget
*/
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'),
'$desc' => DI::l10n()->t('Enter address or web location'),
'$hint' => DI::l10n()->t('Example: bob@example.com, http://example.com/barbara'),
'$value' => $value,
'$follow' => DI::l10n()->t('Connect')
));
'$desc' => DI::l10n()->t('Enter address or web location'),
'$hint' => DI::l10n()->t('Example: bob@example.com, http://example.com/barbara'),
'$value' => $value,
'$follow' => DI::l10n()->t('Connect')
]);
}
/**
@ -60,21 +59,21 @@ class Widget
}
}
$nv = [];
$nv['findpeople'] = DI::l10n()->t('Find People');
$nv['desc'] = DI::l10n()->t('Enter name or interest');
$nv['label'] = DI::l10n()->t('Connect/Follow');
$nv['hint'] = DI::l10n()->t('Examples: Robert Morgenstein, Fishing');
$nv['findthem'] = DI::l10n()->t('Find');
$nv['suggest'] = DI::l10n()->t('Friend Suggestions');
$nv['similar'] = DI::l10n()->t('Similar Interests');
$nv['random'] = DI::l10n()->t('Random Profile');
$nv['inv'] = DI::l10n()->t('Invite Friends');
$nv['directory'] = DI::l10n()->t('Global Directory');
$nv['global_dir'] = OpenWebAuth::getZrlUrl($global_dir, true);
$nv = [];
$nv['findpeople'] = DI::l10n()->t('Find People');
$nv['desc'] = DI::l10n()->t('Enter name or interest');
$nv['label'] = DI::l10n()->t('Connect/Follow');
$nv['hint'] = DI::l10n()->t('Examples: Robert Morgenstein, Fishing');
$nv['findthem'] = DI::l10n()->t('Find');
$nv['suggest'] = DI::l10n()->t('Friend Suggestions');
$nv['similar'] = DI::l10n()->t('Similar Interests');
$nv['random'] = DI::l10n()->t('Random Profile');
$nv['inv'] = DI::l10n()->t('Invite Friends');
$nv['directory'] = DI::l10n()->t('Global Directory');
$nv['global_dir'] = OpenWebAuth::getZrlUrl($global_dir, true);
$nv['local_directory'] = DI::l10n()->t('Local Directory');
$aside = [];
$aside = [];
$aside['$nv'] = $nv;
return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/peoplefind.tpl'), $aside);
@ -87,19 +86,21 @@ class Widget
*/
public static function unavailableNetworks(): array
{
$addonHelper = DI::addonHelper();
// Always hide content from these networks
$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;
}
if (!Addon::isEnabled('pumpio')) {
if (!$addonHelper->isAddonEnabled('pumpio')) {
$networks[] = Protocol::PUMPIO;
}
if (!Addon::isEnabled('tumblr')) {
if (!$addonHelper->isAddonEnabled('tumblr')) {
$networks[] = Protocol::TUMBLR;
}
@ -107,7 +108,7 @@ class Widget
$networks[] = Protocol::DIASPORA;
}
if (!Addon::isEnabled('pnut')) {
if (!$addonHelper->isAddonEnabled('pnut')) {
$networks[] = Protocol::PNUT;
}
return $networks;
@ -120,18 +121,20 @@ class Widget
*/
public static function availableNetworks(): array
{
$networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED];
Addon::loadAddons();
$addonHelper = DI::addonHelper();
if (Addon::isEnabled('discourse')) {
$networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED];
$addonHelper->loadAddons();
if ($addonHelper->isAddonEnabled('discourse')) {
$networks[] = Protocol::DISCOURSE;
}
if (Addon::isEnabled('pumpio')) {
if ($addonHelper->isAddonEnabled('pumpio')) {
$networks[] = Protocol::PUMPIO;
}
if (Addon::isEnabled('tumblr')) {
if ($addonHelper->isAddonEnabled('tumblr')) {
$networks[] = Protocol::TUMBLR;
}
@ -143,7 +146,7 @@ class Widget
$networks[] = Protocol::MAIL;
}
if (Addon::isEnabled('pnut')) {
if ($addonHelper->isAddonEnabled('pnut')) {
$networks[] = Protocol::PNUT;
}
return $networks;
@ -174,7 +177,7 @@ class Widget
private static function filter(string $type, string $title, string $desc, string $all, string $baseUrl, array $options, string $selected = null): string
{
$queryString = parse_url($baseUrl, PHP_URL_QUERY);
$queryArray = [];
$queryArray = [];
if ($queryString) {
parse_str($queryString, $queryArray);
@ -282,8 +285,8 @@ class Widget
return '';
}
$networks = self::unavailableNetworks();
$query = "`uid` = ? AND NOT `deleted` AND `network` != '' AND NOT `network` IN (" . substr(str_repeat("?, ", count($networks)), 0, -2) . ")";
$networks = self::unavailableNetworks();
$query = "`uid` = ? AND NOT `deleted` AND `network` != '' AND NOT `network` IN (" . substr(str_repeat("?, ", count($networks)), 0, -2) . ")";
$condition = array_merge([$query], array_merge([DI::userSession()->getLocalUserId()], $networks));
$r = DBA::select('contact', ['network'], $condition, ['group_by' => ['network'], 'order' => ['network']]);
@ -473,7 +476,7 @@ class Widget
$ret = [];
$cachekey = 'Widget::postedByYear' . $uid . '-' . (int)$wall;
$dthen = DI::cache()->get($cachekey);
$dthen = DI::cache()->get($cachekey);
if (empty($dthen)) {
$dthen = Item::firstPostDate($uid, $wall);
DI::cache()->set($cachekey, $dthen, Duration::HOUR);
@ -486,30 +489,30 @@ class Widget
if ($dthen) {
// Set the start and end date to the beginning of the month
$cutoffday = $dthen;
$thisday = substr($dnow, 4);
$nextday = date('Y-m-d', strtotime($dnow . ' + 1 day'));
$nextday = substr($nextday, 4);
$dnow = substr($dnow, 0, 8) . '01';
$dthen = substr($dthen, 0, 8) . '01';
$thisday = substr($dnow, 4);
$nextday = date('Y-m-d', strtotime($dnow . ' + 1 day'));
$nextday = substr($nextday, 4);
$dnow = substr($dnow, 0, 8) . '01';
$dthen = substr($dthen, 0, 8) . '01';
/*
* Starting with the current month, get the first and last days of every
* month down to and including the month of the first post
*/
while (substr($dnow, 0, 7) >= substr($dthen, 0, 7)) {
$dyear = intval(substr($dnow, 0, 4));
$dstart = substr($dnow, 0, 8) . '01';
$dend = substr($dnow, 0, 8) . Temporal::getDaysInMonth(intval($dnow), intval(substr($dnow, 5)));
$dyear = intval(substr($dnow, 0, 4));
$dstart = substr($dnow, 0, 8) . '01';
$dend = substr($dnow, 0, 8) . Temporal::getDaysInMonth(intval($dnow), intval(substr($dnow, 5)));
$start_month = DateTimeFormat::utc($dstart, 'Y-m-d');
$end_month = DateTimeFormat::utc($dend, 'Y-m-d');
$str = DI::l10n()->getDay(DateTimeFormat::utc($dnow, 'F'));
$end_month = DateTimeFormat::utc($dend, 'Y-m-d');
$str = DI::l10n()->getDay(DateTimeFormat::utc($dnow, 'F'));
if (empty($ret[$dyear])) {
$ret[$dyear] = [];
}
$ret[$dyear][] = [$str, $end_month, $start_month];
$dnow = DateTimeFormat::utc($dnow . ' -1 month', 'Y-m-d');
$dnow = DateTimeFormat::utc($dnow . ' -1 month', 'Y-m-d');
}
}
@ -518,21 +521,21 @@ class Widget
}
$cutoff_year = intval(DateTimeFormat::localNow('Y')) - $visible_years;
$cutoff = array_key_exists($cutoff_year, $ret);
$cutoff = array_key_exists($cutoff_year, $ret);
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/posted_date.tpl'), [
'$title' => DI::l10n()->t('Archives'),
'$size' => $visible_years,
'$title' => DI::l10n()->t('Archives'),
'$size' => $visible_years,
'$cutoff_year' => $cutoff_year,
'$cutoff' => $cutoff,
'$url' => $url,
'$dates' => $ret,
'$showless' => DI::l10n()->t('show less'),
'$showmore' => DI::l10n()->t('show more'),
'$onthisdate' => DI::l10n()->t('On this date'),
'$thisday' => $thisday,
'$nextday' => $nextday,
'$cutoffday' => $cutoffday
'$cutoff' => $cutoff,
'$url' => $url,
'$dates' => $ret,
'$showless' => DI::l10n()->t('show less'),
'$showmore' => DI::l10n()->t('show more'),
'$onthisdate' => DI::l10n()->t('On this date'),
'$thisday' => $thisday,
'$nextday' => $nextday,
'$cutoffday' => $cutoffday
]);
return $o;

View file

@ -18,6 +18,9 @@ class Addon
{
/**
* The addon sub-directory
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAddonPath()` instead
*
* @var string
*/
const DIRECTORY = 'addon';
@ -34,6 +37,8 @@ class Addon
* 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.
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAvailableAddons()` instead
*
* @return array
* @throws \Exception
*/
@ -64,6 +69,8 @@ class Addon
* Returns a list of addons that can be configured at the node level.
* The list is formatted for display in the admin panel aside.
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getEnabledAddonsWithAdminSettings()` instead
*
* @return array
* @throws \Exception
*/
@ -88,7 +95,6 @@ class Addon
return $addons_admin;
}
/**
* Synchronize addons:
*
@ -100,6 +106,7 @@ class Addon
* 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.
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::loadAddons()` instead
*/
public static function loadAddons()
{
@ -109,6 +116,8 @@ class Addon
/**
* uninstalls an addon.
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::uninstallAddon()` instead
*
* @param string $addon name of the addon
* @return void
* @throws \Exception
@ -135,6 +144,8 @@ class Addon
/**
* installs an addon.
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::installAddon()` instead
*
* @param string $addon name of the addon
* @return bool
* @throws \Exception
@ -173,6 +184,8 @@ class Addon
/**
* reload all updated addons
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::reloadAddons()` instead
*
* @return void
* @throws \Exception
*
@ -209,6 +222,9 @@ class Addon
* * Maintainer: Jess <email>
* *
* *\endcode
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAddonInfo()` instead
*
* @param string $addon the name of the addon
* @return array with the addon information
* @throws \Exception
@ -275,6 +291,8 @@ class Addon
/**
* Checks if the provided addon is enabled
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::isAddonEnabled()` instead
*
* @param string $addon
* @return boolean
*/
@ -286,6 +304,8 @@ class Addon
/**
* Returns a list of the enabled addon names
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getEnabledAddons()` instead
*
* @return array
*/
public static function getEnabledList(): array
@ -296,6 +316,8 @@ class Addon
/**
* Returns the list of non-hidden enabled addon names
*
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getVisibleEnabledAddons()` instead
*
* @return array
* @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
*/
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])) {
$configDir = $server[self::CONFIG_DIR_ENV];
@ -51,7 +51,7 @@ class Config
}
$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;
use Friendica\Core\Addon;
use Friendica\Core\Config\Exception\ConfigFileException;
use Friendica\Core\Config\ValueObject\Cache;
@ -46,6 +45,7 @@ class ConfigFileManager
* @var string
*/
private $baseDir;
private string $addonDir;
/**
* @var string
*/
@ -65,9 +65,10 @@ class ConfigFileManager
* @param string $configDir
* @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->addonDir = $addonDir;
$this->configDir = $configDir;
$this->staticDir = $staticDir;
$this->server = $server;
@ -122,7 +123,7 @@ class ConfigFileManager
if (file_exists($configName)) {
return $this->loadConfigFile($configName);
} else if (file_exists($iniName)) {
} elseif (file_exists($iniName)) {
return $this->loadINIConfigFile($iniName);
} else {
return [];
@ -160,17 +161,16 @@ class ConfigFileManager
*/
public function loadAddonConfig(string $name): array
{
$filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
$name . DIRECTORY_SEPARATOR . // openstreetmap/
'config' . DIRECTORY_SEPARATOR . // config/
$name . ".config.php"; // openstreetmap.config.php
$filepath = $this->addonDir . DIRECTORY_SEPARATOR . // /var/www/html/addon/
$name . DIRECTORY_SEPARATOR . // openstreetmap/
'config' . DIRECTORY_SEPARATOR . // config/
$name . ".config.php"; // openstreetmap.config.php
if (file_exists($filepath)) {
return $this->loadConfigFile($filepath);
} else {
if (!file_exists($filepath)) {
return [];
}
return $this->loadConfigFile($filepath);
}
/**

View file

@ -8,7 +8,6 @@
namespace Friendica\Core\Storage\Repository;
use Exception;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
@ -20,6 +19,7 @@ use Friendica\Core\Storage\Capability\ICanConfigureStorage;
use Friendica\Core\Storage\Capability\ICanWriteToStorage;
use Friendica\Database\Database;
use Friendica\Core\Storage\Type;
use Friendica\DI;
use Friendica\Network\HTTPException\InternalServerErrorException;
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
/// clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore
if ($includeAddon) {
Addon::loadAddons();
DI::addonHelper()->loadAddons();
Hook::loadHooks();
}
@ -138,7 +138,7 @@ class StorageManager
// Try the filesystem backend
case Type\Filesystem::getName():
return new Type\FilesystemConfig($this->config, $this->l10n);
// try the database backend
// try the database backend
case Type\Database::getName():
return false;
default:
@ -185,11 +185,11 @@ class StorageManager
$storageConfig = new Type\FilesystemConfig($this->config, $this->l10n);
$this->backendInstances[$name] = new Type\Filesystem($storageConfig->getStoragePath());
break;
// try the database backend
// try the database backend
case Type\Database::getName():
$this->backendInstances[$name] = new Type\Database($this->dba);
break;
// at least, try if there's an addon for the backend
// at least, try if there's an addon for the backend
case Type\SystemResource::getName():
$this->backendInstances[$name] = new Type\SystemResource();
break;
@ -228,11 +228,13 @@ class StorageManager
*/
public function isValidBackend(string $name = null, array $validBackends = null): bool
{
$validBackends = $validBackends ?? array_merge($this->validBackends,
[
Type\SystemResource::getName(),
Type\ExternalResource::getName(),
]);
$validBackends = $validBackends ?? array_merge(
$this->validBackends,
[
Type\SystemResource::getName(),
Type\ExternalResource::getName(),
]
);
return in_array($name, $validBackends);
}

View file

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

View file

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

View file

@ -7,7 +7,6 @@
namespace Friendica\Module\Admin\Addons;
use Friendica\Core\Addon;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Module\BaseAdmin;
@ -24,22 +23,25 @@ class Index extends BaseAdmin
{
parent::content();
$addonHelper = DI::addonHelper();
// reload active themes
if (!empty($_GET['action'])) {
self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons', 't');
switch ($_GET['action']) {
case 'reload':
Addon::reload();
$addonHelper->reloadAddons();
DI::sysmsg()->addInfo(DI::l10n()->t('Addons reloaded'));
break;
case 'toggle' :
case 'toggle':
$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));
} elseif (Addon::install($addon)) {
} elseif ($addonHelper->installAddon($addon)) {
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon));
} else {
DI::sysmsg()->addNotice(DI::l10n()->t('Addon %s failed to install.', $addon));
@ -52,18 +54,34 @@ class Index extends BaseAdmin
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');
return Renderer::replaceMacros($t, [
'$title' => DI::l10n()->t('Administration'),
'$page' => DI::l10n()->t('Addons'),
'$submit' => DI::l10n()->t('Save Settings'),
'$reload' => DI::l10n()->t('Reload active addons'),
'$function' => 'addons',
'$addons' => $addons,
'$pcount' => count($addons),
'$noplugshint' => DI::l10n()->t('There are currently no addons available on your node. You can find the official addon repository at %1$s.', 'https://git.friendi.ca/friendica/friendica-addons'),
'$title' => DI::l10n()->t('Administration'),
'$page' => DI::l10n()->t('Addons'),
'$submit' => DI::l10n()->t('Save Settings'),
'$reload' => DI::l10n()->t('Reload active addons'),
'$function' => 'addons',
'$addons' => $addons,
'$pcount' => count($addons),
'$noplugshint' => DI::l10n()->t('There are currently no addons available on your node. You can find the official addon repository at %1$s.', 'https://git.friendi.ca/friendica/friendica-addons'),
'$form_security_token' => self::getFormSecurityToken('admin_addons'),
]);
}

View file

@ -8,7 +8,6 @@
namespace Friendica\Module\Admin;
use Friendica\App;
use Friendica\Core\Addon;
use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Renderer;
use Friendica\Core\Update;
@ -27,13 +26,14 @@ class Summary extends BaseAdmin
{
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
$warningtext = [];
$templateEngine = Renderer::getTemplateEngine();
$errors = [];
$errors = [];
$templateEngine->testInstall($errors);
foreach ($errors as $error) {
$warningtext[] = DI::l10n()->t('Template engine (%s) error: %s', $templateEngine::$name, $error);
@ -51,7 +51,7 @@ class Summary extends BaseAdmin
// Avoid the database error 1615 "Prepared statement needs to be re-prepared", see https://github.com/friendica/friendica/issues/8550
if (!DI::config()->get('database', 'pdo_emulate_prepares')) {
$table_definition_cache = DBA::getVariable('table_definition_cache');
$table_open_cache = DBA::getVariable('table_open_cache');
$table_open_cache = DBA::getVariable('table_open_cache');
if (!empty($table_definition_cache) && !empty($table_open_cache)) {
$suggested_definition_cache = min(400 + round((int) $table_open_cache / 2, 1), 2000);
if ($suggested_definition_cache > $table_definition_cache) {
@ -100,9 +100,13 @@ class Summary extends BaseAdmin
// Check server vitality
if (!self::checkSelfHostMeta()) {
$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.',
$well_known, $well_known, DI::baseUrl() . '/help/Install');
$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.',
$well_known,
$well_known,
DI::baseUrl() . '/help/Install'
);
}
// Check logfile permission
@ -114,8 +118,8 @@ class Summary extends BaseAdmin
}
// check legacy basepath settings
$configLoader = (new Config())->createConfigFileManager($basePath, $_SERVER);
$configCache = new Cache();
$configLoader = (new Config())->createConfigFileManager($basePath, $addonPath, $_SERVER);
$configCache = new Cache();
$configLoader->setupCache($configCache);
$confBasepath = $configCache->get('system', 'basepath');
$currBasepath = DI::config()->get('system', 'basepath');
@ -125,25 +129,31 @@ class Summary extends BaseAdmin
'from' => $currBasepath,
'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,
$confBasepath);
$confBasepath
);
} elseif (!is_dir($currBasepath)) {
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
'from' => $currBasepath,
'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,
$confBasepath);
$confBasepath
);
} else {
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
'from' => $currBasepath,
'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,
$confBasepath);
$confBasepath
);
}
}
@ -177,7 +187,7 @@ class Summary extends BaseAdmin
'$platform' => App::PLATFORM,
'$codename' => App::CODENAME,
'$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,
'$warningtext' => $warningtext,
]);

View file

@ -8,7 +8,6 @@
namespace Friendica\Module;
use Friendica\BaseModule;
use Friendica\Core\Addon;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Network\HTTPException;
@ -69,43 +68,53 @@ abstract class BaseAdmin extends BaseModule
// not part of $aside to make the template more adjustable
$aside_sub = [
'information' => [DI::l10n()->t('Information'), [
'overview' => ['admin' , DI::l10n()->t('Overview') , 'overview'],
'federation' => ['admin/federation' , DI::l10n()->t('Federation Statistics') , 'federation']
'overview' => ['admin' , DI::l10n()->t('Overview') , 'overview'],
'federation' => ['admin/federation' , DI::l10n()->t('Federation Statistics') , 'federation']
]],
'configuration' => [DI::l10n()->t('Configuration'), [
'site' => ['admin/site' , DI::l10n()->t('Site') , 'site'],
'storage' => ['admin/storage' , DI::l10n()->t('Storage') , 'storage'],
'addons' => ['admin/addons' , DI::l10n()->t('Addons') , 'addons'],
'themes' => ['admin/themes' , DI::l10n()->t('Themes') , 'themes'],
'features' => ['admin/features' , DI::l10n()->t('Additional features') , 'features'],
'tos' => ['admin/tos' , DI::l10n()->t('Terms of Service') , 'tos'],
'site' => ['admin/site' , DI::l10n()->t('Site') , 'site'],
'storage' => ['admin/storage' , DI::l10n()->t('Storage') , 'storage'],
'addons' => ['admin/addons' , DI::l10n()->t('Addons') , 'addons'],
'themes' => ['admin/themes' , DI::l10n()->t('Themes') , 'themes'],
'features' => ['admin/features' , DI::l10n()->t('Additional features') , 'features'],
'tos' => ['admin/tos' , DI::l10n()->t('Terms of Service') , 'tos'],
]],
'database' => [DI::l10n()->t('Database'), [
'dbsync' => ['admin/dbsync' , DI::l10n()->t('DB updates') , 'dbsync'],
'deferred' => ['admin/queue/deferred', DI::l10n()->t('Inspect Deferred Workers'), 'deferred'],
'workerqueue' => ['admin/queue' , DI::l10n()->t('Inspect worker Queue') , 'workerqueue'],
'dbsync' => ['admin/dbsync' , DI::l10n()->t('DB updates') , 'dbsync'],
'deferred' => ['admin/queue/deferred', DI::l10n()->t('Inspect Deferred Workers'), 'deferred'],
'workerqueue' => ['admin/queue' , DI::l10n()->t('Inspect worker Queue') , 'workerqueue'],
]],
'logs' => [DI::l10n()->t('Logs'), [
'logsconfig' => ['admin/logs/', DI::l10n()->t('Logs') , 'logs'],
'logsview' => ['admin/logs/view' , DI::l10n()->t('View Logs') , 'viewlogs'],
'logsconfig' => ['admin/logs/', DI::l10n()->t('Logs') , 'logs'],
'logsview' => ['admin/logs/view' , DI::l10n()->t('View Logs') , 'viewlogs'],
]],
'diagnostics' => [DI::l10n()->t('Diagnostics'), [
'phpinfo' => ['admin/phpinfo?t=' . self::getFormSecurityToken('phpinfo'), DI::l10n()->t('PHP Info') , 'phpinfo'],
'probe' => ['probe' , DI::l10n()->t('probe address') , 'probe'],
'webfinger' => ['webfinger' , DI::l10n()->t('check webfinger') , 'webfinger'],
'babel' => ['babel' , DI::l10n()->t('Babel') , 'babel'],
'debug/ap' => ['debug/ap' , DI::l10n()->t('ActivityPub Conversion') , 'debug/ap'],
'phpinfo' => ['admin/phpinfo?t=' . self::getFormSecurityToken('phpinfo'), DI::l10n()->t('PHP Info') , 'phpinfo'],
'probe' => ['probe' , DI::l10n()->t('probe address') , 'probe'],
'webfinger' => ['webfinger' , DI::l10n()->t('check webfinger') , 'webfinger'],
'babel' => ['babel' , DI::l10n()->t('Babel') , 'babel'],
'debug/ap' => ['debug/ap' , DI::l10n()->t('ActivityPub Conversion') , 'debug/ap'],
]],
];
$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');
DI::page()['aside'] .= Renderer::replaceMacros($t, [
'$admin' => ['addons_admin' => Addon::getAdminList()],
'$subpages' => $aside_sub,
'$admtxt' => DI::l10n()->t('Admin'),
'$admin' => ['addons_admin' => $addons_admin],
'$subpages' => $aside_sub,
'$admtxt' => DI::l10n()->t('Admin'),
'$plugadmtxt' => DI::l10n()->t('Addon Features'),
'$h_pending' => DI::l10n()->t('User registrations waiting for confirmation'),
'$admurl' => 'admin/'
'$h_pending' => DI::l10n()->t('User registrations waiting for confirmation'),
'$admurl' => 'admin/'
]);
return '';

View file

@ -56,7 +56,7 @@ class SaveTag extends BaseModule
$tpl = Renderer::getMarkupTemplate("filer_dialog.tpl");
echo Renderer::replaceMacros($tpl, [
'$field' => ['term', $this->t("Folder:"), '', '', $filetags, $this->t('- select -')],
'$field' => ['term', $this->t("Folder:"), '', '', $filetags, $this->t('- select -')],
'$submit' => $this->t('Save'),
]);

View file

@ -11,7 +11,7 @@ use Friendica\App;
use Friendica\App\Arguments;
use Friendica\App\BaseURL;
use Friendica\BaseModule;
use Friendica\Core\Addon;
use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook;
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
@ -31,6 +31,7 @@ use Psr\Log\LoggerInterface;
*/
class Friendica extends BaseModule
{
private AddonHelper $addonHelper;
/** @var IManageConfigValues */
private $config;
/** @var IManageKeyValuePairs */
@ -38,18 +39,19 @@ class Friendica extends BaseModule
/** @var IHandleUserSessions */
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);
$this->config = $config;
$this->keyValue = $keyValue;
$this->session = $session;
$this->config = $config;
$this->keyValue = $keyValue;
$this->session = $session;
$this->addonHelper = $addonHelper;
}
protected function content(array $request = []): string
{
$visibleAddonList = Addon::getVisibleList();
$visibleAddonList = $this->addonHelper->getVisibleEnabledAddons();
if (!empty($visibleAddonList)) {
$sorted = $visibleAddonList;
@ -83,8 +85,8 @@ class Friendica extends BaseModule
if (!empty($blockList) && ($this->config->get('blocklist', 'public') || $this->session->isAuthenticated())) {
$blocked = [
'title' => $this->t('On this server the following remote servers are blocked.'),
'header' => [
'title' => $this->t('On this server the following remote servers are blocked.'),
'header' => [
$this->t('Blocked domain'),
$this->t('Reason for the block'),
],
@ -102,11 +104,13 @@ class Friendica extends BaseModule
$tpl = Renderer::getMarkupTemplate('friendica.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>',
$this->baseUrl,
'<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.'),
'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'),
@ -148,7 +152,7 @@ class Friendica extends BaseModule
$register_policy = $register_policies[$register_policy_int];
}
$admin = [];
$admin = [];
$administrator = User::getFirstAdmin(['username', 'nickname']);
if (!empty($administrator)) {
$admin = [
@ -157,11 +161,11 @@ class Friendica extends BaseModule
];
}
$visible_addons = Addon::getVisibleList();
$visible_addons = $this->addonHelper->getVisibleEnabledAddons();
$this->config->reload();
$locked_features = [];
$featureLocks = $this->config->get('config', 'feature_lock');
$featureLocks = $this->config->get('config', 'feature_lock');
if (isset($featureLocks)) {
foreach ($featureLocks as $feature => $lock) {
if ($feature === 'config_loaded') {

View file

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

View file

@ -7,7 +7,6 @@
namespace Friendica\Worker;
use Friendica\Core\Addon;
use Friendica\Core\Hook;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
@ -145,7 +144,7 @@ class Cron
// Update "blocked" status of servers
Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers');
Addon::reload();
DI::addonHelper()->reloadAddons();
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],
],
],
\Friendica\Core\Addon\AddonHelper::class => [
'instanceOf' => \Friendica\Core\Addon\AddonProxy::class,
'constructParams' => [
$basepath . '/addon',
],
],
\Friendica\Util\BasePath::class => [
'constructParams' => [
$basepath,
@ -81,6 +87,7 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
'call' => [
['createConfigFileManager', [
$basepath,
$basepath . '/addon',
$serverVars,
], Dice::CHAIN_CALL],
],

View file

@ -8,7 +8,7 @@
namespace Friendica\Test;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon;
use Friendica\Core\Addon\AddonHelper;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook;
use Friendica\DI;
@ -124,7 +124,7 @@ abstract class ApiTestCase extends FixtureTestCase
file_put_contents(
$tmpFile,
base64_decode(
// Empty 1x1 px PNG image
// Empty 1x1 px PNG image
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=='
)
);
@ -201,7 +201,7 @@ abstract class ApiTestCase extends FixtureTestCase
'plugin_admin' => function_exists($addon . '_addon_admin'),
]);
Addon::loadAddons();
$this->dice->create(AddonHelper::class)->loadAddons();
Hook::loadHooks();
}
}

View file

@ -44,7 +44,7 @@ trait FixtureTestTrait
->addRules(include __DIR__ . '/../static/dependencies.config.php')
->addRule(ConfigFileManager::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(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null])
->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\Test\DatabaseTestTrait;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Util\Profiler;
use Psr\Log\NullLogger;
trait CreateDatabaseTrait
{
@ -32,8 +30,13 @@ trait CreateDatabaseTrait
return $this->dba;
}
$configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/');
$config = new ReadOnlyFileConfig(new Cache([
$configFileManager = new ConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
$this->root->url() . '/config',
$this->root->url() . '/static'
);
$config = new ReadOnlyFileConfig(new Cache([
'database' => [
'disable_pdo' => true
],

View file

@ -34,6 +34,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
@ -61,10 +62,11 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
$configCache = new Cache();
$configCache = new Cache();
$configFileLoader->setupCache($configCache);
}
@ -90,10 +92,11 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
$configCache = new Cache();
$configCache = new Cache();
$configFileLoader->setupCache($configCache);
@ -127,10 +130,11 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
$configCache = new Cache();
$configCache = new Cache();
$configFileLoader->setupCache($configCache);
@ -163,10 +167,11 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
$configCache = new Cache();
$configCache = new Cache();
$configFileLoader->setupCache($configCache);
@ -217,6 +222,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
@ -254,10 +260,11 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
$configCache = new Cache();
$configCache = new Cache();
$configFileLoader->setupCache($configCache);
@ -288,10 +295,11 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
$configCache = new Cache();
$configCache = new Cache();
$configFileLoader->setupCache($configCache);
@ -322,6 +330,7 @@ class ConfigFileManagerTest extends MockedTestCase
$configFileLoader = new ConfigFileManager(
$this->root->url(),
$this->root->url() . DIRECTORY_SEPARATOR . 'addon',
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
);
@ -341,8 +350,12 @@ class ConfigFileManagerTest extends MockedTestCase
{
$this->delConfigFile('local.config.php');
$configFileManager = (new Config())->createConfigFileManager($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']);
$configCache = new Cache();
$configFileManager = (new Config())->createConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/'],
);
$configCache = new Cache();
$configFileManager->setupCache($configCache);
@ -367,11 +380,12 @@ class ConfigFileManagerTest extends MockedTestCase
->at($this->root->getChild('config2'))
->setContent(file_get_contents($fileDir . 'B.config.php'));
$configFileManager = (new Config())->createConfigFileManager($this->root->url(),
[
'FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url(),
]);
$configCache = new Cache();
$configFileManager = (new Config())->createConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()],
);
$configCache = new Cache();
$configFileManager->setupCache($configCache);
@ -389,11 +403,12 @@ class ConfigFileManagerTest extends MockedTestCase
->at($this->root->getChild('config'))
->setContent('');
$configFileManager = (new Config())->createConfigFileManager($this->root->url());
$configCache = new Cache();
$configFileManager = (new Config())->createConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
);
$configCache = new Cache();
$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\Util\CreateDatabaseTrait;
use Friendica\Test\Util\VFSTrait;
use org\bovigo\vfs\vfsStream;
class ConfigTest extends DatabaseTestCase
{
@ -55,8 +54,13 @@ class ConfigTest extends DatabaseTestCase
parent::setUp();
$this->configCache = new Cache();
$this->configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/');
$this->configCache = new Cache();
$this->configFileManager = new ConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
$this->root->url() . '/config',
$this->root->url() . '/static'
);
}
/**
@ -94,7 +98,7 @@ class ConfigTest extends DatabaseTestCase
'key1' => 'value1a',
'key4' => 'value4',
],
'other' => [
'other' => [
'key5' => 'value5',
'key6' => 'value6',
],
@ -108,18 +112,18 @@ class ConfigTest extends DatabaseTestCase
'config',
'other'
],
'load' => [
'load' => [
'system',
],
],
'other' => [
'other' => [
'data' => $data,
'possibleCats' => [
'system',
'config',
'other'
],
'load' => [
'load' => [
'other',
],
],
@ -130,18 +134,18 @@ class ConfigTest extends DatabaseTestCase
'config',
'other'
],
'load' => [
'load' => [
'config',
],
],
'all' => [
'all' => [
'data' => $data,
'possibleCats' => [
'system',
'config',
'other'
],
'load' => [
'load' => [
'system',
'config',
'other'
@ -173,7 +177,7 @@ class ConfigTest extends DatabaseTestCase
*/
public function testSetUp(array $data)
{
$this->loadDirectFixture($this->configToDbArray($data) , $this->getDbInstance());
$this->loadDirectFixture($this->configToDbArray($data), $this->getDbInstance());
$this->testedConfig = $this->getInstance();
self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
@ -209,13 +213,13 @@ class ConfigTest extends DatabaseTestCase
{
return [
'config' => [
'data1' => [
'data1' => [
'config' => [
'key1' => 'value1',
'key2' => 'value2',
],
],
'data2' => [
'data2' => [
'config' => [
'key1' => 'overwritten!',
'key3' => 'value3',
@ -230,19 +234,19 @@ class ConfigTest extends DatabaseTestCase
],
],
],
'other' => [
'data1' => [
'other' => [
'data1' => [
'config' => [
'key12' => 'data4',
'key45' => 7,
],
'other' => [
'other' => [
'key1' => 'value1',
'key2' => 'value2',
],
],
'data2' => [
'other' => [
'data2' => [
'other' => [
'key1' => 'overwritten!',
'key3' => 'value3',
],
@ -252,7 +256,7 @@ class ConfigTest extends DatabaseTestCase
]
],
'expect' => [
'other' => [
'other' => [
// load should overwrite values everytime!
'key1' => 'overwritten!',
'key2' => 'value2',
@ -399,26 +403,26 @@ class ConfigTest extends DatabaseTestCase
public function dataTestCat()
{
return [
'test_with_hashmap' => [
'data' => [
'test_with_hashmap' => [
'data' => [
'test_with_hashmap' => [
'notifyall' => [
'last_update' => 1671051565,
'admin' => true,
],
'blockbot' => [
'blockbot' => [
'last_update' => 1658952852,
'admin' => true,
],
],
'config' => [
'config' => [
'register_policy' => 2,
'register_text' => '',
'sitename' => 'Friendica Social Network23',
'hostname' => 'friendica.local',
'private_addons' => false,
],
'system' => [
'system' => [
'dbclean_expire_conversation' => 90,
],
],
@ -428,14 +432,14 @@ class ConfigTest extends DatabaseTestCase
'last_update' => 1671051565,
'admin' => true,
],
'blockbot' => [
'blockbot' => [
'last_update' => 1658952852,
'admin' => true,
],
],
],
'test_with_keys' => [
'data' => [
'test_with_keys' => [
'data' => [
'test_with_keys' => [
[
'last_update' => 1671051565,
@ -446,14 +450,14 @@ class ConfigTest extends DatabaseTestCase
'admin' => true,
],
],
'config' => [
'config' => [
'register_policy' => 2,
'register_text' => '',
'sitename' => 'Friendica Social Network23',
'hostname' => 'friendica.local',
'private_addons' => false,
],
'system' => [
'system' => [
'dbclean_expire_conversation' => 90,
],
],
@ -470,7 +474,7 @@ class ConfigTest extends DatabaseTestCase
],
],
'test_with_inner_array' => [
'data' => [
'data' => [
'test_with_inner_array' => [
'notifyall' => [
'last_update' => 1671051565,
@ -479,19 +483,19 @@ class ConfigTest extends DatabaseTestCase
'no' => 1.5,
],
],
'blogbot' => [
'blogbot' => [
'last_update' => 1658952852,
'admin' => true,
],
],
'config' => [
'config' => [
'register_policy' => 2,
'register_text' => '',
'sitename' => 'Friendica Social Network23',
'hostname' => 'friendica.local',
'private_addons' => false,
],
'system' => [
'system' => [
'dbclean_expire_conversation' => 90,
],
],
@ -504,7 +508,7 @@ class ConfigTest extends DatabaseTestCase
'no' => 1.5,
],
],
'blogbot' => [
'blogbot' => [
'last_update' => 1658952852,
'admin' => true,
],
@ -519,7 +523,7 @@ class ConfigTest extends DatabaseTestCase
public function testGetCategory(array $data, string $category, array $assertion)
{
$this->configCache = new Cache($data);
$config = new ReadOnlyFileConfig($this->configCache);
$config = new ReadOnlyFileConfig($this->configCache);
self::assertEquals($assertion, $config->get($category));
}
@ -528,15 +532,15 @@ class ConfigTest extends DatabaseTestCase
{
return [
'default' => [
'value' => ['test' => ['array']],
'value' => ['test' => ['array']],
'assertion' => ['test' => ['array']],
],
'issue-12803' => [
'value' => 's:48:"s:40:"s:32:"https://punkrock-underground.com";";";',
'value' => 's:48:"s:40:"s:32:"https://punkrock-underground.com";";";',
'assertion' => 'https://punkrock-underground.com',
],
'double-serialized-array' => [
'value' => 's:53:"a:1:{s:9:"testArray";a:1:{s:4:"with";s:7:"entries";}}";',
'value' => 's:53:"a:1:{s:9:"testArray";a:1:{s:4:"with";s:7:"entries";}}";',
'assertion' => ['testArray' => ['with' => 'entries']],
],
];
@ -558,33 +562,33 @@ class ConfigTest extends DatabaseTestCase
$data = [
'config' => [
'admin_email' => 'value1',
'timezone' => 'value2',
'language' => 'value3',
'sitename' => 'value',
'timezone' => 'value2',
'language' => 'value3',
'sitename' => 'value',
],
'system' => [
'url' => 'value1a',
'url' => 'value1a',
'debugging' => true,
'logfile' => 'value4',
'loglevel' => 'notice',
'proflier' => true,
'logfile' => 'value4',
'loglevel' => 'notice',
'proflier' => true,
],
'proxy' => [
'proxy' => [
'trusted_proxies' => 'value5',
],
];
return [
'empty' => [
'data' => $data,
'server' => [],
'data' => $data,
'server' => [],
'assertDisabled' => [],
],
'mixed' => [
'data' => $data,
'server' => [
'FRIENDICA_ADMIN_MAIL' => 'test@friendica.local',
'FRIENDICA_DEBUGGING' => true,
'FRIENDICA_DEBUGGING' => true,
],
'assertDisabled' => [
'config' => [
@ -608,7 +612,13 @@ class ConfigTest extends DatabaseTestCase
$this->setConfigFile('static' . DIRECTORY_SEPARATOR . 'env.config.php', true);
$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);
$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\Model\DatabaseConfig;
use Friendica\Core\Config\Model\ReadOnlyFileConfig;
use Friendica\Core\Config\Model\ConfigTransaction;
use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Database\Database;
use Friendica\Test\DatabaseTestCase;
use Friendica\Test\FixtureTestCase;
use Friendica\Test\MockedTest;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Test\Util\VFSTrait;
use Mockery\Exception\InvalidCountException;
class ConfigTransactionTest extends FixtureTestCase
@ -30,7 +25,12 @@ class ConfigTransactionTest extends FixtureTestCase
{
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
@ -96,7 +96,7 @@ class ConfigTransactionTest extends FixtureTestCase
{
$this->configFileManager = \Mockery::spy(ConfigFileManager::class);
$config = new DatabaseConfig($this->dice->create(Database::class), new Cache());
$config = new DatabaseConfig($this->dice->create(Database::class), new Cache());
$configTransaction = new ConfigTransaction($config);
// commit empty transaction

View file

@ -21,16 +21,12 @@ use Friendica\Core\Storage\Repository\StorageManager;
use Friendica\Core\Storage\Type\Filesystem;
use Friendica\Core\Storage\Type\SystemResource;
use Friendica\Database\Database;
use Friendica\Database\Definition\DbaDefinition;
use Friendica\Database\Definition\ViewDefinition;
use Friendica\DI;
use Friendica\Core\Config\Factory\Config;
use Friendica\Core\Storage\Type;
use Friendica\Test\DatabaseTestCase;
use Friendica\Test\Util\CreateDatabaseTrait;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Test\Util\VFSTrait;
use Friendica\Util\Profiler;
use org\bovigo\vfs\vfsStream;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
@ -60,12 +56,15 @@ class StorageManagerTest extends DatabaseTestCase
vfsStream::newDirectory(Type\FilesystemConfig::DEFAULT_BASE_FOLDER, 0777)->at($this->root);
$this->logger = new NullLogger();
$this->logger = new NullLogger();
$this->database = $this->getDbInstance();
$configFactory = new Config();
$configFileManager = $configFactory->createConfigFileManager($this->root->url());
$configCache = $configFactory->createCache($configFileManager);
$configFileManager = $configFactory->createConfigFileManager(
$this->root->url(),
$this->root->url() . '/addon',
);
$configCache = $configFactory->createCache($configFileManager);
$this->config = new \Friendica\Core\Config\Model\DatabaseConfig($this->database, $configCache);
$this->config->set('storage', 'name', 'Database');
@ -96,21 +95,21 @@ class StorageManagerTest extends DatabaseTestCase
public function dataStorages()
{
return [
'empty' => [
'empty' => [
'name' => '',
'valid' => false,
'interface' => ICanReadFromStorage::class,
'assert' => null,
'assertName' => '',
],
'database' => [
'database' => [
'name' => Type\Database::NAME,
'valid' => true,
'interface' => ICanWriteToStorage::class,
'assert' => Type\Database::class,
'assertName' => Type\Database::NAME,
],
'filesystem' => [
'filesystem' => [
'name' => Filesystem::NAME,
'valid' => true,
'interface' => ICanWriteToStorage::class,
@ -124,7 +123,7 @@ class StorageManagerTest extends DatabaseTestCase
'assert' => SystemResource::class,
'assertName' => SystemResource::NAME,
],
'invalid' => [
'invalid' => [
'name' => 'invalid',
'valid' => false,
'interface' => null,

View file

@ -32,7 +32,12 @@ class DatabaseTest extends FixtureTestCase
parent::setUp();
$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'
);
}
/**
@ -87,7 +92,7 @@ class DatabaseTest extends FixtureTestCase
self::assertTrue($db->update('gserver', ['active-week-users' => 0, 'registered-users' => 0], ['nurl' => 'http://friendica.local']));
$fields = ["`registered-users` = `registered-users` + 1"];
$fields = ["`registered-users` = `registered-users` + 1"];
$fields[] = "`active-week-users` = `active-week-users` + 2";
self::assertTrue($db->update('gserver', $fields, ['nurl' => 'http://friendica.local']));