mirror of
https://github.com/friendica/friendica
synced 2024-11-18 21:43:40 +00:00
Merge pull request #10472 from annando/proxy
Simplified proxy, item cache related stuff removed
This commit is contained in:
commit
6354d7c81d
48 changed files with 1052 additions and 1076 deletions
|
@ -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
|
||||
|
|
87
boot.php
87
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
|
||||
*
|
||||
|
|
58
database.sql
58
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`),
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -7,7 +7,7 @@ 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 | |
|
||||
|
@ -36,6 +36,7 @@ Fields
|
|||
| 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 | |
|
||||
|
@ -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)
|
||||
|
|
|
@ -7,12 +7,13 @@ 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 | | | |
|
||||
| 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 | |
|
||||
|
@ -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)
|
||||
|
|
|
@ -7,10 +7,11 @@ 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 | | | |
|
||||
| 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 | | | |
|
||||
|
@ -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)
|
||||
|
|
31
doc/database/db_post-link.md
Normal file
31
doc/database/db_post-link.md
Normal file
|
@ -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)
|
|
@ -36,7 +36,7 @@ Indexes
|
|||
------------
|
||||
|
||||
| Name | Fields |
|
||||
| ------------- | -------------- |
|
||||
| ----------------- | ------------------- |
|
||||
| PRIMARY | uid, uri-id |
|
||||
| uri-id | uri-id |
|
||||
| owner-id | owner-id |
|
||||
|
@ -48,6 +48,7 @@ Indexes
|
|||
| 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 |
|
||||
|
|
|
@ -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;
|
||||
$media_url = Post\Link::getByLink($uriid, $url);
|
||||
$sizes["medium"] = ["w" => $image[0], "h" => $image[1], "resize" => "fit"];
|
||||
}
|
||||
|
||||
$entities["media"][] = [
|
||||
"id" => $start+1,
|
||||
|
|
|
@ -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"]);
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
|
||||
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data['url'], self::proxyUrl($data['image'], $simplehtml, $uriid), $data['title']);
|
||||
} else {
|
||||
if (!empty($data['image'])) {
|
||||
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br>', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
|
||||
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br>', $data['url'], self::proxyUrl($data['image'], $simplehtml, $uriid), $data['title']);
|
||||
} elseif (!empty($data['preview'])) {
|
||||
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br>', $data['url'], self::proxyUrl($data['preview'], $simplehtml), $data['title']);
|
||||
$return .= sprintf('<a href="%s" target="_blank" rel="noopener noreferrer"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br>', $data['url'], self::proxyUrl($data['preview'], $simplehtml, $uriid), $data['title']);
|
||||
}
|
||||
$return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
|
||||
}
|
||||
|
@ -929,7 +940,7 @@ class BBCode
|
|||
return ['body' => $new_body, 'images' => $saved_image];
|
||||
}
|
||||
|
||||
private static function interpolateSavedImagesIntoItemBody($body, array $images)
|
||||
private static function interpolateSavedImagesIntoItemBody($uriid, $body, array $images)
|
||||
{
|
||||
$newbody = $body;
|
||||
|
||||
|
@ -939,7 +950,7 @@ class BBCode
|
|||
// it loops over the array starting from the first element and going sequentially
|
||||
// to the last element
|
||||
$newbody = str_replace('[$#saved_image' . $cnt . '#$]',
|
||||
'<img src="' . self::proxyUrl($image) . '" alt="' . DI::l10n()->t('Image/photo') . '" />', $newbody);
|
||||
'<img src="' . self::proxyUrl($image, self::INTERNAL, $uriid) . '" alt="' . DI::l10n()->t('Image/photo') . '" />', $newbody);
|
||||
$cnt++;
|
||||
}
|
||||
|
||||
|
@ -989,11 +1000,11 @@ class BBCode
|
|||
* @param callable $callback
|
||||
* @return string The BBCode string with all [share] blocks replaced
|
||||
*/
|
||||
public static function convertShare($text, callable $callback)
|
||||
public static function convertShare($text, callable $callback, int $uriid = 0)
|
||||
{
|
||||
$return = preg_replace_callback(
|
||||
"/(.*?)\[share(.*?)\](.*)\[\/share\]/ism",
|
||||
function ($match) use ($callback) {
|
||||
function ($match) use ($callback, $uriid) {
|
||||
$attribute_string = $match[2];
|
||||
$attributes = [];
|
||||
foreach (['author', 'profile', 'avatar', 'link', 'posted', 'guid'] as $field) {
|
||||
|
@ -1012,7 +1023,7 @@ class BBCode
|
|||
if (!empty($author_contact['id'])) {
|
||||
$attributes['avatar'] = Contact::getAvatarUrlForId($author_contact['id'], ProxyUtils::SIZE_THUMB);
|
||||
} elseif ($attributes['avatar']) {
|
||||
$attributes['avatar'] = ProxyUtils::proxifyUrl($attributes['avatar'], false, ProxyUtils::SIZE_THUMB);
|
||||
$attributes['avatar'] = self::proxyUrl($attributes['avatar'], self::INTERNAL, $uriid, ProxyUtils::SIZE_THUMB);
|
||||
}
|
||||
|
||||
$content = preg_replace(Strings::autoLinkRegEx(), '<a href="$1">$1</a>', $match[3]);
|
||||
|
@ -1252,6 +1263,37 @@ class BBCode
|
|||
return $bbcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a BBCode message for a given URI-ID to a HTML message
|
||||
*
|
||||
* BBcode 2 HTML was written by WAY2WEB.net
|
||||
* extended to work with Mistpark/Friendica - Mike Macgirvin
|
||||
*
|
||||
* Simple HTML values meaning:
|
||||
* - 0: Friendica display
|
||||
* - 1: Unused
|
||||
* - 2: Used for Windows Phone push, Friendica API
|
||||
* - 3: Used before converting to Markdown in bb2diaspora.php
|
||||
* - 4: Used for WordPress, Libertree (before Markdown), pump.io and tumblr
|
||||
* - 5: Unused
|
||||
* - 6: Unused
|
||||
* - 7: Used for dfrn, OStatus
|
||||
* - 8: Used for Twitter, WP backlink text setting
|
||||
* - 9: ActivityPub
|
||||
*
|
||||
* @param int $uriid
|
||||
* @param string $text
|
||||
* @param int $simple_html
|
||||
* @return string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function convertForUriId(int $uriid = 0, string $text = null, int $simple_html = self::INTERNAL)
|
||||
{
|
||||
$try_oembed = ($simple_html == self::INTERNAL);
|
||||
|
||||
return self::convert($text, $try_oembed, $simple_html, false, $uriid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a BBCode message to HTML message
|
||||
*
|
||||
|
@ -1274,10 +1316,11 @@ class BBCode
|
|||
* @param bool $try_oembed
|
||||
* @param int $simple_html
|
||||
* @param bool $for_plaintext
|
||||
* @param int $uriid
|
||||
* @return string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function convert(string $text = null, $try_oembed = true, $simple_html = self::INTERNAL, $for_plaintext = false)
|
||||
public static function convert(string $text = null, $try_oembed = true, $simple_html = self::INTERNAL, $for_plaintext = false, $uriid = 0)
|
||||
{
|
||||
// Accounting for null default column values
|
||||
if (is_null($text) || $text === '') {
|
||||
|
@ -1288,8 +1331,8 @@ class BBCode
|
|||
|
||||
$a = DI::app();
|
||||
|
||||
$text = self::performWithEscapedTags($text, ['code'], function ($text) use ($try_oembed, $simple_html, $for_plaintext, $a) {
|
||||
$text = self::performWithEscapedTags($text, ['noparse', 'nobb', 'pre'], function ($text) use ($try_oembed, $simple_html, $for_plaintext, $a) {
|
||||
$text = self::performWithEscapedTags($text, ['code'], function ($text) use ($try_oembed, $simple_html, $for_plaintext, $a, $uriid) {
|
||||
$text = self::performWithEscapedTags($text, ['noparse', 'nobb', 'pre'], function ($text) use ($try_oembed, $simple_html, $for_plaintext, $a, $uriid) {
|
||||
/*
|
||||
* preg_match_callback function to replace potential Oembed tags with Oembed content
|
||||
*
|
||||
|
@ -1398,7 +1441,7 @@ class BBCode
|
|||
} elseif (!in_array($simple_html, [self::INTERNAL, self::EXTERNAL, self::CONNECTORS])) {
|
||||
$text = self::removeAttachment($text, true);
|
||||
} else {
|
||||
$text = self::convertAttachment($text, $simple_html, $try_oembed);
|
||||
$text = self::convertAttachment($text, $simple_html, $try_oembed, [], $uriid);
|
||||
}
|
||||
|
||||
$nosmile = strpos($text, '[nosmile]') !== false;
|
||||
|
@ -1573,12 +1616,12 @@ class BBCode
|
|||
// [img=widthxheight]image source[/img]
|
||||
$text = preg_replace_callback(
|
||||
"/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism",
|
||||
function ($matches) use ($simple_html) {
|
||||
function ($matches) use ($simple_html, $uriid) {
|
||||
if (strpos($matches[3], "data:image/") === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$matches[3] = self::proxyUrl($matches[3], $simple_html);
|
||||
$matches[3] = self::proxyUrl($matches[3], $simple_html, $uriid);
|
||||
return "[img=" . $matches[1] . "x" . $matches[2] . "]" . $matches[3] . "[/img]";
|
||||
},
|
||||
$text
|
||||
|
@ -1588,8 +1631,8 @@ class BBCode
|
|||
$text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/ism", '<img class="zrl" src="$3" style="width: $1px;" >', $text);
|
||||
|
||||
$text = preg_replace_callback("/\[img\=(.*?)\](.*?)\[\/img\]/ism",
|
||||
function ($matches) use ($simple_html) {
|
||||
$matches[1] = self::proxyUrl($matches[1], $simple_html);
|
||||
function ($matches) use ($simple_html, $uriid) {
|
||||
$matches[1] = self::proxyUrl($matches[1], $simple_html, $uriid);
|
||||
$matches[2] = htmlspecialchars($matches[2], ENT_COMPAT);
|
||||
return '<img src="' . $matches[1] . '" alt="' . $matches[2] . '" title="' . $matches[2] . '">';
|
||||
},
|
||||
|
@ -1599,12 +1642,12 @@ class BBCode
|
|||
// [img]pathtoimage[/img]
|
||||
$text = preg_replace_callback(
|
||||
"/\[img\](.*?)\[\/img\]/ism",
|
||||
function ($matches) use ($simple_html) {
|
||||
function ($matches) use ($simple_html, $uriid) {
|
||||
if (strpos($matches[1], "data:image/") === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$matches[1] = self::proxyUrl($matches[1], $simple_html);
|
||||
$matches[1] = self::proxyUrl($matches[1], $simple_html, $uriid);
|
||||
return "[img]" . $matches[1] . "[/img]";
|
||||
},
|
||||
$text
|
||||
|
@ -1686,7 +1729,7 @@ class BBCode
|
|||
// start which is always required). Allow desc with a missing summary for compatibility.
|
||||
|
||||
if ((!empty($ev['desc']) || !empty($ev['summary'])) && !empty($ev['start'])) {
|
||||
$sub = Event::getHTML($ev, $simple_html);
|
||||
$sub = Event::getHTML($ev, $simple_html, $uriid);
|
||||
|
||||
$text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism", '', $text);
|
||||
$text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism", '', $text);
|
||||
|
@ -1849,10 +1892,10 @@ class BBCode
|
|||
$text,
|
||||
function (array $attributes, array $author_contact, $content, $is_quote_share) use ($simple_html) {
|
||||
return self::convertShareCallback($attributes, $author_contact, $content, $is_quote_share, $simple_html);
|
||||
}
|
||||
}, $uriid
|
||||
);
|
||||
|
||||
$text = self::interpolateSavedImagesIntoItemBody($text, $saved_image);
|
||||
$text = self::interpolateSavedImagesIntoItemBody($uriid, $text, $saved_image);
|
||||
|
||||
return $text;
|
||||
}); // Escaped noparse, nobb, pre
|
||||
|
|
|
@ -329,8 +329,6 @@ class System
|
|||
function info($s)
|
||||
function is_site_admin()
|
||||
function get_temppath()
|
||||
function get_cachefile($file, $writemode = true)
|
||||
function get_itemcachepath()
|
||||
function get_spoolpath()
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -349,6 +349,12 @@ class APContact
|
|||
$apcontact['alias'] = null;
|
||||
}
|
||||
|
||||
if (empty($apcontact['uuid'])) {
|
||||
$apcontact['uri-id'] = ItemURI::getIdByURI($apcontact['url']);
|
||||
} else {
|
||||
$apcontact['uri-id'] = ItemURI::insert(['uri' => $apcontact['uri'], 'guid' => $apcontact['uuid']]);
|
||||
}
|
||||
|
||||
$apcontact['updated'] = DateTimeFormat::utcNow();
|
||||
|
||||
// We delete the old entry when the URL is changed
|
||||
|
|
|
@ -185,6 +185,8 @@ class Contact
|
|||
$fields['gsid'] = GServer::getID($fields['baseurl'], true);
|
||||
}
|
||||
|
||||
$fields['uri-id'] = ItemURI::getIdByURI($fields['url']);
|
||||
|
||||
if (empty($fields['created'])) {
|
||||
$fields['created'] = DateTimeFormat::utcNow();
|
||||
}
|
||||
|
@ -1497,67 +1499,46 @@ class Contact
|
|||
* @param bool $no_update Don't perfom an update if no cached avatar was found
|
||||
* @return string photo path
|
||||
*/
|
||||
private static function getAvatarPath(array $contact, string $field, string $size, string $avatar, $no_update = false)
|
||||
private static function getAvatarPath(array $contact, string $size, $no_update = false)
|
||||
{
|
||||
if (!empty($contact)) {
|
||||
$contact = self::checkAvatarCacheByArray($contact, $no_update);
|
||||
if (!empty($contact['id'])) {
|
||||
return self::getAvatarUrlForId($contact['id'], $size, $contact['updated'] ?? '');
|
||||
} elseif (!empty($contact[$field])) {
|
||||
return $contact[$field];
|
||||
} elseif (!empty($contact['avatar'])) {
|
||||
$avatar = $contact['avatar'];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($avatar)) {
|
||||
$avatar = self::getDefaultAvatar([], $size);
|
||||
}
|
||||
|
||||
if (Proxy::isLocalImage($avatar)) {
|
||||
return $avatar;
|
||||
} else {
|
||||
return Proxy::proxifyUrl($avatar, false, $size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the photo path for a given contact array
|
||||
*
|
||||
* @param array $contact Contact array
|
||||
* @param string $avatar Avatar path that is displayed when no photo had been found
|
||||
* @param bool $no_update Don't perfom an update if no cached avatar was found
|
||||
* @return string photo path
|
||||
*/
|
||||
public static function getPhoto(array $contact, string $avatar = '', bool $no_update = false)
|
||||
public static function getPhoto(array $contact, bool $no_update = false)
|
||||
{
|
||||
return self::getAvatarPath($contact, 'photo', Proxy::SIZE_SMALL, $avatar, $no_update);
|
||||
return self::getAvatarPath($contact, Proxy::SIZE_SMALL, $no_update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the photo path (thumb size) for a given contact array
|
||||
*
|
||||
* @param array $contact Contact array
|
||||
* @param string $avatar Avatar path that is displayed when no photo had been found
|
||||
* @param bool $no_update Don't perfom an update if no cached avatar was found
|
||||
* @return string photo path
|
||||
*/
|
||||
public static function getThumb(array $contact, string $avatar = '', bool $no_update = false)
|
||||
public static function getThumb(array $contact, bool $no_update = false)
|
||||
{
|
||||
return self::getAvatarPath($contact, 'thumb', Proxy::SIZE_THUMB, $avatar, $no_update);
|
||||
return self::getAvatarPath($contact, Proxy::SIZE_THUMB, $no_update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the photo path (micro size) for a given contact array
|
||||
*
|
||||
* @param array $contact Contact array
|
||||
* @param string $avatar Avatar path that is displayed when no photo had been found
|
||||
* @param bool $no_update Don't perfom an update if no cached avatar was found
|
||||
* @return string photo path
|
||||
*/
|
||||
public static function getMicro(array $contact, string $avatar = '', bool $no_update = false)
|
||||
public static function getMicro(array $contact, bool $no_update = false)
|
||||
{
|
||||
return self::getAvatarPath($contact, 'micro', Proxy::SIZE_MICRO, $avatar, $no_update);
|
||||
return self::getAvatarPath($contact, Proxy::SIZE_MICRO, $no_update);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1907,7 +1888,7 @@ class Contact
|
|||
{
|
||||
if (Strings::normaliseLink($new_url) != Strings::normaliseLink($old_url)) {
|
||||
Logger::notice('New URL differs from old URL', ['old' => $old_url, 'new' => $new_url]);
|
||||
// @todo It is to decide what to do when the URL is changed
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DBA::update('contact', $fields, ['id' => $id])) {
|
||||
|
@ -2042,7 +2023,7 @@ class Contact
|
|||
// These fields aren't updated by this routine:
|
||||
// 'xmpp', 'sensitive'
|
||||
|
||||
$fields = ['uid', 'avatar', 'header', 'name', 'nick', 'location', 'keywords', 'about', 'subscribe',
|
||||
$fields = ['uid', 'uri-id', 'avatar', 'header', 'name', 'nick', 'location', 'keywords', 'about', 'subscribe',
|
||||
'manually-approve', 'unsearchable', 'url', 'addr', 'batch', 'notify', 'poll', 'request', 'confirm', 'poco',
|
||||
'network', 'alias', 'baseurl', 'gsid', 'forum', 'prv', 'contact-type', 'pubkey', 'last-item'];
|
||||
$contact = DBA::selectFirst('contact', $fields, ['id' => $id]);
|
||||
|
@ -2071,6 +2052,9 @@ class Contact
|
|||
$uid = $contact['uid'];
|
||||
unset($contact['uid']);
|
||||
|
||||
$uriid = $contact['uri-id'];
|
||||
unset($contact['uri-id']);
|
||||
|
||||
$pubkey = $contact['pubkey'];
|
||||
unset($contact['pubkey']);
|
||||
|
||||
|
@ -2094,6 +2078,14 @@ class Contact
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Strings::normaliseLink($ret['url']) != Strings::normaliseLink($contact['url'])) {
|
||||
$cid = self::getIdForURL($ret['url']);
|
||||
if (!empty($cid) && ($cid != $id)) {
|
||||
Logger::notice('URL of contact changed.', ['id' => $id, 'new_id' => $cid, 'old' => $contact['url'], 'new' => $ret['url']]);
|
||||
return self::updateFromProbeArray($cid, $ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($ret['hide']) && is_bool($ret['hide'])) {
|
||||
$ret['unsearchable'] = $ret['hide'];
|
||||
}
|
||||
|
@ -2116,6 +2108,7 @@ class Contact
|
|||
}
|
||||
|
||||
$update = false;
|
||||
$guid = $ret['guid'] ?? '';
|
||||
|
||||
// make sure to not overwrite existing values with blank entries except some technical fields
|
||||
$keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl'];
|
||||
|
@ -2135,6 +2128,10 @@ class Contact
|
|||
unset($ret['last-item']);
|
||||
}
|
||||
|
||||
if (empty($uriid)) {
|
||||
$update = true;
|
||||
}
|
||||
|
||||
if (!empty($ret['photo']) && ($ret['network'] != Protocol::FEED)) {
|
||||
self::updateAvatar($id, $ret['photo'], $update);
|
||||
}
|
||||
|
@ -2157,6 +2154,12 @@ class Contact
|
|||
return true;
|
||||
}
|
||||
|
||||
if (empty($guid)) {
|
||||
$ret['uri-id'] = ItemURI::getIdByURI($ret['url']);
|
||||
} else {
|
||||
$ret['uri-id'] = ItemURI::insert(['uri' => $ret['uri'], 'guid' => $guid]);
|
||||
}
|
||||
|
||||
$ret['nurl'] = Strings::normaliseLink($ret['url']);
|
||||
$ret['updated'] = $updated;
|
||||
$ret['failed'] = false;
|
||||
|
|
|
@ -41,12 +41,14 @@ use Friendica\Util\XML;
|
|||
class Event
|
||||
{
|
||||
|
||||
public static function getHTML(array $event, $simple = false)
|
||||
public static function getHTML(array $event, $simple = false, $uriid = 0)
|
||||
{
|
||||
if (empty($event)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$uriid = $event['uri-id'] ?? $uriid;
|
||||
|
||||
$bd_format = DI::l10n()->t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8 AM.
|
||||
|
||||
$event_start = DI::l10n()->getDay(
|
||||
|
@ -67,11 +69,11 @@ class Event
|
|||
$o = '';
|
||||
|
||||
if (!empty($event['summary'])) {
|
||||
$o .= "<h3>" . BBCode::convert(Strings::escapeHtml($event['summary']), false, $simple) . "</h3>";
|
||||
$o .= "<h3>" . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['summary']), $simple) . "</h3>";
|
||||
}
|
||||
|
||||
if (!empty($event['desc'])) {
|
||||
$o .= "<div>" . BBCode::convert(Strings::escapeHtml($event['desc']), false, $simple) . "</div>";
|
||||
$o .= "<div>" . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['desc']), $simple) . "</div>";
|
||||
}
|
||||
|
||||
$o .= "<h4>" . DI::l10n()->t('Starts:') . "</h4><p>" . $event_start . "</p>";
|
||||
|
@ -81,7 +83,7 @@ class Event
|
|||
}
|
||||
|
||||
if (!empty($event['location'])) {
|
||||
$o .= "<h4>" . DI::l10n()->t('Location:') . "</h4><p>" . BBCode::convert(Strings::escapeHtml($event['location']), false, $simple) . "</p>";
|
||||
$o .= "<h4>" . DI::l10n()->t('Location:') . "</h4><p>" . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['location']), $simple) . "</p>";
|
||||
}
|
||||
|
||||
return $o;
|
||||
|
@ -89,7 +91,7 @@ class Event
|
|||
|
||||
$o = '<div class="vevent">' . "\r\n";
|
||||
|
||||
$o .= '<div class="summary event-summary">' . BBCode::convert(Strings::escapeHtml($event['summary']), false, $simple) . '</div>' . "\r\n";
|
||||
$o .= '<div class="summary event-summary">' . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['summary']), $simple) . '</div>' . "\r\n";
|
||||
|
||||
$o .= '<div class="event-start"><span class="event-label">' . DI::l10n()->t('Starts:') . '</span> <span class="dtstart" title="'
|
||||
. DateTimeFormat::utc($event['start'], (!empty($event['adjust']) ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s'))
|
||||
|
@ -104,12 +106,12 @@ class Event
|
|||
}
|
||||
|
||||
if (!empty($event['desc'])) {
|
||||
$o .= '<div class="description event-description">' . BBCode::convert(Strings::escapeHtml($event['desc']), false, $simple) . '</div>' . "\r\n";
|
||||
$o .= '<div class="description event-description">' . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['desc']), $simple) . '</div>' . "\r\n";
|
||||
}
|
||||
|
||||
if (!empty($event['location'])) {
|
||||
$o .= '<div class="event-location"><span class="event-label">' . DI::l10n()->t('Location:') . '</span> <span class="location">'
|
||||
. BBCode::convert(Strings::escapeHtml($event['location']), false, $simple)
|
||||
. BBCode::convertForUriId($uriid, Strings::escapeHtml($event['location']), $simple)
|
||||
. '</span></div>' . "\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("<br", BBCode::convert(Strings::escapeHtml($event['desc'])), BBCode::API);
|
||||
list($title, $_trash) = explode("<br", BBCode::convertForUriId($event['uri-id'], Strings::escapeHtml($event['desc'])), BBCode::API);
|
||||
}
|
||||
|
||||
$author_link = $event['author-link'];
|
||||
|
@ -630,9 +633,9 @@ class Event
|
|||
$event['author-link'] = Contact::magicLink($author_link);
|
||||
|
||||
$html = self::getHTML($event);
|
||||
$event['summary'] = BBCode::convert(Strings::escapeHtml($event['summary']));
|
||||
$event['desc'] = BBCode::convert(Strings::escapeHtml($event['desc']));
|
||||
$event['location'] = BBCode::convert(Strings::escapeHtml($event['location']));
|
||||
$event['summary'] = BBCode::convertForUriId($event['uri-id'], Strings::escapeHtml($event['summary']));
|
||||
$event['desc'] = BBCode::convertForUriId($event['uri-id'], Strings::escapeHtml($event['desc']));
|
||||
$event['location'] = BBCode::convertForUriId($event['uri-id'], Strings::escapeHtml($event['location']));
|
||||
$event_list[] = [
|
||||
'id' => $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'),
|
||||
|
|
|
@ -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"]];
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
127
src/Model/Post/Link.php
Normal file
127
src/Model/Post/Link.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2021, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -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.')],
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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"]);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/// @TODO Stop here?
|
||||
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
|
||||
*
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) . '...';
|
||||
|
|
|
@ -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"];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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"]);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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"]);
|
||||
|
||||
|
|
|
@ -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']]);
|
||||
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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');
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -106,11 +106,8 @@
|
|||
|
||||
<h2>{{$performance}}</h2>
|
||||
{{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}}
|
||||
|
|
|
@ -241,11 +241,8 @@
|
|||
<div id="admin-settings-performance-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-performance">
|
||||
<div class="panel-body">
|
||||
{{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}}
|
||||
|
|
|
@ -4620,7 +4620,6 @@ div #datebrowse-sidebar.widget {
|
|||
margin: 25px 0 25px 0;
|
||||
}
|
||||
|
||||
#id_itemcache,
|
||||
#id_basepath,
|
||||
#id_temppath,
|
||||
#id_lockpath,
|
||||
|
@ -4633,7 +4632,6 @@ div #datebrowse-sidebar.widget {
|
|||
width: 440px;
|
||||
}
|
||||
|
||||
#id_itemcache_duration,
|
||||
#id_abandon_days,
|
||||
#id_maxloadavg,
|
||||
#id_poll_interval,
|
||||
|
|
Loading…
Reference in a new issue