diff --git a/CHANGELOG b/CHANGELOG
index e262dc93b..a69cfc015 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,6 @@
Version 2021.09 (unreleased)
+ Friendica Core
+ Simplified the proxy mechanism. The proxy cache directory (/proxy) can now be removed [annando]
Version 2021.07 (2021-07-04)
Friendica Core
diff --git a/boot.php b/boot.php
index e94b82fa3..b3b560a09 100644
--- a/boot.php
+++ b/boot.php
@@ -444,93 +444,6 @@ function get_temppath()
return '';
}
-function get_cachefile($file, $writemode = true)
-{
- $cache = get_itemcachepath();
-
- if ((!$cache) || (!is_dir($cache))) {
- return "";
- }
-
- $subfolder = $cache . "/" . substr($file, 0, 2);
-
- $cachepath = $subfolder . "/" . $file;
-
- if ($writemode) {
- if (!is_dir($subfolder)) {
- mkdir($subfolder);
- chmod($subfolder, 0777);
- }
- }
-
- return $cachepath;
-}
-
-function clear_cache($basepath = "", $path = "")
-{
- if ($path == "") {
- $basepath = get_itemcachepath();
- $path = $basepath;
- }
-
- if (($path == "") || (!is_dir($path))) {
- return;
- }
-
- if (substr(realpath($path), 0, strlen($basepath)) != $basepath) {
- return;
- }
-
- $cachetime = (int) DI::config()->get('system', 'itemcache_duration');
- if ($cachetime == 0) {
- $cachetime = 86400;
- }
-
- if (is_writable($path)) {
- if ($dh = opendir($path)) {
- while (($file = readdir($dh)) !== false) {
- $fullpath = $path . "/" . $file;
- if ((filetype($fullpath) == "dir") && ($file != ".") && ($file != "..")) {
- clear_cache($basepath, $fullpath);
- }
- if ((filetype($fullpath) == "file") && (filectime($fullpath) < (time() - $cachetime))) {
- unlink($fullpath);
- }
- }
- closedir($dh);
- }
- }
-}
-
-function get_itemcachepath()
-{
- // Checking, if the cache is deactivated
- $cachetime = (int) DI::config()->get('system', 'itemcache_duration');
- if ($cachetime < 0) {
- return "";
- }
-
- $itemcache = DI::config()->get('system', 'itemcache');
- if (($itemcache != "") && System::isDirectoryUsable($itemcache)) {
- return BasePath::getRealPath($itemcache);
- }
-
- $temppath = get_temppath();
-
- if ($temppath != "") {
- $itemcache = $temppath . "/itemcache";
- if (!file_exists($itemcache) && !is_dir($itemcache)) {
- mkdir($itemcache);
- }
-
- if (System::isDirectoryUsable($itemcache)) {
- DI::config()->set("system", "itemcache", $itemcache);
- return $itemcache;
- }
- }
- return "";
-}
-
/**
* Returns the path where spool files are stored
*
diff --git a/database.sql b/database.sql
index b6dcb8ab7..5ee4ef053 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
-- ------------------------------------------
--- Friendica 2021.06-rc (Siberian Iris)
--- DB_UPDATE_VERSION 1424
+-- Friendica 2021.09-dev (Siberian Iris)
+-- DB_UPDATE_VERSION 1426
-- ------------------------------------------
@@ -94,6 +94,18 @@ 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 item-uri
+--
+CREATE TABLE IF NOT EXISTS `item-uri` (
+ `id` int unsigned NOT NULL auto_increment,
+ `uri` varbinary(255) NOT NULL COMMENT 'URI of an item',
+ `guid` varbinary(255) COMMENT 'A unique identifier for an item',
+ PRIMARY KEY(`id`),
+ UNIQUE INDEX `uri` (`uri`),
+ INDEX `guid` (`guid`)
+) DEFAULT COLLATE utf8mb4_general_ci COMMENT='URI and GUID for items';
+
--
-- TABLE contact
--
@@ -126,6 +138,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`dfrn-id` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`nurl` varchar(255) NOT NULL DEFAULT '' COMMENT '',
+ `uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the contact url',
`addr` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`alias` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`pubkey` text COMMENT 'RSA public key 4096 bit',
@@ -202,22 +215,12 @@ CREATE TABLE IF NOT EXISTS `contact` (
INDEX `uid_self_contact-type` (`uid`,`self`,`contact-type`),
INDEX `self_network_uid` (`self`,`network`,`uid`),
INDEX `gsid` (`gsid`),
+ INDEX `uri-id` (`uri-id`),
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
+ FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='contact table';
---
--- TABLE item-uri
---
-CREATE TABLE IF NOT EXISTS `item-uri` (
- `id` int unsigned NOT NULL auto_increment,
- `uri` varbinary(255) NOT NULL COMMENT 'URI of an item',
- `guid` varbinary(255) COMMENT 'A unique identifier for an item',
- PRIMARY KEY(`id`),
- UNIQUE INDEX `uri` (`uri`),
- INDEX `guid` (`guid`)
-) DEFAULT COLLATE utf8mb4_general_ci COMMENT='URI and GUID for items';
-
--
-- TABLE tag
--
@@ -332,6 +335,7 @@ CREATE TABLE IF NOT EXISTS `addon` (
--
CREATE TABLE IF NOT EXISTS `apcontact` (
`url` varbinary(255) NOT NULL COMMENT 'URL of the contact',
+ `uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the apcontact url',
`uuid` varchar(255) COMMENT '',
`type` varchar(20) NOT NULL COMMENT '',
`following` varchar(255) COMMENT '',
@@ -364,6 +368,8 @@ CREATE TABLE IF NOT EXISTS `apcontact` (
INDEX `baseurl` (`baseurl`(190)),
INDEX `sharedinbox` (`sharedinbox`(190)),
INDEX `gsid` (`gsid`),
+ UNIQUE INDEX `uri-id` (`uri-id`),
+ FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='ActivityPub compatible contacts - used in the ActivityPub implementation';
@@ -563,6 +569,7 @@ CREATE TABLE IF NOT EXISTS `event` (
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
`cid` int unsigned NOT NULL DEFAULT 0 COMMENT 'contact_id (ID of the contact in contact table)',
`uri` varchar(255) NOT NULL DEFAULT '' COMMENT '',
+ `uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the event uri',
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'creation time',
`edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'last edit time',
`start` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'event start time',
@@ -581,8 +588,10 @@ CREATE TABLE IF NOT EXISTS `event` (
PRIMARY KEY(`id`),
INDEX `uid_start` (`uid`,`start`),
INDEX `cid` (`cid`),
+ INDEX `uri-id` (`uri-id`),
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
- FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
+ FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
+ FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Events';
--
@@ -592,6 +601,7 @@ CREATE TABLE IF NOT EXISTS `fcontact` (
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
`guid` varchar(255) NOT NULL DEFAULT '' COMMENT 'unique id',
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '',
+ `uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the fcontact url',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`photo` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`request` varchar(255) NOT NULL DEFAULT '' COMMENT '',
@@ -608,7 +618,9 @@ CREATE TABLE IF NOT EXISTS `fcontact` (
`updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
PRIMARY KEY(`id`),
INDEX `addr` (`addr`(32)),
- UNIQUE INDEX `url` (`url`(190))
+ UNIQUE INDEX `url` (`url`(190)),
+ UNIQUE INDEX `uri-id` (`uri-id`),
+ FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Diaspora compatible contacts - used in the Diaspora implementation';
--
@@ -1103,6 +1115,19 @@ CREATE TABLE IF NOT EXISTS `post-delivery-data` (
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Delivery data for items';
+--
+-- TABLE post-link
+--
+CREATE TABLE IF NOT EXISTS `post-link` (
+ `id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
+ `uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
+ `url` varbinary(511) NOT NULL COMMENT 'External URL',
+ `mimetype` varchar(60) COMMENT '',
+ PRIMARY KEY(`id`),
+ UNIQUE INDEX `uri-id-url` (`uri-id`,`url`),
+ FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
+) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Post related external links';
+
--
-- TABLE post-media
--
@@ -1278,6 +1303,7 @@ CREATE TABLE IF NOT EXISTS `post-thread-user` (
INDEX `post-user-id` (`post-user-id`),
INDEX `commented` (`commented`),
INDEX `uid_received` (`uid`,`received`),
+ INDEX `uid_wall_received` (`uid`,`wall`,`received`),
INDEX `uid_pinned` (`uid`,`pinned`),
INDEX `uid_commented` (`uid`,`commented`),
INDEX `uid_starred` (`uid`,`starred`),
diff --git a/doc/database.md b/doc/database.md
index 60e3253fe..51f4ae5c6 100644
--- a/doc/database.md
+++ b/doc/database.md
@@ -53,6 +53,7 @@ Database Tables
| [post-category](help/database/db_post-category) | post relation to categories |
| [post-content](help/database/db_post-content) | Content for all posts |
| [post-delivery-data](help/database/db_post-delivery-data) | Delivery data for items |
+| [post-link](help/database/db_post-link) | Post related external links |
| [post-media](help/database/db_post-media) | Attached media |
| [post-tag](help/database/db_post-tag) | post relation to tags |
| [post-thread](help/database/db_post-thread) | Thread related data |
diff --git a/doc/database/db_apcontact.md b/doc/database/db_apcontact.md
index ede71d1d0..5abf60f10 100644
--- a/doc/database/db_apcontact.md
+++ b/doc/database/db_apcontact.md
@@ -9,6 +9,7 @@ Fields
| Field | Description | Type | Null | Key | Default | Extra |
| ---------------- | ------------------------------------------------------------------- | -------------- | ---- | --- | ------------------- | ----- |
| url | URL of the contact | varbinary(255) | NO | PRI | NULL | |
+| uri-id | Id of the item-uri table entry that contains the apcontact url | int unsigned | YES | | NULL | |
| uuid | | varchar(255) | YES | | NULL | |
| type | | varchar(20) | NO | | NULL | |
| following | | varchar(255) | YES | | NULL | |
@@ -47,12 +48,14 @@ Indexes
| baseurl | baseurl(190) |
| sharedinbox | sharedinbox(190) |
| gsid | gsid |
+| uri-id | UNIQUE, uri-id |
Foreign Keys
------------
| Field | Target Table | Target Field |
|-------|--------------|--------------|
+| uri-id | [item-uri](help/database/db_item-uri) | id |
| gsid | [gserver](help/database/db_gserver) | id |
Return to [database documentation](help/database)
diff --git a/doc/database/db_contact.md b/doc/database/db_contact.md
index 23a3b533a..5a97c6e4d 100644
--- a/doc/database/db_contact.md
+++ b/doc/database/db_contact.md
@@ -6,89 +6,90 @@ contact table
Fields
------
-| Field | Description | Type | Null | Key | Default | Extra |
-| ------------------------- | --------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
-| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
-| uid | Owner User id | mediumint unsigned | NO | | 0 | |
-| created | | datetime | NO | | 0001-01-01 00:00:00 | |
-| updated | Date of last contact update | datetime | YES | | 0001-01-01 00:00:00 | |
-| self | 1 if the contact is the user him/her self | boolean | NO | | 0 | |
-| remote_self | | boolean | NO | | 0 | |
-| rel | The kind of the relation between the user and the contact | tinyint unsigned | NO | | 0 | |
-| duplex | | boolean | NO | | 0 | |
-| network | Network of the contact | char(4) | NO | | | |
-| protocol | Protocol of the contact | char(4) | NO | | | |
-| name | Name that this contact is known by | varchar(255) | NO | | | |
-| nick | Nick- and user name of the contact | varchar(255) | NO | | | |
-| location | | varchar(255) | YES | | | |
-| about | | text | YES | | NULL | |
-| keywords | public keywords (interests) of the contact | text | YES | | NULL | |
-| gender | Deprecated | varchar(32) | NO | | | |
-| xmpp | | varchar(255) | NO | | | |
-| attag | | varchar(255) | NO | | | |
-| avatar | | varchar(255) | NO | | | |
-| photo | Link to the profile photo of the contact | varchar(255) | YES | | | |
-| thumb | Link to the profile photo (thumb size) | varchar(255) | YES | | | |
-| micro | Link to the profile photo (micro size) | varchar(255) | YES | | | |
-| header | Header picture | varchar(255) | YES | | NULL | |
-| site-pubkey | | text | YES | | NULL | |
-| issued-id | | varchar(255) | NO | | | |
-| dfrn-id | | varchar(255) | NO | | | |
-| url | | varchar(255) | NO | | | |
-| nurl | | varchar(255) | NO | | | |
-| addr | | varchar(255) | NO | | | |
-| alias | | varchar(255) | NO | | | |
-| pubkey | RSA public key 4096 bit | text | YES | | NULL | |
-| prvkey | RSA private key 4096 bit | text | YES | | NULL | |
-| batch | | varchar(255) | NO | | | |
-| request | | varchar(255) | YES | | NULL | |
-| notify | | varchar(255) | YES | | NULL | |
-| poll | | varchar(255) | YES | | NULL | |
-| confirm | | varchar(255) | YES | | NULL | |
-| subscribe | | varchar(255) | YES | | NULL | |
-| poco | | varchar(255) | YES | | NULL | |
-| aes_allow | | boolean | NO | | 0 | |
-| ret-aes | | boolean | NO | | 0 | |
-| usehub | | boolean | NO | | 0 | |
-| subhub | | boolean | NO | | 0 | |
-| hub-verify | | varchar(255) | NO | | | |
-| last-update | Date of the last try to update the contact info | datetime | NO | | 0001-01-01 00:00:00 | |
-| success_update | Date of the last successful contact update | datetime | NO | | 0001-01-01 00:00:00 | |
-| failure_update | Date of the last failed update | datetime | NO | | 0001-01-01 00:00:00 | |
-| failed | Connection failed | boolean | YES | | NULL | |
-| name-date | | datetime | NO | | 0001-01-01 00:00:00 | |
-| uri-date | | datetime | NO | | 0001-01-01 00:00:00 | |
-| avatar-date | | datetime | NO | | 0001-01-01 00:00:00 | |
-| term-date | | datetime | NO | | 0001-01-01 00:00:00 | |
-| last-item | date of the last post | datetime | NO | | 0001-01-01 00:00:00 | |
-| last-discovery | date of the last follower discovery | datetime | NO | | 0001-01-01 00:00:00 | |
-| priority | | tinyint unsigned | NO | | 0 | |
-| blocked | Node-wide block status | boolean | NO | | 1 | |
-| block_reason | Node-wide block reason | text | YES | | NULL | |
-| readonly | posts of the contact are readonly | boolean | NO | | 0 | |
-| writable | | boolean | NO | | 0 | |
-| forum | contact is a forum | boolean | NO | | 0 | |
-| prv | contact is a private group | boolean | NO | | 0 | |
-| contact-type | | tinyint | NO | | 0 | |
-| manually-approve | | boolean | YES | | NULL | |
-| hidden | | boolean | NO | | 0 | |
-| archive | | boolean | NO | | 0 | |
-| pending | | boolean | NO | | 1 | |
-| deleted | Contact has been deleted | boolean | NO | | 0 | |
-| rating | | tinyint | 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 | varchar(255) | YES | | | |
-| gsid | Global Server ID | int unsigned | YES | | NULL | |
-| reason | | text | YES | | NULL | |
-| closeness | | tinyint unsigned | NO | | 99 | |
-| info | | mediumtext | YES | | NULL | |
-| profile-id | Deprecated | int unsigned | YES | | NULL | |
-| bdyear | | varchar(4) | NO | | | |
-| bd | | date | NO | | 0001-01-01 | |
-| notify_new_posts | | boolean | NO | | 0 | |
-| fetch_further_information | | tinyint unsigned | NO | | 0 | |
-| ffi_keyword_denylist | | text | YES | | NULL | |
+| Field | Description | Type | Null | Key | Default | Extra |
+| ------------------------- | ------------------------------------------------------------ | ------------------ | ---- | --- | ------------------- | -------------- |
+| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
+| uid | Owner User id | mediumint unsigned | NO | | 0 | |
+| created | | datetime | NO | | 0001-01-01 00:00:00 | |
+| updated | Date of last contact update | datetime | YES | | 0001-01-01 00:00:00 | |
+| self | 1 if the contact is the user him/her self | boolean | NO | | 0 | |
+| remote_self | | boolean | NO | | 0 | |
+| rel | The kind of the relation between the user and the contact | tinyint unsigned | NO | | 0 | |
+| duplex | | boolean | NO | | 0 | |
+| network | Network of the contact | char(4) | NO | | | |
+| protocol | Protocol of the contact | char(4) | NO | | | |
+| name | Name that this contact is known by | varchar(255) | NO | | | |
+| nick | Nick- and user name of the contact | varchar(255) | NO | | | |
+| location | | varchar(255) | YES | | | |
+| about | | text | YES | | NULL | |
+| keywords | public keywords (interests) of the contact | text | YES | | NULL | |
+| gender | Deprecated | varchar(32) | NO | | | |
+| xmpp | | varchar(255) | NO | | | |
+| attag | | varchar(255) | NO | | | |
+| avatar | | varchar(255) | NO | | | |
+| photo | Link to the profile photo of the contact | varchar(255) | YES | | | |
+| thumb | Link to the profile photo (thumb size) | varchar(255) | YES | | | |
+| micro | Link to the profile photo (micro size) | varchar(255) | YES | | | |
+| header | Header picture | varchar(255) | YES | | NULL | |
+| site-pubkey | | text | YES | | NULL | |
+| issued-id | | varchar(255) | NO | | | |
+| dfrn-id | | varchar(255) | NO | | | |
+| url | | varchar(255) | NO | | | |
+| nurl | | varchar(255) | NO | | | |
+| uri-id | Id of the item-uri table entry that contains the contact url | int unsigned | YES | | NULL | |
+| addr | | varchar(255) | NO | | | |
+| alias | | varchar(255) | NO | | | |
+| pubkey | RSA public key 4096 bit | text | YES | | NULL | |
+| prvkey | RSA private key 4096 bit | text | YES | | NULL | |
+| batch | | varchar(255) | NO | | | |
+| request | | varchar(255) | YES | | NULL | |
+| notify | | varchar(255) | YES | | NULL | |
+| poll | | varchar(255) | YES | | NULL | |
+| confirm | | varchar(255) | YES | | NULL | |
+| subscribe | | varchar(255) | YES | | NULL | |
+| poco | | varchar(255) | YES | | NULL | |
+| aes_allow | | boolean | NO | | 0 | |
+| ret-aes | | boolean | NO | | 0 | |
+| usehub | | boolean | NO | | 0 | |
+| subhub | | boolean | NO | | 0 | |
+| hub-verify | | varchar(255) | NO | | | |
+| last-update | Date of the last try to update the contact info | datetime | NO | | 0001-01-01 00:00:00 | |
+| success_update | Date of the last successful contact update | datetime | NO | | 0001-01-01 00:00:00 | |
+| failure_update | Date of the last failed update | datetime | NO | | 0001-01-01 00:00:00 | |
+| failed | Connection failed | boolean | YES | | NULL | |
+| name-date | | datetime | NO | | 0001-01-01 00:00:00 | |
+| uri-date | | datetime | NO | | 0001-01-01 00:00:00 | |
+| avatar-date | | datetime | NO | | 0001-01-01 00:00:00 | |
+| term-date | | datetime | NO | | 0001-01-01 00:00:00 | |
+| last-item | date of the last post | datetime | NO | | 0001-01-01 00:00:00 | |
+| last-discovery | date of the last follower discovery | datetime | NO | | 0001-01-01 00:00:00 | |
+| priority | | tinyint unsigned | NO | | 0 | |
+| blocked | Node-wide block status | boolean | NO | | 1 | |
+| block_reason | Node-wide block reason | text | YES | | NULL | |
+| readonly | posts of the contact are readonly | boolean | NO | | 0 | |
+| writable | | boolean | NO | | 0 | |
+| forum | contact is a forum | boolean | NO | | 0 | |
+| prv | contact is a private group | boolean | NO | | 0 | |
+| contact-type | | tinyint | NO | | 0 | |
+| manually-approve | | boolean | YES | | NULL | |
+| hidden | | boolean | NO | | 0 | |
+| archive | | boolean | NO | | 0 | |
+| pending | | boolean | NO | | 1 | |
+| deleted | Contact has been deleted | boolean | NO | | 0 | |
+| rating | | tinyint | 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 | varchar(255) | YES | | | |
+| gsid | Global Server ID | int unsigned | YES | | NULL | |
+| reason | | text | YES | | NULL | |
+| closeness | | tinyint unsigned | NO | | 99 | |
+| info | | mediumtext | YES | | NULL | |
+| profile-id | Deprecated | int unsigned | YES | | NULL | |
+| bdyear | | varchar(4) | NO | | | |
+| bd | | date | NO | | 0001-01-01 | |
+| notify_new_posts | | boolean | NO | | 0 | |
+| fetch_further_information | | tinyint unsigned | NO | | 0 | |
+| ffi_keyword_denylist | | text | YES | | NULL | |
Indexes
------------
@@ -118,6 +119,7 @@ Indexes
| uid_self_contact-type | uid, self, contact-type |
| self_network_uid | self, network, uid |
| gsid | gsid |
+| uri-id | uri-id |
Foreign Keys
------------
@@ -125,6 +127,7 @@ Foreign Keys
| Field | Target Table | Target Field |
|-------|--------------|--------------|
| uid | [user](help/database/db_user) | uid |
+| uri-id | [item-uri](help/database/db_item-uri) | id |
| gsid | [gserver](help/database/db_gserver) | id |
Return to [database documentation](help/database)
diff --git a/doc/database/db_event.md b/doc/database/db_event.md
index 37048599b..5550d1a1a 100644
--- a/doc/database/db_event.md
+++ b/doc/database/db_event.md
@@ -6,28 +6,29 @@ Events
Fields
------
-| Field | Description | Type | Null | Key | Default | Extra |
-| --------- | ------------------------------------------------------ | ------------------ | ---- | --- | ------------------- | -------------- |
-| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
-| guid | | varchar(255) | NO | | | |
-| uid | Owner User id | mediumint unsigned | NO | | 0 | |
-| cid | contact_id (ID of the contact in contact table) | int unsigned | NO | | 0 | |
-| uri | | varchar(255) | NO | | | |
-| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
-| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
-| start | event start time | datetime | NO | | 0001-01-01 00:00:00 | |
-| finish | event end time | datetime | NO | | 0001-01-01 00:00:00 | |
-| summary | short description or title of the event | text | YES | | NULL | |
-| desc | event description | text | YES | | NULL | |
-| location | event location | text | YES | | NULL | |
-| type | event or birthday | varchar(20) | NO | | | |
-| nofinish | if event does have no end this is 1 | boolean | NO | | 0 | |
-| adjust | adjust to timezone of the recipient (0 or 1) | boolean | NO | | 1 | |
-| ignore | 0 or 1 | boolean | NO | | 0 | |
-| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
-| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
-| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
-| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
+| Field | Description | Type | Null | Key | Default | Extra |
+| --------- | ---------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
+| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
+| guid | | varchar(255) | NO | | | |
+| uid | Owner User id | mediumint unsigned | NO | | 0 | |
+| cid | contact_id (ID of the contact in contact table) | int unsigned | NO | | 0 | |
+| uri | | varchar(255) | NO | | | |
+| uri-id | Id of the item-uri table entry that contains the event uri | int unsigned | YES | | NULL | |
+| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
+| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
+| start | event start time | datetime | NO | | 0001-01-01 00:00:00 | |
+| finish | event end time | datetime | NO | | 0001-01-01 00:00:00 | |
+| summary | short description or title of the event | text | YES | | NULL | |
+| desc | event description | text | YES | | NULL | |
+| location | event location | text | YES | | NULL | |
+| type | event or birthday | varchar(20) | NO | | | |
+| nofinish | if event does have no end this is 1 | boolean | NO | | 0 | |
+| adjust | adjust to timezone of the recipient (0 or 1) | boolean | NO | | 1 | |
+| ignore | 0 or 1 | boolean | NO | | 0 | |
+| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
+| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
+| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
+| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
Indexes
------------
@@ -37,6 +38,7 @@ Indexes
| PRIMARY | id |
| uid_start | uid, start |
| cid | cid |
+| uri-id | uri-id |
Foreign Keys
------------
@@ -45,5 +47,6 @@ Foreign Keys
|-------|--------------|--------------|
| uid | [user](help/database/db_user) | uid |
| cid | [contact](help/database/db_contact) | id |
+| uri-id | [item-uri](help/database/db_item-uri) | id |
Return to [database documentation](help/database)
diff --git a/doc/database/db_fcontact.md b/doc/database/db_fcontact.md
index 43a073f61..51cfac764 100644
--- a/doc/database/db_fcontact.md
+++ b/doc/database/db_fcontact.md
@@ -6,25 +6,26 @@ Diaspora compatible contacts - used in the Diaspora implementation
Fields
------
-| Field | Description | Type | Null | Key | Default | Extra |
-| -------- | ------------- | ---------------- | ---- | --- | ------------------- | -------------- |
-| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
-| guid | unique id | varchar(255) | NO | | | |
-| url | | varchar(255) | NO | | | |
-| name | | varchar(255) | NO | | | |
-| photo | | varchar(255) | NO | | | |
-| request | | varchar(255) | NO | | | |
-| nick | | varchar(255) | NO | | | |
-| addr | | varchar(255) | NO | | | |
-| batch | | varchar(255) | NO | | | |
-| notify | | varchar(255) | NO | | | |
-| poll | | varchar(255) | NO | | | |
-| confirm | | varchar(255) | NO | | | |
-| priority | | tinyint unsigned | NO | | 0 | |
-| network | | char(4) | NO | | | |
-| alias | | varchar(255) | NO | | | |
-| pubkey | | text | YES | | NULL | |
-| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
+| Field | Description | Type | Null | Key | Default | Extra |
+| -------- | ------------------------------------------------------------- | ---------------- | ---- | --- | ------------------- | -------------- |
+| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
+| guid | unique id | varchar(255) | NO | | | |
+| url | | varchar(255) | NO | | | |
+| uri-id | Id of the item-uri table entry that contains the fcontact url | int unsigned | YES | | NULL | |
+| name | | varchar(255) | NO | | | |
+| photo | | varchar(255) | NO | | | |
+| request | | varchar(255) | NO | | | |
+| nick | | varchar(255) | NO | | | |
+| addr | | varchar(255) | NO | | | |
+| batch | | varchar(255) | NO | | | |
+| notify | | varchar(255) | NO | | | |
+| poll | | varchar(255) | NO | | | |
+| confirm | | varchar(255) | NO | | | |
+| priority | | tinyint unsigned | NO | | 0 | |
+| network | | char(4) | NO | | | |
+| alias | | varchar(255) | NO | | | |
+| pubkey | | text | YES | | NULL | |
+| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
Indexes
------------
@@ -34,6 +35,13 @@ Indexes
| PRIMARY | id |
| addr | addr(32) |
| url | UNIQUE, url(190) |
+| uri-id | UNIQUE, uri-id |
+Foreign Keys
+------------
+
+| Field | Target Table | Target Field |
+|-------|--------------|--------------|
+| uri-id | [item-uri](help/database/db_item-uri) | id |
Return to [database documentation](help/database)
diff --git a/doc/database/db_post-link.md b/doc/database/db_post-link.md
new file mode 100644
index 000000000..a16245356
--- /dev/null
+++ b/doc/database/db_post-link.md
@@ -0,0 +1,31 @@
+Table post-link
+===========
+
+Post related external links
+
+Fields
+------
+
+| Field | Description | Type | Null | Key | Default | Extra |
+| -------- | --------------------------------------------------------- | -------------- | ---- | --- | ------- | -------------- |
+| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
+| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | | NULL | |
+| url | External URL | varbinary(511) | NO | | NULL | |
+| mimetype | | varchar(60) | YES | | NULL | |
+
+Indexes
+------------
+
+| Name | Fields |
+| ---------- | ------------------- |
+| PRIMARY | id |
+| uri-id-url | UNIQUE, uri-id, url |
+
+Foreign Keys
+------------
+
+| Field | Target Table | Target Field |
+|-------|--------------|--------------|
+| uri-id | [item-uri](help/database/db_item-uri) | id |
+
+Return to [database documentation](help/database)
diff --git a/doc/database/db_post-thread-user.md b/doc/database/db_post-thread-user.md
index 3efb5a77a..7307dc78d 100644
--- a/doc/database/db_post-thread-user.md
+++ b/doc/database/db_post-thread-user.md
@@ -35,23 +35,24 @@ Fields
Indexes
------------
-| Name | Fields |
-| ------------- | -------------- |
-| PRIMARY | uid, uri-id |
-| uri-id | uri-id |
-| owner-id | owner-id |
-| author-id | author-id |
-| causer-id | causer-id |
-| uid | uid |
-| contact-id | contact-id |
-| psid | psid |
-| post-user-id | post-user-id |
-| commented | commented |
-| uid_received | uid, received |
-| uid_pinned | uid, pinned |
-| uid_commented | uid, commented |
-| uid_starred | uid, starred |
-| uid_mention | uid, mention |
+| Name | Fields |
+| ----------------- | ------------------- |
+| PRIMARY | uid, uri-id |
+| uri-id | uri-id |
+| owner-id | owner-id |
+| author-id | author-id |
+| causer-id | causer-id |
+| uid | uid |
+| contact-id | contact-id |
+| psid | psid |
+| post-user-id | post-user-id |
+| commented | commented |
+| uid_received | uid, received |
+| uid_wall_received | uid, wall, received |
+| uid_pinned | uid, pinned |
+| uid_commented | uid, commented |
+| uid_starred | uid, starred |
+| uid_mention | uid, mention |
Foreign Keys
------------
diff --git a/include/api.php b/include/api.php
index 492d3d1cb..25efa8f1b 100644
--- a/include/api.php
+++ b/include/api.php
@@ -64,7 +64,6 @@ use Friendica\Security\OAuth1\OAuthUtil;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Images;
use Friendica\Util\Network;
-use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Strings;
use Friendica\Util\XML;
@@ -2552,10 +2551,10 @@ function api_convert_item($item)
{
$body = api_add_attachments_to_body($item);
- $entities = api_get_entitities($statustext, $body);
+ $entities = api_get_entitities($statustext, $body, $item['uri-id']);
// Add pictures to the attachment array and remove them from the body
- $attachments = api_get_attachments($body);
+ $attachments = api_get_attachments($body, $item['uri-id']);
// Workaround for ostatus messages where the title is identically to the body
$html = BBCode::convert(api_clean_plain_items($body), false, BBCode::API, true);
@@ -2650,11 +2649,12 @@ function api_add_attachments_to_body(array $item)
/**
*
* @param string $body
+ * @param int $uriid
*
* @return array
* @throws InternalServerErrorException
*/
-function api_get_attachments(&$body)
+function api_get_attachments(&$body, $uriid)
{
$body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
$body = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $body);
@@ -2675,11 +2675,7 @@ function api_get_attachments(&$body)
$imagedata = Images::getInfoFromURLCached($image);
if ($imagedata) {
- if (DI::config()->get("system", "proxy_disabled")) {
- $attachments[] = ["url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]];
- } else {
- $attachments[] = ["url" => ProxyUtils::proxifyUrl($image, false), "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]];
- }
+ $attachments[] = ["url" => Post\Link::getByLink($uriid, $image), "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]];
}
}
@@ -2695,7 +2691,7 @@ function api_get_attachments(&$body)
* @throws InternalServerErrorException
* @todo Links at the first character of the post
*/
-function api_get_entitities(&$text, $bbcode)
+function api_get_entitities(&$text, $bbcode, $uriid)
{
$include_entities = strtolower($_REQUEST['include_entities'] ?? 'false');
@@ -2703,7 +2699,7 @@ function api_get_entitities(&$text, $bbcode)
preg_match_all("/\[img](.*?)\[\/img\]/ism", $bbcode, $images);
foreach ($images[1] as $image) {
- $replace = ProxyUtils::proxifyUrl($image, false);
+ $replace = Post\Link::getByLink($uriid, $image);
$text = str_replace($image, $replace, $text);
}
return [];
@@ -2815,31 +2811,8 @@ function api_get_entitities(&$text, $bbcode)
if (!($start === false)) {
$image = Images::getInfoFromURLCached($url);
if ($image) {
- // If image cache is activated, then use the following sizes:
- // thumb (150), small (340), medium (600) and large (1024)
- if (!DI::config()->get("system", "proxy_disabled")) {
- $media_url = ProxyUtils::proxifyUrl($url, false);
-
- $sizes = [];
- $scale = Images::getScalingDimensions($image[0], $image[1], 150);
- $sizes["thumb"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
-
- if (($image[0] > 150) || ($image[1] > 150)) {
- $scale = Images::getScalingDimensions($image[0], $image[1], 340);
- $sizes["small"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
- }
-
- $scale = Images::getScalingDimensions($image[0], $image[1], 600);
- $sizes["medium"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
-
- if (($image[0] > 600) || ($image[1] > 600)) {
- $scale = Images::getScalingDimensions($image[0], $image[1], 1024);
- $sizes["large"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
- }
- } else {
- $media_url = $url;
- $sizes["medium"] = ["w" => $image[0], "h" => $image[1], "resize" => "fit"];
- }
+ $media_url = Post\Link::getByLink($uriid, $url);
+ $sizes["medium"] = ["w" => $image[0], "h" => $image[1], "resize" => "fit"];
$entities["media"][] = [
"id" => $start+1,
diff --git a/mod/display.php b/mod/display.php
index c9d39b1db..7a8bca457 100644
--- a/mod/display.php
+++ b/mod/display.php
@@ -334,8 +334,8 @@ function display_content(App $a, $update = false, $update_uid = 0)
$o .= conversation($a, [$item], 'display', $update_uid, false, 'commented', $item_uid);
// Preparing the meta header
- $description = trim(HTML::toPlaintext(BBCode::convert($item["body"], false), 0, true));
- $title = trim(HTML::toPlaintext(BBCode::convert($item["title"], false), 0, true));
+ $description = trim(BBCode::toPlaintext($item["body"]));
+ $title = trim(BBCode::toPlaintext($item["title"]));
$author_name = $item["author-name"];
$image = DI::baseUrl()->remove($item["author-avatar"]);
diff --git a/mod/message.php b/mod/message.php
index 06542bbaf..2705708ea 100644
--- a/mod/message.php
+++ b/mod/message.php
@@ -325,7 +325,7 @@ function message_content(App $a)
$to_name_e = $message['name'];
$contact = Contact::getByURL($message['from-url'], false, ['thumb', 'addr', 'id', 'avatar']);
- $from_photo = Contact::getThumb($contact, $message['from-photo']);
+ $from_photo = Contact::getThumb($contact);
$mails[] = [
'id' => $message['id'],
@@ -457,7 +457,7 @@ function render_messages(array $msg, $t)
}
$contact = Contact::getByURL($rr['url'], false, ['thumb', 'addr', 'id', 'avatar']);
- $from_photo = Contact::getThumb($contact, $rr['thumb'] ?: $rr['from-photo']);
+ $from_photo = Contact::getThumb($contact);
$rslt .= Renderer::replaceMacros($tpl, [
'$id' => $rr['id'],
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index 634ea9aac..37f650bbe 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -37,6 +37,7 @@ use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Event;
use Friendica\Model\Photo;
+use Friendica\Model\Post;
use Friendica\Model\Tag;
use Friendica\Object\Image;
use Friendica\Protocol\Activity;
@@ -251,7 +252,7 @@ class BBCode
$post = self::getAttachmentData($body);
// Get all linked images with alternative image description
- if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
+ if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) {
if (Photo::isLocal($picture[1])) {
$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2]];
@@ -433,18 +434,27 @@ class BBCode
*/
public static function toPlaintext($text, $keep_urls = true)
{
+ // Remove pictures in advance to avoid unneeded proxy calls
+ $text = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $2 ', $text);
+ $text = preg_replace("/\[img.*?\[\/img\]/ism", ' ', $text);
+
+ // Remove attachment
+ $text = self::removeAttachment($text);
+
$naked_text = HTML::toPlaintext(self::convert($text, false, 0, true), 0, !$keep_urls);
return $naked_text;
}
- private static function proxyUrl($image, $simplehtml = self::INTERNAL)
+ private static function proxyUrl($image, $simplehtml = self::INTERNAL, $uriid = 0, $size = '')
{
// Only send proxied pictures to API and for internal display
- if (in_array($simplehtml, [self::INTERNAL, self::API])) {
- return ProxyUtils::proxifyUrl($image);
- } else {
+ if (!in_array($simplehtml, [self::INTERNAL, self::API])) {
return $image;
+ } elseif ($uriid) {
+ return Post\Link::getByLink($uriid, $image, $size);
+ } else {
+ return ProxyUtils::proxifyUrl($image, $size);
}
}
@@ -608,10 +618,11 @@ class BBCode
* @param integer $simplehtml
* @param bool $tryoembed
* @param array $data
+ * @param int $uriid
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function convertAttachment($text, $simplehtml = self::INTERNAL, $tryoembed = true, array $data = [])
+ public static function convertAttachment($text, $simplehtml = self::INTERNAL, $tryoembed = true, array $data = [], $uriid = 0)
{
$data = $data ?: self::getAttachmentData($text);
if (empty($data) || empty($data['url'])) {
@@ -648,12 +659,12 @@ class BBCode
if (!empty($data['title']) && !empty($data['url'])) {
if (!empty($data['image']) && empty($data['text']) && ($data['type'] == 'photo')) {
- $return .= sprintf('
', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
+ $return .= sprintf('
', $data['url'], self::proxyUrl($data['image'], $simplehtml, $uriid), $data['title']);
} else {
if (!empty($data['image'])) {
- $return .= sprintf('
', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
+ $return .= sprintf('
', $data['url'], self::proxyUrl($data['image'], $simplehtml, $uriid), $data['title']);
} elseif (!empty($data['preview'])) {
- $return .= sprintf('
', $data['url'], self::proxyUrl($data['preview'], $simplehtml), $data['title']);
+ $return .= sprintf('
', $data['url'], self::proxyUrl($data['preview'], $simplehtml, $uriid), $data['title']);
}
$return .= sprintf('
" . BBCode::convert(Strings::escapeHtml($event['desc']), false, $simple) . "
";
+ $o .= "" . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['desc']), $simple) . "
";
}
$o .= "" . $event_start . "
";
@@ -81,7 +83,7 @@ class Event
}
if (!empty($event['location'])) {
- $o .= "" . BBCode::convert(Strings::escapeHtml($event['location']), false, $simple) . "
";
+ $o .= "" . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['location']), $simple) . "
";
}
return $o;
@@ -89,7 +91,7 @@ class Event
$o = '' . "\r\n";
- $o .= '
' . BBCode::convert(Strings::escapeHtml($event['summary']), false, $simple) . '
' . "\r\n";
+ $o .= '
' . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['summary']), $simple) . '
' . "\r\n";
$o .= '
' . DI::l10n()->t('Starts:') . ' ' . BBCode::convert(Strings::escapeHtml($event['desc']), false, $simple) . '
' . "\r\n";
+ $o .= '
' . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['desc']), $simple) . '
' . "\r\n";
}
if (!empty($event['location'])) {
$o .= '
' . DI::l10n()->t('Location:') . ' '
- . BBCode::convert(Strings::escapeHtml($event['location']), false, $simple)
+ . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['location']), $simple)
. '
' . "\r\n";
// Include a map of the location if the [map] BBCode is used.
@@ -273,6 +275,7 @@ class Event
$event['cid'] = intval($arr['cid'] ?? 0);
$event['guid'] = ($arr['guid'] ?? '') ?: System::createUUID();
$event['uri'] = ($arr['uri'] ?? '') ?: Item::newURI($event['uid'], $event['guid']);
+ $event['uri-id'] = ItemURI::insert(['uri' => $event['uri'], 'guid' => $event['guid']]);
$event['type'] = ($arr['type'] ?? '') ?: 'event';
$event['summary'] = $arr['summary'] ?? '';
$event['desc'] = $arr['desc'] ?? '';
@@ -620,9 +623,9 @@ class Event
$drop = [DI::baseUrl() . '/events/drop/' . $event['id'] , DI::l10n()->t('Delete event') , '', ''];
}
- $title = BBCode::convert(Strings::escapeHtml($event['summary']));
+ $title = BBCode::convertForUriId($event['uri-id'], Strings::escapeHtml($event['summary']));
if (!$title) {
- list($title, $_trash) = explode("
$event['id'],
'start' => $start,
@@ -937,7 +940,7 @@ class Event
$tpl = Renderer::getMarkupTemplate('event_stream_item.tpl');
$return = Renderer::replaceMacros($tpl, [
'$id' => $item['event-id'],
- '$title' => BBCode::convert($item['event-summary']),
+ '$title' => BBCode::convertForUriId($item['uri-id'], $item['event-summary']),
'$dtstart_label' => DI::l10n()->t('Starts:'),
'$dtstart_title' => $dtstart_title,
'$dtstart_dt' => $dtstart_dt,
@@ -955,7 +958,7 @@ class Event
'$author_name' => $item['author-name'],
'$author_link' => $profile_link,
'$author_avatar' => $item['author-avatar'],
- '$description' => BBCode::convert($item['event-desc']),
+ '$description' => BBCode::convertForUriId($item['uri-id'], $item['event-desc']),
'$location_label' => DI::l10n()->t('Location:'),
'$show_map_label' => DI::l10n()->t('Show map'),
'$hide_map_label' => DI::l10n()->t('Hide map'),
diff --git a/src/Model/FContact.php b/src/Model/FContact.php
index cf75a03db..0fc463327 100644
--- a/src/Model/FContact.php
+++ b/src/Model/FContact.php
@@ -60,7 +60,7 @@ class FContact
$update = true;
}
- if ($person["guid"] == "") {
+ if (empty($person['guid']) || empty($person['uri-id'])) {
$update = true;
}
}
@@ -100,6 +100,7 @@ class FContact
'batch' => $arr["batch"], 'notify' => $arr["notify"],
'poll' => $arr["poll"], 'confirm' => $arr["confirm"],
'alias' => $arr["alias"], 'pubkey' => $arr["pubkey"],
+ 'uri-id' => ItemURI::insert(['uri' => $arr['url'], 'guid' => $arr['guid']]),
'updated' => DateTimeFormat::utcNow()];
$condition = ['url' => $arr["url"], 'network' => $arr["network"]];
diff --git a/src/Model/Item.php b/src/Model/Item.php
index fb88da8a2..86b9270fe 100644
--- a/src/Model/Item.php
+++ b/src/Model/Item.php
@@ -1008,9 +1008,6 @@ class Item
// Check for hashtags in the body and repair or add hashtag links
$item['body'] = self::setHashtags($item['body']);
- // Fill the cache field
- self::putInCache($item);
-
if (stristr($item['verb'], Activity::POKE)) {
$notify_type = Delivery::POKE;
} else {
@@ -2643,7 +2640,7 @@ class Item
) {
self::addRedirToImageTags($item);
- $item['rendered-html'] = BBCode::convert($item['body']);
+ $item['rendered-html'] = BBCode::convertForUriId($item['uri-id'], $item['body']);
$item['rendered-hash'] = hash('md5', BBCode::VERSION . '::' . $body);
$hook_data = ['item' => $item, 'rendered-html' => $item['rendered-html'], 'rendered-hash' => $item['rendered-hash']];
@@ -2783,13 +2780,13 @@ class Item
if (!empty($shared_attachments)) {
$s = self::addVisualAttachments($shared_attachments, $item, $s, true);
- $s = self::addLinkAttachment($shared_attachments, $body, $s, true, []);
+ $s = self::addLinkAttachment($shared_uri_id ?: $item['uri-id'], $shared_attachments, $body, $s, true, []);
$s = self::addNonVisualAttachments($shared_attachments, $item, $s, true);
$body = preg_replace("/\s*\[share .*?\].*?\[\/share\]\s*/ism", '', $body);
}
$s = self::addVisualAttachments($attachments, $item, $s, false);
- $s = self::addLinkAttachment($attachments, $body, $s, false, $shared_links);
+ $s = self::addLinkAttachment($item['uri-id'], $attachments, $body, $s, false, $shared_links);
$s = self::addNonVisualAttachments($attachments, $item, $s, false);
// Map.
@@ -2970,7 +2967,7 @@ class Item
* @param array $ignore_links A list of URLs to ignore
* @return string modified content
*/
- private static function addLinkAttachment(array $attachments, string $body, string $content, bool $shared, array $ignore_links)
+ private static function addLinkAttachment(int $uriid, array $attachments, string $body, string $content, bool $shared, array $ignore_links)
{
$stamp1 = microtime(true);
// @ToDo Check only for audio and video
@@ -3056,7 +3053,7 @@ class Item
}
// @todo Use a template
- $rendered = BBCode::convertAttachment('', BBCode::INTERNAL, false, $data);
+ $rendered = BBCode::convertAttachment('', BBCode::INTERNAL, false, $data, $uriid);
} elseif (!self::containsLink($content, $data['url'], Post\Media::HTML)) {
$rendered = Renderer::replaceMacros(Renderer::getMarkupTemplate('content/link.tpl'), [
'$url' => $data['url'],
diff --git a/src/Model/Post.php b/src/Model/Post.php
index 902525f99..7b77276de 100644
--- a/src/Model/Post.php
+++ b/src/Model/Post.php
@@ -156,6 +156,27 @@ class Post
return DBA::count('post-user-view', $condition, $params);
}
+ /**
+ * Counts the post-thread-user-view records satisfying the provided condition
+ *
+ * @param array $condition array of fields for condition
+ * @param array $params Array of several parameters
+ *
+ * @return int
+ *
+ * Example:
+ * $condition = ["uid" => 1, "network" => 'dspr'];
+ * or:
+ * $condition = ["`uid` = ? AND `network` IN (?, ?)", 1, 'dfrn', 'dspr'];
+ *
+ * $count = Post::count($condition);
+ * @throws \Exception
+ */
+ public static function countThread(array $condition = [], array $params = [])
+ {
+ return DBA::count('post-thread-user-view', $condition, $params);
+ }
+
/**
* Counts the post-view records satisfying the provided condition
*
diff --git a/src/Model/Post/Link.php b/src/Model/Post/Link.php
new file mode 100644
index 000000000..758f00f1c
--- /dev/null
+++ b/src/Model/Post/Link.php
@@ -0,0 +1,127 @@
+.
+ *
+ */
+
+namespace Friendica\Model\Post;
+
+use Friendica\Core\Logger;
+use Friendica\Core\System;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Util\Proxy;
+
+/**
+ * Class Link
+ *
+ * This Model class handles post related external links
+ */
+class Link
+{
+ public static function getByLink(int $uri_id, string $url, $size = '')
+ {
+ if (empty($uri_id) || empty($url) || Proxy::isLocalImage($url)) {
+ return $url;
+ }
+
+ if (!in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'])) {
+ Logger::info('Bad URL, quitting', ['uri-id' => $uri_id, 'url' => $url, 'callstack' => System::callstack(20)]);
+ return $url;
+ }
+
+ $link = DBA::selectFirst('post-link', ['id'], ['uri-id' => $uri_id, 'url' => $url]);
+ if (!empty($link['id'])) {
+ $id = $link['id'];
+ Logger::info('Found', ['id' => $id, 'uri-id' => $uri_id, 'url' => $url]);
+ } else {
+ $mime = self::fetchMimeType($url);
+
+ DBA::insert('post-link', ['uri-id' => $uri_id, 'url' => $url, 'mimetype' => $mime]);
+ $id = DBA::lastInsertId();
+ Logger::info('Inserted', ['id' => $id, 'uri-id' => $uri_id, 'url' => $url]);
+ }
+
+ if (empty($id)) {
+ return $url;
+ }
+
+ $url = DI::baseUrl() . '/photo/link/';
+ switch ($size) {
+ case Proxy::SIZE_MICRO:
+ $url .= Proxy::PIXEL_MICRO . '/';
+ break;
+ case Proxy::SIZE_THUMB:
+ $url .= Proxy::PIXEL_THUMB . '/';
+ break;
+ case Proxy::SIZE_SMALL:
+ $url .= Proxy::PIXEL_SMALL . '/';
+ break;
+ case Proxy::SIZE_MEDIUM:
+ $url .= Proxy::PIXEL_MEDIUM . '/';
+ break;
+ case Proxy::SIZE_LARGE:
+ $url .= Proxy::PIXEL_LARGE . '/';
+ break;
+ }
+ return $url . $id;
+ }
+
+ private static function fetchMimeType(string $url)
+ {
+ $timeout = DI::config()->get('system', 'xrd_timeout');
+
+ $curlResult = DI::httpRequest()->head($url, ['timeout' => $timeout]);
+ if ($curlResult->isSuccess()) {
+ if (empty($media['mimetype'])) {
+ return $curlResult->getHeader('Content-Type');
+ }
+ }
+ return '';
+ }
+
+ /**
+ * Add external links and replace them in the body
+ *
+ * @param integer $uriid
+ * @param string $body
+ * @return string Body with replaced links
+ */
+ public static function insertFromBody(int $uriid, string $body)
+ {
+ if (preg_match_all("/\[img\=([0-9]*)x([0-9]*)\](http.*?)\[\/img\]/ism", $body, $pictures, PREG_SET_ORDER)) {
+ foreach ($pictures as $picture) {
+ $body = str_replace($picture[3], self::getByLink($uriid, $picture[3]), $body);
+ }
+ }
+
+ if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
+ foreach ($pictures as $picture) {
+ $body = str_replace($picture[1], self::getByLink($uriid, $picture[1]), $body);
+ }
+ }
+
+ if (preg_match_all("/\[img\](http[^\[\]]*)\[\/img\]/ism", $body, $pictures, PREG_SET_ORDER)) {
+ foreach ($pictures as $picture) {
+ $body = str_replace($picture[1], self::getByLink($uriid, $picture[1]), $body);
+ }
+ }
+
+ return trim($body);
+ }
+}
diff --git a/src/Module/Admin/Site.php b/src/Module/Admin/Site.php
index a04b4194d..068b01326 100644
--- a/src/Module/Admin/Site.php
+++ b/src/Module/Admin/Site.php
@@ -194,13 +194,10 @@ class Site extends BaseAdmin
$dbclean_unclaimed = (!empty($_POST['dbclean_unclaimed']) ? intval($_POST['dbclean_unclaimed']) : 0);
$dbclean_expire_conv = (!empty($_POST['dbclean_expire_conv']) ? intval($_POST['dbclean_expire_conv']) : 0);
$suppress_tags = !empty($_POST['suppress_tags']);
- $itemcache = (!empty($_POST['itemcache']) ? Strings::escapeTags(trim($_POST['itemcache'])) : '');
- $itemcache_duration = (!empty($_POST['itemcache_duration']) ? intval($_POST['itemcache_duration']) : 0);
$max_comments = (!empty($_POST['max_comments']) ? intval($_POST['max_comments']) : 0);
$max_display_comments = (!empty($_POST['max_display_comments']) ? intval($_POST['max_display_comments']) : 0);
$temppath = (!empty($_POST['temppath']) ? Strings::escapeTags(trim($_POST['temppath'])) : '');
$singleuser = (!empty($_POST['singleuser']) ? Strings::escapeTags(trim($_POST['singleuser'])) : '');
- $proxy_disabled = !empty($_POST['proxy_disabled']);
$only_tag_search = !empty($_POST['only_tag_search']);
$rino = (!empty($_POST['rino']) ? intval($_POST['rino']) : 0);
$check_new_version_url = (!empty($_POST['check_new_version_url']) ? Strings::escapeTags(trim($_POST['check_new_version_url'])) : 'none');
@@ -395,12 +392,6 @@ class Site extends BaseAdmin
DI::config()->set('system', 'dbclean-expire-unclaimed', $dbclean_unclaimed);
- if ($itemcache != '') {
- $itemcache = BasePath::getRealPath($itemcache);
- }
-
- DI::config()->set('system', 'itemcache', $itemcache);
- DI::config()->set('system', 'itemcache_duration', $itemcache_duration);
DI::config()->set('system', 'max_comments', $max_comments);
DI::config()->set('system', 'max_display_comments', $max_display_comments);
@@ -410,7 +401,6 @@ class Site extends BaseAdmin
DI::config()->set('system', 'temppath', $temppath);
- DI::config()->set('system', 'proxy_disabled' , $proxy_disabled);
DI::config()->set('system', 'only_tag_search' , $only_tag_search);
DI::config()->set('system', 'worker_queues' , $worker_queues);
@@ -506,7 +496,6 @@ class Site extends BaseAdmin
// Automatically create temporary paths
get_temppath();
- get_itemcachepath();
/* Register policy */
$register_choices = [
@@ -674,12 +663,9 @@ class Site extends BaseAdmin
'$dbclean_expire_days' => ['dbclean_expire_days', DI::l10n()->t('Lifespan of remote items'), DI::config()->get('system', 'dbclean-expire-days'), DI::l10n()->t('When the database cleanup is enabled, this defines the days after which remote items will be deleted. Own items, and marked or filed items are always kept. 0 disables this behaviour.')],
'$dbclean_unclaimed' => ['dbclean_unclaimed', DI::l10n()->t('Lifespan of unclaimed items'), DI::config()->get('system', 'dbclean-expire-unclaimed'), DI::l10n()->t('When the database cleanup is enabled, this defines the days after which unclaimed remote items (mostly content from the relay) will be deleted. Default value is 90 days. Defaults to the general lifespan value of remote items if set to 0.')],
'$dbclean_expire_conv' => ['dbclean_expire_conv', DI::l10n()->t('Lifespan of raw conversation data'), DI::config()->get('system', 'dbclean_expire_conversation'), DI::l10n()->t('The conversation data is used for ActivityPub and OStatus, as well as for debug purposes. It should be safe to remove it after 14 days, default is 90 days.')],
- '$itemcache' => ['itemcache', DI::l10n()->t('Path to item cache'), DI::config()->get('system', 'itemcache'), DI::l10n()->t('The item caches buffers generated bbcode and external images.')],
- '$itemcache_duration' => ['itemcache_duration', DI::l10n()->t('Cache duration in seconds'), DI::config()->get('system', 'itemcache_duration'), DI::l10n()->t('How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1.')],
'$max_comments' => ['max_comments', DI::l10n()->t('Maximum numbers of comments per post'), DI::config()->get('system', 'max_comments'), DI::l10n()->t('How much comments should be shown for each post? Default value is 100.')],
'$max_display_comments' => ['max_display_comments', DI::l10n()->t('Maximum numbers of comments per post on the display page'), DI::config()->get('system', 'max_display_comments'), DI::l10n()->t('How many comments should be shown on the single view for each post? Default value is 1000.')],
'$temppath' => ['temppath', DI::l10n()->t('Temp path'), DI::config()->get('system', 'temppath'), DI::l10n()->t('If you have a restricted system where the webserver can\'t access the system temp path, enter another path here.')],
- '$proxy_disabled' => ['proxy_disabled', DI::l10n()->t('Disable picture proxy'), DI::config()->get('system', 'proxy_disabled'), DI::l10n()->t('The picture proxy increases performance and privacy. It shouldn\'t be used on systems with very low bandwidth.')],
'$only_tag_search' => ['only_tag_search', DI::l10n()->t('Only search in tags'), DI::config()->get('system', 'only_tag_search'), DI::l10n()->t('On large systems the text search can slow down the system extremely.')],
'$relocate_url' => ['relocate_url', DI::l10n()->t('New base url'), DI::baseUrl()->get(), DI::l10n()->t('Change base url for this server. Sends relocate message to all Friendica and Diaspora* contacts of all users.')],
diff --git a/src/Module/Api/Mastodon/Statuses.php b/src/Module/Api/Mastodon/Statuses.php
index 77915cab2..1007bea0b 100644
--- a/src/Module/Api/Mastodon/Statuses.php
+++ b/src/Module/Api/Mastodon/Statuses.php
@@ -140,6 +140,8 @@ class Statuses extends BaseApi
$item['gravity'] = GRAVITY_COMMENT;
$item['object-type'] = Activity\ObjectType::COMMENT;
} else {
+ self::checkThrottleLimit();
+
$item['gravity'] = GRAVITY_PARENT;
$item['object-type'] = Activity\ObjectType::NOTE;
}
diff --git a/src/Module/BaseApi.php b/src/Module/BaseApi.php
index f5a16da76..9d5c36f42 100644
--- a/src/Module/BaseApi.php
+++ b/src/Module/BaseApi.php
@@ -25,9 +25,11 @@ use Friendica\BaseModule;
use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\DI;
+use Friendica\Model\Post;
use Friendica\Network\HTTPException;
use Friendica\Security\BasicAuth;
use Friendica\Security\OAuth;
+use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPInputData;
require_once __DIR__ . '/../../include/api.php';
@@ -282,6 +284,60 @@ class BaseApi extends BaseModule
}
}
+ public static function checkThrottleLimit()
+ {
+ $uid = self::getCurrentUserID();
+
+ // Check for throttling (maximum posts per day, week and month)
+ $throttle_day = DI::config()->get('system', 'throttle_limit_day');
+ if ($throttle_day > 0) {
+ $datefrom = date(DateTimeFormat::MYSQL, time() - 24*60*60);
+
+ $condition = ["`gravity` = ? AND `uid` = ? AND `wall` AND `received` > ?", GRAVITY_PARENT, $uid, $datefrom];
+ $posts_day = Post::countThread($condition);
+
+ if ($posts_day > $throttle_day) {
+ Logger::info('Daily posting limit reached', ['uid' => $uid, 'posts' => $posts_day, 'limit' => $throttle_day]);
+ $error = DI::l10n()->t('Too Many Requests');
+ $error_description = DI::l10n()->tt("Daily posting limit of %d post reached. The post was rejected.", "Daily posting limit of %d posts reached. The post was rejected.", $throttle_day);
+ $errorobj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
+ System::jsonError(429, $errorobj->toArray());
+ }
+ }
+
+ $throttle_week = DI::config()->get('system', 'throttle_limit_week');
+ if ($throttle_week > 0) {
+ $datefrom = date(DateTimeFormat::MYSQL, time() - 24*60*60*7);
+
+ $condition = ["`gravity` = ? AND `uid` = ? AND `wall` AND `received` > ?", GRAVITY_PARENT, $uid, $datefrom];
+ $posts_week = Post::countThread($condition);
+
+ if ($posts_week > $throttle_week) {
+ Logger::info('Weekly posting limit reached', ['uid' => $uid, 'posts' => $posts_week, 'limit' => $throttle_week]);
+ $error = DI::l10n()->t('Too Many Requests');
+ $error_description = DI::l10n()->tt("Weekly posting limit of %d post reached. The post was rejected.", "Weekly posting limit of %d posts reached. The post was rejected.", $throttle_week);
+ $errorobj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
+ System::jsonError(429, $errorobj->toArray());
+ }
+ }
+
+ $throttle_month = DI::config()->get('system', 'throttle_limit_month');
+ if ($throttle_month > 0) {
+ $datefrom = date(DateTimeFormat::MYSQL, time() - 24*60*60*30);
+
+ $condition = ["`gravity` = ? AND `uid` = ? AND `wall` AND `received` > ?", GRAVITY_PARENT, $uid, $datefrom];
+ $posts_month = Post::countThread($condition);
+
+ if ($posts_month > $throttle_month) {
+ Logger::info('Monthly posting limit reached', ['uid' => $uid, 'posts' => $posts_month, 'limit' => $throttle_month]);
+ $error = DI::l10n()->t('Too Many Requests');
+ $error_description = DI::l10n()->t("Monthly posting limit of %d post reached. The post was rejected.", "Monthly posting limit of %d posts reached. The post was rejected.", $throttle_month);
+ $errorobj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description);
+ System::jsonError(429, $errorobj->toArray());
+ }
+ }
+ }
+
/**
* Get user info array.
*
diff --git a/src/Module/Contact.php b/src/Module/Contact.php
index cc6cc7e05..2609a5b8b 100644
--- a/src/Module/Contact.php
+++ b/src/Module/Contact.php
@@ -650,11 +650,11 @@ class Contact extends BaseModule
'$profileurllabel'=> DI::l10n()->t('Profile URL'),
'$profileurl' => $contact['url'],
'$account_type' => Model\Contact::getAccountType($contact),
- '$location' => BBCode::convert($contact['location']),
+ '$location' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['location']),
'$location_label' => DI::l10n()->t('Location:'),
- '$xmpp' => BBCode::convert($contact['xmpp']),
+ '$xmpp' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['xmpp']),
'$xmpp_label' => DI::l10n()->t('XMPP:'),
- '$about' => BBCode::convert($contact['about'], false),
+ '$about' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['about'], BBCode::EXTERNAL),
'$about_label' => DI::l10n()->t('About:'),
'$keywords' => $contact['keywords'],
'$keywords_label' => DI::l10n()->t('Tags:'),
@@ -1111,7 +1111,7 @@ class Contact extends BaseModule
'url' => $url,
'img_hover' => DI::l10n()->t('Visit %s\'s profile [%s]', $contact['name'], $contact['url']),
'photo_menu' => Model\Contact::photoMenu($contact),
- 'thumb' => Model\Contact::getThumb($contact, '', true),
+ 'thumb' => Model\Contact::getThumb($contact, true),
'alt_text' => $alt_text,
'name' => $contact['name'],
'nick' => $contact['nick'],
diff --git a/src/Module/Photo.php b/src/Module/Photo.php
index 44be9a31a..e669de8a3 100644
--- a/src/Module/Photo.php
+++ b/src/Module/Photo.php
@@ -176,7 +176,7 @@ class Photo extends BaseModule
{
switch($type) {
case "preview":
- $media = DBA::selectFirst('post-media', ['preview', 'url', 'type', 'uri-id'], ['id' => $uid]);
+ $media = DBA::selectFirst('post-media', ['preview', 'url', 'mimetype', 'type', 'uri-id'], ['id' => $uid]);
if (empty($media)) {
return false;
}
@@ -194,9 +194,9 @@ class Photo extends BaseModule
return MPhoto::getPhoto($matches[1], $matches[2]);
}
- return MPhoto::createPhotoForExternalResource($url, (int)local_user());
+ return MPhoto::createPhotoForExternalResource($url, (int)local_user(), $media['mimetype']);
case "media":
- $media = DBA::selectFirst('post-media', ['url', 'uri-id'], ['id' => $uid, 'type' => Post\Media::IMAGE]);
+ $media = DBA::selectFirst('post-media', ['url', 'mimetype', 'uri-id'], ['id' => $uid, 'type' => Post\Media::IMAGE]);
if (empty($media)) {
return false;
}
@@ -205,7 +205,14 @@ class Photo extends BaseModule
return MPhoto::getPhoto($matches[1], $matches[2]);
}
- return MPhoto::createPhotoForExternalResource($media['url'], (int)local_user());
+ return MPhoto::createPhotoForExternalResource($media['url'], (int)local_user(), $media['mimetype']);
+ case "link":
+ $link = DBA::selectFirst('post-link', ['url', 'mimetype'], ['id' => $uid]);
+ if (empty($link)) {
+ return false;
+ }
+
+ return MPhoto::createPhotoForExternalResource($link['url'], (int)local_user(), $link['mimetype']);
case "contact":
$contact = Contact::getById($uid, ['uid', 'url', 'avatar', 'photo', 'xmpp', 'addr']);
if (empty($contact)) {
diff --git a/src/Module/Proxy.php b/src/Module/Proxy.php
index 317ec530a..b1683e8f5 100644
--- a/src/Module/Proxy.php
+++ b/src/Module/Proxy.php
@@ -24,10 +24,9 @@ namespace Friendica\Module;
use Friendica\BaseModule;
use Friendica\Core\Logger;
use Friendica\Core\System;
-use Friendica\DI;
-use Friendica\Model\Photo;
use Friendica\Object\Image;
use Friendica\Util\HTTPSignature;
+use Friendica\Util\Images;
use Friendica\Util\Proxy as ProxyUtils;
/**
@@ -41,50 +40,27 @@ class Proxy extends BaseModule
{
/**
- * Initializer method for this class.
- *
- * Sets application instance and checks if /proxy/ path is writable.
- *
+ * Fetch remote image content
*/
public static function rawContent(array $parameters = [])
{
- // Set application instance here
- $a = DI::app();
-
- /*
- * Pictures are stored in one of the following ways:
- *
- * 1. If a folder "proxy" exists and is writeable, then use this for caching
- * 2. If a cache path is defined, use this
- * 3. If everything else failed, cache into the database
- *
- * Question: Do we really need these three methods?
- */
- if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
- header('HTTP/1.1 304 Not Modified');
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
- header('Etag: ' . $_SERVER['HTTP_IF_NONE_MATCH']);
- header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
- header('Cache-Control: max-age=31536000');
-
- if (function_exists('header_remove')) {
- header_remove('Last-Modified');
- header_remove('Expires');
- header_remove('Cache-Control');
+ if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
+ header("HTTP/1.1 304 Not Modified");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT");
+ if (!empty($_SERVER["HTTP_IF_NONE_MATCH"])) {
+ header("Etag: " . $_SERVER["HTTP_IF_NONE_MATCH"]);
}
-
- /// @TODO Stop here?
- exit();
+ header("Expires: " . gmdate("D, d M Y H:i:s", time() + (31536000)) . " GMT");
+ header("Cache-Control: max-age=31536000");
+ if (function_exists("header_remove")) {
+ header_remove("Last-Modified");
+ header_remove("Expires");
+ header_remove("Cache-Control");
+ }
+ exit;
}
- if (function_exists('header_remove')) {
- header_remove('Pragma');
- header_remove('pragma');
- }
-
- $direct_cache = self::setupDirectCache();
-
- $request = self::getRequestInfo();
+ $request = self::getRequestInfo($parameters);
if (empty($request['url'])) {
throw new \Friendica\Network\HTTPException\BadRequestException();
@@ -95,35 +71,20 @@ class Proxy extends BaseModule
System::externalRedirect($request['url']);
}
- // Webserver already tried direct cache...
-
- // Try to use filecache;
- $cachefile = self::responseFromCache($request);
-
- // Try to use photo from db
- self::responseFromDB($request);
-
- //
- // If script is here, the requested url has never cached before.
- // Let's fetch it, scale it if required, then save it in cache.
- //
-
// It shouldn't happen but it does - spaces in URL
$request['url'] = str_replace(' ', '+', $request['url']);
+
+ // Fetch the content with the local user
$fetchResult = HTTPSignature::fetchRaw($request['url'], local_user(), ['timeout' => 10]);
$img_str = $fetchResult->getBody();
- // If there is an error then return a blank image
- if ((substr($fetchResult->getReturnCode(), 0, 1) == '4') || empty($img_str)) {
+ if (!$fetchResult->isSuccess() || empty($img_str)) {
Logger::info('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]);
self::responseError();
// stop.
}
- $tempfile = tempnam(get_temppath(), 'cache');
- file_put_contents($tempfile, $img_str);
- $mime = mime_content_type($tempfile);
- unlink($tempfile);
+ $mime = Images::getMimeTypeByData($img_str);
$image = new Image($img_str, $mime);
if (!$image->isValid()) {
@@ -132,80 +93,33 @@ class Proxy extends BaseModule
// stop.
}
- $basepath = $a->getBasePath();
- $filepermission = DI::config()->get('system', 'proxy_file_chmod');
-
- // Store original image
- if ($direct_cache) {
- // direct cache , store under ./proxy/
- $filename = $basepath . '/proxy/' . ProxyUtils::proxifyUrl($request['url'], true);
- file_put_contents($filename, $image->asString());
- if (!empty($filepermission)) {
- chmod($filename, $filepermission);
- }
- } elseif($cachefile !== '') {
- // cache file
- file_put_contents($cachefile, $image->asString());
- } else {
- // database
- Photo::store($image, 0, 0, $request['urlhash'], $request['url'], '', 100);
- }
-
-
// reduce quality - if it isn't a GIF
if ($image->getType() != 'image/gif') {
$image->scaleDown($request['size']);
}
-
- // Store scaled image
- if ($direct_cache && $request['sizetype'] != '') {
- $filename = $basepath . '/proxy/' . ProxyUtils::proxifyUrl($request['url'], true) . $request['sizetype'];
- file_put_contents($filename, $image->asString());
- if (!empty($filepermission)) {
- chmod($filename, $filepermission);
- }
- }
-
self::responseImageHttpCache($image);
// stop.
}
-
/**
* Build info about requested image to be proxied
*
* @return array
* [
* 'url' => requested url,
- * 'urlhash' => sha1 has of the url prefixed with 'pic:',
* 'size' => requested image size (int)
* 'sizetype' => requested image size (string): ':micro', ':thumb', ':small', ':medium', ':large'
* ]
* @throws \Exception
*/
- private static function getRequestInfo()
+ private static function getRequestInfo(array $parameters)
{
- $a = DI::app();
$size = ProxyUtils::PIXEL_LARGE;
$sizetype = '';
- // Look for filename in the arguments
- // @TODO: Replace with parameter from router
- if (($a->argc > 1) && !isset($_REQUEST['url'])) {
- if (isset($a->argv[3])) {
- $url = $a->argv[3];
- } elseif (isset($a->argv[2])) {
- $url = $a->argv[2];
- } else {
- $url = $a->argv[1];
- }
-
- /// @TODO: Why? And what about $url in this case?
- /// @TODO: Replace with parameter from router
- if (isset($a->argv[3]) && ($a->argv[3] == 'thumb')) {
- $size = 200;
- }
+ if (!empty($parameters['url']) && empty($_REQUEST['url'])) {
+ $url = $parameters['url'];
// thumb, small, medium and large.
if (substr($url, -6) == ':micro') {
@@ -238,87 +152,17 @@ class Proxy extends BaseModule
$url = str_replace(['.jpg', '.jpeg', '.gif', '.png'], ['','','',''], $url);
$url = base64_decode(strtr($url, '-_', '+/'), true);
-
} else {
$url = $_REQUEST['url'] ?? '';
}
return [
'url' => $url,
- 'urlhash' => 'pic:' . sha1($url),
'size' => $size,
'sizetype' => $sizetype,
];
}
-
- /**
- * setup ./proxy folder for direct cache
- *
- * @return bool False if direct cache can't be used.
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- private static function setupDirectCache()
- {
- $a = DI::app();
- $basepath = $a->getBasePath();
-
- // If the cache path isn't there, try to create it
- if (!is_dir($basepath . '/proxy') && is_writable($basepath)) {
- mkdir($basepath . '/proxy');
- }
-
- // Checking if caching into a folder in the webroot is activated and working
- $direct_cache = (is_dir($basepath . '/proxy') && is_writable($basepath . '/proxy'));
- // we don't use direct cache if image url is passed in args and not in querystring
- $direct_cache = $direct_cache && ($a->argc > 1) && !isset($_REQUEST['url']);
-
- return $direct_cache;
- }
-
-
- /**
- * Try to reply with image in cachefile
- *
- * @param array $request Array from getRequestInfo
- *
- * @return string Cache file name, empty string if cache is not enabled.
- *
- * If cachefile exists, script ends here and this function will never returns
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- * @throws \ImagickException
- */
- private static function responseFromCache(&$request)
- {
- $cachefile = get_cachefile(hash('md5', $request['url']));
- if ($cachefile != '' && file_exists($cachefile)) {
- $img = new Image(file_get_contents($cachefile), mime_content_type($cachefile));
- self::responseImageHttpCache($img);
- // stop.
- }
- return $cachefile;
- }
-
- /**
- * Try to reply with image in database
- *
- * @param array $request Array from getRequestInfo
- *
- * If the image exists in database, then script ends here and this function will never returns
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- * @throws \ImagickException
- */
- private static function responseFromDB(&$request)
- {
- $photo = Photo::getPhoto($request['urlhash']);
-
- if ($photo !== false) {
- $img = Photo::getImageForPhoto($photo);
- self::responseImageHttpCache($img);
- // stop.
- }
- }
-
/**
* In case of an error just stop. We don't return content to avoid caching problems
*
diff --git a/src/Module/Search/Acl.php b/src/Module/Search/Acl.php
index ab031f9cb..aa5a0e367 100644
--- a/src/Module/Search/Acl.php
+++ b/src/Module/Search/Acl.php
@@ -78,7 +78,7 @@ class Acl extends BaseModule
$contacts = [];
foreach ($result as $contact) {
$contacts[] = [
- 'photo' => Contact::getMicro($contact, '', true),
+ 'photo' => Contact::getMicro($contact, true),
'name' => htmlspecialchars($contact['name']),
'nick' => $contact['addr'] ?: $contact['url'],
'network' => $contact['network'],
diff --git a/src/Object/Api/Mastodon/Account.php b/src/Object/Api/Mastodon/Account.php
index d2053647a..2b95e0687 100644
--- a/src/Object/Api/Mastodon/Account.php
+++ b/src/Object/Api/Mastodon/Account.php
@@ -111,7 +111,7 @@ class Account extends BaseDataTransferObject
$created = $userContactCreated < $publicContactCreated && ($userContactCreated != DBA::NULL_DATETIME) ? $userContactCreated : $publicContactCreated;
$this->created_at = DateTimeFormat::utc($created, DateTimeFormat::JSON);
- $this->note = BBCode::convert($publicContact['about'], false);
+ $this->note = BBCode::convertForUriId($publicContact['uri-id'] ?? 0, $publicContact['about'], BBCode::EXTERNAL);
$this->url = $publicContact['url'];
$this->avatar = Contact::getAvatarUrlForId($userContact['id'] ?? 0 ?: $publicContact['id'], Proxy::SIZE_SMALL, $userContact['updated'] ?? '' ?: $publicContact['updated']);
$this->avatar_static = $this->avatar;
diff --git a/src/Object/Api/Mastodon/Status.php b/src/Object/Api/Mastodon/Status.php
index 0985c0002..90e8732ce 100644
--- a/src/Object/Api/Mastodon/Status.php
+++ b/src/Object/Api/Mastodon/Status.php
@@ -131,7 +131,7 @@ class Status extends BaseDataTransferObject
$this->muted = $userAttributes->muted;
$this->bookmarked = $userAttributes->bookmarked;
$this->pinned = $userAttributes->pinned;
- $this->content = BBCode::convert($item['raw-body'] ?? $item['body'], false, BBCode::API);
+ $this->content = BBCode::convertForUriId($item['uri-id'], ($item['raw-body'] ?? $item['body']), BBCode::EXTERNAL);
$this->reblog = $reblog;
$this->application = $application->toArray();
$this->account = $account->toArray();
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index f5d8e48de..f4892b6c0 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -744,7 +744,7 @@ class Processor
$title = $matches[3];
}
- $title = trim(HTML::toPlaintext(BBCode::convert($title, false, BBCode::API, true), 0));
+ $title = trim(BBCode::toPlaintext($title));
if (strlen($title) > 20) {
$title = substr($title, 0, 20) . '...';
diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php
index 0eac87f6a..cdf153830 100644
--- a/src/Protocol/ActivityPub/Transmitter.php
+++ b/src/Protocol/ActivityPub/Transmitter.php
@@ -1464,7 +1464,7 @@ class Transmitter
{
$event = [];
$event['name'] = $item['event-summary'];
- $event['content'] = BBCode::convert($item['event-desc'], false, BBCode::ACTIVITYPUB);
+ $event['content'] = BBCode::convertForUriId($item['uri-id'], $item['event-desc'], BBCode::ACTIVITYPUB);
$event['startTime'] = DateTimeFormat::utc($item['event-start'] . '+00:00', DateTimeFormat::ATOM);
if (!$item['event-nofinish']) {
@@ -1571,7 +1571,7 @@ class Transmitter
$regexp = "/[@!]\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
$body = preg_replace_callback($regexp, ['self', 'mentionCallback'], $body);
- $data['content'] = BBCode::convert($body, false, BBCode::ACTIVITYPUB);
+ $data['content'] = BBCode::convertForUriId($item['uri-id'], $body, BBCode::ACTIVITYPUB);
}
// The regular "content" field does contain a minimized HTML. This is done since systems like
@@ -1583,7 +1583,7 @@ class Transmitter
$richbody = preg_replace_callback($regexp, ['self', 'mentionCallback'], $item['body']);
$richbody = BBCode::removeAttachment($richbody);
- $data['contentMap'][$language] = BBCode::convert($richbody, false, BBCode::EXTERNAL);
+ $data['contentMap'][$language] = BBCode::convertForUriId($item['uri-id'], $richbody, BBCode::EXTERNAL);
}
$data['source'] = ['content' => $item['body'], 'mediaType' => "text/bbcode"];
diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php
index 797a3973b..4d2744498 100644
--- a/src/Protocol/DFRN.php
+++ b/src/Protocol/DFRN.php
@@ -918,7 +918,7 @@ class DFRN
$htmlbody = "[b]" . $item['title'] . "[/b]\n\n" . $htmlbody;
}
- $htmlbody = BBCode::convert($htmlbody, false, BBCode::OSTATUS);
+ $htmlbody = BBCode::convertForUriId($item['uri-id'], $htmlbody, BBCode::OSTATUS);
}
$author = self::addEntryAuthor($doc, "author", $item["author-link"], $item);
diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php
index 42f470e23..c088876d9 100644
--- a/src/Protocol/Feed.php
+++ b/src/Protocol/Feed.php
@@ -1107,9 +1107,9 @@ class Feed
XML::addElement($doc, $entry, "id", $item["uri"]);
XML::addElement($doc, $entry, "title", html_entity_decode($title, ENT_QUOTES, 'UTF-8'));
- $body = OStatus::formatPicturePost($item['body']);
+ $body = OStatus::formatPicturePost($item['body'], $item['uri-id']);
- $body = BBCode::convert($body, false, BBCode::OSTATUS);
+ $body = BBCode::convertForUriId($item['uri-id'], $body, BBCode::OSTATUS, false);
XML::addElement($doc, $entry, "content", $body, ["type" => "html"]);
@@ -1186,7 +1186,7 @@ class Feed
private static function getTitle(array $item)
{
if ($item['title'] != '') {
- return BBCode::convert($item['title'], false, BBCode::OSTATUS);
+ return BBCode::convertForUriId($item['uri-id'], $item['title'], BBCode::OSTATUS);
}
// Fetch information about the post
@@ -1199,7 +1199,7 @@ class Feed
// Remove the share element before fetching the first line
$title = trim(preg_replace("/\[share.*?\](.*?)\[\/share\]/ism","\n$1\n",$item['body']));
- $title = HTML::toPlaintext(BBCode::convert($title, false), 0, true)."\n";
+ $title = BBCode::toPlaintext($title)."\n";
$pos = strpos($title, "\n");
$trailer = "";
if (($pos == 0) || ($pos > 100)) {
diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php
index 919f327b8..03ff68d96 100644
--- a/src/Protocol/OStatus.php
+++ b/src/Protocol/OStatus.php
@@ -1195,7 +1195,7 @@ class OStatus
* @return string The cleaned body
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function formatPicturePost($body)
+ public static function formatPicturePost($body, $uriid)
{
$siteinfo = BBCode::getAttachedData($body);
@@ -1207,7 +1207,7 @@ class OStatus
}
// Is it a remote picture? Then make a smaller preview here
- $preview = ProxyUtils::proxifyUrl($preview, false, ProxyUtils::SIZE_SMALL);
+ $preview = Post\Link::getByLink($uriid, $preview, ProxyUtils::SIZE_SMALL);
// Is it a local picture? Then make it smaller here
$preview = str_replace(["-0.jpg", "-0.png"], ["-2.jpg", "-2.png"], $preview);
@@ -1803,7 +1803,7 @@ class OStatus
if (!$toplevel) {
if (!empty($item['title'])) {
- $title = BBCode::convert($item['title'], false, BBCode::OSTATUS);
+ $title = BBCode::convertForUriId($item['uri-id'], $item['title'], BBCode::OSTATUS);
} else {
$title = sprintf("New note by %s", $owner["nick"]);
}
@@ -1886,13 +1886,13 @@ class OStatus
XML::addElement($doc, $entry, "title", html_entity_decode($title, ENT_QUOTES, 'UTF-8'));
$body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
- $body = self::formatPicturePost($body);
+ $body = self::formatPicturePost($body, $item['uri-id']);
if (!empty($item['title'])) {
$body = "[b]".$item['title']."[/b]\n\n".$body;
}
- $body = BBCode::convert($body, false, BBCode::OSTATUS);
+ $body = BBCode::convertForUriId($item['uri-id'], $body, BBCode::OSTATUS);
XML::addElement($doc, $entry, "content", $body, ["type" => "html"]);
diff --git a/src/Util/Images.php b/src/Util/Images.php
index a65f9a1a8..7b11ea3f6 100644
--- a/src/Util/Images.php
+++ b/src/Util/Images.php
@@ -193,18 +193,7 @@ class Images
$filesize = strlen($img_str);
try {
- if (function_exists("getimagesizefromstring")) {
- $data = @getimagesizefromstring($img_str);
- } else {
- $tempfile = tempnam(get_temppath(), "cache");
-
- $stamp1 = microtime(true);
- file_put_contents($tempfile, $img_str);
- DI::profiler()->saveTimestamp($stamp1, "file");
-
- $data = getimagesize($tempfile);
- unlink($tempfile);
- }
+ $data = @getimagesizefromstring($img_str);
} catch (\Exception $e) {
return [];
}
diff --git a/src/Util/Proxy.php b/src/Util/Proxy.php
index 437b52e1e..443725a3d 100644
--- a/src/Util/Proxy.php
+++ b/src/Util/Proxy.php
@@ -21,6 +21,8 @@
namespace Friendica\Util;
+use Friendica\Core\Logger;
+use Friendica\Core\System;
use Friendica\DI;
/**
@@ -28,12 +30,6 @@ use Friendica\DI;
*/
class Proxy
{
-
- /**
- * Default time to keep images in proxy storage
- */
- const DEFAULT_TIME = 86400; // 1 Day
-
/**
* Sizes constants
*/
@@ -76,55 +72,30 @@ class Proxy
* Transform a remote URL into a local one.
*
* This function only performs the URL replacement on http URL and if the
- * provided URL isn't local, "the isn't deactivated" (sic) and if the config
- * system.proxy_disabled is set to false.
+ * provided URL isn't local
*
* @param string $url The URL to proxyfy
- * @param bool $writemode Returns a local path the remote URL should be saved to
* @param string $size One of the ProxyUtils::SIZE_* constants
*
* @return string The proxyfied URL or relative path
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function proxifyUrl($url, $writemode = false, $size = '')
+ public static function proxifyUrl($url, $size = '')
{
- // Get application instance
- $a = DI::app();
-
// Trim URL first
$url = trim($url);
- // Is no http in front of it?
- /// @TODO To weak test for being a valid URL
- if (substr($url, 0, 4) !== 'http') {
- return $url;
- }
-
- // Only continue if it isn't a local image and the isn't deactivated
- if (self::isLocalImage($url)) {
- $url = str_replace(Strings::normaliseLink(DI::baseUrl()) . '/', DI::baseUrl() . '/', $url);
- return $url;
- }
-
- // Is the proxy disabled?
- if (DI::config()->get('system', 'proxy_disabled')) {
+ // Quit if not an HTTP/HTTPS link or if local
+ if (!in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https']) || self::isLocalImage($url)) {
return $url;
}
// Image URL may have encoded ampersands for display which aren't desirable for proxy
$url = html_entity_decode($url, ENT_NOQUOTES, 'utf-8');
- // Creating a sub directory to reduce the amount of files in the cache directory
- $basepath = $a->getBasePath() . '/proxy';
-
$shortpath = hash('md5', $url);
$longpath = substr($shortpath, 0, 2);
- if (is_dir($basepath) && $writemode && !is_dir($basepath . '/' . $longpath)) {
- mkdir($basepath . '/' . $longpath);
- chmod($basepath . '/' . $longpath, 0777);
- }
-
$longpath .= '/' . strtr(base64_encode($url), '+/', '-_');
// Extract the URL extension
@@ -141,14 +112,11 @@ class Proxy
$size = ':' . $size;
}
+ Logger::info('Created proxy link', ['url' => $url, 'callstack' => System::callstack(20)]);
+
// Too long files aren't supported by Apache
- // Writemode in combination with long files shouldn't be possible
- if ((strlen($proxypath) > 250) && $writemode) {
- return $shortpath;
- } elseif (strlen($proxypath) > 250) {
+ if (strlen($proxypath) > 250) {
return DI::baseUrl() . '/proxy/' . $shortpath . '?url=' . urlencode($url);
- } elseif ($writemode) {
- return $longpath;
} else {
return $proxypath . $size;
}
@@ -189,11 +157,7 @@ class Proxy
return true;
}
- // links normalised - bug #431
- $baseurl = Strings::normaliseLink(DI::baseUrl());
- $url = Strings::normaliseLink($url);
-
- return (substr($url, 0, strlen($baseurl)) == $baseurl);
+ return Network::isLocalLink($url);
}
/**
diff --git a/src/Worker/ClearCache.php b/src/Worker/ClearCache.php
index 5b71c2f8b..baf15387d 100644
--- a/src/Worker/ClearCache.php
+++ b/src/Worker/ClearCache.php
@@ -38,29 +38,6 @@ class ClearCache
// clear old cache
DI::cache()->clear();
- // clear old item cache files
- clear_cache();
-
- // clear cache for photos
- clear_cache($a->getBasePath(), $a->getBasePath() . "/photo");
-
- // clear smarty cache
- clear_cache($a->getBasePath() . "/view/smarty3/compiled", $a->getBasePath() . "/view/smarty3/compiled");
-
- // clear cache for image proxy
- if (!DI::config()->get("system", "proxy_disabled")) {
- clear_cache($a->getBasePath(), $a->getBasePath() . "/proxy");
-
- $cachetime = DI::config()->get('system', 'proxy_cache_time');
-
- if (!$cachetime) {
- $cachetime = ProxyUtils::DEFAULT_TIME;
- }
-
- $condition = ['`uid` = 0 AND `resource-id` LIKE "pic:%" AND `created` < NOW() - INTERVAL ? SECOND', $cachetime];
- Photo::delete($condition);
- }
-
// Delete the cached OEmbed entries that are older than three month
DBA::delete('oembed', ["`created` < NOW() - INTERVAL 3 MONTH"]);
diff --git a/src/Worker/ExpirePosts.php b/src/Worker/ExpirePosts.php
index 3659edfde..de650f667 100644
--- a/src/Worker/ExpirePosts.php
+++ b/src/Worker/ExpirePosts.php
@@ -183,6 +183,10 @@ class ExpirePosts
AND NOT EXISTS(SELECT `thr-parent-id` FROM `post-user` WHERE `thr-parent-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `external-id` FROM `post-user` WHERE `external-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `uri-id` FROM `mail` WHERE `uri-id` = `item-uri`.`id`)
+ AND NOT EXISTS(SELECT `uri-id` FROM `event` WHERE `uri-id` = `item-uri`.`id`)
+ AND NOT EXISTS(SELECT `uri-id` FROM `contact` WHERE `uri-id` = `item-uri`.`id`)
+ AND NOT EXISTS(SELECT `uri-id` FROM `apcontact` WHERE `uri-id` = `item-uri`.`id`)
+ AND NOT EXISTS(SELECT `uri-id` FROM `fcontact` WHERE `uri-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `parent-uri-id` FROM `mail` WHERE `parent-uri-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `thr-parent-id` FROM `mail` WHERE `thr-parent-id` = `item-uri`.`id`)", $item['uri-id']]);
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index be939b1a1..e47f0d5dc 100644
--- a/static/dbstructure.config.php
+++ b/static/dbstructure.config.php
@@ -55,7 +55,7 @@
use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1424);
+ define('DB_UPDATE_VERSION', 1426);
}
return [
@@ -152,6 +152,19 @@ return [
"email" => ["email(64)"],
]
],
+ "item-uri" => [
+ "comment" => "URI and GUID for items",
+ "fields" => [
+ "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"],
+ "uri" => ["type" => "varbinary(255)", "not null" => "1", "comment" => "URI of an item"],
+ "guid" => ["type" => "varbinary(255)", "comment" => "A unique identifier for an item"]
+ ],
+ "indexes" => [
+ "PRIMARY" => ["id"],
+ "uri" => ["UNIQUE", "uri"],
+ "guid" => ["guid"]
+ ]
+ ],
"contact" => [
"comment" => "contact table",
"fields" => [
@@ -183,6 +196,7 @@ return [
"dfrn-id" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"url" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"nurl" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
+ "uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the contact url"],
"addr" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"alias" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"pubkey" => ["type" => "text", "comment" => "RSA public key 4096 bit"],
@@ -260,20 +274,8 @@ return [
"uid_contact-type" => ["uid", "contact-type"],
"uid_self_contact-type" => ["uid", "self", "contact-type"],
"self_network_uid" => ["self", "network", "uid"],
- "gsid" => ["gsid"]
- ]
- ],
- "item-uri" => [
- "comment" => "URI and GUID for items",
- "fields" => [
- "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"],
- "uri" => ["type" => "varbinary(255)", "not null" => "1", "comment" => "URI of an item"],
- "guid" => ["type" => "varbinary(255)", "comment" => "A unique identifier for an item"]
- ],
- "indexes" => [
- "PRIMARY" => ["id"],
- "uri" => ["UNIQUE", "uri"],
- "guid" => ["guid"]
+ "gsid" => ["gsid"],
+ "uri-id" => ["uri-id"],
]
],
"tag" => [
@@ -393,6 +395,7 @@ return [
"comment" => "ActivityPub compatible contacts - used in the ActivityPub implementation",
"fields" => [
"url" => ["type" => "varbinary(255)", "not null" => "1", "primary" => "1", "comment" => "URL of the contact"],
+ "uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the apcontact url"],
"uuid" => ["type" => "varchar(255)", "comment" => ""],
"type" => ["type" => "varchar(20)", "not null" => "1", "comment" => ""],
"following" => ["type" => "varchar(255)", "comment" => ""],
@@ -426,7 +429,8 @@ return [
"followers" => ["followers(190)"],
"baseurl" => ["baseurl(190)"],
"sharedinbox" => ["sharedinbox(190)"],
- "gsid" => ["gsid"]
+ "gsid" => ["gsid"],
+ "uri-id" => ["UNIQUE", "uri-id"],
]
],
"application" => [
@@ -628,6 +632,7 @@ return [
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
"cid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "contact_id (ID of the contact in contact table)"],
"uri" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
+ "uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the event uri"],
"created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "creation time"],
"edited" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "last edit time"],
"start" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "event start time"],
@@ -648,6 +653,7 @@ return [
"PRIMARY" => ["id"],
"uid_start" => ["uid", "start"],
"cid" => ["cid"],
+ "uri-id" => ["uri-id"],
]
],
"fcontact" => [
@@ -656,6 +662,7 @@ return [
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
"guid" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "unique id"],
"url" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
+ "uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the fcontact url"],
"name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"photo" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
"request" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
@@ -675,6 +682,7 @@ return [
"PRIMARY" => ["id"],
"addr" => ["addr(32)"],
"url" => ["UNIQUE", "url(190)"],
+ "uri-id" => ["UNIQUE", "uri-id"],
]
],
"fsuggest" => [
@@ -1151,6 +1159,19 @@ return [
"PRIMARY" => ["uri-id"],
]
],
+ "post-link" => [
+ "comment" => "Post related external links",
+ "fields" => [
+ "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
+ "uri-id" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"],
+ "url" => ["type" => "varbinary(511)", "not null" => "1", "comment" => "External URL"],
+ "mimetype" => ["type" => "varchar(60)", "comment" => ""],
+ ],
+ "indexes" => [
+ "PRIMARY" => ["id"],
+ "uri-id-url" => ["UNIQUE", "uri-id", "url"],
+ ]
+ ],
"post-media" => [
"comment" => "Attached media",
"fields" => [
@@ -1311,6 +1332,7 @@ return [
"post-user-id" => ["post-user-id"],
"commented" => ["commented"],
"uid_received" => ["uid", "received"],
+ "uid_wall_received" => ["uid", "wall", "received"],
"uid_pinned" => ["uid", "pinned"],
"uid_commented" => ["uid", "commented"],
"uid_starred" => ["uid", "starred"],
diff --git a/static/defaults.config.php b/static/defaults.config.php
index 25a23bf9d..20f351ab0 100644
--- a/static/defaults.config.php
+++ b/static/defaults.config.php
@@ -570,10 +570,6 @@ return [
// xrd_timeout (Integer)
// Timeout in seconds for fetching the XRD links.
'xrd_timeout' => 20,
-
- // proxy_file_chmod (Octal Integer like 0640)
- // If set, defines the files permissions for downloaded files in the /proxy/ directory, default is system-dependent
- 'proxy_file_chmod' => 0,
],
'experimental' => [
// exp_themes (Boolean)
diff --git a/tests/legacy/ApiTest.php b/tests/legacy/ApiTest.php
index c94571d85..8fe0771be 100644
--- a/tests/legacy/ApiTest.php
+++ b/tests/legacy/ApiTest.php
@@ -2344,7 +2344,7 @@ class ApiTest extends FixtureTest
public function testApiGetAttachments()
{
$body = 'body';
- self::assertEmpty(api_get_attachments($body));
+ self::assertEmpty(api_get_attachments($body, 0));
}
/**
@@ -2355,7 +2355,7 @@ class ApiTest extends FixtureTest
public function testApiGetAttachmentsWithImage()
{
$body = '[img]http://via.placeholder.com/1x1.png[/img]';
- self::assertIsArray(api_get_attachments($body));
+ self::assertIsArray(api_get_attachments($body, 0));
}
/**
@@ -2367,7 +2367,7 @@ class ApiTest extends FixtureTest
{
$_SERVER['HTTP_USER_AGENT'] = 'AndStatus';
$body = '[img]http://via.placeholder.com/1x1.png[/img]';
- self::assertIsArray(api_get_attachments($body));
+ self::assertIsArray(api_get_attachments($body, 0));
}
/**
@@ -2378,7 +2378,7 @@ class ApiTest extends FixtureTest
public function testApiGetEntitities()
{
$text = 'text';
- self::assertIsArray(api_get_entitities($text, 'bbcode'));
+ self::assertIsArray(api_get_entitities($text, 'bbcode', 0));
}
/**
@@ -2390,7 +2390,7 @@ class ApiTest extends FixtureTest
{
$_REQUEST['include_entities'] = 'true';
$text = 'text';
- $result = api_get_entitities($text, 'bbcode');
+ $result = api_get_entitities($text, 'bbcode', 0);
self::assertIsArray($result['hashtags']);
self::assertIsArray($result['symbols']);
self::assertIsArray($result['urls']);
diff --git a/tests/src/Content/Text/BBCodeTest.php b/tests/src/Content/Text/BBCodeTest.php
index 46f153edc..2b5dc22a1 100644
--- a/tests/src/Content/Text/BBCodeTest.php
+++ b/tests/src/Content/Text/BBCodeTest.php
@@ -51,9 +51,6 @@ class BBCodeTest extends MockedTest
$this->configMock->shouldReceive('get')
->with('system', 'allowed_link_protocols')
->andReturn(null);
- $this->configMock->shouldReceive('get')
- ->with('system', 'itemcache_duration')
- ->andReturn(-1);
$this->configMock->shouldReceive('get')
->with('system', 'url')
->andReturn('friendica.local');
diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po
index 8983dbcef..e565fb164 100644
--- a/view/lang/C/messages.po
+++ b/view/lang/C/messages.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2021.09-dev\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-07-04 19:56+0000\n"
+"POT-Creation-Date: 2021-07-08 15:39+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME
\n"
"Language-Team: LANGUAGE \n"
@@ -18,29 +18,29 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
-#: include/api.php:1136
+#: include/api.php:1135 src/Module/BaseApi.php:302
#, php-format
msgid "Daily posting limit of %d post reached. The post was rejected."
msgid_plural "Daily posting limit of %d posts reached. The post was rejected."
msgstr[0] ""
msgstr[1] ""
-#: include/api.php:1150
+#: include/api.php:1149 src/Module/BaseApi.php:318
#, php-format
msgid "Weekly posting limit of %d post reached. The post was rejected."
msgid_plural "Weekly posting limit of %d posts reached. The post was rejected."
msgstr[0] ""
msgstr[1] ""
-#: include/api.php:1164
+#: include/api.php:1163 src/Module/BaseApi.php:334
#, php-format
msgid "Monthly posting limit of %d post reached. The post was rejected."
msgstr ""
-#: include/api.php:4527 mod/photos.php:106 mod/photos.php:210
+#: include/api.php:4500 mod/photos.php:106 mod/photos.php:210
#: mod/photos.php:638 mod/photos.php:1042 mod/photos.php:1059
-#: mod/photos.php:1608 src/Model/User.php:1105 src/Model/User.php:1113
-#: src/Model/User.php:1121 src/Module/Settings/Profile/Photo/Crop.php:98
+#: mod/photos.php:1608 src/Model/User.php:1114 src/Model/User.php:1122
+#: src/Model/User.php:1130 src/Module/Settings/Profile/Photo/Crop.php:98
#: src/Module/Settings/Profile/Photo/Crop.php:114
#: src/Module/Settings/Profile/Photo/Crop.php:130
#: src/Module/Settings/Profile/Photo/Crop.php:176
@@ -54,7 +54,7 @@ msgstr ""
msgid "%1$s poked %2$s"
msgstr ""
-#: include/conversation.php:228 src/Model/Item.php:2609
+#: include/conversation.php:228 src/Model/Item.php:2606
msgid "event"
msgstr ""
@@ -62,7 +62,7 @@ msgstr ""
msgid "status"
msgstr ""
-#: include/conversation.php:236 mod/tagger.php:90 src/Model/Item.php:2611
+#: include/conversation.php:236 mod/tagger.php:90 src/Model/Item.php:2608
msgid "photo"
msgstr ""
@@ -833,8 +833,8 @@ msgstr ""
#: mod/unfollow.php:82 mod/wall_attach.php:78 mod/wall_attach.php:81
#: mod/wall_upload.php:99 mod/wall_upload.php:102 mod/wallmessage.php:35
#: mod/wallmessage.php:59 mod/wallmessage.php:96 mod/wallmessage.php:120
-#: src/Module/Attach.php:56 src/Module/BaseApi.php:79 src/Module/BaseApi.php:90
-#: src/Module/BaseApi.php:101 src/Module/BaseApi.php:112
+#: src/Module/Attach.php:56 src/Module/BaseApi.php:81 src/Module/BaseApi.php:92
+#: src/Module/BaseApi.php:103 src/Module/BaseApi.php:114
#: src/Module/BaseNotifications.php:88 src/Module/Contact.php:385
#: src/Module/Contact/Advanced.php:43 src/Module/Delegation.php:118
#: src/Module/FollowConfirm.php:16 src/Module/FriendSuggest.php:44
@@ -926,21 +926,21 @@ msgstr ""
msgid "Next"
msgstr ""
-#: mod/cal.php:280 mod/events.php:426 src/Model/Event.php:463
+#: mod/cal.php:280 mod/events.php:426 src/Model/Event.php:464
msgid "today"
msgstr ""
-#: mod/cal.php:281 mod/events.php:427 src/Model/Event.php:464
+#: mod/cal.php:281 mod/events.php:427 src/Model/Event.php:465
#: src/Util/Temporal.php:330
msgid "month"
msgstr ""
-#: mod/cal.php:282 mod/events.php:428 src/Model/Event.php:465
+#: mod/cal.php:282 mod/events.php:428 src/Model/Event.php:466
#: src/Util/Temporal.php:331
msgid "week"
msgstr ""
-#: mod/cal.php:283 mod/events.php:429 src/Model/Event.php:466
+#: mod/cal.php:283 mod/events.php:429 src/Model/Event.php:467
#: src/Util/Temporal.php:332
msgid "day"
msgstr ""
@@ -949,7 +949,7 @@ msgstr ""
msgid "list"
msgstr ""
-#: mod/cal.php:297 src/Console/User.php:182 src/Model/User.php:667
+#: mod/cal.php:297 src/Console/User.php:182 src/Model/User.php:676
#: src/Module/Admin/Users/Active.php:73 src/Module/Admin/Users/Blocked.php:74
#: src/Module/Admin/Users/Index.php:80 src/Module/Admin/Users/Pending.php:71
#: src/Module/Api/Twitter/ContactEndpoint.php:71
@@ -1115,11 +1115,11 @@ msgstr ""
msgid "Invalid profile URL."
msgstr ""
-#: mod/dfrn_request.php:355 src/Model/Contact.php:2297
+#: mod/dfrn_request.php:355 src/Model/Contact.php:2284
msgid "Disallowed profile URL."
msgstr ""
-#: mod/dfrn_request.php:361 src/Model/Contact.php:2302
+#: mod/dfrn_request.php:361 src/Model/Contact.php:2289
#: src/Module/Friendica.php:80
msgid "Blocked domain"
msgstr ""
@@ -1329,7 +1329,7 @@ msgid "Description:"
msgstr ""
#: mod/events.php:563 src/Model/Event.php:84 src/Model/Event.php:111
-#: src/Model/Event.php:472 src/Model/Event.php:959 src/Model/Profile.php:420
+#: src/Model/Event.php:473 src/Model/Event.php:960 src/Model/Profile.php:420
#: src/Module/Contact.php:654 src/Module/Directory.php:156
#: src/Module/Notifications/Introductions.php:172
#: src/Module/Profile/Profile.php:190
@@ -1366,7 +1366,7 @@ msgstr ""
msgid "Basic"
msgstr ""
-#: mod/events.php:577 src/Module/Admin/Site.php:584 src/Module/Contact.php:961
+#: mod/events.php:577 src/Module/Admin/Site.php:573 src/Module/Contact.php:961
#: src/Module/Profile/Profile.php:245
msgid "Advanced"
msgstr ""
@@ -2175,7 +2175,7 @@ msgstr ""
#: mod/settings.php:540 mod/settings.php:638 mod/settings.php:773
#: src/Module/Admin/Addons/Index.php:69 src/Module/Admin/Features.php:87
-#: src/Module/Admin/Logs/Settings.php:82 src/Module/Admin/Site.php:579
+#: src/Module/Admin/Logs/Settings.php:82 src/Module/Admin/Site.php:568
#: src/Module/Admin/Themes/Index.php:113 src/Module/Admin/Tos.php:66
#: src/Module/Settings/Delegation.php:170 src/Module/Settings/Display.php:189
msgid "Save Settings"
@@ -3634,39 +3634,39 @@ msgstr ""
msgid "last"
msgstr ""
-#: src/Content/Text/BBCode.php:942 src/Content/Text/BBCode.php:1613
-#: src/Content/Text/BBCode.php:1614
+#: src/Content/Text/BBCode.php:953 src/Content/Text/BBCode.php:1656
+#: src/Content/Text/BBCode.php:1657
msgid "Image/photo"
msgstr ""
-#: src/Content/Text/BBCode.php:1072
+#: src/Content/Text/BBCode.php:1083
#, php-format
msgid ""
"%2$s %3$s"
msgstr ""
-#: src/Content/Text/BBCode.php:1097 src/Model/Item.php:3137
-#: src/Model/Item.php:3143 src/Model/Item.php:3144
+#: src/Content/Text/BBCode.php:1108 src/Model/Item.php:3134
+#: src/Model/Item.php:3140 src/Model/Item.php:3141
msgid "Link to source"
msgstr ""
-#: src/Content/Text/BBCode.php:1531 src/Content/Text/HTML.php:951
+#: src/Content/Text/BBCode.php:1574 src/Content/Text/HTML.php:951
msgid "Click to open/close"
msgstr ""
-#: src/Content/Text/BBCode.php:1562
+#: src/Content/Text/BBCode.php:1605
msgid "$1 wrote:"
msgstr ""
-#: src/Content/Text/BBCode.php:1616 src/Content/Text/BBCode.php:1617
+#: src/Content/Text/BBCode.php:1659 src/Content/Text/BBCode.php:1660
msgid "Encrypted content"
msgstr ""
-#: src/Content/Text/BBCode.php:1830
+#: src/Content/Text/BBCode.php:1873
msgid "Invalid source protocol"
msgstr ""
-#: src/Content/Text/BBCode.php:1845
+#: src/Content/Text/BBCode.php:1888
msgid "Invalid link protocol"
msgstr ""
@@ -4187,137 +4187,137 @@ msgstr ""
msgid "Could not connect to database."
msgstr ""
-#: src/Core/L10n.php:377 src/Model/Event.php:431
+#: src/Core/L10n.php:377 src/Model/Event.php:432
#: src/Module/Settings/Display.php:178
msgid "Monday"
msgstr ""
-#: src/Core/L10n.php:377 src/Model/Event.php:432
+#: src/Core/L10n.php:377 src/Model/Event.php:433
msgid "Tuesday"
msgstr ""
-#: src/Core/L10n.php:377 src/Model/Event.php:433
+#: src/Core/L10n.php:377 src/Model/Event.php:434
msgid "Wednesday"
msgstr ""
-#: src/Core/L10n.php:377 src/Model/Event.php:434
+#: src/Core/L10n.php:377 src/Model/Event.php:435
msgid "Thursday"
msgstr ""
-#: src/Core/L10n.php:377 src/Model/Event.php:435
+#: src/Core/L10n.php:377 src/Model/Event.php:436
msgid "Friday"
msgstr ""
-#: src/Core/L10n.php:377 src/Model/Event.php:436
+#: src/Core/L10n.php:377 src/Model/Event.php:437
msgid "Saturday"
msgstr ""
-#: src/Core/L10n.php:377 src/Model/Event.php:430
+#: src/Core/L10n.php:377 src/Model/Event.php:431
#: src/Module/Settings/Display.php:178
msgid "Sunday"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:451
+#: src/Core/L10n.php:381 src/Model/Event.php:452
msgid "January"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:452
+#: src/Core/L10n.php:381 src/Model/Event.php:453
msgid "February"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:453
+#: src/Core/L10n.php:381 src/Model/Event.php:454
msgid "March"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:454
+#: src/Core/L10n.php:381 src/Model/Event.php:455
msgid "April"
msgstr ""
-#: src/Core/L10n.php:381 src/Core/L10n.php:401 src/Model/Event.php:442
+#: src/Core/L10n.php:381 src/Core/L10n.php:401 src/Model/Event.php:443
msgid "May"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:455
+#: src/Core/L10n.php:381 src/Model/Event.php:456
msgid "June"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:456
+#: src/Core/L10n.php:381 src/Model/Event.php:457
msgid "July"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:457
+#: src/Core/L10n.php:381 src/Model/Event.php:458
msgid "August"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:458
+#: src/Core/L10n.php:381 src/Model/Event.php:459
msgid "September"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:459
+#: src/Core/L10n.php:381 src/Model/Event.php:460
msgid "October"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:460
+#: src/Core/L10n.php:381 src/Model/Event.php:461
msgid "November"
msgstr ""
-#: src/Core/L10n.php:381 src/Model/Event.php:461
+#: src/Core/L10n.php:381 src/Model/Event.php:462
msgid "December"
msgstr ""
-#: src/Core/L10n.php:397 src/Model/Event.php:423
+#: src/Core/L10n.php:397 src/Model/Event.php:424
msgid "Mon"
msgstr ""
-#: src/Core/L10n.php:397 src/Model/Event.php:424
+#: src/Core/L10n.php:397 src/Model/Event.php:425
msgid "Tue"
msgstr ""
-#: src/Core/L10n.php:397 src/Model/Event.php:425
+#: src/Core/L10n.php:397 src/Model/Event.php:426
msgid "Wed"
msgstr ""
-#: src/Core/L10n.php:397 src/Model/Event.php:426
+#: src/Core/L10n.php:397 src/Model/Event.php:427
msgid "Thu"
msgstr ""
-#: src/Core/L10n.php:397 src/Model/Event.php:427
+#: src/Core/L10n.php:397 src/Model/Event.php:428
msgid "Fri"
msgstr ""
-#: src/Core/L10n.php:397 src/Model/Event.php:428
+#: src/Core/L10n.php:397 src/Model/Event.php:429
msgid "Sat"
msgstr ""
-#: src/Core/L10n.php:397 src/Model/Event.php:422
+#: src/Core/L10n.php:397 src/Model/Event.php:423
msgid "Sun"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:438
+#: src/Core/L10n.php:401 src/Model/Event.php:439
msgid "Jan"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:439
+#: src/Core/L10n.php:401 src/Model/Event.php:440
msgid "Feb"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:440
+#: src/Core/L10n.php:401 src/Model/Event.php:441
msgid "Mar"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:441
+#: src/Core/L10n.php:401 src/Model/Event.php:442
msgid "Apr"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:443
+#: src/Core/L10n.php:401 src/Model/Event.php:444
msgid "Jun"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:444
+#: src/Core/L10n.php:401 src/Model/Event.php:445
msgid "Jul"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:445
+#: src/Core/L10n.php:401 src/Model/Event.php:446
msgid "Aug"
msgstr ""
@@ -4325,15 +4325,15 @@ msgstr ""
msgid "Sep"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:447
+#: src/Core/L10n.php:401 src/Model/Event.php:448
msgid "Oct"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:448
+#: src/Core/L10n.php:401 src/Model/Event.php:449
msgid "Nov"
msgstr ""
-#: src/Core/L10n.php:401 src/Model/Event.php:449
+#: src/Core/L10n.php:401 src/Model/Event.php:450
msgid "Dec"
msgstr ""
@@ -4644,128 +4644,128 @@ msgstr ""
msgid "Forum"
msgstr ""
-#: src/Model/Contact.php:2307
+#: src/Model/Contact.php:2294
msgid "Connect URL missing."
msgstr ""
-#: src/Model/Contact.php:2316
+#: src/Model/Contact.php:2303
msgid ""
"The contact could not be added. Please check the relevant network "
"credentials in your Settings -> Social Networks page."
msgstr ""
-#: src/Model/Contact.php:2359
+#: src/Model/Contact.php:2346
msgid ""
"This site is not configured to allow communications with other networks."
msgstr ""
-#: src/Model/Contact.php:2360 src/Model/Contact.php:2373
+#: src/Model/Contact.php:2347 src/Model/Contact.php:2360
msgid "No compatible communication protocols or feeds were discovered."
msgstr ""
-#: src/Model/Contact.php:2371
+#: src/Model/Contact.php:2358
msgid "The profile address specified does not provide adequate information."
msgstr ""
-#: src/Model/Contact.php:2376
+#: src/Model/Contact.php:2363
msgid "An author or name was not found."
msgstr ""
-#: src/Model/Contact.php:2379
+#: src/Model/Contact.php:2366
msgid "No browser URL could be matched to this address."
msgstr ""
-#: src/Model/Contact.php:2382
+#: src/Model/Contact.php:2369
msgid ""
"Unable to match @-style Identity Address with a known protocol or email "
"contact."
msgstr ""
-#: src/Model/Contact.php:2383
+#: src/Model/Contact.php:2370
msgid "Use mailto: in front of address to force email check."
msgstr ""
-#: src/Model/Contact.php:2389
+#: src/Model/Contact.php:2376
msgid ""
"The profile address specified belongs to a network which has been disabled "
"on this site."
msgstr ""
-#: src/Model/Contact.php:2394
+#: src/Model/Contact.php:2381
msgid ""
"Limited profile. This person will be unable to receive direct/personal "
"notifications from you."
msgstr ""
-#: src/Model/Contact.php:2453
+#: src/Model/Contact.php:2440
msgid "Unable to retrieve contact information."
msgstr ""
-#: src/Model/Event.php:50 src/Model/Event.php:871
+#: src/Model/Event.php:50 src/Model/Event.php:872
#: src/Module/Debug/Localtime.php:36
msgid "l F d, Y \\@ g:i A"
msgstr ""
-#: src/Model/Event.php:77 src/Model/Event.php:94 src/Model/Event.php:470
-#: src/Model/Event.php:941
+#: src/Model/Event.php:77 src/Model/Event.php:94 src/Model/Event.php:471
+#: src/Model/Event.php:942
msgid "Starts:"
msgstr ""
-#: src/Model/Event.php:80 src/Model/Event.php:100 src/Model/Event.php:471
-#: src/Model/Event.php:945
+#: src/Model/Event.php:80 src/Model/Event.php:100 src/Model/Event.php:472
+#: src/Model/Event.php:946
msgid "Finishes:"
msgstr ""
-#: src/Model/Event.php:420
+#: src/Model/Event.php:421
msgid "all-day"
msgstr ""
-#: src/Model/Event.php:446
+#: src/Model/Event.php:447
msgid "Sept"
msgstr ""
-#: src/Model/Event.php:468
+#: src/Model/Event.php:469
msgid "No events to display"
msgstr ""
-#: src/Model/Event.php:587
+#: src/Model/Event.php:588
msgid "l, F j"
msgstr ""
-#: src/Model/Event.php:618
+#: src/Model/Event.php:619
msgid "Edit event"
msgstr ""
-#: src/Model/Event.php:619
+#: src/Model/Event.php:620
msgid "Duplicate event"
msgstr ""
-#: src/Model/Event.php:620
+#: src/Model/Event.php:621
msgid "Delete event"
msgstr ""
-#: src/Model/Event.php:872
+#: src/Model/Event.php:873
msgid "D g:i A"
msgstr ""
-#: src/Model/Event.php:873
+#: src/Model/Event.php:874
msgid "g:i A"
msgstr ""
-#: src/Model/Event.php:960 src/Model/Event.php:962
+#: src/Model/Event.php:961 src/Model/Event.php:963
msgid "Show map"
msgstr ""
-#: src/Model/Event.php:961
+#: src/Model/Event.php:962
msgid "Hide map"
msgstr ""
-#: src/Model/Event.php:1053
+#: src/Model/Event.php:1054
#, php-format
msgid "%s's birthday"
msgstr ""
-#: src/Model/Event.php:1054
+#: src/Model/Event.php:1055
#, php-format
msgid "Happy Birthday %s"
msgstr ""
@@ -4814,33 +4814,33 @@ msgstr ""
msgid "Edit groups"
msgstr ""
-#: src/Model/Item.php:1663
+#: src/Model/Item.php:1660
#, php-format
msgid "Detected languages in this post:\\n%s"
msgstr ""
-#: src/Model/Item.php:2613
+#: src/Model/Item.php:2610
msgid "activity"
msgstr ""
-#: src/Model/Item.php:2615
+#: src/Model/Item.php:2612
msgid "comment"
msgstr ""
-#: src/Model/Item.php:2618
+#: src/Model/Item.php:2615
msgid "post"
msgstr ""
-#: src/Model/Item.php:2732
+#: src/Model/Item.php:2729
#, php-format
msgid "Content warning: %s"
msgstr ""
-#: src/Model/Item.php:3102
+#: src/Model/Item.php:3099
msgid "bytes"
msgstr ""
-#: src/Model/Item.php:3131 src/Model/Item.php:3132
+#: src/Model/Item.php:3128 src/Model/Item.php:3129
msgid "View on separate page"
msgstr ""
@@ -4958,138 +4958,138 @@ msgstr ""
msgid "Enter a valid existing folder"
msgstr ""
-#: src/Model/User.php:186 src/Model/User.php:991
+#: src/Model/User.php:195 src/Model/User.php:1000
msgid "SERIOUS ERROR: Generation of security keys failed."
msgstr ""
-#: src/Model/User.php:576 src/Model/User.php:609
+#: src/Model/User.php:585 src/Model/User.php:618
msgid "Login failed"
msgstr ""
-#: src/Model/User.php:641
+#: src/Model/User.php:650
msgid "Not enough information to authenticate"
msgstr ""
-#: src/Model/User.php:736
+#: src/Model/User.php:745
msgid "Password can't be empty"
msgstr ""
-#: src/Model/User.php:755
+#: src/Model/User.php:764
msgid "Empty passwords are not allowed."
msgstr ""
-#: src/Model/User.php:759
+#: src/Model/User.php:768
msgid ""
"The new password has been exposed in a public data dump, please choose "
"another."
msgstr ""
-#: src/Model/User.php:765
+#: src/Model/User.php:774
msgid ""
"The password can't contain accentuated letters, white spaces or colons (:)"
msgstr ""
-#: src/Model/User.php:871
+#: src/Model/User.php:880
msgid "Passwords do not match. Password unchanged."
msgstr ""
-#: src/Model/User.php:878
+#: src/Model/User.php:887
msgid "An invitation is required."
msgstr ""
-#: src/Model/User.php:882
+#: src/Model/User.php:891
msgid "Invitation could not be verified."
msgstr ""
-#: src/Model/User.php:890
+#: src/Model/User.php:899
msgid "Invalid OpenID url"
msgstr ""
-#: src/Model/User.php:903 src/Security/Authentication.php:224
+#: src/Model/User.php:912 src/Security/Authentication.php:224
msgid ""
"We encountered a problem while logging in with the OpenID you provided. "
"Please check the correct spelling of the ID."
msgstr ""
-#: src/Model/User.php:903 src/Security/Authentication.php:224
+#: src/Model/User.php:912 src/Security/Authentication.php:224
msgid "The error message was:"
msgstr ""
-#: src/Model/User.php:909
+#: src/Model/User.php:918
msgid "Please enter the required information."
msgstr ""
-#: src/Model/User.php:923
+#: src/Model/User.php:932
#, php-format
msgid ""
"system.username_min_length (%s) and system.username_max_length (%s) are "
"excluding each other, swapping values."
msgstr ""
-#: src/Model/User.php:930
+#: src/Model/User.php:939
#, php-format
msgid "Username should be at least %s character."
msgid_plural "Username should be at least %s characters."
msgstr[0] ""
msgstr[1] ""
-#: src/Model/User.php:934
+#: src/Model/User.php:943
#, php-format
msgid "Username should be at most %s character."
msgid_plural "Username should be at most %s characters."
msgstr[0] ""
msgstr[1] ""
-#: src/Model/User.php:942
+#: src/Model/User.php:951
msgid "That doesn't appear to be your full (First Last) name."
msgstr ""
-#: src/Model/User.php:947
+#: src/Model/User.php:956
msgid "Your email domain is not among those allowed on this site."
msgstr ""
-#: src/Model/User.php:951
+#: src/Model/User.php:960
msgid "Not a valid email address."
msgstr ""
-#: src/Model/User.php:954
+#: src/Model/User.php:963
msgid "The nickname was blocked from registration by the nodes admin."
msgstr ""
-#: src/Model/User.php:958 src/Model/User.php:966
+#: src/Model/User.php:967 src/Model/User.php:975
msgid "Cannot use that email."
msgstr ""
-#: src/Model/User.php:973
+#: src/Model/User.php:982
msgid "Your nickname can only contain a-z, 0-9 and _."
msgstr ""
-#: src/Model/User.php:981 src/Model/User.php:1038
+#: src/Model/User.php:990 src/Model/User.php:1047
msgid "Nickname is already registered. Please choose another."
msgstr ""
-#: src/Model/User.php:1025 src/Model/User.php:1029
+#: src/Model/User.php:1034 src/Model/User.php:1038
msgid "An error occurred during registration. Please try again."
msgstr ""
-#: src/Model/User.php:1052
+#: src/Model/User.php:1061
msgid "An error occurred creating your default profile. Please try again."
msgstr ""
-#: src/Model/User.php:1059
+#: src/Model/User.php:1068
msgid "An error occurred creating your self contact. Please try again."
msgstr ""
-#: src/Model/User.php:1064
+#: src/Model/User.php:1073
msgid "Friends"
msgstr ""
-#: src/Model/User.php:1068
+#: src/Model/User.php:1077
msgid ""
"An error occurred creating your default contact group. Please try again."
msgstr ""
-#: src/Model/User.php:1297
+#: src/Model/User.php:1306
#, php-format
msgid ""
"\n"
@@ -5097,7 +5097,7 @@ msgid ""
"\t\t\tthe administrator of %2$s has set up an account for you."
msgstr ""
-#: src/Model/User.php:1300
+#: src/Model/User.php:1309
#, php-format
msgid ""
"\n"
@@ -5134,12 +5134,12 @@ msgid ""
"\t\tThank you and welcome to %4$s."
msgstr ""
-#: src/Model/User.php:1333 src/Model/User.php:1440
+#: src/Model/User.php:1342 src/Model/User.php:1449
#, php-format
msgid "Registration details for %s"
msgstr ""
-#: src/Model/User.php:1353
+#: src/Model/User.php:1362
#, php-format
msgid ""
"\n"
@@ -5155,12 +5155,12 @@ msgid ""
"\t\t"
msgstr ""
-#: src/Model/User.php:1372
+#: src/Model/User.php:1381
#, php-format
msgid "Registration at %s"
msgstr ""
-#: src/Model/User.php:1396
+#: src/Model/User.php:1405
#, php-format
msgid ""
"\n"
@@ -5169,7 +5169,7 @@ msgid ""
"\t\t\t"
msgstr ""
-#: src/Model/User.php:1404
+#: src/Model/User.php:1413
#, php-format
msgid ""
"\n"
@@ -5237,7 +5237,7 @@ msgstr ""
#: src/Module/Admin/Blocklist/Server.php:88 src/Module/Admin/Federation.php:159
#: src/Module/Admin/Item/Delete.php:65 src/Module/Admin/Logs/Settings.php:80
#: src/Module/Admin/Logs/View.php:64 src/Module/Admin/Queue.php:72
-#: src/Module/Admin/Site.php:576 src/Module/Admin/Summary.php:232
+#: src/Module/Admin/Site.php:565 src/Module/Admin/Summary.php:232
#: src/Module/Admin/Themes/Details.php:90 src/Module/Admin/Themes/Index.php:111
#: src/Module/Admin/Tos.php:58 src/Module/Admin/Users/Active.php:136
#: src/Module/Admin/Users/Blocked.php:137 src/Module/Admin/Users/Create.php:61
@@ -5791,281 +5791,281 @@ msgstr ""
msgid "Relocation started. Could take a while to complete."
msgstr ""
-#: src/Module/Admin/Site.php:248
+#: src/Module/Admin/Site.php:245
msgid "Invalid storage backend setting value."
msgstr ""
-#: src/Module/Admin/Site.php:446 src/Module/Settings/Display.php:134
+#: src/Module/Admin/Site.php:436 src/Module/Settings/Display.php:134
msgid "No special theme for mobile devices"
msgstr ""
-#: src/Module/Admin/Site.php:463 src/Module/Settings/Display.php:144
+#: src/Module/Admin/Site.php:453 src/Module/Settings/Display.php:144
#, php-format
msgid "%s - (Experimental)"
msgstr ""
-#: src/Module/Admin/Site.php:475
+#: src/Module/Admin/Site.php:465
msgid "No community page for local users"
msgstr ""
-#: src/Module/Admin/Site.php:476
+#: src/Module/Admin/Site.php:466
msgid "No community page"
msgstr ""
-#: src/Module/Admin/Site.php:477
+#: src/Module/Admin/Site.php:467
msgid "Public postings from users of this site"
msgstr ""
-#: src/Module/Admin/Site.php:478
+#: src/Module/Admin/Site.php:468
msgid "Public postings from the federated network"
msgstr ""
-#: src/Module/Admin/Site.php:479
+#: src/Module/Admin/Site.php:469
msgid "Public postings from local users and the federated network"
msgstr ""
-#: src/Module/Admin/Site.php:485
+#: src/Module/Admin/Site.php:475
msgid "Multi user instance"
msgstr ""
-#: src/Module/Admin/Site.php:513
+#: src/Module/Admin/Site.php:502
msgid "Closed"
msgstr ""
-#: src/Module/Admin/Site.php:514
+#: src/Module/Admin/Site.php:503
msgid "Requires approval"
msgstr ""
-#: src/Module/Admin/Site.php:515
+#: src/Module/Admin/Site.php:504
msgid "Open"
msgstr ""
-#: src/Module/Admin/Site.php:519 src/Module/Install.php:215
+#: src/Module/Admin/Site.php:508 src/Module/Install.php:215
msgid "No SSL policy, links will track page SSL state"
msgstr ""
-#: src/Module/Admin/Site.php:520 src/Module/Install.php:216
+#: src/Module/Admin/Site.php:509 src/Module/Install.php:216
msgid "Force all links to use SSL"
msgstr ""
-#: src/Module/Admin/Site.php:521 src/Module/Install.php:217
+#: src/Module/Admin/Site.php:510 src/Module/Install.php:217
msgid "Self-signed certificate, use SSL for local links only (discouraged)"
msgstr ""
-#: src/Module/Admin/Site.php:525
+#: src/Module/Admin/Site.php:514
msgid "Don't check"
msgstr ""
-#: src/Module/Admin/Site.php:526
+#: src/Module/Admin/Site.php:515
msgid "check the stable version"
msgstr ""
-#: src/Module/Admin/Site.php:527
+#: src/Module/Admin/Site.php:516
msgid "check the development version"
msgstr ""
-#: src/Module/Admin/Site.php:531
+#: src/Module/Admin/Site.php:520
msgid "none"
msgstr ""
-#: src/Module/Admin/Site.php:532
+#: src/Module/Admin/Site.php:521
msgid "Local contacts"
msgstr ""
-#: src/Module/Admin/Site.php:533
+#: src/Module/Admin/Site.php:522
msgid "Interactors"
msgstr ""
-#: src/Module/Admin/Site.php:546
+#: src/Module/Admin/Site.php:535
msgid "Database (legacy)"
msgstr ""
-#: src/Module/Admin/Site.php:577 src/Module/BaseAdmin.php:90
+#: src/Module/Admin/Site.php:566 src/Module/BaseAdmin.php:90
msgid "Site"
msgstr ""
-#: src/Module/Admin/Site.php:578
+#: src/Module/Admin/Site.php:567
msgid "General Information"
msgstr ""
-#: src/Module/Admin/Site.php:580
+#: src/Module/Admin/Site.php:569
msgid "Republish users to directory"
msgstr ""
-#: src/Module/Admin/Site.php:581 src/Module/Register.php:139
+#: src/Module/Admin/Site.php:570 src/Module/Register.php:139
msgid "Registration"
msgstr ""
-#: src/Module/Admin/Site.php:582
+#: src/Module/Admin/Site.php:571
msgid "File upload"
msgstr ""
-#: src/Module/Admin/Site.php:583
+#: src/Module/Admin/Site.php:572
msgid "Policies"
msgstr ""
-#: src/Module/Admin/Site.php:585
+#: src/Module/Admin/Site.php:574
msgid "Auto Discovered Contact Directory"
msgstr ""
-#: src/Module/Admin/Site.php:586
+#: src/Module/Admin/Site.php:575
msgid "Performance"
msgstr ""
-#: src/Module/Admin/Site.php:587
+#: src/Module/Admin/Site.php:576
msgid "Worker"
msgstr ""
-#: src/Module/Admin/Site.php:588
+#: src/Module/Admin/Site.php:577
msgid "Message Relay"
msgstr ""
-#: src/Module/Admin/Site.php:589
+#: src/Module/Admin/Site.php:578
msgid ""
"Use the command \"console relay\" in the command line to add or remove "
"relays."
msgstr ""
-#: src/Module/Admin/Site.php:590
+#: src/Module/Admin/Site.php:579
msgid "The system is not subscribed to any relays at the moment."
msgstr ""
-#: src/Module/Admin/Site.php:591
+#: src/Module/Admin/Site.php:580
msgid "The system is currently subscribed to the following relays:"
msgstr ""
-#: src/Module/Admin/Site.php:593
+#: src/Module/Admin/Site.php:582
msgid "Relocate Instance"
msgstr ""
-#: src/Module/Admin/Site.php:594
+#: src/Module/Admin/Site.php:583
msgid ""
"Warning! Advanced function. Could make this server "
"unreachable."
msgstr ""
-#: src/Module/Admin/Site.php:598
+#: src/Module/Admin/Site.php:587
msgid "Site name"
msgstr ""
-#: src/Module/Admin/Site.php:599
+#: src/Module/Admin/Site.php:588
msgid "Sender Email"
msgstr ""
-#: src/Module/Admin/Site.php:599
+#: src/Module/Admin/Site.php:588
msgid ""
"The email address your server shall use to send notification emails from."
msgstr ""
-#: src/Module/Admin/Site.php:600
+#: src/Module/Admin/Site.php:589
msgid "Name of the system actor"
msgstr ""
-#: src/Module/Admin/Site.php:600
+#: src/Module/Admin/Site.php:589
msgid ""
"Name of the internal system account that is used to perform ActivityPub "
"requests. This must be an unused username. If set, this can't be changed "
"again."
msgstr ""
-#: src/Module/Admin/Site.php:601
+#: src/Module/Admin/Site.php:590
msgid "Banner/Logo"
msgstr ""
-#: src/Module/Admin/Site.php:602
+#: src/Module/Admin/Site.php:591
msgid "Email Banner/Logo"
msgstr ""
-#: src/Module/Admin/Site.php:603
+#: src/Module/Admin/Site.php:592
msgid "Shortcut icon"
msgstr ""
-#: src/Module/Admin/Site.php:603
+#: src/Module/Admin/Site.php:592
msgid "Link to an icon that will be used for browsers."
msgstr ""
-#: src/Module/Admin/Site.php:604
+#: src/Module/Admin/Site.php:593
msgid "Touch icon"
msgstr ""
-#: src/Module/Admin/Site.php:604
+#: src/Module/Admin/Site.php:593
msgid "Link to an icon that will be used for tablets and mobiles."
msgstr ""
-#: src/Module/Admin/Site.php:605
+#: src/Module/Admin/Site.php:594
msgid "Additional Info"
msgstr ""
-#: src/Module/Admin/Site.php:605
+#: src/Module/Admin/Site.php:594
#, php-format
msgid ""
"For public servers: you can add additional information here that will be "
"listed at %s/servers."
msgstr ""
-#: src/Module/Admin/Site.php:606
+#: src/Module/Admin/Site.php:595
msgid "System language"
msgstr ""
-#: src/Module/Admin/Site.php:607
+#: src/Module/Admin/Site.php:596
msgid "System theme"
msgstr ""
-#: src/Module/Admin/Site.php:607
+#: src/Module/Admin/Site.php:596
msgid ""
"Default system theme - may be over-ridden by user profiles - Change default theme settings"
msgstr ""
-#: src/Module/Admin/Site.php:608
+#: src/Module/Admin/Site.php:597
msgid "Mobile system theme"
msgstr ""
-#: src/Module/Admin/Site.php:608
+#: src/Module/Admin/Site.php:597
msgid "Theme for mobile devices"
msgstr ""
-#: src/Module/Admin/Site.php:609 src/Module/Install.php:225
+#: src/Module/Admin/Site.php:598 src/Module/Install.php:225
msgid "SSL link policy"
msgstr ""
-#: src/Module/Admin/Site.php:609 src/Module/Install.php:227
+#: src/Module/Admin/Site.php:598 src/Module/Install.php:227
msgid "Determines whether generated links should be forced to use SSL"
msgstr ""
-#: src/Module/Admin/Site.php:610
+#: src/Module/Admin/Site.php:599
msgid "Force SSL"
msgstr ""
-#: src/Module/Admin/Site.php:610
+#: src/Module/Admin/Site.php:599
msgid ""
"Force all Non-SSL requests to SSL - Attention: on some systems it could lead "
"to endless loops."
msgstr ""
-#: src/Module/Admin/Site.php:611
+#: src/Module/Admin/Site.php:600
msgid "Hide help entry from navigation menu"
msgstr ""
-#: src/Module/Admin/Site.php:611
+#: src/Module/Admin/Site.php:600
msgid ""
"Hides the menu entry for the Help pages from the navigation menu. You can "
"still access it calling /help directly."
msgstr ""
-#: src/Module/Admin/Site.php:612
+#: src/Module/Admin/Site.php:601
msgid "Single user instance"
msgstr ""
-#: src/Module/Admin/Site.php:612
+#: src/Module/Admin/Site.php:601
msgid "Make this instance multi-user or single-user for the named user"
msgstr ""
-#: src/Module/Admin/Site.php:614
+#: src/Module/Admin/Site.php:603
msgid "File storage backend"
msgstr ""
-#: src/Module/Admin/Site.php:614
+#: src/Module/Admin/Site.php:603
msgid ""
"The backend used to store uploaded data. If you change the storage backend, "
"you can manually move the existing files. If you do not do so, the files "
@@ -6074,202 +6074,202 @@ msgid ""
"for more information about the choices and the moving procedure."
msgstr ""
-#: src/Module/Admin/Site.php:616
+#: src/Module/Admin/Site.php:605
msgid "Maximum image size"
msgstr ""
-#: src/Module/Admin/Site.php:616
+#: src/Module/Admin/Site.php:605
msgid ""
"Maximum size in bytes of uploaded images. Default is 0, which means no "
"limits."
msgstr ""
-#: src/Module/Admin/Site.php:617
+#: src/Module/Admin/Site.php:606
msgid "Maximum image length"
msgstr ""
-#: src/Module/Admin/Site.php:617
+#: src/Module/Admin/Site.php:606
msgid ""
"Maximum length in pixels of the longest side of uploaded images. Default is "
"-1, which means no limits."
msgstr ""
-#: src/Module/Admin/Site.php:618
+#: src/Module/Admin/Site.php:607
msgid "JPEG image quality"
msgstr ""
-#: src/Module/Admin/Site.php:618
+#: src/Module/Admin/Site.php:607
msgid ""
"Uploaded JPEGS will be saved at this quality setting [0-100]. Default is "
"100, which is full quality."
msgstr ""
-#: src/Module/Admin/Site.php:620
+#: src/Module/Admin/Site.php:609
msgid "Register policy"
msgstr ""
-#: src/Module/Admin/Site.php:621
+#: src/Module/Admin/Site.php:610
msgid "Maximum Daily Registrations"
msgstr ""
-#: src/Module/Admin/Site.php:621
+#: src/Module/Admin/Site.php:610
msgid ""
"If registration is permitted above, this sets the maximum number of new user "
"registrations to accept per day. If register is set to closed, this setting "
"has no effect."
msgstr ""
-#: src/Module/Admin/Site.php:622
+#: src/Module/Admin/Site.php:611
msgid "Register text"
msgstr ""
-#: src/Module/Admin/Site.php:622
+#: src/Module/Admin/Site.php:611
msgid ""
"Will be displayed prominently on the registration page. You can use BBCode "
"here."
msgstr ""
-#: src/Module/Admin/Site.php:623
+#: src/Module/Admin/Site.php:612
msgid "Forbidden Nicknames"
msgstr ""
-#: src/Module/Admin/Site.php:623
+#: src/Module/Admin/Site.php:612
msgid ""
"Comma separated list of nicknames that are forbidden from registration. "
"Preset is a list of role names according RFC 2142."
msgstr ""
-#: src/Module/Admin/Site.php:624
+#: src/Module/Admin/Site.php:613
msgid "Accounts abandoned after x days"
msgstr ""
-#: src/Module/Admin/Site.php:624
+#: src/Module/Admin/Site.php:613
msgid ""
"Will not waste system resources polling external sites for abandonded "
"accounts. Enter 0 for no time limit."
msgstr ""
-#: src/Module/Admin/Site.php:625
+#: src/Module/Admin/Site.php:614
msgid "Allowed friend domains"
msgstr ""
-#: src/Module/Admin/Site.php:625
+#: src/Module/Admin/Site.php:614
msgid ""
"Comma separated list of domains which are allowed to establish friendships "
"with this site. Wildcards are accepted. Empty to allow any domains"
msgstr ""
-#: src/Module/Admin/Site.php:626
+#: src/Module/Admin/Site.php:615
msgid "Allowed email domains"
msgstr ""
-#: src/Module/Admin/Site.php:626
+#: src/Module/Admin/Site.php:615
msgid ""
"Comma separated list of domains which are allowed in email addresses for "
"registrations to this site. Wildcards are accepted. Empty to allow any "
"domains"
msgstr ""
-#: src/Module/Admin/Site.php:627
+#: src/Module/Admin/Site.php:616
msgid "No OEmbed rich content"
msgstr ""
-#: src/Module/Admin/Site.php:627
+#: src/Module/Admin/Site.php:616
msgid ""
"Don't show the rich content (e.g. embedded PDF), except from the domains "
"listed below."
msgstr ""
-#: src/Module/Admin/Site.php:628
+#: src/Module/Admin/Site.php:617
msgid "Trusted third-party domains"
msgstr ""
-#: src/Module/Admin/Site.php:628
+#: src/Module/Admin/Site.php:617
msgid ""
"Comma separated list of domains from which content is allowed to be embedded "
"in posts like with OEmbed. All sub-domains of the listed domains are allowed "
"as well."
msgstr ""
-#: src/Module/Admin/Site.php:629
+#: src/Module/Admin/Site.php:618
msgid "Block public"
msgstr ""
-#: src/Module/Admin/Site.php:629
+#: src/Module/Admin/Site.php:618
msgid ""
"Check to block public access to all otherwise public personal pages on this "
"site unless you are currently logged in."
msgstr ""
-#: src/Module/Admin/Site.php:630
+#: src/Module/Admin/Site.php:619
msgid "Force publish"
msgstr ""
-#: src/Module/Admin/Site.php:630
+#: src/Module/Admin/Site.php:619
msgid ""
"Check to force all profiles on this site to be listed in the site directory."
msgstr ""
-#: src/Module/Admin/Site.php:630
+#: src/Module/Admin/Site.php:619
msgid "Enabling this may violate privacy laws like the GDPR"
msgstr ""
-#: src/Module/Admin/Site.php:631
+#: src/Module/Admin/Site.php:620
msgid "Global directory URL"
msgstr ""
-#: src/Module/Admin/Site.php:631
+#: src/Module/Admin/Site.php:620
msgid ""
"URL to the global directory. If this is not set, the global directory is "
"completely unavailable to the application."
msgstr ""
-#: src/Module/Admin/Site.php:632
+#: src/Module/Admin/Site.php:621
msgid "Private posts by default for new users"
msgstr ""
-#: src/Module/Admin/Site.php:632
+#: src/Module/Admin/Site.php:621
msgid ""
"Set default post permissions for all new members to the default privacy "
"group rather than public."
msgstr ""
-#: src/Module/Admin/Site.php:633
+#: src/Module/Admin/Site.php:622
msgid "Don't include post content in email notifications"
msgstr ""
-#: src/Module/Admin/Site.php:633
+#: src/Module/Admin/Site.php:622
msgid ""
"Don't include the content of a post/comment/private message/etc. in the "
"email notifications that are sent out from this site, as a privacy measure."
msgstr ""
-#: src/Module/Admin/Site.php:634
+#: src/Module/Admin/Site.php:623
msgid "Disallow public access to addons listed in the apps menu."
msgstr ""
-#: src/Module/Admin/Site.php:634
+#: src/Module/Admin/Site.php:623
msgid ""
"Checking this box will restrict addons listed in the apps menu to members "
"only."
msgstr ""
-#: src/Module/Admin/Site.php:635
+#: src/Module/Admin/Site.php:624
msgid "Don't embed private images in posts"
msgstr ""
-#: src/Module/Admin/Site.php:635
+#: src/Module/Admin/Site.php:624
msgid ""
"Don't replace locally-hosted private photos in posts with an embedded copy "
"of the image. This means that contacts who receive posts containing private "
"photos will have to authenticate and load each image, which may take a while."
msgstr ""
-#: src/Module/Admin/Site.php:636
+#: src/Module/Admin/Site.php:625
msgid "Explicit Content"
msgstr ""
-#: src/Module/Admin/Site.php:636
+#: src/Module/Admin/Site.php:625
msgid ""
"Set this to announce that your node is used mostly for explicit content that "
"might not be suited for minors. This information will be published in the "
@@ -6278,234 +6278,234 @@ msgid ""
"will be shown at the user registration page."
msgstr ""
-#: src/Module/Admin/Site.php:637
+#: src/Module/Admin/Site.php:626
msgid "Allow Users to set remote_self"
msgstr ""
-#: src/Module/Admin/Site.php:637
+#: src/Module/Admin/Site.php:626
msgid ""
"With checking this, every user is allowed to mark every contact as a "
"remote_self in the repair contact dialog. Setting this flag on a contact "
"causes mirroring every posting of that contact in the users stream."
msgstr ""
-#: src/Module/Admin/Site.php:638
+#: src/Module/Admin/Site.php:627
msgid "Block multiple registrations"
msgstr ""
-#: src/Module/Admin/Site.php:638
+#: src/Module/Admin/Site.php:627
msgid "Disallow users to register additional accounts for use as pages."
msgstr ""
-#: src/Module/Admin/Site.php:639
+#: src/Module/Admin/Site.php:628
msgid "Disable OpenID"
msgstr ""
-#: src/Module/Admin/Site.php:639
+#: src/Module/Admin/Site.php:628
msgid "Disable OpenID support for registration and logins."
msgstr ""
-#: src/Module/Admin/Site.php:640
+#: src/Module/Admin/Site.php:629
msgid "No Fullname check"
msgstr ""
-#: src/Module/Admin/Site.php:640
+#: src/Module/Admin/Site.php:629
msgid ""
"Allow users to register without a space between the first name and the last "
"name in their full name."
msgstr ""
-#: src/Module/Admin/Site.php:641
+#: src/Module/Admin/Site.php:630
msgid "Community pages for visitors"
msgstr ""
-#: src/Module/Admin/Site.php:641
+#: src/Module/Admin/Site.php:630
msgid ""
"Which community pages should be available for visitors. Local users always "
"see both pages."
msgstr ""
-#: src/Module/Admin/Site.php:642
+#: src/Module/Admin/Site.php:631
msgid "Posts per user on community page"
msgstr ""
-#: src/Module/Admin/Site.php:642
+#: src/Module/Admin/Site.php:631
msgid ""
"The maximum number of posts per user on the community page. (Not valid for "
"\"Global Community\")"
msgstr ""
-#: src/Module/Admin/Site.php:643
+#: src/Module/Admin/Site.php:632
msgid "Disable OStatus support"
msgstr ""
-#: src/Module/Admin/Site.php:643
+#: src/Module/Admin/Site.php:632
msgid ""
"Disable built-in OStatus (StatusNet, GNU Social etc.) compatibility. All "
"communications in OStatus are public, so privacy warnings will be "
"occasionally displayed."
msgstr ""
-#: src/Module/Admin/Site.php:644
+#: src/Module/Admin/Site.php:633
msgid "OStatus support can only be enabled if threading is enabled."
msgstr ""
-#: src/Module/Admin/Site.php:646
+#: src/Module/Admin/Site.php:635
msgid ""
"Diaspora support can't be enabled because Friendica was installed into a sub "
"directory."
msgstr ""
-#: src/Module/Admin/Site.php:647
+#: src/Module/Admin/Site.php:636
msgid "Enable Diaspora support"
msgstr ""
-#: src/Module/Admin/Site.php:647
+#: src/Module/Admin/Site.php:636
msgid "Provide built-in Diaspora network compatibility."
msgstr ""
-#: src/Module/Admin/Site.php:648
+#: src/Module/Admin/Site.php:637
msgid "Only allow Friendica contacts"
msgstr ""
-#: src/Module/Admin/Site.php:648
+#: src/Module/Admin/Site.php:637
msgid ""
"All contacts must use Friendica protocols. All other built-in communication "
"protocols disabled."
msgstr ""
-#: src/Module/Admin/Site.php:649
+#: src/Module/Admin/Site.php:638
msgid "Verify SSL"
msgstr ""
-#: src/Module/Admin/Site.php:649
+#: src/Module/Admin/Site.php:638
msgid ""
"If you wish, you can turn on strict certificate checking. This will mean you "
"cannot connect (at all) to self-signed SSL sites."
msgstr ""
-#: src/Module/Admin/Site.php:650
+#: src/Module/Admin/Site.php:639
msgid "Proxy user"
msgstr ""
-#: src/Module/Admin/Site.php:651
+#: src/Module/Admin/Site.php:640
msgid "Proxy URL"
msgstr ""
-#: src/Module/Admin/Site.php:652
+#: src/Module/Admin/Site.php:641
msgid "Network timeout"
msgstr ""
-#: src/Module/Admin/Site.php:652
+#: src/Module/Admin/Site.php:641
msgid "Value is in seconds. Set to 0 for unlimited (not recommended)."
msgstr ""
-#: src/Module/Admin/Site.php:653
+#: src/Module/Admin/Site.php:642
msgid "Maximum Load Average"
msgstr ""
-#: src/Module/Admin/Site.php:653
+#: src/Module/Admin/Site.php:642
#, php-format
msgid ""
"Maximum system load before delivery and poll processes are deferred - "
"default %d."
msgstr ""
-#: src/Module/Admin/Site.php:654
+#: src/Module/Admin/Site.php:643
msgid "Maximum Load Average (Frontend)"
msgstr ""
-#: src/Module/Admin/Site.php:654
+#: src/Module/Admin/Site.php:643
msgid "Maximum system load before the frontend quits service - default 50."
msgstr ""
-#: src/Module/Admin/Site.php:655
+#: src/Module/Admin/Site.php:644
msgid "Minimal Memory"
msgstr ""
-#: src/Module/Admin/Site.php:655
+#: src/Module/Admin/Site.php:644
msgid ""
"Minimal free memory in MB for the worker. Needs access to /proc/meminfo - "
"default 0 (deactivated)."
msgstr ""
-#: src/Module/Admin/Site.php:656
+#: src/Module/Admin/Site.php:645
msgid "Periodically optimize tables"
msgstr ""
-#: src/Module/Admin/Site.php:656
+#: src/Module/Admin/Site.php:645
msgid "Periodically optimize tables like the cache and the workerqueue"
msgstr ""
-#: src/Module/Admin/Site.php:658
+#: src/Module/Admin/Site.php:647
msgid "Discover followers/followings from contacts"
msgstr ""
-#: src/Module/Admin/Site.php:658
+#: src/Module/Admin/Site.php:647
msgid ""
"If enabled, contacts are checked for their followers and following contacts."
msgstr ""
-#: src/Module/Admin/Site.php:659
+#: src/Module/Admin/Site.php:648
msgid "None - deactivated"
msgstr ""
-#: src/Module/Admin/Site.php:660
+#: src/Module/Admin/Site.php:649
msgid ""
"Local contacts - contacts of our local contacts are discovered for their "
"followers/followings."
msgstr ""
-#: src/Module/Admin/Site.php:661
+#: src/Module/Admin/Site.php:650
msgid ""
"Interactors - contacts of our local contacts and contacts who interacted on "
"locally visible postings are discovered for their followers/followings."
msgstr ""
-#: src/Module/Admin/Site.php:663
+#: src/Module/Admin/Site.php:652
msgid "Synchronize the contacts with the directory server"
msgstr ""
-#: src/Module/Admin/Site.php:663
+#: src/Module/Admin/Site.php:652
msgid ""
"if enabled, the system will check periodically for new contacts on the "
"defined directory server."
msgstr ""
-#: src/Module/Admin/Site.php:665
+#: src/Module/Admin/Site.php:654
msgid "Days between requery"
msgstr ""
-#: src/Module/Admin/Site.php:665
+#: src/Module/Admin/Site.php:654
msgid "Number of days after which a server is requeried for his contacts."
msgstr ""
-#: src/Module/Admin/Site.php:666
+#: src/Module/Admin/Site.php:655
msgid "Discover contacts from other servers"
msgstr ""
-#: src/Module/Admin/Site.php:666
+#: src/Module/Admin/Site.php:655
msgid ""
"Periodically query other servers for contacts. The system queries Friendica, "
"Mastodon and Hubzilla servers."
msgstr ""
-#: src/Module/Admin/Site.php:667
+#: src/Module/Admin/Site.php:656
msgid "Search the local directory"
msgstr ""
-#: src/Module/Admin/Site.php:667
+#: src/Module/Admin/Site.php:656
msgid ""
"Search the local directory instead of the global directory. When searching "
"locally, every search will be executed on the global directory in the "
"background. This improves the search results when the search is repeated."
msgstr ""
-#: src/Module/Admin/Site.php:669
+#: src/Module/Admin/Site.php:658
msgid "Publish server information"
msgstr ""
-#: src/Module/Admin/Site.php:669
+#: src/Module/Admin/Site.php:658
msgid ""
"If enabled, general server and usage data will be published. The data "
"contains the name and version of the server, number of users with public "
@@ -6513,50 +6513,50 @@ msgid ""
"href=\"http://the-federation.info/\">the-federation.info for details."
msgstr ""
-#: src/Module/Admin/Site.php:671
+#: src/Module/Admin/Site.php:660
msgid "Check upstream version"
msgstr ""
-#: src/Module/Admin/Site.php:671
+#: src/Module/Admin/Site.php:660
msgid ""
"Enables checking for new Friendica versions at github. If there is a new "
"version, you will be informed in the admin panel overview."
msgstr ""
-#: src/Module/Admin/Site.php:672
+#: src/Module/Admin/Site.php:661
msgid "Suppress Tags"
msgstr ""
-#: src/Module/Admin/Site.php:672
+#: src/Module/Admin/Site.php:661
msgid "Suppress showing a list of hashtags at the end of the posting."
msgstr ""
-#: src/Module/Admin/Site.php:673
+#: src/Module/Admin/Site.php:662
msgid "Clean database"
msgstr ""
-#: src/Module/Admin/Site.php:673
+#: src/Module/Admin/Site.php:662
msgid ""
"Remove old remote items, orphaned database records and old content from some "
"other helper tables."
msgstr ""
-#: src/Module/Admin/Site.php:674
+#: src/Module/Admin/Site.php:663
msgid "Lifespan of remote items"
msgstr ""
-#: src/Module/Admin/Site.php:674
+#: src/Module/Admin/Site.php:663
msgid ""
"When the database cleanup is enabled, this defines the days after which "
"remote items will be deleted. Own items, and marked or filed items are "
"always kept. 0 disables this behaviour."
msgstr ""
-#: src/Module/Admin/Site.php:675
+#: src/Module/Admin/Site.php:664
msgid "Lifespan of unclaimed items"
msgstr ""
-#: src/Module/Admin/Site.php:675
+#: src/Module/Admin/Site.php:664
msgid ""
"When the database cleanup is enabled, this defines the days after which "
"unclaimed remote items (mostly content from the relay) will be deleted. "
@@ -6564,184 +6564,156 @@ msgid ""
"items if set to 0."
msgstr ""
-#: src/Module/Admin/Site.php:676
+#: src/Module/Admin/Site.php:665
msgid "Lifespan of raw conversation data"
msgstr ""
-#: src/Module/Admin/Site.php:676
+#: src/Module/Admin/Site.php:665
msgid ""
"The conversation data is used for ActivityPub and OStatus, as well as for "
"debug purposes. It should be safe to remove it after 14 days, default is 90 "
"days."
msgstr ""
-#: src/Module/Admin/Site.php:677
-msgid "Path to item cache"
-msgstr ""
-
-#: src/Module/Admin/Site.php:677
-msgid "The item caches buffers generated bbcode and external images."
-msgstr ""
-
-#: src/Module/Admin/Site.php:678
-msgid "Cache duration in seconds"
-msgstr ""
-
-#: src/Module/Admin/Site.php:678
-msgid ""
-"How long should the cache files be hold? Default value is 86400 seconds (One "
-"day). To disable the item cache, set the value to -1."
-msgstr ""
-
-#: src/Module/Admin/Site.php:679
+#: src/Module/Admin/Site.php:666
msgid "Maximum numbers of comments per post"
msgstr ""
-#: src/Module/Admin/Site.php:679
+#: src/Module/Admin/Site.php:666
msgid "How much comments should be shown for each post? Default value is 100."
msgstr ""
-#: src/Module/Admin/Site.php:680
+#: src/Module/Admin/Site.php:667
msgid "Maximum numbers of comments per post on the display page"
msgstr ""
-#: src/Module/Admin/Site.php:680
+#: src/Module/Admin/Site.php:667
msgid ""
"How many comments should be shown on the single view for each post? Default "
"value is 1000."
msgstr ""
-#: src/Module/Admin/Site.php:681
+#: src/Module/Admin/Site.php:668
msgid "Temp path"
msgstr ""
-#: src/Module/Admin/Site.php:681
+#: src/Module/Admin/Site.php:668
msgid ""
"If you have a restricted system where the webserver can't access the system "
"temp path, enter another path here."
msgstr ""
-#: src/Module/Admin/Site.php:682
-msgid "Disable picture proxy"
-msgstr ""
-
-#: src/Module/Admin/Site.php:682
-msgid ""
-"The picture proxy increases performance and privacy. It shouldn't be used on "
-"systems with very low bandwidth."
-msgstr ""
-
-#: src/Module/Admin/Site.php:683
+#: src/Module/Admin/Site.php:669
msgid "Only search in tags"
msgstr ""
-#: src/Module/Admin/Site.php:683
+#: src/Module/Admin/Site.php:669
msgid "On large systems the text search can slow down the system extremely."
msgstr ""
-#: src/Module/Admin/Site.php:685
+#: src/Module/Admin/Site.php:671
msgid "New base url"
msgstr ""
-#: src/Module/Admin/Site.php:685
+#: src/Module/Admin/Site.php:671
msgid ""
"Change base url for this server. Sends relocate message to all Friendica and "
"Diaspora* contacts of all users."
msgstr ""
-#: src/Module/Admin/Site.php:687
+#: src/Module/Admin/Site.php:673
msgid "RINO Encryption"
msgstr ""
-#: src/Module/Admin/Site.php:687
+#: src/Module/Admin/Site.php:673
msgid "Encryption layer between nodes."
msgstr ""
-#: src/Module/Admin/Site.php:687 src/Module/Admin/Site.php:693
+#: src/Module/Admin/Site.php:673 src/Module/Admin/Site.php:679
#: src/Module/Contact.php:562 src/Module/Settings/TwoFactor/Index.php:118
msgid "Disabled"
msgstr ""
-#: src/Module/Admin/Site.php:687
+#: src/Module/Admin/Site.php:673
msgid "Enabled"
msgstr ""
-#: src/Module/Admin/Site.php:689
+#: src/Module/Admin/Site.php:675
msgid "Maximum number of parallel workers"
msgstr ""
-#: src/Module/Admin/Site.php:689
+#: src/Module/Admin/Site.php:675
#, php-format
msgid ""
"On shared hosters set this to %d. On larger systems, values of %d are great. "
"Default value is %d."
msgstr ""
-#: src/Module/Admin/Site.php:690
+#: src/Module/Admin/Site.php:676
msgid "Enable fastlane"
msgstr ""
-#: src/Module/Admin/Site.php:690
+#: src/Module/Admin/Site.php:676
msgid ""
"When enabed, the fastlane mechanism starts an additional worker if processes "
"with higher priority are blocked by processes of lower priority."
msgstr ""
-#: src/Module/Admin/Site.php:692
+#: src/Module/Admin/Site.php:678
msgid "Direct relay transfer"
msgstr ""
-#: src/Module/Admin/Site.php:692
+#: src/Module/Admin/Site.php:678
msgid ""
"Enables the direct transfer to other servers without using the relay servers"
msgstr ""
-#: src/Module/Admin/Site.php:693
+#: src/Module/Admin/Site.php:679
msgid "Relay scope"
msgstr ""
-#: src/Module/Admin/Site.php:693
+#: src/Module/Admin/Site.php:679
msgid ""
"Can be \"all\" or \"tags\". \"all\" means that every public post should be "
"received. \"tags\" means that only posts with selected tags should be "
"received."
msgstr ""
-#: src/Module/Admin/Site.php:693
+#: src/Module/Admin/Site.php:679
msgid "all"
msgstr ""
-#: src/Module/Admin/Site.php:693
+#: src/Module/Admin/Site.php:679
msgid "tags"
msgstr ""
-#: src/Module/Admin/Site.php:694
+#: src/Module/Admin/Site.php:680
msgid "Server tags"
msgstr ""
-#: src/Module/Admin/Site.php:694
+#: src/Module/Admin/Site.php:680
msgid "Comma separated list of tags for the \"tags\" subscription."
msgstr ""
-#: src/Module/Admin/Site.php:695
+#: src/Module/Admin/Site.php:681
msgid "Deny Server tags"
msgstr ""
-#: src/Module/Admin/Site.php:695
+#: src/Module/Admin/Site.php:681
msgid "Comma separated list of tags that are rejected."
msgstr ""
-#: src/Module/Admin/Site.php:696
+#: src/Module/Admin/Site.php:682
msgid "Allow user tags"
msgstr ""
-#: src/Module/Admin/Site.php:696
+#: src/Module/Admin/Site.php:682
msgid ""
"If enabled, the tags from the saved searches will used for the \"tags\" "
"subscription in addition to the \"relay_server_tags\"."
msgstr ""
-#: src/Module/Admin/Site.php:699
+#: src/Module/Admin/Site.php:685
msgid "Start Relocation"
msgstr ""
@@ -7329,16 +7301,21 @@ msgstr ""
msgid "User registrations waiting for confirmation"
msgstr ""
-#: src/Module/BaseApi.php:126
+#: src/Module/BaseApi.php:128
#, php-format
msgid "API endpoint %s %s is not implemented"
msgstr ""
-#: src/Module/BaseApi.php:127
+#: src/Module/BaseApi.php:129
msgid ""
"The API endpoint is currently not implemented but might be in the future."
msgstr ""
+#: src/Module/BaseApi.php:301 src/Module/BaseApi.php:317
+#: src/Module/BaseApi.php:333
+msgid "Too Many Requests"
+msgstr ""
+
#: src/Module/BaseProfile.php:55 src/Module/Contact.php:947
msgid "Profile Details"
msgstr ""
diff --git a/view/templates/admin/site.tpl b/view/templates/admin/site.tpl
index 75d9437d7..64d49d3a3 100644
--- a/view/templates/admin/site.tpl
+++ b/view/templates/admin/site.tpl
@@ -106,11 +106,8 @@
{{$performance}}
{{include file="field_checkbox.tpl" field=$only_tag_search}}
- {{include file="field_input.tpl" field=$itemcache}}
- {{include file="field_input.tpl" field=$itemcache_duration}}
{{include file="field_input.tpl" field=$max_comments}}
{{include file="field_input.tpl" field=$max_display_comments}}
- {{include file="field_checkbox.tpl" field=$proxy_disabled}}
{{include file="field_checkbox.tpl" field=$dbclean}}
{{include file="field_input.tpl" field=$dbclean_expire_days}}
{{include file="field_input.tpl" field=$dbclean_unclaimed}}
diff --git a/view/theme/frio/templates/admin/site.tpl b/view/theme/frio/templates/admin/site.tpl
index 69076833d..ad8715177 100644
--- a/view/theme/frio/templates/admin/site.tpl
+++ b/view/theme/frio/templates/admin/site.tpl
@@ -241,11 +241,8 @@