Merge pull request #14020 from annando/issue-13714

Issue 13714: Support for "commentsEnabled" and "capabilities"
pull/14015/head
Hypolite Petovan 2024-03-21 17:21:51 +00:00 committed by GitHub
commit faac52e078
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 75 additions and 13 deletions

View File

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2024.06-dev (Yellow Archangel) -- Friendica 2024.06-dev (Yellow Archangel)
-- DB_UPDATE_VERSION 1558 -- DB_UPDATE_VERSION 1559
-- ------------------------------------------ -- ------------------------------------------
@ -1347,7 +1347,7 @@ CREATE TABLE IF NOT EXISTS `post-engagement` (
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri', `uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
`owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner', `owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner',
`contact-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Person, organisation, news, community, relay', `contact-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Person, organisation, news, community, relay',
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio', `media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio)',
`language` char(2) COMMENT 'Language information about this post in the ISO 639-1 format', `language` char(2) COMMENT 'Language information about this post in the ISO 639-1 format',
`searchtext` mediumtext COMMENT 'Simplified text for the full text search', `searchtext` mediumtext COMMENT 'Simplified text for the full text search',
`size` int unsigned COMMENT 'Body size', `size` int unsigned COMMENT 'Body size',
@ -1471,7 +1471,7 @@ CREATE TABLE IF NOT EXISTS `post-question-option` (
CREATE TABLE IF NOT EXISTS `post-searchindex` ( CREATE TABLE IF NOT EXISTS `post-searchindex` (
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri', `uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
`owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner', `owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner',
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio', `media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio)',
`language` char(2) COMMENT 'Language information about this post in the ISO 639-1 format', `language` char(2) COMMENT 'Language information about this post in the ISO 639-1 format',
`searchtext` mediumtext COMMENT 'Simplified text for the full text search', `searchtext` mediumtext COMMENT 'Simplified text for the full text search',
`size` int unsigned COMMENT 'Body size', `size` int unsigned COMMENT 'Body size',
@ -1550,6 +1550,7 @@ CREATE TABLE IF NOT EXISTS `post-user` (
`post-reason` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Reason why the post arrived at the user', `post-reason` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Reason why the post arrived at the user',
`vid` smallint unsigned COMMENT 'Id of the verb table entry that contains the activity verbs', `vid` smallint unsigned COMMENT 'Id of the verb table entry that contains the activity verbs',
`private` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '0=public, 1=private, 2=unlisted', `private` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '0=public, 1=private, 2=unlisted',
`restrictions` tinyint unsigned COMMENT 'Bit array of post restrictions (1 = Reply, 2 = Like, 4 = Announce)',
`global` boolean NOT NULL DEFAULT '0' COMMENT '', `global` boolean NOT NULL DEFAULT '0' COMMENT '',
`visible` boolean NOT NULL DEFAULT '0' COMMENT '', `visible` boolean NOT NULL DEFAULT '0' COMMENT '',
`deleted` boolean NOT NULL DEFAULT '0' COMMENT 'item has been marked for deletion', `deleted` boolean NOT NULL DEFAULT '0' COMMENT 'item has been marked for deletion',
@ -2201,6 +2202,7 @@ CREATE VIEW `post-user-view` AS SELECT
`post-content`.`location` AS `location`, `post-content`.`location` AS `location`,
`post-content`.`coord` AS `coord`, `post-content`.`coord` AS `coord`,
`post-content`.`sensitive` AS `sensitive`, `post-content`.`sensitive` AS `sensitive`,
`post-user`.`restrictions` AS `restrictions`,
`post-content`.`app` AS `app`, `post-content`.`app` AS `app`,
`post-content`.`object-type` AS `object-type`, `post-content`.`object-type` AS `object-type`,
`post-content`.`object` AS `object`, `post-content`.`object` AS `object`,
@ -2386,6 +2388,7 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`post-content`.`location` AS `location`, `post-content`.`location` AS `location`,
`post-content`.`coord` AS `coord`, `post-content`.`coord` AS `coord`,
`post-content`.`sensitive` AS `sensitive`, `post-content`.`sensitive` AS `sensitive`,
`post-user`.`restrictions` AS `restrictions`,
`post-content`.`app` AS `app`, `post-content`.`app` AS `app`,
`post-content`.`object-type` AS `object-type`, `post-content`.`object-type` AS `object-type`,
`post-content`.`object` AS `object`, `post-content`.`object` AS `object`,

View File

@ -11,7 +11,7 @@ Fields
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | | | uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
| owner-id | Item owner | int unsigned | NO | | 0 | | | owner-id | Item owner | int unsigned | NO | | 0 | |
| contact-type | Person, organisation, news, community, relay | tinyint | NO | | 0 | | | contact-type | Person, organisation, news, community, relay | tinyint | NO | | 0 | |
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio | tinyint | NO | | 0 | | | media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio) | tinyint | NO | | 0 | |
| language | Language information about this post in the ISO 639-1 format | char(2) | YES | | NULL | | | language | Language information about this post in the ISO 639-1 format | char(2) | YES | | NULL | |
| searchtext | Simplified text for the full text search | mediumtext | YES | | NULL | | | searchtext | Simplified text for the full text search | mediumtext | YES | | NULL | |
| size | Body size | int unsigned | YES | | NULL | | | size | Body size | int unsigned | YES | | NULL | |

View File

@ -10,7 +10,7 @@ Fields
| ---------- | --------------------------------------------------------------------- | ------------ | ---- | --- | ------- | ----- | | ---------- | --------------------------------------------------------------------- | ------------ | ---- | --- | ------- | ----- |
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | | | uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
| owner-id | Item owner | int unsigned | NO | | 0 | | | owner-id | Item owner | int unsigned | NO | | 0 | |
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio | tinyint | NO | | 0 | | | media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio) | tinyint | NO | | 0 | |
| language | Language information about this post in the ISO 639-1 format | char(2) | YES | | NULL | | | language | Language information about this post in the ISO 639-1 format | char(2) | YES | | NULL | |
| searchtext | Simplified text for the full text search | mediumtext | YES | | NULL | | | searchtext | Simplified text for the full text search | mediumtext | YES | | NULL | |
| size | Body size | int unsigned | YES | | NULL | | | size | Body size | int unsigned | YES | | NULL | |

View File

@ -25,6 +25,7 @@ Fields
| post-reason | Reason why the post arrived at the user | tinyint unsigned | NO | | 0 | | | post-reason | Reason why the post arrived at the user | tinyint unsigned | NO | | 0 | |
| vid | Id of the verb table entry that contains the activity verbs | smallint unsigned | YES | | NULL | | | vid | Id of the verb table entry that contains the activity verbs | smallint unsigned | YES | | NULL | |
| private | 0=public, 1=private, 2=unlisted | tinyint unsigned | NO | | 0 | | | private | 0=public, 1=private, 2=unlisted | tinyint unsigned | NO | | 0 | |
| restrictions | Bit array of post restrictions (1 = Reply, 2 = Like, 4 = Announce) | tinyint unsigned | YES | | NULL | |
| global | | boolean | NO | | 0 | | | global | | boolean | NO | | 0 | |
| visible | | boolean | NO | | 0 | | | visible | | boolean | NO | | 0 | |
| deleted | item has been marked for deletion | boolean | NO | | 0 | | | deleted | item has been marked for deletion | boolean | NO | | 0 | |

View File

@ -108,7 +108,7 @@ class Item
'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-gsid', 'owner-id', 'owner-link', 'owner-alias', 'owner-name', 'owner-avatar', 'owner-network', 'owner-contact-type', 'owner-updated', 'owner-gsid',
'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-gsid', 'causer-id', 'causer-link', 'causer-alias', 'causer-name', 'causer-avatar', 'causer-contact-type', 'causer-network', 'causer-gsid',
'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar', 'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar',
'writable', 'self', 'cid', 'alias', 'writable', 'restrictions', 'self', 'cid', 'alias',
'event-created', 'event-edited', 'event-start', 'event-finish', 'event-created', 'event-edited', 'event-start', 'event-finish',
'event-summary', 'event-desc', 'event-location', 'event-type', 'event-summary', 'event-desc', 'event-location', 'event-type',
'event-nofinish', 'event-ignore', 'event-id', 'event-nofinish', 'event-ignore', 'event-id',
@ -168,6 +168,11 @@ class Item
const GRAVITY_COMMENT = 6; const GRAVITY_COMMENT = 6;
const GRAVITY_UNKNOWN = 9; const GRAVITY_UNKNOWN = 9;
// Restrictions
const CANT_REPLY = 1;
const CANT_LIKE = 2;
const CANT_ANNOUNCE = 4;
/** /**
* Update existing item entries * Update existing item entries
* *
@ -759,7 +764,7 @@ class Item
{ {
$fields = [ $fields = [
'uid', 'uri', 'parent-uri', 'id', 'deleted', 'uid', 'uri', 'parent-uri', 'id', 'deleted',
'uri-id', 'parent-uri-id', 'uri-id', 'parent-uri-id', 'restrictions', 'verb',
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
'wall', 'private', 'origin', 'author-id' 'wall', 'private', 'origin', 'author-id'
]; ];
@ -783,6 +788,11 @@ class Item
return []; return [];
} }
if (self::hasRestrictions($item, $parent['author-id'], $parent['restrictions'])) {
Logger::notice('Restrictions apply - ignoring item', ['restrictions' => $parent['restrictions'], 'verb' => $parent['verb'], 'uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
return 0;
}
if ($parent['uri-id'] == $parent['parent-uri-id']) { if ($parent['uri-id'] == $parent['parent-uri-id']) {
return $parent; return $parent;
} }
@ -1439,6 +1449,27 @@ class Item
return $post_user_id; return $post_user_id;
} }
private static function hasRestrictions(array $item, int $author_id, int $restrictions = null): bool
{
if (empty($restrictions) || ($author_id == $item['author-id'])) {
return false;
}
if (($restrictions & self::CANT_REPLY) && ($item['verb'] == Activity::POST)) {
return true;
}
if (($restrictions & self::CANT_ANNOUNCE) && ($item['verb'] == Activity::ANNOUNCE)) {
return true;
}
if (($restrictions & self::CANT_LIKE) && in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE, Activity::ATTEND, Activity::ATTENDMAYBE, Activity::ATTENDNO])) {
return true;
}
return false;
}
private static function reshareChannelPost(int $uri_id, int $reshare_id = 0) private static function reshareChannelPost(int $uri_id, int $reshare_id = 0)
{ {
if (!DI::config()->get('system', 'allow_relay_channels')) { if (!DI::config()->get('system', 'allow_relay_channels')) {

View File

@ -212,12 +212,25 @@ class Post
$shareable = in_array($conv->getProfileOwner(), [0, DI::userSession()->getLocalUserId()]) && $item['private'] != Item::PRIVATE; $shareable = in_array($conv->getProfileOwner(), [0, DI::userSession()->getLocalUserId()]) && $item['private'] != Item::PRIVATE;
$announceable = $shareable && in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::TWITTER, Protocol::TUMBLR, Protocol::BLUESKY]); $announceable = $shareable && in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::TWITTER, Protocol::TUMBLR, Protocol::BLUESKY]);
$commentable = ($item['network'] != Protocol::TUMBLR); $commentable = ($item['network'] != Protocol::TUMBLR);
$likeable = true;
// On Diaspora only toplevel posts can be reshared // On Diaspora only toplevel posts can be reshared
if ($announceable && ($item['network'] == Protocol::DIASPORA) && ($item['gravity'] != Item::GRAVITY_PARENT)) { if ($announceable && ($item['network'] == Protocol::DIASPORA) && ($item['gravity'] != Item::GRAVITY_PARENT)) {
$announceable = false; $announceable = false;
} }
if ($item['restrictions'] & Item::CANT_REPLY) {
$commentable = false;
}
if ($item['restrictions'] & Item::CANT_LIKE) {
$likeable = false;
}
if ($item['restrictions'] & Item::CANT_ANNOUNCE) {
$announceable = false;
}
$edpost = false; $edpost = false;
if (DI::userSession()->getLocalUserId()) { if (DI::userSession()->getLocalUserId()) {
@ -423,8 +436,10 @@ class Post
} }
if ($conv->isWritable()) { if ($conv->isWritable()) {
if ($likeable) {
$buttons['like'] = [DI::l10n()->t("I like this \x28toggle\x29"), DI::l10n()->t('Like')]; $buttons['like'] = [DI::l10n()->t("I like this \x28toggle\x29"), DI::l10n()->t('Like')];
$buttons['dislike'] = [DI::l10n()->t("I don't like this \x28toggle\x29"), DI::l10n()->t('Dislike')]; $buttons['dislike'] = [DI::l10n()->t("I don't like this \x28toggle\x29"), DI::l10n()->t('Dislike')];
}
if ($shareable) { if ($shareable) {
$buttons['share'] = [DI::l10n()->t('Quote share this'), DI::l10n()->t('Quote Share')]; $buttons['share'] = [DI::l10n()->t('Quote share this'), DI::l10n()->t('Quote Share')];
} }

View File

@ -927,7 +927,16 @@ class Processor
$restrictions = []; $restrictions = [];
} }
// @todo Store restrictions $item['restrictions'] = null;
foreach ($restrictions as $restriction) {
if ($restriction == Tag::CAN_REPLY) {
$item['restrictions'] = $item['restrictions'] | Item::CANT_REPLY;
} elseif ($restriction == Tag::CAN_LIKE) {
$item['restrictions'] = $item['restrictions'] | Item::CANT_LIKE;
} elseif ($restriction == Tag::CAN_ANNOUNCE) {
$item['restrictions'] = $item['restrictions'] | Item::CANT_ANNOUNCE;
}
}
$item['location'] = $activity['location']; $item['location'] = $activity['location'];

View File

@ -56,7 +56,7 @@ use Friendica\Database\DBA;
// This file is required several times during the test in DbaDefinition which justifies this condition // This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1558); define('DB_UPDATE_VERSION', 1559);
} }
return [ return [
@ -1368,7 +1368,7 @@ return [
"uri-id" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"], "uri-id" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"],
"owner-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "Item owner"], "owner-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "Item owner"],
"contact-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Person, organisation, news, community, relay"], "contact-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Person, organisation, news, community, relay"],
"media-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Type of media in a bit array (1 = image, 2 = video, 4 = audio"], "media-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Type of media in a bit array (1 = image, 2 = video, 4 = audio)"],
"language" => ["type" => "char(2)", "comment" => "Language information about this post in the ISO 639-1 format"], "language" => ["type" => "char(2)", "comment" => "Language information about this post in the ISO 639-1 format"],
"searchtext" => ["type" => "mediumtext", "comment" => "Simplified text for the full text search"], "searchtext" => ["type" => "mediumtext", "comment" => "Simplified text for the full text search"],
"size" => ["type" => "int unsigned", "comment" => "Body size"], "size" => ["type" => "int unsigned", "comment" => "Body size"],
@ -1490,7 +1490,7 @@ return [
"fields" => [ "fields" => [
"uri-id" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"], "uri-id" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"],
"owner-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "Item owner"], "owner-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "Item owner"],
"media-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Type of media in a bit array (1 = image, 2 = video, 4 = audio"], "media-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Type of media in a bit array (1 = image, 2 = video, 4 = audio)"],
"language" => ["type" => "char(2)", "comment" => "Language information about this post in the ISO 639-1 format"], "language" => ["type" => "char(2)", "comment" => "Language information about this post in the ISO 639-1 format"],
"searchtext" => ["type" => "mediumtext", "comment" => "Simplified text for the full text search"], "searchtext" => ["type" => "mediumtext", "comment" => "Simplified text for the full text search"],
"size" => ["type" => "int unsigned", "comment" => "Body size"], "size" => ["type" => "int unsigned", "comment" => "Body size"],
@ -1562,6 +1562,7 @@ return [
"post-reason" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "Reason why the post arrived at the user"], "post-reason" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "Reason why the post arrived at the user"],
"vid" => ["type" => "smallint unsigned", "foreign" => ["verb" => "id", "on delete" => "restrict"], "comment" => "Id of the verb table entry that contains the activity verbs"], "vid" => ["type" => "smallint unsigned", "foreign" => ["verb" => "id", "on delete" => "restrict"], "comment" => "Id of the verb table entry that contains the activity verbs"],
"private" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "0=public, 1=private, 2=unlisted"], "private" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "0=public, 1=private, 2=unlisted"],
"restrictions" => ["type" => "tinyint unsigned", "comment" => "Bit array of post restrictions (1 = Reply, 2 = Like, 4 = Announce)"],
"global" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "global" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
"visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
"deleted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item has been marked for deletion"], "deleted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item has been marked for deletion"],

View File

@ -228,6 +228,7 @@
"location" => ["post-content", "location"], "location" => ["post-content", "location"],
"coord" => ["post-content", "coord"], "coord" => ["post-content", "coord"],
"sensitive" => ["post-content", "sensitive"], "sensitive" => ["post-content", "sensitive"],
"restrictions" => ["post-user", "restrictions"],
"app" => ["post-content", "app"], "app" => ["post-content", "app"],
"object-type" => ["post-content", "object-type"], "object-type" => ["post-content", "object-type"],
"object" => ["post-content", "object"], "object" => ["post-content", "object"],
@ -411,6 +412,7 @@
"location" => ["post-content", "location"], "location" => ["post-content", "location"],
"coord" => ["post-content", "coord"], "coord" => ["post-content", "coord"],
"sensitive" => ["post-content", "sensitive"], "sensitive" => ["post-content", "sensitive"],
"restrictions" => ["post-user", "restrictions"],
"app" => ["post-content", "app"], "app" => ["post-content", "app"],
"object-type" => ["post-content", "object-type"], "object-type" => ["post-content", "object-type"],
"object" => ["post-content", "object"], "object" => ["post-content", "object"],