Merge branch 'develop' into replace-hooks-with-eventdispatcher

This commit is contained in:
Art4 2025-02-11 09:59:13 +00:00
commit dd6f479401
50 changed files with 1113 additions and 543 deletions

View file

@ -24,7 +24,7 @@ chdir(dirname(__DIR__));
require dirname(__DIR__) . '/vendor/autoload.php';
fwrite(STDOUT, '`bin/daemon.php` is deprecated since 2024.02 and will be removed in 5 months, please use `bin/console.php daemon` instead.' . \PHP_EOL);
fwrite(STDOUT, '`bin/daemon.php` is deprecated since 2025.02 and will be removed in 5 months, please use `bin/console.php daemon` instead.' . \PHP_EOL);
// BC: Add console command as second argument
$argv = $_SERVER['argv'] ?? [];

View file

@ -19,7 +19,7 @@ chdir(dirname(__DIR__));
require dirname(__DIR__) . '/vendor/autoload.php';
fwrite(STDOUT, '`bin/jetstream.php` is deprecated since 2024.02 and will be removed in 5 months, please use `bin/console.php jetstream` instead.' . \PHP_EOL);
fwrite(STDOUT, '`bin/jetstream.php` is deprecated since 2025.02 and will be removed in 5 months, please use `bin/console.php jetstream` instead.' . \PHP_EOL);
// BC: Add console command as second argument
$argv = $_SERVER['argv'] ?? [];

View file

@ -21,7 +21,7 @@ chdir(dirname(__DIR__));
require dirname(__DIR__) . '/vendor/autoload.php';
fwrite(STDOUT, '`bin/worker.php` is deprecated since 2024.02 and will be removed in 5 months, please use `bin/console.php worker` instead.' . \PHP_EOL);
fwrite(STDOUT, '`bin/worker.php` is deprecated since 2025.02 and will be removed in 5 months, please use `bin/console.php worker` instead.' . \PHP_EOL);
// BC: Add console command as second argument
$argv = $_SERVER['argv'] ?? [];

View file

@ -174,6 +174,7 @@
"bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix"
],
"cs:fix-develop": "TARGET_BRANCH=develop COMMAND=fix bin/dev/fix-codestyle.sh",
"db:update-structure": "bin/console.php dbstructure dumpsql > database.sql",
"install:prod": "@composer install -o --no-dev"
}
}

View file

@ -45,7 +45,7 @@ Indexes
------------
| Name | Fields |
|-----------------------| ----------------------- |
| --------------------- | ----------------------- |
| PRIMARY | id |
| uid_uri-id | UNIQUE, uid, uri-id |
| uri-id_origin_deleted | uri-id, origin, deleted |

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\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
@ -1071,6 +1070,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))) {
@ -1079,7 +1079,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) : [];
}
@ -1135,7 +1135,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) : [];
}
@ -1215,7 +1215,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

@ -196,17 +196,6 @@ class Page implements ArrayAccess
IManagePersonalConfigValues $pConfig,
int $localUID
) {
$interval = ($localUID ? $pConfig->get($localUID, 'system', 'update_interval') : 40000);
// If the update is 'deactivated' set it to the highest integer number (~24 days)
if ($interval < 0) {
$interval = 2147483647;
}
if ($interval < 10000) {
$interval = 40000;
}
// Default title: current module called
if (empty($this->page['title']) && $args->getModuleName()) {
$this->page['title'] = ucfirst($args->getModuleName());
@ -272,13 +261,13 @@ class Page implements ArrayAccess
'dictMaxFilesExceeded' => $l10n->t("You can't upload any more files."),
],
'$local_user' => $localUID,
'$generator' => 'Friendica' . ' ' . App::VERSION,
'$update_interval' => $interval,
'$shortcut_icon' => $shortcut_icon,
'$touch_icon' => $touch_icon,
'$block_public' => intval($config->get('system', 'block_public')),
'$stylesheets' => $this->stylesheets,
'$local_user' => $localUID,
'$generator' => 'Friendica' . ' ' . App::VERSION,
'$update_content' => (int)$pConfig->get($localUID, 'system', 'update_content'),
'$shortcut_icon' => $shortcut_icon,
'$touch_icon' => $touch_icon,
'$block_public' => intval($config->get('system', 'block_public')),
'$stylesheets' => $this->stylesheets,
// Dropzone
'$max_imagesize' => round(Images::getMaxUploadBytes() / 1000000, 0),

View file

@ -11,7 +11,7 @@ use FastRoute\DataGenerator\GroupCountBased;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use FastRoute\RouteParser\Std;
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;
@ -88,6 +88,8 @@ class Router
private EventDispatcherInterface $eventDispatcher;
private AddonHelper $addonHelper;
/** @var bool */
private $isLocalUser;
@ -112,7 +114,7 @@ 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, EventDispatcherInterface $eventDispatcher, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, EventDispatcherInterface $eventDispatcher, AddonHelper $addonHelper, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
{
$this->baseRoutesFilepath = $baseRoutesFilepath;
$this->l10n = $l10n;
@ -123,6 +125,7 @@ class Router
$this->server = $server;
$this->logger = $logger;
$this->eventDispatcher = $eventDispatcher;
$this->addonHelper = $addonHelper;
$this->isLocalUser = !empty($userSession->getLocalUserId());
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
@ -298,7 +301,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

@ -154,7 +154,7 @@ class BaseSettings extends BaseModule
$tabs[] = [
'label' => $this->t('Import Contacts'),
'url' => 'settings/importcontacts',
'selected' => static::class == Settings\UserExport::class ? 'active' : '',
'selected' => static::class == Settings\ContactImport::class ? 'active' : '',
'accesskey' => '',
];

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

@ -103,13 +103,7 @@ class Display extends BaseSettings
$show_page_drop = (bool)$request['show_page_drop'];
$display_eventlist = (bool)$request['display_eventlist'];
$preview_mode = (int)$request['preview_mode'];
$browser_update = (int)$request['browser_update'];
if ($browser_update != -1) {
$browser_update = $browser_update * 1000;
if ($browser_update < 10000) {
$browser_update = 10000;
}
}
$update_content = (int)$request['update_content'];
$enabled_timelines = [];
foreach ($enable as $code => $enabled) {
@ -144,7 +138,7 @@ class Display extends BaseSettings
$this->pConfig->set($uid, 'system', 'itemspage_network', $itemspage_network);
$this->pConfig->set($uid, 'system', 'itemspage_mobile_network', $itemspage_mobile_network);
$this->pConfig->set($uid, 'system', 'update_interval', $browser_update);
$this->pConfig->set($uid, 'system', 'update_content', $update_content);
$this->pConfig->set($uid, 'system', 'no_smilies', !$enable_smile);
$this->pConfig->set($uid, 'system', 'infinite_scroll', $infinite_scroll);
$this->pConfig->set($uid, 'system', 'no_smart_threading', !$enable_smart_threading);
@ -238,11 +232,7 @@ class Display extends BaseSettings
$itemspage_mobile_network = intval($this->pConfig->get($uid, 'system', 'itemspage_mobile_network'));
$itemspage_mobile_network = (($itemspage_mobile_network > 0 && $itemspage_mobile_network < 101) ? $itemspage_mobile_network : $this->config->get('system', 'itemspage_network_mobile'));
$browser_update = intval($this->pConfig->get($uid, 'system', 'update_interval'));
if ($browser_update != -1) {
$browser_update = (($browser_update == 0) ? 40 : $browser_update / 1000); // default if not set: 40 seconds
}
$update_content = $this->pConfig->get($uid, 'system', 'update_content') ?? false;
$enable_smile = !$this->pConfig->get($uid, 'system', 'no_smilies', false);
$infinite_scroll = $this->pConfig->get($uid, 'system', 'infinite_scroll', false);
$enable_smart_threading = !$this->pConfig->get($uid, 'system', 'no_smart_threading', false);
@ -332,7 +322,7 @@ class Display extends BaseSettings
'$itemspage_network' => ['itemspage_network', $this->t('Number of items to display per page:'), $itemspage_network, $this->t('Maximum of 100 items')],
'$itemspage_mobile_network' => ['itemspage_mobile_network', $this->t('Number of items to display per page when viewed from mobile device:'), $itemspage_mobile_network, $this->t('Maximum of 100 items')],
'$ajaxint' => ['browser_update', $this->t('Update browser every xx seconds'), $browser_update, $this->t('Minimum of 10 seconds. Enter -1 to disable it.')],
'$update_content' => ['update_content', $this->t('Regularly update the page content'), $update_content, $this->t('When enabled, new content on network, community and channels are added on top.')],
'$enable_smile' => ['enable_smile', $this->t('Display emoticons'), $enable_smile, $this->t('When enabled, emoticons are replaced with matching symbols.')],
'$infinite_scroll' => ['infinite_scroll', $this->t('Infinite scroll'), $infinite_scroll, $this->t('Automatic fetch new items when reaching the page end.')],
'$enable_smart_threading' => ['enable_smart_threading', $this->t('Enable Smart Threading'), $enable_smart_threading, $this->t('Enable the automatic suppression of extraneous thread indentation.')],

View file

@ -45,19 +45,16 @@ class Display extends DisplayModule
$parentUriId = $item['parent-uri-id'];
if (empty($force)) {
$browserUpdate = intval($this->pConfig->get($profileUid, 'system', 'update_interval') ?? 40000);
if ($browserUpdate >= 1000) {
$updateDate = date(DateTimeFormat::MYSQL, time() - ($browserUpdate * 2 / 1000));
if ($this->pConfig->get($profileUid, 'system', 'update_content')) {
$updateDate = date(DateTimeFormat::MYSQL, time() - 120);
if (!Post::exists([
"`parent-uri-id` = ? AND `uid` IN (?, ?) AND `received` > ?",
$parentUriId, 0,
$profileUid, $updateDate])) {
$this->logger->debug('No updated content. Ending process',
['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
$this->logger->debug('No updated content. Ending process', ['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
return '';
} else {
$this->logger->debug('Updated content found.',
['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
$this->logger->debug('Updated content found.', ['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
}
}
} else {

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']));

View file

@ -501,12 +501,14 @@ function NavUpdate() {
// start live update
['network', 'profile', 'channel', 'community', 'notes', 'display', 'contact'].forEach(function (src) {
if ($('#live-' + src).length) {
if ($('#live-' + src).length && (force_update || (updateContent && ['network', 'channel', 'community'].includes(src)))) {
liveUpdate(src);
}
});
if (!$('#live-network').length) {
if ($('#live-network').length) {
networkUpdate();
} else {
var update_url = 'ping_network?ping=1';
$.get(update_url, function(net) {
updateCounter('net', net);
@ -522,7 +524,7 @@ function NavUpdate() {
}
});
}
timer = setTimeout(NavUpdate, updateInterval);
timer = setTimeout(NavUpdate, 30000);
}
function updateConvItems(data) {
@ -568,38 +570,14 @@ function updateConvItems(data) {
}
}
function liveUpdate(src) {
if ((src == null) || stopped || !profile_uid) {
$('.like-rotator').hide(); return;
}
if (($('.comment-edit-text-full').length) || in_progress) {
if (livetime) {
clearTimeout(livetime);
}
livetime = setTimeout(function() {liveUpdate(src)}, 5000);
return;
}
if (livetime != null) {
livetime = null;
}
prev = 'live-' + src;
in_progress = true;
function getUpdateUrl(src)
{
let force = force_update || $(document).scrollTop() === 0;
var orgHeight = $("section").height();
var udargs = ((netargs.length) ? '/' + netargs : '');
var update_url = src + udargs + '&p=' + profile_uid + '&force=' + (force ? 1 : 0) + '&item=' + update_item;
if (force_update) {
force_update = false;
}
if (getUrlParameter('page')) {
update_url += '&page=' + getUrlParameter('page');
}
@ -629,6 +607,36 @@ function liveUpdate(src) {
if (match.length > 0) {
update_url += '&first_uriid=' + match[0].innerHTML;
}
return update_url;
}
function liveUpdate(src) {
if ((src == null) || stopped || !profile_uid) {
$('.like-rotator').hide(); return;
}
if (($('.comment-edit-text-full').length) || in_progress) {
if (livetime) {
clearTimeout(livetime);
}
livetime = setTimeout(function() {liveUpdate(src)}, 5000);
return;
}
if (livetime != null) {
livetime = null;
}
prev = 'live-' + src;
in_progress = true;
var orgHeight = $("section").height();
var update_url = getUpdateUrl(src);
if (force_update) {
force_update = false;
}
$.get('update_' + update_url, function(data) {
in_progress = false;
@ -647,12 +655,12 @@ function liveUpdate(src) {
$(window).scrollTop($(window).scrollTop() + $("section").height() - orgHeight);
});
});
}
if (src == 'network') {
$.get('ping_' + update_url, function(net) {
updateCounter('net', net);
});
}
function networkUpdate() {
$.get('ping_' + getUpdateUrl('network'), function(net) {
updateCounter('net', net);
});
}
function updateCounter(type, counter) {

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2025.02-dev\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-05 22:44+0000\n"
"POT-Creation-Date: 2025-02-09 20:13+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -70,7 +70,7 @@ msgstr ""
#: src/Module/Settings/ContactImport.php:49
#: src/Module/Settings/ContactImport.php:96
#: src/Module/Settings/Delegation.php:76 src/Module/Settings/Display.php:80
#: src/Module/Settings/Display.php:194
#: src/Module/Settings/Display.php:188
#: src/Module/Settings/Profile/Photo/Crop.php:148
#: src/Module/Settings/Profile/Photo/Index.php:96
#: src/Module/Settings/RemoveMe.php:103 src/Module/Settings/UserExport.php:64
@ -285,7 +285,7 @@ msgstr ""
#: mod/message.php:188 mod/message.php:344 mod/photos.php:1252
#: src/Content/Conversation.php:389 src/Content/Conversation.php:1565
#: src/Module/Item/Compose.php:202 src/Module/Post/Edit.php:136
#: src/Object/Post.php:607
#: src/Object/Post.php:608
msgid "Please wait"
msgstr ""
@ -307,7 +307,7 @@ msgstr ""
#: src/Module/Moderation/Report/Create.php:249
#: src/Module/Profile/Profile.php:265 src/Module/Settings/Profile/Index.php:248
#: src/Module/Settings/Server/Action.php:65 src/Module/User/Delegation.php:177
#: src/Object/Post.php:1148 view/theme/duepuntozero/config.php:73
#: src/Object/Post.php:1149 view/theme/duepuntozero/config.php:73
#: view/theme/frio/config.php:155 view/theme/quattro/config.php:75
#: view/theme/vier/config.php:123
msgid "Submit"
@ -590,25 +590,25 @@ msgstr ""
#: mod/photos.php:1090 mod/photos.php:1146 mod/photos.php:1226
#: src/Module/Contact.php:599 src/Module/Item/Compose.php:184
#: src/Object/Post.php:1145
#: src/Object/Post.php:1146
msgid "This is you"
msgstr ""
#: mod/photos.php:1092 mod/photos.php:1148 mod/photos.php:1228
#: src/Module/Moderation/Reports.php:105 src/Object/Post.php:601
#: src/Object/Post.php:1147
#: src/Module/Moderation/Reports.php:105 src/Object/Post.php:602
#: src/Object/Post.php:1148
msgid "Comment"
msgstr ""
#: mod/photos.php:1094 mod/photos.php:1150 mod/photos.php:1230
#: src/Content/Conversation.php:403 src/Module/Calendar/Event/Form.php:234
#: src/Module/Item/Compose.php:197 src/Module/Post/Edit.php:156
#: src/Object/Post.php:1161
#: src/Object/Post.php:1162
msgid "Preview"
msgstr ""
#: mod/photos.php:1095 src/Content/Conversation.php:357
#: src/Module/Post/Edit.php:121 src/Object/Post.php:1149
#: src/Module/Post/Edit.php:121 src/Object/Post.php:1150
msgid "Loading..."
msgstr ""
@ -650,104 +650,104 @@ msgstr ""
msgid "Apologies but the website is unavailable at the moment."
msgstr ""
#: src/App/Page.php:247
#: src/App/Page.php:236
msgid "Delete this item?"
msgstr ""
#: src/App/Page.php:248
#: src/App/Page.php:237
msgid "Block this author? They won't be able to follow you nor see your public posts, and you won't be able to see their posts and their notifications."
msgstr ""
#: src/App/Page.php:249
#: src/App/Page.php:238
msgid "Ignore this author? You won't be able to see their posts and their notifications."
msgstr ""
#: src/App/Page.php:250
#: src/App/Page.php:239
msgid "Collapse this author's posts?"
msgstr ""
#: src/App/Page.php:251
#: src/App/Page.php:240
msgid "Ignore this author's server?"
msgstr ""
#: src/App/Page.php:252 src/Module/Settings/Server/Action.php:47
#: src/App/Page.php:241 src/Module/Settings/Server/Action.php:47
#: src/Module/Settings/Server/Index.php:94
msgid "You won't see any content from this server including reshares in your Network page, the community pages and individual conversations."
msgstr ""
#: src/App/Page.php:254
#: src/App/Page.php:243
msgid "Like not successful"
msgstr ""
#: src/App/Page.php:255
#: src/App/Page.php:244
msgid "Dislike not successful"
msgstr ""
#: src/App/Page.php:256
#: src/App/Page.php:245
msgid "Sharing not successful"
msgstr ""
#: src/App/Page.php:257
#: src/App/Page.php:246
msgid "Attendance unsuccessful"
msgstr ""
#: src/App/Page.php:258
#: src/App/Page.php:247
msgid "Backend error"
msgstr ""
#: src/App/Page.php:259
#: src/App/Page.php:248
msgid "Network error"
msgstr ""
#: src/App/Page.php:262
#: src/App/Page.php:251
msgid "Drop files here to upload"
msgstr ""
#: src/App/Page.php:263
#: src/App/Page.php:252
msgid "Your browser does not support drag and drop file uploads."
msgstr ""
#: src/App/Page.php:264
#: src/App/Page.php:253
msgid "Please use the fallback form below to upload your files like in the olden days."
msgstr ""
#: src/App/Page.php:265
#: src/App/Page.php:254
msgid "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB."
msgstr ""
#: src/App/Page.php:266
#: src/App/Page.php:255
msgid "You can't upload files of this type."
msgstr ""
#: src/App/Page.php:267
#: src/App/Page.php:256
msgid "Server responded with {{statusCode}} code."
msgstr ""
#: src/App/Page.php:268
#: src/App/Page.php:257
msgid "Cancel upload"
msgstr ""
#: src/App/Page.php:269
#: src/App/Page.php:258
msgid "Upload canceled."
msgstr ""
#: src/App/Page.php:270
#: src/App/Page.php:259
msgid "Are you sure you want to cancel this upload?"
msgstr ""
#: src/App/Page.php:271
#: src/App/Page.php:260
msgid "Remove file"
msgstr ""
#: src/App/Page.php:272
#: src/App/Page.php:261
msgid "You can't upload any more files."
msgstr ""
#: src/App/Page.php:356
#: src/App/Page.php:345
msgid "toggle mobile"
msgstr ""
#: src/App/Page.php:367 src/Module/Admin/Logs/View.php:92
#: src/App/Page.php:356 src/Module/Admin/Logs/View.php:92
#: view/theme/frio/php/minimal.php:39 view/theme/frio/php/standard.php:138
msgid "Close"
msgstr ""
@ -1235,7 +1235,7 @@ msgid "Visible to <strong>everybody</strong>"
msgstr ""
#: src/Content/Conversation.php:327 src/Module/Item/Compose.php:196
#: src/Object/Post.php:1160
#: src/Object/Post.php:1161
msgid "Please enter a image/video/audio/webpage URL:"
msgstr ""
@ -1280,52 +1280,52 @@ msgid "attach file"
msgstr ""
#: src/Content/Conversation.php:362 src/Module/Item/Compose.php:186
#: src/Module/Post/Edit.php:162 src/Object/Post.php:1150
#: src/Module/Post/Edit.php:162 src/Object/Post.php:1151
msgid "Bold"
msgstr ""
#: src/Content/Conversation.php:363 src/Module/Item/Compose.php:187
#: src/Module/Post/Edit.php:163 src/Object/Post.php:1151
#: src/Module/Post/Edit.php:163 src/Object/Post.php:1152
msgid "Italic"
msgstr ""
#: src/Content/Conversation.php:364 src/Module/Item/Compose.php:188
#: src/Module/Post/Edit.php:164 src/Object/Post.php:1152
#: src/Module/Post/Edit.php:164 src/Object/Post.php:1153
msgid "Underline"
msgstr ""
#: src/Content/Conversation.php:365 src/Module/Item/Compose.php:189
#: src/Module/Post/Edit.php:165 src/Object/Post.php:1154
#: src/Module/Post/Edit.php:165 src/Object/Post.php:1155
msgid "Quote"
msgstr ""
#: src/Content/Conversation.php:366 src/Module/Item/Compose.php:190
#: src/Module/Post/Edit.php:166 src/Object/Post.php:1155
#: src/Module/Post/Edit.php:166 src/Object/Post.php:1156
msgid "Add emojis"
msgstr ""
#: src/Content/Conversation.php:367 src/Module/Item/Compose.php:191
#: src/Object/Post.php:1153
#: src/Object/Post.php:1154
msgid "Content Warning"
msgstr ""
#: src/Content/Conversation.php:368 src/Module/Item/Compose.php:192
#: src/Module/Post/Edit.php:167 src/Object/Post.php:1156
#: src/Module/Post/Edit.php:167 src/Object/Post.php:1157
msgid "Code"
msgstr ""
#: src/Content/Conversation.php:369 src/Module/Item/Compose.php:193
#: src/Object/Post.php:1157
#: src/Object/Post.php:1158
msgid "Image"
msgstr ""
#: src/Content/Conversation.php:370 src/Module/Item/Compose.php:194
#: src/Module/Post/Edit.php:168 src/Object/Post.php:1158
#: src/Module/Post/Edit.php:168 src/Object/Post.php:1159
msgid "Link"
msgstr ""
#: src/Content/Conversation.php:371 src/Module/Item/Compose.php:195
#: src/Module/Post/Edit.php:169 src/Object/Post.php:1159
#: src/Module/Post/Edit.php:169 src/Object/Post.php:1160
msgid "Link or Media"
msgstr ""
@ -1499,7 +1499,7 @@ msgstr ""
msgid "Filed under:"
msgstr ""
#: src/Content/Conversation.php:1547 src/Object/Post.php:558
#: src/Content/Conversation.php:1547 src/Object/Post.php:559
#, php-format
msgid "%s from %s"
msgstr ""
@ -1748,7 +1748,7 @@ msgstr ""
#: src/Content/Feature.php:131 src/Content/Widget.php:610
#: src/Module/Admin/Site.php:463 src/Module/BaseSettings.php:113
#: src/Module/Settings/Channels.php:211 src/Module/Settings/Display.php:323
#: src/Module/Settings/Channels.php:211 src/Module/Settings/Display.php:313
msgid "Channels"
msgstr ""
@ -1918,7 +1918,7 @@ msgstr ""
msgid "Languages"
msgstr ""
#: src/Content/Item.php:435 src/Object/Post.php:585
#: src/Content/Item.php:435 src/Object/Post.php:586
msgid "Search Text"
msgstr ""
@ -2011,7 +2011,7 @@ msgstr ""
#: src/Content/Nav.php:229 src/Content/Nav.php:289
#: src/Module/BaseProfile.php:70 src/Module/BaseProfile.php:73
#: src/Module/BaseProfile.php:81 src/Module/BaseProfile.php:84
#: src/Module/Settings/Display.php:324 view/theme/frio/theme.php:225
#: src/Module/Settings/Display.php:314 view/theme/frio/theme.php:225
#: view/theme/frio/theme.php:229
msgid "Calendar"
msgstr ""
@ -2846,37 +2846,37 @@ msgid "%s (%s)"
msgstr ""
#: src/Core/L10n.php:481 src/Model/Event.php:416
#: src/Module/Settings/Display.php:292
#: src/Module/Settings/Display.php:282
msgid "Monday"
msgstr ""
#: src/Core/L10n.php:481 src/Model/Event.php:417
#: src/Module/Settings/Display.php:293
#: src/Module/Settings/Display.php:283
msgid "Tuesday"
msgstr ""
#: src/Core/L10n.php:481 src/Model/Event.php:418
#: src/Module/Settings/Display.php:294
#: src/Module/Settings/Display.php:284
msgid "Wednesday"
msgstr ""
#: src/Core/L10n.php:481 src/Model/Event.php:419
#: src/Module/Settings/Display.php:295
#: src/Module/Settings/Display.php:285
msgid "Thursday"
msgstr ""
#: src/Core/L10n.php:481 src/Model/Event.php:420
#: src/Module/Settings/Display.php:296
#: src/Module/Settings/Display.php:286
msgid "Friday"
msgstr ""
#: src/Core/L10n.php:481 src/Model/Event.php:421
#: src/Module/Settings/Display.php:297
#: src/Module/Settings/Display.php:287
msgid "Saturday"
msgstr ""
#: src/Core/L10n.php:481 src/Model/Event.php:415
#: src/Module/Settings/Display.php:291
#: src/Module/Settings/Display.php:281
msgid "Sunday"
msgstr ""
@ -3305,17 +3305,17 @@ msgid "today"
msgstr ""
#: src/Model/Event.php:449 src/Module/Calendar/Show.php:117
#: src/Module/Settings/Display.php:302 src/Util/Temporal.php:343
#: src/Module/Settings/Display.php:292 src/Util/Temporal.php:343
msgid "month"
msgstr ""
#: src/Model/Event.php:450 src/Module/Calendar/Show.php:118
#: src/Module/Settings/Display.php:303 src/Util/Temporal.php:344
#: src/Module/Settings/Display.php:293 src/Util/Temporal.php:344
msgid "week"
msgstr ""
#: src/Model/Event.php:451 src/Module/Calendar/Show.php:119
#: src/Module/Settings/Display.php:304 src/Util/Temporal.php:345
#: src/Module/Settings/Display.php:294 src/Util/Temporal.php:345
msgid "day"
msgstr ""
@ -3880,7 +3880,7 @@ msgid "Disable"
msgstr ""
#: src/Module/Admin/Addons/Details.php:75
#: src/Module/Admin/Themes/Details.php:41 src/Module/Settings/Display.php:351
#: src/Module/Admin/Themes/Details.php:41 src/Module/Settings/Display.php:341
msgid "Enable"
msgstr ""
@ -3931,7 +3931,7 @@ msgstr ""
#: src/Module/Settings/Connectors.php:143
#: src/Module/Settings/Connectors.php:228
#: src/Module/Settings/ContactImport.php:110
#: src/Module/Settings/Delegation.php:179 src/Module/Settings/Display.php:317
#: src/Module/Settings/Delegation.php:179 src/Module/Settings/Display.php:307
#: src/Module/Settings/Features.php:61
msgid "Save Settings"
msgstr ""
@ -4282,11 +4282,11 @@ msgstr ""
msgid "%s is no valid input for maximum image size"
msgstr ""
#: src/Module/Admin/Site.php:361 src/Module/Settings/Display.php:212
#: src/Module/Admin/Site.php:361 src/Module/Settings/Display.php:206
msgid "No special theme for mobile devices"
msgstr ""
#: src/Module/Admin/Site.php:378 src/Module/Settings/Display.php:222
#: src/Module/Admin/Site.php:378 src/Module/Settings/Display.php:216
#, php-format
msgid "%s - (Experimental)"
msgstr ""
@ -5189,7 +5189,7 @@ msgid "Can be \"all\" or \"tags\". \"all\" means that every public post should b
msgstr ""
#: src/Module/Admin/Site.php:584 src/Module/Contact/Profile.php:315
#: src/Module/Settings/Display.php:259
#: src/Module/Settings/Display.php:249
#: src/Module/Settings/TwoFactor/Index.php:132
msgid "Disabled"
msgstr ""
@ -5745,7 +5745,7 @@ msgstr ""
#: src/Module/Contact.php:537 src/Module/Conversation/Channel.php:98
#: src/Module/Conversation/Community.php:91
#: src/Module/Conversation/Network.php:295
#: src/Module/Moderation/BaseUsers.php:102 src/Object/Post.php:605
#: src/Module/Moderation/BaseUsers.php:102 src/Object/Post.php:606
msgid "More"
msgstr ""
@ -5928,7 +5928,7 @@ msgstr ""
msgid "Create New Event"
msgstr ""
#: src/Module/Calendar/Show.php:120 src/Module/Settings/Display.php:305
#: src/Module/Calendar/Show.php:120 src/Module/Settings/Display.php:295
msgid "list"
msgstr ""
@ -9556,12 +9556,12 @@ msgid "When selected, the channel results are reshared. This only works for publ
msgstr ""
#: src/Module/Settings/Channels.php:176 src/Module/Settings/Channels.php:197
#: src/Module/Settings/Display.php:349
#: src/Module/Settings/Display.php:339
msgid "Label"
msgstr ""
#: src/Module/Settings/Channels.php:177 src/Module/Settings/Channels.php:198
#: src/Module/Settings/Display.php:350
#: src/Module/Settings/Display.php:340
#: src/Module/Settings/TwoFactor/AppSpecific.php:123
msgid "Description"
msgstr ""
@ -9940,218 +9940,218 @@ msgstr ""
msgid "No entries."
msgstr ""
#: src/Module/Settings/Display.php:180
#: src/Module/Settings/Display.php:174
msgid "The theme you chose isn't available."
msgstr ""
#: src/Module/Settings/Display.php:220
#: src/Module/Settings/Display.php:214
#, php-format
msgid "%s - (Unsupported)"
msgstr ""
#: src/Module/Settings/Display.php:260
#: src/Module/Settings/Display.php:250
msgid "Color/Black"
msgstr ""
#: src/Module/Settings/Display.php:261 view/theme/frio/php/scheme.php:95
#: src/Module/Settings/Display.php:251 view/theme/frio/php/scheme.php:95
msgid "Black"
msgstr ""
#: src/Module/Settings/Display.php:262
#: src/Module/Settings/Display.php:252
msgid "Color/White"
msgstr ""
#: src/Module/Settings/Display.php:263
#: src/Module/Settings/Display.php:253
msgid "White"
msgstr ""
#: src/Module/Settings/Display.php:268
#: src/Module/Settings/Display.php:258
msgid "No preview"
msgstr ""
#: src/Module/Settings/Display.php:269
#: src/Module/Settings/Display.php:259
msgid "No image"
msgstr ""
#: src/Module/Settings/Display.php:270
#: src/Module/Settings/Display.php:260
msgid "Small Image"
msgstr ""
#: src/Module/Settings/Display.php:271
#: src/Module/Settings/Display.php:261
msgid "Large Image"
msgstr ""
#: src/Module/Settings/Display.php:316
#: src/Module/Settings/Display.php:306
msgid "Display Settings"
msgstr ""
#: src/Module/Settings/Display.php:318
#: src/Module/Settings/Display.php:308
msgid "General Theme Settings"
msgstr ""
#: src/Module/Settings/Display.php:319
#: src/Module/Settings/Display.php:309
msgid "Custom Theme Settings"
msgstr ""
#: src/Module/Settings/Display.php:320
#: src/Module/Settings/Display.php:310
msgid "Content Settings"
msgstr ""
#: src/Module/Settings/Display.php:321 view/theme/duepuntozero/config.php:74
#: src/Module/Settings/Display.php:311 view/theme/duepuntozero/config.php:74
#: view/theme/frio/config.php:156 view/theme/quattro/config.php:76
#: view/theme/vier/config.php:124
msgid "Theme settings"
msgstr ""
#: src/Module/Settings/Display.php:322
#: src/Module/Settings/Display.php:312
msgid "Timelines"
msgstr ""
#: src/Module/Settings/Display.php:329
#: src/Module/Settings/Display.php:319
msgid "Display Theme:"
msgstr ""
#: src/Module/Settings/Display.php:330
#: src/Module/Settings/Display.php:320
msgid "Mobile Theme:"
msgstr ""
#: src/Module/Settings/Display.php:333
#: src/Module/Settings/Display.php:323
msgid "Number of items to display per page:"
msgstr ""
#: src/Module/Settings/Display.php:333 src/Module/Settings/Display.php:334
#: src/Module/Settings/Display.php:323 src/Module/Settings/Display.php:324
msgid "Maximum of 100 items"
msgstr ""
#: src/Module/Settings/Display.php:334
#: src/Module/Settings/Display.php:324
msgid "Number of items to display per page when viewed from mobile device:"
msgstr ""
#: src/Module/Settings/Display.php:335
msgid "Update browser every xx seconds"
#: src/Module/Settings/Display.php:325
msgid "Regularly update the page content"
msgstr ""
#: src/Module/Settings/Display.php:335
msgid "Minimum of 10 seconds. Enter -1 to disable it."
#: src/Module/Settings/Display.php:325
msgid "When enabled, new content on network, community and channels are added on top."
msgstr ""
#: src/Module/Settings/Display.php:336
#: src/Module/Settings/Display.php:326
msgid "Display emoticons"
msgstr ""
#: src/Module/Settings/Display.php:336
#: src/Module/Settings/Display.php:326
msgid "When enabled, emoticons are replaced with matching symbols."
msgstr ""
#: src/Module/Settings/Display.php:337
#: src/Module/Settings/Display.php:327
msgid "Infinite scroll"
msgstr ""
#: src/Module/Settings/Display.php:337
#: src/Module/Settings/Display.php:327
msgid "Automatic fetch new items when reaching the page end."
msgstr ""
#: src/Module/Settings/Display.php:338
#: src/Module/Settings/Display.php:328
msgid "Enable Smart Threading"
msgstr ""
#: src/Module/Settings/Display.php:338
#: src/Module/Settings/Display.php:328
msgid "Enable the automatic suppression of extraneous thread indentation."
msgstr ""
#: src/Module/Settings/Display.php:339
#: src/Module/Settings/Display.php:329
msgid "Display the Dislike feature"
msgstr ""
#: src/Module/Settings/Display.php:339
#: src/Module/Settings/Display.php:329
msgid "Display the Dislike button and dislike reactions on posts and comments."
msgstr ""
#: src/Module/Settings/Display.php:340
#: src/Module/Settings/Display.php:330
msgid "Display the resharer"
msgstr ""
#: src/Module/Settings/Display.php:340
#: src/Module/Settings/Display.php:330
msgid "Display the first resharer as icon and text on a reshared item."
msgstr ""
#: src/Module/Settings/Display.php:341
#: src/Module/Settings/Display.php:331
msgid "Stay local"
msgstr ""
#: src/Module/Settings/Display.php:341
#: src/Module/Settings/Display.php:331
msgid "Don't go to a remote system when following a contact link."
msgstr ""
#: src/Module/Settings/Display.php:342
#: src/Module/Settings/Display.php:332
msgid "Show the post deletion checkbox"
msgstr ""
#: src/Module/Settings/Display.php:342
#: src/Module/Settings/Display.php:332
msgid "Display the checkbox for the post deletion on the network page."
msgstr ""
#: src/Module/Settings/Display.php:343
#: src/Module/Settings/Display.php:333
msgid "DIsplay the event list"
msgstr ""
#: src/Module/Settings/Display.php:343
#: src/Module/Settings/Display.php:333
msgid "Display the birthday reminder and event list on the network page."
msgstr ""
#: src/Module/Settings/Display.php:344
#: src/Module/Settings/Display.php:334
msgid "Link preview mode"
msgstr ""
#: src/Module/Settings/Display.php:344
#: src/Module/Settings/Display.php:334
msgid "Appearance of the link preview that is added to each post with a link."
msgstr ""
#: src/Module/Settings/Display.php:345
#: src/Module/Settings/Display.php:335
msgid "Hide pictures with empty alternative text"
msgstr ""
#: src/Module/Settings/Display.php:345
#: src/Module/Settings/Display.php:335
msgid "Don't display pictures that are missing the alternative text."
msgstr ""
#: src/Module/Settings/Display.php:346
#: src/Module/Settings/Display.php:336
msgid "Hide custom emojis"
msgstr ""
#: src/Module/Settings/Display.php:346
#: src/Module/Settings/Display.php:336
msgid "Don't display custom emojis."
msgstr ""
#: src/Module/Settings/Display.php:347
#: src/Module/Settings/Display.php:337
msgid "Platform icons style"
msgstr ""
#: src/Module/Settings/Display.php:347
#: src/Module/Settings/Display.php:337
msgid "Style of the platform icons"
msgstr ""
#: src/Module/Settings/Display.php:352
#: src/Module/Settings/Display.php:342
msgid "Bookmark"
msgstr ""
#: src/Module/Settings/Display.php:354
#: src/Module/Settings/Display.php:344
msgid "Enable timelines that you want to see in the channels widget. Bookmark timelines that you want to see in the top menu."
msgstr ""
#: src/Module/Settings/Display.php:356
#: src/Module/Settings/Display.php:346
msgid "Channel languages:"
msgstr ""
#: src/Module/Settings/Display.php:356
#: src/Module/Settings/Display.php:346
msgid "Select all the languages you want to see in your channels. \"Unspecified\" describes all posts for which no language information was detected (e.g. posts with just an image or too little text to be sure of the language). If you want to see all languages, you will need to select all items in the list."
msgstr ""
#: src/Module/Settings/Display.php:358
#: src/Module/Settings/Display.php:348
msgid "Beginning of week:"
msgstr ""
#: src/Module/Settings/Display.php:359
#: src/Module/Settings/Display.php:349
msgid "Default calendar view:"
msgstr ""
@ -11655,97 +11655,97 @@ msgstr ""
msgid "via Wall-To-Wall:"
msgstr ""
#: src/Object/Post.php:602
#: src/Object/Post.php:603
#, php-format
msgid "Reply to %s"
msgstr ""
#: src/Object/Post.php:624
#: src/Object/Post.php:625
msgid "Notifier task is pending"
msgstr ""
#: src/Object/Post.php:625
#: src/Object/Post.php:626
msgid "Delivery to remote servers is pending"
msgstr ""
#: src/Object/Post.php:626
#: src/Object/Post.php:627
msgid "Delivery to remote servers is underway"
msgstr ""
#: src/Object/Post.php:627
#: src/Object/Post.php:628
msgid "Delivery to remote servers is mostly done"
msgstr ""
#: src/Object/Post.php:628
#: src/Object/Post.php:629
msgid "Delivery to remote servers is done"
msgstr ""
#: src/Object/Post.php:650
#: src/Object/Post.php:651
#, php-format
msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
#: src/Object/Post.php:651
#: src/Object/Post.php:652
msgid "Show more"
msgstr ""
#: src/Object/Post.php:652
#: src/Object/Post.php:653
msgid "Show fewer"
msgstr ""
#: src/Object/Post.php:689
#: src/Object/Post.php:690
#, php-format
msgid "Reshared by: %s"
msgstr ""
#: src/Object/Post.php:694
#: src/Object/Post.php:695
#, php-format
msgid "Viewed by: %s"
msgstr ""
#: src/Object/Post.php:699
#: src/Object/Post.php:700
#, php-format
msgid "Read by: %s"
msgstr ""
#: src/Object/Post.php:704
#: src/Object/Post.php:705
#, php-format
msgid "Liked by: %s"
msgstr ""
#: src/Object/Post.php:709
#: src/Object/Post.php:710
#, php-format
msgid "Disliked by: %s"
msgstr ""
#: src/Object/Post.php:714
#: src/Object/Post.php:715
#, php-format
msgid "Attended by: %s"
msgstr ""
#: src/Object/Post.php:719
#: src/Object/Post.php:720
#, php-format
msgid "Maybe attended by: %s"
msgstr ""
#: src/Object/Post.php:724
#: src/Object/Post.php:725
#, php-format
msgid "Not attended by: %s"
msgstr ""
#: src/Object/Post.php:729
#: src/Object/Post.php:730
#, php-format
msgid "Commented by: %s"
msgstr ""
#: src/Object/Post.php:734
#: src/Object/Post.php:735
#, php-format
msgid "Reacted with %s by: %s"
msgstr ""
#: src/Object/Post.php:757
#: src/Object/Post.php:758
#, php-format
msgid "Quote shared by: %s"
msgstr ""

View file

@ -71,7 +71,7 @@ window.onload = function(){
};
</script>
<script type="text/javascript">
const updateInterval = {{$update_interval}};
const updateContent = {{$update_content}};
const localUser = {{if $local_user}}{{$local_user}}{{else}}false{{/if}};
</script>
<script type="text/javascript" src="view/js/main.js?v={{$VERSION}}"></script>

View file

@ -18,8 +18,8 @@
{{/if}}
{{include file="field_input.tpl" field=$itemspage_mobile_network}}
{{include file="field_input.tpl" field=$ajaxint}}
{{include file="field_checkbox.tpl" field=$enable_smile}}
{{include file="field_checkbox.tpl" field=$update_content}}
{{include file="field_checkbox.tpl" field=$infinite_scroll}}
{{include file="field_checkbox.tpl" field=$enable_smart_threading}}
{{include file="field_checkbox.tpl" field=$enable_dislike}}

View file

@ -1813,6 +1813,10 @@ blockquote.shared_content {
font-weight: 500;
color: $font_color_darker;
}
.contact-info h1.media-heading {
font-size: 15px;
font-weight: 700;
}
.media .contact-info-comment {
display: table-cell;
}

View file

@ -112,7 +112,7 @@
<script type="text/javascript" src="view/asset/dompurify/dist/purify.min.js?v={{$VERSION}}">
</script>
<script type="text/javascript">
const updateInterval = {{$update_interval}};
const updateContent = {{$update_content}};
const localUser = {{if $local_user}}{{$local_user}}{{else}}false{{/if}};
</script>
<script type="text/javascript" src="view/js/main.js?v={{$VERSION}}"></script>

View file

@ -65,8 +65,8 @@
<div class="panel-body">
{{include file="field_input.tpl" field=$itemspage_network}}
{{include file="field_input.tpl" field=$itemspage_mobile_network}}
{{include file="field_input.tpl" field=$ajaxint}}
{{include file="field_checkbox.tpl" field=$enable_smile}}
{{include file="field_checkbox.tpl" field=$update_content}}
{{include file="field_checkbox.tpl" field=$infinite_scroll}}
{{include file="field_checkbox.tpl" field=$enable_smart_threading}}
{{include file="field_checkbox.tpl" field=$enable_dislike}}

View file

@ -187,7 +187,7 @@ as the value of $top_child_total (this is done at the end of this file)
{{* contact info header for smartphones *}}
<div class="contact-info-xs hidden-lg hidden-md"><!-- <= For smartphone (responsive) -->
<h2 class="media-heading">
<h1 class="media-heading">
<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card"><span>{{$item.name}}</span></a>
<p class="text-muted">
<small>
@ -214,7 +214,7 @@ as the value of $top_child_total (this is done at the end of this file)
{{/if}}
</small>
</p>
</h2>
</h1>
</div>
{{else}} {{* End of if $item.thread_level == 1 *}}
{{* contact info header for comments *}}