diff --git a/database.sql b/database.sql
index 74b7552c30..11fbd514e7 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2023.09-dev (Giant Rhubarb)
--- DB_UPDATE_VERSION 1524
+-- DB_UPDATE_VERSION 1529
-- ------------------------------------------
@@ -101,6 +101,19 @@ CREATE TABLE IF NOT EXISTS `user` (
FOREIGN KEY (`parent-uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='The local users';
+--
+-- TABLE user-gserver
+--
+CREATE TABLE IF NOT EXISTS `user-gserver` (
+ `uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
+ `gsid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Gserver id',
+ `ignored` boolean NOT NULL DEFAULT '0' COMMENT 'server accounts are ignored for the user',
+ PRIMARY KEY(`uid`,`gsid`),
+ INDEX `gsid` (`gsid`),
+ FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
+ FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
+) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User settings about remote servers';
+
--
-- TABLE item-uri
--
@@ -160,8 +173,8 @@ CREATE TABLE IF NOT EXISTS `contact` (
`archive` boolean NOT NULL DEFAULT '0' COMMENT '',
`unsearchable` boolean NOT NULL DEFAULT '0' COMMENT 'Contact prefers to not be searchable',
`sensitive` boolean NOT NULL DEFAULT '0' COMMENT 'Contact posts sensitive content',
- `baseurl` varbinary(383) DEFAULT '' COMMENT 'baseurl of the contact',
- `gsid` int unsigned COMMENT 'Global Server ID',
+ `baseurl` varbinary(383) DEFAULT '' COMMENT 'baseurl of the contact from the gserver record, can be missing',
+ `gsid` int unsigned COMMENT 'Global Server ID, can be missing',
`bd` date NOT NULL DEFAULT '0001-01-01' COMMENT '',
`reason` text COMMENT '',
`self` boolean NOT NULL DEFAULT '0' COMMENT '1 if the contact is the user him/her self',
@@ -1586,7 +1599,7 @@ CREATE TABLE IF NOT EXISTS `profile` (
`profile-name` varchar(255) COMMENT 'Deprecated',
`is-default` boolean COMMENT 'Deprecated',
`hide-friends` boolean NOT NULL DEFAULT '0' COMMENT 'Hide friend list from viewers of this profile',
- `name` varchar(255) NOT NULL DEFAULT '' COMMENT '',
+ `name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Unused in favor of user.username',
`pdesc` varchar(255) COMMENT 'Deprecated',
`dob` varchar(32) NOT NULL DEFAULT '0000-00-00' COMMENT 'Day of birth',
`address` varchar(255) NOT NULL DEFAULT '' COMMENT '',
@@ -2032,6 +2045,7 @@ CREATE VIEW `post-user-view` AS SELECT
`author`.`hidden` AS `author-hidden`,
`author`.`updated` AS `author-updated`,
`author`.`gsid` AS `author-gsid`,
+ `author`.`baseurl` AS `author-baseurl`,
`post-user`.`owner-id` AS `owner-id`,
`owner`.`uri-id` AS `owner-uri-id`,
`owner`.`url` AS `owner-link`,
@@ -2044,6 +2058,7 @@ CREATE VIEW `post-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
+ `owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`,
`post-user`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`,
@@ -2056,6 +2071,7 @@ CREATE VIEW `post-user-view` AS SELECT
`causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
+ `causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`,
@@ -2189,6 +2205,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`contact`.`pending` AS `contact-pending`,
`contact`.`rel` AS `contact-rel`,
`contact`.`uid` AS `contact-uid`,
+ `contact`.`gsid` AS `contact-gsid`,
`contact`.`contact-type` AS `contact-contact-type`,
IF (`post-user`.`network` IN ('apub', 'dfrn', 'dspr', 'stat'), true, `contact`.`writable`) AS `writable`,
`contact`.`self` AS `self`,
@@ -2224,6 +2241,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
+ `owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`,
`post-thread-user`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`,
@@ -2236,6 +2254,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
+ `causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`,
`post-delivery-data`.`postopts` AS `postopts`,
`post-delivery-data`.`inform` AS `inform`,
@@ -2391,6 +2410,7 @@ CREATE VIEW `post-view` AS SELECT
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
`owner`.`contact-type` AS `owner-contact-type`,
+ `owner`.`gsid` AS `owner-gsid`,
`post`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`,
`causer`.`url` AS `causer-link`,
@@ -2403,6 +2423,7 @@ CREATE VIEW `post-view` AS SELECT
`causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
`causer`.`contact-type` AS `causer-contact-type`,
+ `causer`.`gsid` AS `causer-gsid`,
`post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`,
`post-question`.`voters` AS `question-voters`,
@@ -2533,6 +2554,7 @@ CREATE VIEW `post-thread-view` AS SELECT
`owner`.`blocked` AS `owner-blocked`,
`owner`.`hidden` AS `owner-hidden`,
`owner`.`updated` AS `owner-updated`,
+ `owner`.`gsid` AS `owner-gsid`,
`owner`.`contact-type` AS `owner-contact-type`,
`post-thread`.`causer-id` AS `causer-id`,
`causer`.`uri-id` AS `causer-uri-id`,
@@ -2545,6 +2567,7 @@ CREATE VIEW `post-thread-view` AS SELECT
`causer`.`network` AS `causer-network`,
`causer`.`blocked` AS `causer-blocked`,
`causer`.`hidden` AS `causer-hidden`,
+ `causer`.`gsid` AS `causer-gsid`,
`causer`.`contact-type` AS `causer-contact-type`,
`post-question`.`id` AS `question-id`,
`post-question`.`multiple` AS `question-multiple`,
@@ -2666,18 +2689,16 @@ CREATE VIEW `network-item-view` AS SELECT
`post-user`.`contact-id` AS `contact-id`,
`ownercontact`.`contact-type` AS `contact-type`
FROM `post-user`
- INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
+ INNER JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id`
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id`
- LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `post-thread-user`.`uid` AND `author`.`cid` = `post-thread-user`.`author-id`
- LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `post-thread-user`.`uid` AND `owner`.`cid` = `post-thread-user`.`owner-id`
WHERE `post-user`.`visible` AND NOT `post-user`.`deleted`
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
- AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
- AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`);
+ AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = `post-thread-user`.`uid` AND `cid` IN (`authorcontact`.`id`, `ownercontact`.`id`) AND (`blocked` OR `ignored`))
+ AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`);
--
-- VIEW network-thread-view
@@ -2700,14 +2721,12 @@ CREATE VIEW `network-thread-view` AS SELECT
STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-thread-user`.`contact-id`
STRAIGHT_JOIN `contact` AS `authorcontact` ON `authorcontact`.`id` = `post-thread-user`.`author-id`
STRAIGHT_JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `post-thread-user`.`owner-id`
- LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `post-thread-user`.`uid` AND `author`.`cid` = `post-thread-user`.`author-id`
- LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `post-thread-user`.`uid` AND `owner`.`cid` = `post-thread-user`.`owner-id`
WHERE `post-user`.`visible` AND NOT `post-user`.`deleted`
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
AND (`post-thread-user`.`hidden` IS NULL OR NOT `post-thread-user`.`hidden`)
AND NOT `authorcontact`.`blocked` AND NOT `ownercontact`.`blocked`
- AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
- AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`);
+ AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = `post-thread-user`.`uid` AND `cid` IN (`authorcontact`.`id`, `ownercontact`.`id`) AND (`blocked` OR `ignored`))
+ AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = `post-thread-user`.`uid` AND `gsid` IN (`authorcontact`.`gsid`, `ownercontact`.`gsid`) AND `ignored`);
--
-- VIEW owner-view
diff --git a/doc/Update.md b/doc/Update.md
index d019d03b03..40de14082c 100644
--- a/doc/Update.md
+++ b/doc/Update.md
@@ -10,8 +10,10 @@ If you installed Friendica in the ``path/to/friendica`` folder:
1. Unpack the new Friendica archive in ``path/to/friendica_new``.
2. Copy the following items from ``path/to/friendica`` to ``path/to/friendica_new``:
* ``config/local.config.php``
- * ``proxy/``
-The following items only need to be copied if they are located inside your friendica path:
+ * ``proxy/``
+ * ``.htaccess`` if using Apache web server
+
+ The following items only need to be copied if they are located inside your friendica path:
* your storage folder as set in **Admin -> Site -> File Upload -> Storage base path**
* your item cache as set in **Admin -> Site -> Performance -> Path to item cache**
* your temp folder as set in **Admin -> Site -> Advanced -> Temp path**
diff --git a/doc/database.md b/doc/database.md
index b928591574..2848706570 100644
--- a/doc/database.md
+++ b/doc/database.md
@@ -86,6 +86,7 @@ Database Tables
| [tag](help/database/db_tag) | tags and mentions |
| [user](help/database/db_user) | The local users |
| [user-contact](help/database/db_user-contact) | User specific public contact data |
+| [user-gserver](help/database/db_user-gserver) | User settings about remote servers |
| [userd](help/database/db_userd) | Deleted usernames |
| [verb](help/database/db_verb) | Activity Verbs |
| [worker-ipc](help/database/db_worker-ipc) | Inter process communication between the frontend and the worker |
diff --git a/doc/database/db_contact.md b/doc/database/db_contact.md
index 496210067a..8221f279e2 100644
--- a/doc/database/db_contact.md
+++ b/doc/database/db_contact.md
@@ -51,8 +51,8 @@ Fields
| archive | | boolean | NO | | 0 | |
| unsearchable | Contact prefers to not be searchable | boolean | NO | | 0 | |
| sensitive | Contact posts sensitive content | boolean | NO | | 0 | |
-| baseurl | baseurl of the contact | varbinary(383) | YES | | | |
-| gsid | Global Server ID | int unsigned | YES | | NULL | |
+| baseurl | baseurl of the contact from the gserver record, can be missing | varbinary(383) | YES | | | |
+| gsid | Global Server ID, can be missing | int unsigned | YES | | NULL | |
| bd | | date | NO | | 0001-01-01 | |
| reason | | text | YES | | NULL | |
| self | 1 if the contact is the user him/her self | boolean | NO | | 0 | |
diff --git a/doc/database/db_profile.md b/doc/database/db_profile.md
index ec47b94ec6..c4a8b01709 100644
--- a/doc/database/db_profile.md
+++ b/doc/database/db_profile.md
@@ -13,7 +13,7 @@ Fields
| profile-name | Deprecated | varchar(255) | YES | | NULL | |
| is-default | Deprecated | boolean | YES | | NULL | |
| hide-friends | Hide friend list from viewers of this profile | boolean | NO | | 0 | |
-| name | | varchar(255) | NO | | | |
+| name | Unused in favor of user.username | varchar(255) | NO | | | |
| pdesc | Deprecated | varchar(255) | YES | | NULL | |
| dob | Day of birth | varchar(32) | NO | | 0000-00-00 | |
| address | | varchar(255) | NO | | | |
diff --git a/doc/database/db_user-gserver.md b/doc/database/db_user-gserver.md
new file mode 100644
index 0000000000..6cfbe34eb1
--- /dev/null
+++ b/doc/database/db_user-gserver.md
@@ -0,0 +1,31 @@
+Table user-gserver
+===========
+
+User settings about remote servers
+
+Fields
+------
+
+| Field | Description | Type | Null | Key | Default | Extra |
+| ------- | ---------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
+| uid | Owner User id | mediumint unsigned | NO | | 0 | |
+| gsid | Gserver id | int unsigned | NO | | 0 | |
+| ignored | server accounts are ignored for the user | boolean | NO | | 0 | |
+
+Indexes
+------------
+
+| Name | Fields |
+| ------- | --------- |
+| PRIMARY | uid, gsid |
+| gsid | gsid |
+
+Foreign Keys
+------------
+
+| Field | Target Table | Target Field |
+|-------|--------------|--------------|
+| uid | [user](help/database/db_user) | uid |
+| gsid | [gserver](help/database/db_gserver) | id |
+
+Return to [database documentation](help/database)
diff --git a/src/App/Page.php b/src/App/Page.php
index 96bb59425e..e369d482e8 100644
--- a/src/App/Page.php
+++ b/src/App/Page.php
@@ -245,10 +245,12 @@ class Page implements ArrayAccess
*/
$this->page['htmlhead'] = Renderer::replaceMacros($tpl, [
'$l10n' => [
- 'delitem' => $l10n->t('Delete this item?'),
- 'blockAuthor' => $l10n->t('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.'),
- 'ignoreAuthor' => $l10n->t('Ignore this author? You won\'t be able to see their posts and their notifications.'),
- 'collapseAuthor' => $l10n->t('Collapse this author\'s posts?'),
+ 'delitem' => $l10n->t('Delete this item?'),
+ 'blockAuthor' => $l10n->t("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."),
+ 'ignoreAuthor' => $l10n->t("Ignore this author? You won't be able to see their posts and their notifications."),
+ 'collapseAuthor' => $l10n->t("Collapse this author's posts?"),
+ 'ignoreServer' => $l10n->t("Ignore this author's server?"),
+ 'ignoreServerDesc' => $l10n->t("You won't see any content from this server including reshares in your Network page, the community pages and individual conversations."),
'likeError' => $l10n->t('Like not successful'),
'dislikeError' => $l10n->t('Dislike not successful'),
diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php
index 710422ee76..7edd4415db 100644
--- a/src/Content/Conversation.php
+++ b/src/Content/Conversation.php
@@ -38,6 +38,7 @@ use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Item as ItemModel;
use Friendica\Model\Post;
+use Friendica\Model\Post\Category;
use Friendica\Model\Tag;
use Friendica\Model\User;
use Friendica\Model\Verb;
@@ -45,6 +46,8 @@ use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Object\Post as PostObject;
use Friendica\Object\Thread;
use Friendica\Protocol\Activity;
+use Friendica\User\Settings\Entity\UserGServer;
+use Friendica\User\Settings\Repository;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
@@ -90,22 +93,25 @@ class Conversation
private $mode;
/** @var IHandleUserSessions */
private $session;
+ /** @var Repository\UserGServer */
+ private $userGServer;
- public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IManageConfigValues $config, IManagePersonalConfigValues $pConfig, App\Page $page, App\Mode $mode, App $app, IHandleUserSessions $session)
+ public function __construct(Repository\UserGServer $userGServer, LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IManageConfigValues $config, IManagePersonalConfigValues $pConfig, App\Page $page, App\Mode $mode, App $app, IHandleUserSessions $session)
{
- $this->activity = $activity;
- $this->item = $item;
- $this->config = $config;
- $this->mode = $mode;
- $this->baseURL = $baseURL;
- $this->profiler = $profiler;
- $this->logger = $logger;
- $this->l10n = $l10n;
- $this->args = $args;
- $this->pConfig = $pConfig;
- $this->page = $page;
- $this->app = $app;
- $this->session = $session;
+ $this->activity = $activity;
+ $this->item = $item;
+ $this->config = $config;
+ $this->mode = $mode;
+ $this->baseURL = $baseURL;
+ $this->profiler = $profiler;
+ $this->logger = $logger;
+ $this->l10n = $l10n;
+ $this->args = $args;
+ $this->pConfig = $pConfig;
+ $this->page = $page;
+ $this->app = $app;
+ $this->session = $session;
+ $this->userGServer = $userGServer;
}
/**
@@ -459,8 +465,14 @@ class Conversation
$live_update_div = '';
+ $userGservers = $this->userGServer->listIgnoredByUser($this->session->getLocalUserId());
+
+ $ignoredGsids = array_map(function (UserGServer $userGServer) {
+ return $userGServer->gsid;
+ }, $userGservers->getArrayCopy());
+
if ($mode === self::MODE_NETWORK) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
/*
* The special div is needed for liveUpdate to kick in for this page.
@@ -486,7 +498,7 @@ class Conversation
. "'; \r\n";
}
} elseif ($mode === self::MODE_PROFILE) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$tab = !empty($_GET['tab']) ? trim($_GET['tab']) : 'posts';
@@ -511,7 +523,7 @@ class Conversation
. "; var netargs = '?f='; \r\n";
}
} elseif ($mode === self::MODE_DISPLAY) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$live_update_div = '
' . "\r\n"
@@ -519,7 +531,7 @@ class Conversation
. "";
}
} elseif ($mode === self::MODE_COMMUNITY) {
- $items = $this->addChildren($items, true, $order, $uid, $mode);
+ $items = $this->addChildren($items, true, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$live_update_div = '' . "\r\n"
@@ -530,7 +542,7 @@ class Conversation
. "'; \r\n";
}
} elseif ($mode === self::MODE_CONTACTS) {
- $items = $this->addChildren($items, false, $order, $uid, $mode);
+ $items = $this->addChildren($items, false, $order, $uid, $mode, $ignoredGsids);
if (!$update) {
$live_update_div = '' . "\r\n"
@@ -743,7 +755,12 @@ class Conversation
$row['direction'] = ['direction' => 6, 'title' => $this->l10n->t('You are following %s.', $row['causer-name'] ?: $row['author-name'])];
break;
case ItemModel::PR_TAG:
- $row['direction'] = ['direction' => 4, 'title' => $this->l10n->t('You subscribed to one or more tags in this post.')];
+ $tags = Category::getArrayByURIId($row['uri-id'], $row['uid'], Category::SUBCRIPTION);
+ if (!empty($tags)) {
+ $row['direction'] = ['direction' => 4, 'title' => $this->l10n->t('You subscribed to %s.', implode(', ', $tags))];
+ } else {
+ $row['direction'] = ['direction' => 4, 'title' => $this->l10n->t('You subscribed to one or more tags in this post.')];
+ }
break;
case ItemModel::PR_ANNOUNCEMENT:
if (!empty($row['causer-id']) && $this->pConfig->get($this->session->getLocalUserId(), 'system', 'display_resharer')) {
@@ -812,13 +829,14 @@ class Conversation
*
* @param array $parents Parent items
* @param bool $block_authors
- * @param bool $order
+ * @param string $order Either "received" or "commented"
* @param int $uid
- * @param string $mode
+ * @param string $mode One of self::MODE_*
+ * @param array $ignoredGsids List of ids of servers ignored by the user
* @return array items with parents and comments
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @throws InternalServerErrorException
*/
- private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode): array
+ private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode, array $ignoredGsids = []): array
{
$this->profiler->startRecording('rendering');
if (count($parents) > 1) {
@@ -900,6 +918,13 @@ class Conversation
continue;
}
+ if (in_array($row['author-gsid'], $ignoredGsids)
+ || in_array($row['owner-gsid'], $ignoredGsids)
+ || in_array($row['causer-gsid'], $ignoredGsids)
+ ) {
+ continue;
+ }
+
if (($mode != self::MODE_CONTACTS) && !$row['origin']) {
$row['featured'] = false;
}
@@ -1462,6 +1487,7 @@ class Conversation
'received' => $item['received'],
'created_date' => $item['created'],
'uriid' => $item['uri-id'],
+ 'author_gsid' => $item['author-gsid'],
'network' => $item['network'],
'network_name' => ContactSelector::networkToName($item['author-network'], $item['author-link'], $item['network'], $item['author-gsid']),
'network_icon' => ContactSelector::networkToIcon($item['network'], $item['author-link'], $item['author-gsid']),
diff --git a/src/Content/Item.php b/src/Content/Item.php
index c25e5296f0..163db89aa4 100644
--- a/src/Content/Item.php
+++ b/src/Content/Item.php
@@ -34,15 +34,16 @@ use Friendica\Core\Protocol;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\DBA;
+use Friendica\DI;
use Friendica\Model\Attach;
+use Friendica\Model\Circle;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\FileTag;
-use Friendica\Model\Circle;
use Friendica\Model\Item as ItemModel;
use Friendica\Model\Photo;
-use Friendica\Model\Tag;
use Friendica\Model\Post;
+use Friendica\Model\Tag;
use Friendica\Model\User;
use Friendica\Network\HTTPException;
use Friendica\Object\EMail\ItemCCEMail;
@@ -54,6 +55,7 @@ use Friendica\Util\ParseUrl;
use Friendica\Util\Profiler;
use Friendica\Util\Proxy;
use Friendica\Util\XML;
+use GuzzleHttp\Psr7\Uri;
/**
* A content helper class for displaying items
@@ -367,7 +369,7 @@ class Item
{
$this->profiler->startRecording('rendering');
$sub_link = $contact_url = $pm_url = $status_link = '';
- $photos_link = $posts_link = $block_link = $ignore_link = '';
+ $photos_link = $posts_link = $block_link = $ignore_link = $collapse_link = $ignoreserver_link = '';
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $item['uid'] && $item['gravity'] == ItemModel::GRAVITY_PARENT && !$item['self'] && !$item['mention']) {
$sub_link = 'javascript:doFollowThread(' . $item['id'] . '); return false;';
@@ -407,6 +409,11 @@ class Item
$collapse_link = $item['self'] ? '' : $contact_url . '/collapse?t=' . $formSecurityToken;
}
+ $authorBaseUri = new Uri($item['author-baseurl'] ?? '');
+ if (!empty($item['author-gsid']) && $authorBaseUri->getHost() && !DI::baseUrl()->isLocalUrl($authorBaseUri)) {
+ $ignoreserver_link = 'settings/server/' . $item['author-gsid'] . '/ignore';
+ }
+
if ($cid && !$item['self']) {
$contact_url = 'contact/' . $cid;
$posts_link = $contact_url . '/posts';
@@ -427,7 +434,8 @@ class Item
$this->l10n->t('Send PM') => $pm_url,
$this->l10n->t('Block') => $block_link,
$this->l10n->t('Ignore') => $ignore_link,
- $this->l10n->t('Collapse') => $collapse_link
+ $this->l10n->t('Collapse') => $collapse_link,
+ $this->l10n->t("Ignore %s server", $authorBaseUri->getHost()) => $ignoreserver_link,
];
if (!empty($item['language'])) {
diff --git a/src/DI.php b/src/DI.php
index 34cf1c68d5..2d6eb6ede4 100644
--- a/src/DI.php
+++ b/src/DI.php
@@ -671,6 +671,15 @@ abstract class DI
return self::$dice->create(Security\Authentication::class);
}
+ //
+ // "User" namespace instances
+ //
+
+ public static function userGServer(): User\Settings\Repository\UserGServer
+ {
+ return self::$dice->create(User\Settings\Repository\UserGServer::class);
+ }
+
//
// "Util" namespace instances
//
diff --git a/src/Federation/Entity/GServer.php b/src/Federation/Entity/GServer.php
new file mode 100644
index 0000000000..0e331f4803
--- /dev/null
+++ b/src/Federation/Entity/GServer.php
@@ -0,0 +1,151 @@
+.
+ *
+ */
+
+namespace Friendica\Federation\Entity;
+
+use DateTimeImmutable;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * @property-read int $id
+ * @property-read string $url
+ * @property-read string $nurl
+ * @property-read string $version
+ * @property-read string $siteName
+ * @property-read string $info
+ * @property-read int $registerPolicy
+ * @property-read int $registeredUsers
+ * @property-read string $poco
+ * @property-read string $noscrape
+ * @property-read string $network
+ * @property-read string $platform
+ * @property-read int $relaySubscribe
+ * @property-read string $relayScope
+ * @property-read DateTimeImmutable $created
+ * @property-read ?DateTimeImmutable $lastPocoQuery
+ * @property-read ?DateTimeImmutable $lastContact
+ * @property-read ?DateTimeImmutable $lastFailure
+ * @property-read int $directoryType
+ * @property-read int $detectionMethod
+ * @property-read bool $failed
+ * @property-read DateTimeImmutable $nextContact
+ * @property-read int $protocol
+ * @property-read int $activeWeekUsers
+ * @property-read int $activeMonthUsers
+ * @property-read int $activeHalfyearUsers
+ * @property-read int $localPosts
+ * @property-read int $localComments
+ * @property-read bool $blocked
+ */
+class GServer extends \Friendica\BaseEntity
+{
+ /** @var ?int */
+ protected $id;
+ /** @var UriInterface */
+ protected $url;
+ /** @var UriInterface */
+ protected $nurl;
+ /** @var string */
+ protected $version;
+ /** @var string */
+ protected $siteName;
+ /** @var string */
+ protected $info;
+ /** @var int One of Module\Register::* constant values */
+ protected $registerPolicy;
+ /** @var int */
+ protected $registeredUsers;
+ /** @var ?UriInterface */
+ protected $poco;
+ /** @var ?UriInterface */
+ protected $noscrape;
+ /** @var string One of the Protocol::* constant values */
+ protected $network;
+ /** @var string */
+ protected $platform;
+ /** @var bool */
+ protected $relaySubscribe;
+ /** @var string */
+ protected $relayScope;
+ /** @var DateTimeImmutable */
+ protected $created;
+ /** @var DateTimeImmutable */
+ protected $lastPocoQuery;
+ /** @var DateTimeImmutable */
+ protected $lastContact;
+ /** @var DateTimeImmutable */
+ protected $lastFailure;
+ /** @var int One of Model\Gserver::DT_* constant values */
+ protected $directoryType;
+ /** @var ?int One of Model\Gserver::DETECT_* constant values */
+ protected $detectionMethod;
+ /** @var bool */
+ protected $failed;
+ /** @var DateTimeImmutable */
+ protected $nextContact;
+ /** @var ?int One of Model\Post\DeliveryData::* constant values */
+ protected $protocol;
+ /** @var ?int */
+ protected $activeWeekUsers;
+ /** @var ?int */
+ protected $activeMonthUsers;
+ /** @var ?int */
+ protected $activeHalfyearUsers;
+ /** @var ?int */
+ protected $localPosts;
+ /** @var ?int */
+ protected $localComments;
+ /** @var bool */
+ protected $blocked;
+
+ public function __construct(UriInterface $url, UriInterface $nurl, string $version, string $siteName, string $info, int $registerPolicy, int $registeredUsers, ?UriInterface $poco, ?UriInterface $noscrape, string $network, string $platform, bool $relaySubscribe, string $relayScope, DateTimeImmutable $created, ?DateTimeImmutable $lastPocoQuery, ?DateTimeImmutable $lastContact, ?DateTimeImmutable $lastFailure, int $directoryType, ?int $detectionMethod, bool $failed, ?DateTimeImmutable $nextContact, ?int $protocol, ?int $activeWeekUsers, ?int $activeMonthUsers, ?int $activeHalfyearUsers, ?int $localPosts, ?int $localComments, bool $blocked, ?int $id = null)
+ {
+ $this->url = $url;
+ $this->nurl = $nurl;
+ $this->version = $version;
+ $this->siteName = $siteName;
+ $this->info = $info;
+ $this->registerPolicy = $registerPolicy;
+ $this->registeredUsers = $registeredUsers;
+ $this->poco = $poco;
+ $this->noscrape = $noscrape;
+ $this->network = $network;
+ $this->platform = $platform;
+ $this->relaySubscribe = $relaySubscribe;
+ $this->relayScope = $relayScope;
+ $this->created = $created;
+ $this->lastPocoQuery = $lastPocoQuery;
+ $this->lastContact = $lastContact;
+ $this->lastFailure = $lastFailure;
+ $this->directoryType = $directoryType;
+ $this->detectionMethod = $detectionMethod;
+ $this->failed = $failed;
+ $this->nextContact = $nextContact;
+ $this->protocol = $protocol;
+ $this->activeWeekUsers = $activeWeekUsers;
+ $this->activeMonthUsers = $activeMonthUsers;
+ $this->activeHalfyearUsers = $activeHalfyearUsers;
+ $this->localPosts = $localPosts;
+ $this->localComments = $localComments;
+ $this->blocked = $blocked;
+ $this->id = $id;
+ }
+}
diff --git a/src/Federation/Factory/GServer.php b/src/Federation/Factory/GServer.php
new file mode 100644
index 0000000000..681cad7af4
--- /dev/null
+++ b/src/Federation/Factory/GServer.php
@@ -0,0 +1,68 @@
+.
+ *
+ */
+
+namespace Friendica\Federation\Factory;
+
+use Friendica\Capabilities\ICanCreateFromTableRow;
+use Friendica\Database\DBA;
+use Friendica\Federation\Entity;
+use GuzzleHttp\Psr7\Uri;
+
+class GServer extends \Friendica\BaseFactory implements ICanCreateFromTableRow
+{
+ /**
+ * @inheritDoc
+ */
+ public function createFromTableRow(array $row): Entity\GServer
+ {
+ return new Entity\GServer(
+ new Uri($row['url']),
+ new Uri($row['nurl']),
+ $row['version'],
+ $row['site_name'],
+ $row['info'] ?? '',
+ $row['register_policy'],
+ $row['registered-users'],
+ $row['poco'] ? new Uri($row['poco']) : null,
+ $row['noscrape'] ? new Uri($row['noscrape']) : null,
+ $row['network'],
+ $row['platform'],
+ $row['relay-subscribe'],
+ $row['relay-scope'],
+ new \DateTimeImmutable($row['created']),
+ $row['last_poco_query'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_poco_query']) : null,
+ $row['last_contact'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_contact']) : null,
+ $row['last_failure'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['last_failure']) : null,
+ $row['directory-type'],
+ $row['detection-method'],
+ $row['failed'],
+ $row['next_contact'] !== DBA::NULL_DATETIME ? new \DateTimeImmutable($row['next_contact']) : null,
+ $row['protocol'],
+ $row['active-week-users'],
+ $row['active-month-users'],
+ $row['active-halfyear-users'],
+ $row['local-posts'],
+ $row['local-comments'],
+ $row['blocked'],
+ $row['id'],
+ );
+ }
+}
diff --git a/src/Federation/Repository/GServer.php b/src/Federation/Repository/GServer.php
new file mode 100644
index 0000000000..47a9244f6a
--- /dev/null
+++ b/src/Federation/Repository/GServer.php
@@ -0,0 +1,47 @@
+.
+ *
+ */
+
+namespace Friendica\Federation\Repository;
+
+use Friendica\Database\Database;
+use Friendica\Federation\Factory;
+use Friendica\Federation\Entity;
+use Psr\Log\LoggerInterface;
+
+class GServer extends \Friendica\BaseRepository
+{
+ protected static $table_name = 'gserver';
+
+ public function __construct(Database $database, LoggerInterface $logger, Factory\GServer $factory)
+ {
+ parent::__construct($database, $logger, $factory);
+ }
+
+ /**
+ * @param int $gsid
+ * @return Entity\GServer
+ * @throws \Friendica\Network\HTTPException\NotFoundException
+ */
+ public function selectOneById(int $gsid): Entity\GServer
+ {
+ return $this->_selectOne(['id' => $gsid]);
+ }
+}
diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index a18d6b9d0f..dcb7ff99c4 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -793,10 +793,10 @@ class Contact
/**
* Updates the self-contact for the provided user id
*
- * @param int $uid
- * @param bool $update_avatar Force the avatar update
+ * @param int $uid
+ * @param bool $update_avatar Force the avatar update
* @return bool "true" if updated
- * @throws HTTPException\InternalServerErrorException
+ * @throws \Exception
*/
public static function updateSelfFromUserID(int $uid, bool $update_avatar = false): bool
{
diff --git a/src/Model/Item.php b/src/Model/Item.php
index a2304056d3..9eddf885ca 100644
--- a/src/Model/Item.php
+++ b/src/Model/Item.php
@@ -32,6 +32,7 @@ use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
+use Friendica\Model\Post\Category;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
@@ -95,9 +96,9 @@ class Item
'wall', 'private', 'starred', 'origin', 'parent-origin', 'title', 'body', 'language',
'content-warning', 'location', 'coord', 'app', 'rendered-hash', 'rendered-html', 'object',
'quote-uri', 'quote-uri-id', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'mention', 'global',
- 'author-id', 'author-link', 'author-alias', 'author-name', 'author-avatar', 'author-network', 'author-updated', 'author-gsid', 'author-addr', 'author-uri-id',
- 'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated',
- 'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network',
+ 'author-id', 'author-link', 'author-alias', 'author-name', 'author-avatar', 'author-network', 'author-updated', 'author-gsid', 'author-baseurl', 'author-addr', 'author-uri-id',
+ 'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-gsid',
+ 'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-gsid',
'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar',
'writable', 'self', 'cid', 'alias',
'event-created', 'event-edited', 'event-start', 'event-finish',
@@ -1509,10 +1510,13 @@ class Item
return;
}
- $uids = Tag::getUIDListByURIId($item['uri-id']);
- foreach ($uids as $uid) {
+ foreach (Tag::getUIDListByURIId($item['uri-id']) as $uid => $tags) {
$stored = self::storeForUserByUriId($item['uri-id'], $uid, ['post-reason' => self::PR_TAG]);
Logger::info('Stored item for users', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'stored' => $stored]);
+ foreach ($tags as $tag) {
+ $stored = Category::storeFileByURIId($item['uri-id'], $uid, Category::SUBCRIPTION, $tag);
+ Logger::debug('Stored tag subscription for user', ['uri-id' => $item['uri-id'], 'uid' => $uid, $tag, 'stored' => $stored]);
+ }
}
}
diff --git a/src/Model/Post.php b/src/Model/Post.php
index 770ab08317..6f855867f6 100644
--- a/src/Model/Post.php
+++ b/src/Model/Post.php
@@ -453,12 +453,10 @@ class Post
AND (NOT `causer-blocked` OR `causer-id` = ? OR `causer-id` IS NULL) AND NOT `contact-blocked`
AND ((NOT `contact-readonly` AND NOT `contact-pending` AND (`contact-rel` IN (?, ?)))
OR `self` OR `contact-uid` = ?)
- AND NOT `" . $view . "`.`uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `uid` = ? AND `hidden`)
- AND NOT `author-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `blocked` AND `cid` = `author-id`)
- AND NOT `owner-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `blocked` AND `cid` = `owner-id`)
- AND NOT `author-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `ignored` AND `cid` = `author-id`)
- AND NOT `owner-id` IN (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `ignored` AND `cid` = `owner-id`)",
- 0, Contact::SHARING, Contact::FRIEND, 0, $uid, $uid, $uid, $uid, $uid]);
+ AND NOT EXISTS(SELECT `uri-id` FROM `post-user` WHERE `uid` = ? AND `uri-id` = " . DBA::quoteIdentifier($view) . ".`uri-id` AND `hidden`)
+ AND NOT EXISTS(SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` IN (`author-id`, `owner-id`) AND (`blocked` OR `ignored`))
+ AND NOT EXISTS(SELECT `gsid` FROM `user-gserver` WHERE `uid` = ? AND `gsid` IN (`author-gsid`, `owner-gsid`, `causer-gsid`) AND `ignored`)",
+ 0, Contact::SHARING, Contact::FRIEND, 0, $uid, $uid, $uid]);
$select_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], $selected));
diff --git a/src/Model/Post/Category.php b/src/Model/Post/Category.php
index 2c35a40ad4..c242e8ffd8 100644
--- a/src/Model/Post/Category.php
+++ b/src/Model/Post/Category.php
@@ -33,9 +33,10 @@ use Friendica\Model\Tag;
*/
class Category
{
- const UNKNOWN = 0;
- const CATEGORY = 3;
- const FILE = 5;
+ const UNKNOWN = 0;
+ const CATEGORY = 3;
+ const FILE = 5;
+ const SUBCRIPTION = 10;
/**
* Delete all categories and files from a given uri-id and user
@@ -80,7 +81,7 @@ class Category
{
$file_text = '';
- $tags = DBA::selectToArray('category-view', ['type', 'name'], ['uri-id' => $uri_id, 'uid' => $uid]);
+ $tags = DBA::selectToArray('category-view', ['type', 'name'], ['uri-id' => $uri_id, 'uid' => $uid, 'type' => [Category::FILE, Category::CATEGORY]]);
foreach ($tags as $tag) {
if ($tag['type'] == self::CATEGORY) {
$file_text .= '<' . $tag['name'] . '>';
@@ -177,12 +178,7 @@ class Category
continue;
}
- DBA::replace('post-category', [
- 'uri-id' => $uri_id,
- 'uid' => $uid,
- 'type' => self::FILE,
- 'tid' => $tagid
- ]);
+ self::storeByURIId($uri_id, $uid, self::FILE, $tagid);
}
}
@@ -193,13 +189,18 @@ class Category
}
}
- public static function storeFileByURIId(int $uri_id, int $uid, int $type, string $file)
+ public static function storeFileByURIId(int $uri_id, int $uid, int $type, string $file, string $url = ''): bool
{
- $tagid = Tag::getID($file);
+ $tagid = Tag::getID($file, $url);
if (empty($tagid)) {
return false;
}
+ return self::storeByURIId($uri_id, $uid, $type, $tagid);
+ }
+
+ private static function storeByURIId(int $uri_id, int $uid, int $type, int $tagid): bool
+ {
return DBA::replace('post-category', [
'uri-id' => $uri_id,
'uid' => $uid,
diff --git a/src/Model/Post/UserNotification.php b/src/Model/Post/UserNotification.php
index 012a49dbf5..726e82d7e0 100644
--- a/src/Model/Post/UserNotification.php
+++ b/src/Model/Post/UserNotification.php
@@ -133,14 +133,14 @@ class UserNotification
public static function setNotification(int $uri_id, int $uid)
{
$fields = ['id', 'uri-id', 'parent-uri-id', 'uid', 'body', 'parent', 'gravity', 'vid', 'gravity',
- 'contact-id', 'author-id', 'owner-id', 'causer-id',
+ 'contact-id', 'author-id', 'author-gsid', 'owner-id', 'owner-gsid', 'causer-id', 'causer-gsid',
'private', 'thr-parent', 'thr-parent-id', 'parent-uri-id', 'parent-uri', 'verb'];
$item = Post::selectFirst($fields, ['uri-id' => $uri_id, 'uid' => $uid, 'origin' => false]);
if (!DBA::isResult($item)) {
return;
}
- $parent = Post::selectFirstPost(['author-id', 'owner-id', 'causer-id'], ['uri-id' => $item['parent-uri-id']]);
+ $parent = Post::selectFirstPost(['author-id', 'author-gsid', 'owner-id', 'owner-gsid', 'causer-id', 'causer-gsid',], ['uri-id' => $item['parent-uri-id']]);
if (!DBA::isResult($parent)) {
return;
}
@@ -195,6 +195,13 @@ class UserNotification
}
}
+ foreach (array_unique([$parent['author-gsid'], $parent['owner-gsid'], $parent['causer-gsid'], $item['author-gsid'], $item['owner-gsid'], $item['causer-gsid']]) as $gsid) {
+ if ($gsid && DI::userGServer()->isIgnoredByUser($uid, $gsid)) {
+ Logger::debug('Server is ignored by user', ['uid' => $uid, 'gsid' => $gsid, 'uri-id' => $item['uri-id']]);
+ return;
+ }
+ }
+
$user = User::getById($uid, ['account-type', 'account_removed', 'account_expired']);
if (in_array($user['account-type'], [User::ACCOUNT_TYPE_COMMUNITY, User::ACCOUNT_TYPE_RELAY])) {
return;
diff --git a/src/Model/Profile.php b/src/Model/Profile.php
index 0602df10aa..c1a350673e 100644
--- a/src/Model/Profile.php
+++ b/src/Model/Profile.php
@@ -37,6 +37,7 @@ use Friendica\DI;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
use Friendica\Network\HTTPException;
+use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora;
use Friendica\Security\PermissionSet\Entity\PermissionSet;
@@ -93,10 +94,11 @@ class Profile
/**
* Update a profile entry and distribute the changes if needed
*
- * @param array $fields Profile fields to update
- * @param integer $uid User id
+ * @param array $fields Profile fields to update
+ * @param integer $uid User id
*
* @return boolean Whether update was successful
+ * @throws \Exception
*/
public static function update(array $fields, int $uid): bool
{
@@ -116,10 +118,6 @@ class Profile
return false;
}
- if ($old_owner['name'] != $owner['name']) {
- User::update(['username' => $owner['name']], $uid);
- }
-
$profile_fields = ['postal-code', 'dob', 'prv_keywords', 'homepage'];
foreach ($profile_fields as $field) {
if ($old_owner[$field] != $owner[$field]) {
diff --git a/src/Model/Tag.php b/src/Model/Tag.php
index 1645dc1255..04f3f1627e 100644
--- a/src/Model/Tag.php
+++ b/src/Model/Tag.php
@@ -828,12 +828,13 @@ class Tag
public static function getUIDListByURIId(int $uriId): array
{
$uids = [];
- $tags = self::getByURIId($uriId, [self::HASHTAG]);
- foreach ($tags as $tag) {
- $uids = array_merge($uids, self::getUIDListByTag(self::TAG_CHARACTER[self::HASHTAG] . $tag['name']));
+ foreach (self::getByURIId($uriId, [self::HASHTAG]) as $tag) {
+ foreach (self::getUIDListByTag(self::TAG_CHARACTER[self::HASHTAG] . $tag['name']) as $uid) {
+ $uids[$uid][] = $tag['name'];
+ }
}
- return array_unique($uids);
+ return $uids;
}
}
diff --git a/src/Model/User.php b/src/Model/User.php
index 18da3e9560..af7a81a15d 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -37,6 +37,7 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Module;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
+use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Network\HTTPException;
use Friendica\Object\Image;
@@ -1328,33 +1329,18 @@ class User
/**
* Update a user entry and distribute the changes if needed
*
- * @param array $fields
+ * @param array $fields
* @param integer $uid
* @return boolean
+ * @throws Exception
*/
public static function update(array $fields, int $uid): bool
{
- $old_owner = self::getOwnerDataById($uid);
- if (empty($old_owner)) {
- return false;
- }
-
if (!DBA::update('user', $fields, ['uid' => $uid])) {
return false;
}
- $update = Contact::updateSelfFromUserID($uid);
-
- $owner = self::getOwnerDataById($uid);
- if (empty($owner)) {
- return false;
- }
-
- if ($old_owner['name'] != $owner['name']) {
- Profile::update(['name' => $owner['name']], $uid);
- }
-
- if ($update) {
+ if (Contact::updateSelfFromUserID($uid)) {
Profile::publishUpdate($uid);
}
diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php
index e405f78081..29f0343517 100644
--- a/src/Moderation/Repository/Report.php
+++ b/src/Moderation/Repository/Report.php
@@ -48,7 +48,7 @@ final class Report extends \Friendica\BaseRepository
$this->factory = $factory;
$this->postFactory = $postFactory;
- $this->ruleFactory = $postFactory;
+ $this->ruleFactory = $ruleFactory;
}
public function selectOneById(int $lastInsertId): \Friendica\Moderation\Entity\Report
diff --git a/src/Module/BaseSettings.php b/src/Module/BaseSettings.php
index a1e88e9a10..4b26a0f262 100644
--- a/src/Module/BaseSettings.php
+++ b/src/Module/BaseSettings.php
@@ -151,6 +151,13 @@ class BaseSettings extends BaseModule
'accesskey' => 'b',
];
+ $tabs[] = [
+ 'label' => $this->t('Remote servers'),
+ 'url' => 'settings/server',
+ 'selected' => static::class == Settings\Server\Index::class ? 'active' : '',
+ 'accesskey' => 's',
+ ];
+
$tabs[] = [
'label' => $this->t('Export personal data'),
'url' => 'settings/userexport',
diff --git a/src/Module/Contact/Profile.php b/src/Module/Contact/Profile.php
index 090f7cd86a..d6f5a90ce8 100644
--- a/src/Module/Contact/Profile.php
+++ b/src/Module/Contact/Profile.php
@@ -23,8 +23,7 @@ namespace Friendica\Module\Contact;
use Friendica\App;
use Friendica\BaseModule;
-use Friendica\Contact\LocalRelationship\Entity;
-use Friendica\Contact\LocalRelationship\Repository;
+use Friendica\Contact\LocalRelationship;
use Friendica\Content\ContactSelector;
use Friendica\Content\Nav;
use Friendica\Content\Text\BBCode;
@@ -34,13 +33,16 @@ use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
+use Friendica\Core\Session\Capability\IHandleUserSessions;
+use Friendica\Database\Database;
use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Contact;
use Friendica\Model\Circle;
+use Friendica\Model\Contact;
use Friendica\Module;
use Friendica\Module\Response;
+use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException;
+use Friendica\User\Settings;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
@@ -50,31 +52,37 @@ use Psr\Log\LoggerInterface;
*/
class Profile extends BaseModule
{
- /**
- * @var Repository\LocalRelationship
- */
+ /** @var LocalRelationship\Repository\LocalRelationship */
private $localRelationship;
- /**
- * @var App\Page
- */
+ /** @var App\Page */
private $page;
- /**
- * @var IManageConfigValues
- */
+ /** @var IManageConfigValues */
private $config;
+ /** @var IHandleUserSessions */
+ private $session;
+ /** @var SystemMessages */
+ private $systemMessages;
+ /** @var Database */
+ private $db;
+ /** @var Settings\Repository\UserGServer */
+ private $userGServer;
- public function __construct(L10n $l10n, Repository\LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, IManageConfigValues $config, array $server, array $parameters = [])
+ public function __construct(Settings\Repository\UserGServer $userGServer, Database $db, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, LocalRelationship\Repository\LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, IManageConfigValues $config, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->localRelationship = $localRelationship;
$this->page = $page;
$this->config = $config;
+ $this->session = $session;
+ $this->systemMessages = $systemMessages;
+ $this->db = $db;
+ $this->userGServer = $userGServer;
}
protected function post(array $request = [])
{
- if (!DI::userSession()->getLocalUserId()) {
+ if (!$this->session->getLocalUserId()) {
return;
}
@@ -82,8 +90,8 @@ class Profile extends BaseModule
// Backward compatibility: The update still needs a user-specific contact ID
// Change to user-contact table check by version 2022.03
- $cdata = Contact::getPublicAndUserContactID($contact_id, DI::userSession()->getLocalUserId());
- if (empty($cdata['user']) || !DBA::exists('contact', ['id' => $cdata['user'], 'deleted' => false])) {
+ $cdata = Contact::getPublicAndUserContactID($contact_id, $this->session->getLocalUserId());
+ if (empty($cdata['user']) || !$this->db->exists('contact', ['id' => $cdata['user'], 'deleted' => false])) {
return;
}
@@ -124,35 +132,35 @@ class Profile extends BaseModule
$fields['info'] = $_POST['info'];
}
- if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => DI::userSession()->getLocalUserId()])) {
- DI::sysmsg()->addNotice($this->t('Failed to update contact record.'));
+ if (!Contact::update($fields, ['id' => $cdata['user'], 'uid' => $this->session->getLocalUserId()])) {
+ $this->systemMessages->addNotice($this->t('Failed to update contact record.'));
}
}
protected function content(array $request = []): string
{
- if (!DI::userSession()->getLocalUserId()) {
+ if (!$this->session->getLocalUserId()) {
return Module\Security\Login::form($_SERVER['REQUEST_URI']);
}
// Backward compatibility: Ensure to use the public contact when the user contact is provided
// Remove by version 2022.03
- $data = Contact::getPublicAndUserContactID(intval($this->parameters['id']), DI::userSession()->getLocalUserId());
+ $data = Contact::getPublicAndUserContactID(intval($this->parameters['id']), $this->session->getLocalUserId());
if (empty($data)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
}
$contact = Contact::getById($data['public']);
- if (!DBA::isResult($contact)) {
+ if (!$this->db->isResult($contact)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
}
// Don't display contacts that are about to be deleted
- if (DBA::isResult($contact) && (!empty($contact['deleted']) || !empty($contact['network']) && $contact['network'] == Protocol::PHANTOM)) {
+ if ($this->db->isResult($contact) && (!empty($contact['deleted']) || !empty($contact['network']) && $contact['network'] == Protocol::PHANTOM)) {
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
}
- $localRelationship = $this->localRelationship->getForUserContact(DI::userSession()->getLocalUserId(), $contact['id']);
+ $localRelationship = $this->localRelationship->getForUserContact($this->session->getLocalUserId(), $contact['id']);
if ($localRelationship->rel === Contact::SELF) {
$this->baseUrl->redirect('profile/' . $contact['nick'] . '/profile');
@@ -167,55 +175,55 @@ class Profile extends BaseModule
}
if ($cmd === 'updateprofile') {
- self::updateContactFromProbe($contact['id']);
+ $this->updateContactFromProbe($contact['id']);
}
if ($cmd === 'block') {
if ($localRelationship->blocked) {
// @TODO Backward compatibility, replace with $localRelationship->unblock()
- Contact\User::setBlocked($contact['id'], DI::userSession()->getLocalUserId(), false);
+ Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), false);
$message = $this->t('Contact has been unblocked');
} else {
// @TODO Backward compatibility, replace with $localRelationship->block()
- Contact\User::setBlocked($contact['id'], DI::userSession()->getLocalUserId(), true);
+ Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), true);
$message = $this->t('Contact has been blocked');
}
// @TODO: add $this->localRelationship->save($localRelationship);
- DI::sysmsg()->addInfo($message);
+ $this->systemMessages->addInfo($message);
}
if ($cmd === 'ignore') {
if ($localRelationship->ignored) {
// @TODO Backward compatibility, replace with $localRelationship->unblock()
- Contact\User::setIgnored($contact['id'], DI::userSession()->getLocalUserId(), false);
+ Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), false);
$message = $this->t('Contact has been unignored');
} else {
// @TODO Backward compatibility, replace with $localRelationship->block()
- Contact\User::setIgnored($contact['id'], DI::userSession()->getLocalUserId(), true);
+ Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), true);
$message = $this->t('Contact has been ignored');
}
// @TODO: add $this->localRelationship->save($localRelationship);
- DI::sysmsg()->addInfo($message);
+ $this->systemMessages->addInfo($message);
}
if ($cmd === 'collapse') {
if ($localRelationship->collapsed) {
// @TODO Backward compatibility, replace with $localRelationship->unblock()
- Contact\User::setCollapsed($contact['id'], DI::userSession()->getLocalUserId(), false);
+ Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), false);
$message = $this->t('Contact has been uncollapsed');
} else {
// @TODO Backward compatibility, replace with $localRelationship->block()
- Contact\User::setCollapsed($contact['id'], DI::userSession()->getLocalUserId(), true);
+ Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), true);
$message = $this->t('Contact has been collapsed');
}
// @TODO: add $this->localRelationship->save($localRelationship);
- DI::sysmsg()->addInfo($message);
+ $this->systemMessages->addInfo($message);
}
$this->baseUrl->redirect('contact/' . $contact['id']);
@@ -259,6 +267,17 @@ class Profile extends BaseModule
$insecure = $this->t('Private communications are not available for this contact.');
+ // @TODO: Figure out why gsid can be empty
+ if (empty($contact['gsid'])) {
+ $this->logger->notice('Empty gsid for contact', ['contact' => $contact]);
+ }
+
+ $serverIgnored =
+ $contact['gsid'] &&
+ $this->userGServer->isIgnoredByUser($this->session->getLocalUserId(), $contact['gsid']) ?
+ $this->t('This contact is on a server you ignored.')
+ : '';
+
$last_update = (($contact['last-update'] <= DBA::NULL_DATETIME) ? $this->t('Never') : DateTimeFormat::local($contact['last-update'], 'D, j M Y, g:i A'));
if ($contact['last-update'] > DBA::NULL_DATETIME) {
@@ -363,6 +382,8 @@ class Profile extends BaseModule
'$collapsed' => $localRelationship->collapsed ? $this->t('Currently collapsed') : '',
'$archived' => ($contact['archive'] ? $this->t('Currently archived') : ''),
'$insecure' => (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::MAIL, Protocol::DIASPORA]) ? '' : $insecure),
+ '$serverIgnored' => $serverIgnored,
+ '$manageServers' => $this->t('Manage remote servers'),
'$cinfo' => ['info', '', $localRelationship->info, ''],
'$hidden' => ['hidden', $this->t('Hide this contact from others'), $localRelationship->hidden, $this->t('Replies/likes to your public posts may still be visible')],
'$notify_new_posts' => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')],
@@ -413,11 +434,11 @@ class Profile extends BaseModule
* This includes actions like e.g. 'block', 'hide', 'delete' and others
*
* @param array $contact Public contact row
- * @param Entity\LocalRelationship $localRelationship
+ * @param LocalRelationship\Entity\LocalRelationship $localRelationship
* @return array with contact related actions
* @throws HTTPException\InternalServerErrorException
*/
- private function getContactActions(array $contact, Entity\LocalRelationship $localRelationship): array
+ private function getContactActions(array $contact, LocalRelationship\Entity\LocalRelationship $localRelationship): array
{
$poll_enabled = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]);
$contact_actions = [];
@@ -518,10 +539,9 @@ class Profile extends BaseModule
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- private static function updateContactFromProbe(int $contact_id)
+ private function updateContactFromProbe(int $contact_id)
{
- $contact = DBA::selectFirst('contact', ['url'], ['id' => $contact_id, 'uid' => [0, DI::userSession()->getLocalUserId()], 'deleted' => false]);
- if (!DBA::isResult($contact)) {
+ if (!$this->db->exists('contact', ['id' => $contact_id, 'uid' => [0, $this->session->getLocalUserId()], 'deleted' => false])) {
return;
}
diff --git a/src/Module/Conversation/Community.php b/src/Module/Conversation/Community.php
index 7525ba1c16..3c3bbb8a83 100644
--- a/src/Module/Conversation/Community.php
+++ b/src/Module/Conversation/Community.php
@@ -356,7 +356,7 @@ class Community extends BaseModule
}
}
- $r = Post::selectThreadForUser(0, ['uri-id', 'commented', 'author-link'], $condition, $params);
+ $r = Post::selectThreadForUser(DI::userSession()->getLocalUserId() ?: 0, ['uri-id', 'commented', 'author-link'], $condition, $params);
$items = Post::toArray($r);
if (empty($items)) {
diff --git a/src/Module/Item/Display.php b/src/Module/Item/Display.php
index 21046628fe..714598a8e6 100644
--- a/src/Module/Item/Display.php
+++ b/src/Module/Item/Display.php
@@ -133,7 +133,9 @@ class Display extends BaseModule
}
if (empty($item)) {
- throw new HTTPException\NotFoundException($this->t('The requested item doesn\'t exist or has been deleted.'));
+ $this->page['aside'] = '';
+ $displayNotFound = new DisplayNotFound($this->l10n, $this->baseUrl, $this->args, $this->logger, $this->profiler, $this->response, $this->server, $this->parameters);
+ return $displayNotFound->content();
}
if ($item['gravity'] != Item::GRAVITY_PARENT) {
diff --git a/src/Module/RobotsTxt.php b/src/Module/RobotsTxt.php
index 415a8ab472..a084c1f4a6 100644
--- a/src/Module/RobotsTxt.php
+++ b/src/Module/RobotsTxt.php
@@ -38,6 +38,8 @@ class RobotsTxt extends BaseModule
'/search',
'/help',
'/proxy',
+ '/photo',
+ '/avatar',
];
header('Content-Type: text/plain');
@@ -50,6 +52,10 @@ class RobotsTxt extends BaseModule
echo 'User-agent: ChatGPT-User' . PHP_EOL;
echo 'Disallow: /' . PHP_EOL;
+ echo PHP_EOL;
+ echo 'User-agent: GPTBot' . PHP_EOL;
+ echo 'Disallow: /' . PHP_EOL;
+
System::exit();
}
}
diff --git a/src/Module/Settings/Account.php b/src/Module/Settings/Account.php
index 1039b92e2e..8ff00addb5 100644
--- a/src/Module/Settings/Account.php
+++ b/src/Module/Settings/Account.php
@@ -573,7 +573,7 @@ class Account extends BaseSettings
'$delete_openid' => ['delete_openid', DI::l10n()->t('Delete OpenID URL'), false, ''],
'$h_basic' => DI::l10n()->t('Basic Settings'),
- '$username' => ['username', DI::l10n()->t('Full Name:'), $username, '', false, 'autocomplete="off"'],
+ '$username' => ['username', DI::l10n()->t('Display name:'), $username, '', false, 'autocomplete="off"'],
'$email' => ['email', DI::l10n()->t('Email Address:'), $email, '', '', 'autocomplete="off"', 'email'],
'$timezone' => ['timezone_select', DI::l10n()->t('Your Timezone:'), Temporal::getTimezoneSelect($timezone), ''],
'$language' => ['language', DI::l10n()->t('Your Language:'), $language, DI::l10n()->t('Set the language we use to show you friendica interface and to send you emails'), $lang_choices],
diff --git a/src/Module/Settings/Profile/Index.php b/src/Module/Settings/Profile/Index.php
index c8b27e394a..38d816833f 100644
--- a/src/Module/Settings/Profile/Index.php
+++ b/src/Module/Settings/Profile/Index.php
@@ -21,43 +21,75 @@
namespace Friendica\Module\Settings\Profile;
+use Friendica\App;
use Friendica\Core\ACL;
use Friendica\Core\Hook;
+use Friendica\Core\L10n;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
+use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\Theme;
use Friendica\Database\DBA;
-use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
-use Friendica\Profile\ProfileField\Collection\ProfileFields;
-use Friendica\Profile\ProfileField\Entity\ProfileField;
+use Friendica\Module\Response;
+use Friendica\Navigation\SystemMessages;
+use Friendica\Profile\ProfileField;
use Friendica\Model\User;
use Friendica\Module\BaseSettings;
use Friendica\Module\Security\Login;
use Friendica\Network\HTTPException;
+use Friendica\Security\PermissionSet;
+use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Profiler;
use Friendica\Util\Temporal;
use Friendica\Core\Worker;
+use Psr\Log\LoggerInterface;
class Index extends BaseSettings
{
+ /** @var ProfileField\Repository\ProfileField */
+ private $profileFieldRepo;
+ /** @var ProfileField\Factory\ProfileField */
+ private $profileFieldFactory;
+ /** @var SystemMessages */
+ private $systemMessages;
+ /** @var PermissionSet\Repository\PermissionSet */
+ private $permissionSetRepo;
+ /** @var PermissionSet\Factory\PermissionSet */
+ private $permissionSetFactory;
+ /** @var ACLFormatter */
+ private $aclFormatter;
+
+ public function __construct(ACLFormatter $aclFormatter, PermissionSet\Factory\PermissionSet $permissionSetFactory, PermissionSet\Repository\PermissionSet $permissionSetRepo, SystemMessages $systemMessages, ProfileField\Factory\ProfileField $profileFieldFactory, ProfileField\Repository\ProfileField $profileFieldRepo, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
+ {
+ parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
+
+ $this->profileFieldRepo = $profileFieldRepo;
+ $this->profileFieldFactory = $profileFieldFactory;
+ $this->systemMessages = $systemMessages;
+ $this->permissionSetRepo = $permissionSetRepo;
+ $this->permissionSetFactory = $permissionSetFactory;
+ $this->aclFormatter = $aclFormatter;
+ }
+
protected function post(array $request = [])
{
- if (!DI::userSession()->getLocalUserId()) {
+ if (!$this->session->getLocalUserId()) {
return;
}
- $profile = Profile::getByUID(DI::userSession()->getLocalUserId());
- if (!DBA::isResult($profile)) {
+ $profile = Profile::getByUID($this->session->getLocalUserId());
+ if (!$profile) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/settings/profile', 'settings_profile');
- Hook::callAll('profile_post', $_POST);
+ Hook::callAll('profile_post', $request);
- $dob = trim($_POST['dob'] ?? '');
+ $dob = trim($request['dob'] ?? '');
if ($dob && !in_array($dob, ['0000-00-00', DBA::NULL_DATE])) {
$y = substr($dob, 0, 4);
@@ -79,39 +111,40 @@ class Index extends BaseSettings
}
}
- $name = trim($_POST['name'] ?? '');
- if (!strlen($name)) {
- DI::sysmsg()->addNotice(DI::l10n()->t('Profile Name is required.'));
+ $username = trim($request['username'] ?? '');
+ if (!$username) {
+ $this->systemMessages->addNotice($this->t('Display Name is required.'));
return;
}
- $about = trim($_POST['about']);
- $address = trim($_POST['address']);
- $locality = trim($_POST['locality']);
- $region = trim($_POST['region']);
- $postal_code = trim($_POST['postal_code']);
- $country_name = trim($_POST['country_name']);
- $pub_keywords = self::cleanKeywords(trim($_POST['pub_keywords']));
- $prv_keywords = self::cleanKeywords(trim($_POST['prv_keywords']));
- $xmpp = trim($_POST['xmpp']);
- $matrix = trim($_POST['matrix']);
- $homepage = trim($_POST['homepage']);
+ $about = trim($request['about']);
+ $address = trim($request['address']);
+ $locality = trim($request['locality']);
+ $region = trim($request['region']);
+ $postal_code = trim($request['postal_code']);
+ $country_name = trim($request['country_name']);
+ $pub_keywords = self::cleanKeywords(trim($request['pub_keywords']));
+ $prv_keywords = self::cleanKeywords(trim($request['prv_keywords']));
+ $xmpp = trim($request['xmpp']);
+ $matrix = trim($request['matrix']);
+ $homepage = trim($request['homepage']);
if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) {
// neither http nor https in URL, add them
$homepage = 'http://' . $homepage;
}
- $profileFieldsNew = self::getProfileFieldsFromInput(
- DI::userSession()->getLocalUserId(),
- $_REQUEST['profile_field'],
- $_REQUEST['profile_field_order']
+ $profileFieldsNew = $this->getProfileFieldsFromInput(
+ $this->session->getLocalUserId(),
+ $request['profile_field'],
+ $request['profile_field_order']
);
- DI::profileField()->saveCollectionForUser(DI::userSession()->getLocalUserId(), $profileFieldsNew);
+ $this->profileFieldRepo->saveCollectionForUser($this->session->getLocalUserId(), $profileFieldsNew);
+
+ User::update(['username' => $username], $this->session->getLocalUserId());
$result = Profile::update(
[
- 'name' => $name,
'about' => $about,
'dob' => $dob,
'address' => $address,
@@ -125,23 +158,23 @@ class Index extends BaseSettings
'pub_keywords' => $pub_keywords,
'prv_keywords' => $prv_keywords,
],
- DI::userSession()->getLocalUserId()
+ $this->session->getLocalUserId()
);
- Worker::add(Worker::PRIORITY_MEDIUM, 'CheckRelMeProfileLink', DI::userSession()->getLocalUserId());
+ Worker::add(Worker::PRIORITY_MEDIUM, 'CheckRelMeProfileLink', $this->session->getLocalUserId());
if (!$result) {
- DI::sysmsg()->addNotice(DI::l10n()->t('Profile couldn\'t be updated.'));
+ $this->systemMessages->addNotice($this->t("Profile couldn't be updated."));
return;
}
- DI::baseUrl()->redirect('settings/profile');
+ $this->baseUrl->redirect('settings/profile');
}
protected function content(array $request = []): string
{
- if (!DI::userSession()->getLocalUserId()) {
- DI::sysmsg()->addNotice(DI::l10n()->t('You must be logged in to use this module'));
+ if (!$this->session->getLocalUserId()) {
+ $this->systemMessages->addNotice($this->t('You must be logged in to use this module'));
return Login::form();
}
@@ -149,147 +182,145 @@ class Index extends BaseSettings
$o = '';
- $profile = User::getOwnerDataById(DI::userSession()->getLocalUserId());
- if (!DBA::isResult($profile)) {
+ $owner = User::getOwnerDataById($this->session->getLocalUserId());
+ if (!$owner) {
throw new HTTPException\NotFoundException();
}
- $a = DI::app();
-
- DI::page()->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
- DI::page()->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
+ $this->page->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
+ $this->page->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
$custom_fields = [];
- $profileFields = DI::profileField()->selectByUserId(DI::userSession()->getLocalUserId());
+ $profileFields = $this->profileFieldRepo->selectByUserId($this->session->getLocalUserId());
foreach ($profileFields as $profileField) {
- /** @var ProfileField $profileField */
$defaultPermissions = $profileField->permissionSet->withAllowedContacts(
Contact::pruneUnavailable($profileField->permissionSet->allow_cid)
);
$custom_fields[] = [
- 'id' => $profileField->id,
+ 'id' => $profileField->id,
'legend' => $profileField->label,
'fields' => [
- 'label' => ['profile_field[' . $profileField->id . '][label]', DI::l10n()->t('Label:'), $profileField->label],
- 'value' => ['profile_field[' . $profileField->id . '][value]', DI::l10n()->t('Value:'), $profileField->value],
- 'acl' => ACL::getFullSelectorHTML(
- DI::page(),
- $a->getLoggedInUserId(),
+ 'label' => ['profile_field[' . $profileField->id . '][label]', $this->t('Label:'), $profileField->label],
+ 'value' => ['profile_field[' . $profileField->id . '][value]', $this->t('Value:'), $profileField->value],
+ 'acl' => ACL::getFullSelectorHTML(
+ $this->page,
+ $this->session->getLocalUserId(),
false,
$defaultPermissions->toArray(),
['network' => Protocol::DFRN],
'profile_field[' . $profileField->id . ']'
),
],
- 'permissions' => DI::l10n()->t('Field Permissions'),
- 'permdesc' => DI::l10n()->t("(click to open/close)"),
+
+ 'permissions' => $this->t('Field Permissions'),
+ 'permdesc' => $this->t("(click to open/close)"),
];
- };
+ }
$custom_fields[] = [
- 'id' => 'new',
- 'legend' => DI::l10n()->t('Add a new profile field'),
+ 'id' => 'new',
+ 'legend' => $this->t('Add a new profile field'),
'fields' => [
- 'label' => ['profile_field[new][label]', DI::l10n()->t('Label:')],
- 'value' => ['profile_field[new][value]', DI::l10n()->t('Value:')],
- 'acl' => ACL::getFullSelectorHTML(
- DI::page(),
- $a->getLoggedInUserId(),
+ 'label' => ['profile_field[new][label]', $this->t('Label:')],
+ 'value' => ['profile_field[new][value]', $this->t('Value:')],
+ 'acl' => ACL::getFullSelectorHTML(
+ $this->page,
+ $this->session->getLocalUserId(),
false,
['allow_cid' => []],
['network' => Protocol::DFRN],
'profile_field[new]'
),
],
- 'permissions' => DI::l10n()->t('Field Permissions'),
- 'permdesc' => DI::l10n()->t("(click to open/close)"),
+
+ 'permissions' => $this->t('Field Permissions'),
+ 'permdesc' => $this->t("(click to open/close)"),
];
- DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'), [
- ]);
+ $this->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'));
- $personal_account = ($profile['account-type'] != User::ACCOUNT_TYPE_COMMUNITY);
+ $personal_account = ($owner['account-type'] != User::ACCOUNT_TYPE_COMMUNITY);
- if ($profile['homepage_verified']) {
- $homepage_help_text = DI::l10n()->t('The homepage is verified. A rel="me" link back to your Friendica profile page was found on the homepage.');
+ if ($owner['homepage_verified']) {
+ $homepage_help_text = $this->t('The homepage is verified. A rel="me" link back to your Friendica profile page was found on the homepage.');
} else {
- $homepage_help_text = DI::l10n()->t('To verify your homepage, add a rel="me" link to it, pointing to your profile URL (%s).', $profile['url']);
+ $homepage_help_text = $this->t('To verify your homepage, add a rel="me" link to it, pointing to your profile URL (%s).', $owner['url']);
}
$tpl = Renderer::getMarkupTemplate('settings/profile/index.tpl');
$o .= Renderer::replaceMacros($tpl, [
- '$personal_account' => $personal_account,
-
- '$form_security_token' => self::getFormSecurityToken('settings_profile'),
- '$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'),
-
- '$profile_action' => DI::l10n()->t('Profile Actions'),
- '$banner' => DI::l10n()->t('Edit Profile Details'),
- '$submit' => DI::l10n()->t('Submit'),
- '$profpic' => DI::l10n()->t('Change Profile Photo'),
- '$profpiclink' => '/profile/' . $profile['nickname'] . '/photos',
- '$viewprof' => DI::l10n()->t('View Profile'),
-
- '$lbl_personal_section' => DI::l10n()->t('Personal'),
- '$lbl_picture_section' => DI::l10n()->t('Profile picture'),
- '$lbl_location_section' => DI::l10n()->t('Location'),
- '$lbl_miscellaneous_section' => DI::l10n()->t('Miscellaneous'),
- '$lbl_custom_fields_section' => DI::l10n()->t('Custom Profile Fields'),
-
- '$lbl_profile_photo' => DI::l10n()->t('Upload Profile Photo'),
-
- '$baseurl' => DI::baseUrl(),
- '$nickname' => $profile['nickname'],
- '$name' => ['name', DI::l10n()->t('Display name:'), $profile['name']],
- '$about' => ['about', DI::l10n()->t('Description:'), $profile['about']],
- '$dob' => Temporal::getDateofBirthField($profile['dob'], $profile['timezone']),
- '$address' => ['address', DI::l10n()->t('Street Address:'), $profile['address']],
- '$locality' => ['locality', DI::l10n()->t('Locality/City:'), $profile['locality']],
- '$region' => ['region', DI::l10n()->t('Region/State:'), $profile['region']],
- '$postal_code' => ['postal_code', DI::l10n()->t('Postal/Zip Code:'), $profile['postal-code']],
- '$country_name' => ['country_name', DI::l10n()->t('Country:'), $profile['country-name']],
- '$age' => ((intval($profile['dob'])) ? '(' . DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($profile['dob'], $profile['timezone'])) . ')' : ''),
- '$xmpp' => ['xmpp', DI::l10n()->t('XMPP (Jabber) address:'), $profile['xmpp'], DI::l10n()->t('The XMPP address will be published so that people can follow you there.')],
- '$matrix' => ['matrix', DI::l10n()->t('Matrix (Element) address:'), $profile['matrix'], DI::l10n()->t('The Matrix address will be published so that people can follow you there.')],
- '$homepage' => ['homepage', DI::l10n()->t('Homepage URL:'), $profile['homepage'], $homepage_help_text],
- '$pub_keywords' => ['pub_keywords', DI::l10n()->t('Public Keywords:'), $profile['pub_keywords'], DI::l10n()->t('(Used for suggesting potential friends, can be seen by others)')],
- '$prv_keywords' => ['prv_keywords', DI::l10n()->t('Private Keywords:'), $profile['prv_keywords'], DI::l10n()->t('(Used for searching profiles, never shown to others)')],
- '$custom_fields_description' => DI::l10n()->t("