Merge pull request #9901 from annando/post-thread-user
New table "post-thread-user", removed tabled "user-item"
This commit is contained in:
commit
0ef5bf29d4
96
database.sql
96
database.sql
|
@ -1,6 +1,6 @@
|
|||
-- ------------------------------------------
|
||||
-- Friendica 2021.03-dev (Red Hot Poker)
|
||||
-- DB_UPDATE_VERSION 1396
|
||||
-- DB_UPDATE_VERSION 1397
|
||||
-- ------------------------------------------
|
||||
|
||||
|
||||
|
@ -684,7 +684,6 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
`guid` varchar(255) NOT NULL DEFAULT '' COMMENT 'A unique identifier for this item',
|
||||
`uri` varchar(255) NOT NULL DEFAULT '' COMMENT '',
|
||||
`uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`uri-hash` varchar(80) NOT NULL DEFAULT '' COMMENT 'RIPEMD-128 hash from uri',
|
||||
`parent` int unsigned COMMENT 'item.id of the parent to this item if it is a reply of some form; otherwise this must be set to the id of this item',
|
||||
`parent-uri` varchar(255) NOT NULL DEFAULT '' COMMENT 'uri of the top-level parent to this item',
|
||||
`parent-uri-id` int unsigned COMMENT 'Id of the item-uri table that contains the top-level parent uri',
|
||||
|
@ -710,16 +709,19 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
`deleted` boolean NOT NULL DEFAULT '0' COMMENT 'item has been deleted',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner id which owns this copy of the item',
|
||||
`contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'contact.id',
|
||||
`wall` boolean NOT NULL DEFAULT '0' COMMENT 'This item was posted to the wall of uid',
|
||||
`origin` boolean NOT NULL DEFAULT '0' COMMENT 'item originated at this site',
|
||||
`pubmail` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`starred` boolean NOT NULL DEFAULT '0' COMMENT 'item has been favourited',
|
||||
`unseen` boolean NOT NULL DEFAULT '1' COMMENT 'item has not been seen',
|
||||
`mention` boolean NOT NULL DEFAULT '0' COMMENT 'The owner of this item was mentioned in it',
|
||||
`forum_mode` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`origin` boolean NOT NULL DEFAULT '0' COMMENT 'item originated at this site',
|
||||
`psid` int unsigned COMMENT 'ID of the permission set of this post',
|
||||
`resource-id` varchar(32) NOT NULL DEFAULT '' COMMENT 'Used to link other tables to items, it identifies the linked resource (e.g. photo) and if set must also set resource_type',
|
||||
`starred` boolean NOT NULL DEFAULT '0' COMMENT 'item has been favourited',
|
||||
`wall` boolean NOT NULL DEFAULT '0' COMMENT 'This item was posted to the wall of uid',
|
||||
`pubmail` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`forum_mode` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
`event-id` int unsigned COMMENT 'Used to link to the event.id',
|
||||
`type` varchar(20) COMMENT '',
|
||||
`bookmark` boolean COMMENT '',
|
||||
`mention` boolean NOT NULL DEFAULT '0' COMMENT 'The owner of this item was mentioned in it',
|
||||
`resource-id` varchar(32) COMMENT 'Deprecated',
|
||||
`uri-hash` varchar(80) COMMENT 'Deprecated',
|
||||
`iaid` int unsigned COMMENT 'Deprecated',
|
||||
`icid` int unsigned COMMENT 'Deprecated',
|
||||
`attach` mediumtext COMMENT 'Deprecated',
|
||||
|
@ -729,8 +731,6 @@ CREATE TABLE IF NOT EXISTS `item` (
|
|||
`deny_gid` mediumtext COMMENT 'Deprecated',
|
||||
`postopts` text COMMENT 'Deprecated',
|
||||
`inform` mediumtext COMMENT 'Deprecated',
|
||||
`type` varchar(20) COMMENT 'Deprecated',
|
||||
`bookmark` boolean COMMENT 'Deprecated',
|
||||
`file` mediumtext COMMENT 'Deprecated',
|
||||
`location` varchar(255) COMMENT 'Deprecated',
|
||||
`coord` varchar(255) COMMENT 'Deprecated',
|
||||
|
@ -970,22 +970,6 @@ CREATE TABLE IF NOT EXISTS `parsed_url` (
|
|||
INDEX `created` (`created`)
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='cache for \'parse_url\' queries';
|
||||
|
||||
--
|
||||
-- TABLE participation
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `participation` (
|
||||
`iid` int unsigned NOT NULL COMMENT '',
|
||||
`server` varchar(60) NOT NULL COMMENT '',
|
||||
`cid` int unsigned NOT NULL COMMENT '',
|
||||
`fid` int unsigned NOT NULL COMMENT '',
|
||||
PRIMARY KEY(`iid`,`server`),
|
||||
INDEX `cid` (`cid`),
|
||||
INDEX `fid` (`fid`),
|
||||
FOREIGN KEY (`iid`) REFERENCES `item` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`fid`) REFERENCES `fcontact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Storage for participation messages from Diaspora';
|
||||
|
||||
--
|
||||
-- TABLE pconfig
|
||||
--
|
||||
|
@ -1141,6 +1125,26 @@ CREATE TABLE IF NOT EXISTS `post-tag` (
|
|||
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='post relation to tags';
|
||||
|
||||
--
|
||||
-- TABLE post-thread-user
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `post-thread-user` (
|
||||
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner id which owns this copy of the item',
|
||||
`pinned` boolean NOT NULL DEFAULT '0' COMMENT 'The thread is pinned on the profile page',
|
||||
`starred` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`ignored` boolean NOT NULL DEFAULT '0' COMMENT 'Ignore updates for this thread',
|
||||
`wall` boolean NOT NULL DEFAULT '0' COMMENT 'This item was posted to the wall of uid',
|
||||
`pubmail` boolean NOT NULL DEFAULT '0' COMMENT '',
|
||||
`forum_mode` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
PRIMARY KEY(`uid`,`uri-id`),
|
||||
INDEX `uid_wall` (`uid`,`wall`),
|
||||
INDEX `uid_pinned` (`uid`,`pinned`),
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Thread related data per user';
|
||||
|
||||
--
|
||||
-- TABLE post-user
|
||||
--
|
||||
|
@ -1166,6 +1170,19 @@ CREATE TABLE IF NOT EXISTS `post-user` (
|
|||
FOREIGN KEY (`psid`) REFERENCES `permissionset` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User specific post data';
|
||||
|
||||
--
|
||||
-- TABLE post-user-notification
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `post-user-notification` (
|
||||
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||
`uid` mediumint unsigned NOT NULL COMMENT 'Owner id which owns this copy of the item',
|
||||
`notification-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
PRIMARY KEY(`uid`,`uri-id`),
|
||||
INDEX `uri-id` (`uri-id`),
|
||||
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User post notifications';
|
||||
|
||||
--
|
||||
-- TABLE process
|
||||
--
|
||||
|
@ -1429,23 +1446,6 @@ CREATE TABLE IF NOT EXISTS `user-contact` (
|
|||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User specific public contact data';
|
||||
|
||||
--
|
||||
-- TABLE user-item
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `user-item` (
|
||||
`iid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item id',
|
||||
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
|
||||
`hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Marker to hide an item from the user',
|
||||
`ignored` boolean COMMENT 'Ignore this thread if set',
|
||||
`pinned` boolean COMMENT 'The item is pinned on the profile page',
|
||||
`notification-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
|
||||
PRIMARY KEY(`uid`,`iid`),
|
||||
INDEX `uid_pinned` (`uid`,`pinned`),
|
||||
INDEX `iid_uid` (`iid`,`uid`),
|
||||
FOREIGN KEY (`iid`) REFERENCES `item` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User specific item data';
|
||||
|
||||
--
|
||||
-- TABLE worker-ipc
|
||||
--
|
||||
|
@ -1848,13 +1848,13 @@ CREATE VIEW `network-item-view` AS SELECT
|
|||
FROM `item`
|
||||
INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent`
|
||||
STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
|
||||
LEFT JOIN `user-item` ON `user-item`.`iid` = `item`.`id` AND `user-item`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `post-user` ON `post-user`.`uri-id` = `item`.`uri-id` AND `post-user`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `thread`.`uid` AND `author`.`cid` = `thread`.`author-id`
|
||||
LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `thread`.`uid` AND `owner`.`cid` = `thread`.`owner-id`
|
||||
LEFT JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `thread`.`owner-id`
|
||||
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
|
||||
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
|
||||
AND (`user-item`.`hidden` IS NULL OR NOT `user-item`.`hidden`)
|
||||
AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`)
|
||||
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
|
||||
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`);
|
||||
|
||||
|
@ -1879,13 +1879,13 @@ CREATE VIEW `network-thread-view` AS SELECT
|
|||
FROM `thread`
|
||||
STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
|
||||
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
|
||||
LEFT JOIN `user-item` ON `user-item`.`iid` = `item`.`id` AND `user-item`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `post-user` ON `post-user`.`uri-id` = `item`.`uri-id` AND `post-user`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `thread`.`uid` AND `author`.`cid` = `thread`.`author-id`
|
||||
LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `thread`.`uid` AND `owner`.`cid` = `thread`.`owner-id`
|
||||
LEFT JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `thread`.`owner-id`
|
||||
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
|
||||
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
|
||||
AND (`user-item`.`hidden` IS NULL OR NOT `user-item`.`hidden`)
|
||||
AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`)
|
||||
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
|
||||
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`);
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ Database Tables
|
|||
| [notify-threads](help/database/db_notify-threads) | |
|
||||
| [oembed](help/database/db_oembed) | cache for OEmbed queries |
|
||||
| [parsed_url](help/database/db_parsed_url) | cache for "parse_url" queries |
|
||||
| [participation](help/database/db_participation) | Storage for participation messages from Diaspora |
|
||||
| [pconfig](help/database/db_pconfig) | personal (per user) configuration storage |
|
||||
| [photo](help/database/db_photo) | photo storage |
|
||||
| [poll](help/database/db_poll) | data for polls |
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
Table participation
|
||||
===================
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------------|------------------|------------------|------|-----|---------------------|-------|
|
||||
| iid | item id | int(10) unsigned | NO | PRI | | |
|
||||
| server | Name of server | varchar(60) | NO | PRI | | |
|
||||
| cid | contact id | int(10) unsigned | NO | | | |
|
||||
|
||||
Return to [database documentation](help/database)
|
|
@ -43,7 +43,6 @@ use Friendica\Model\Notification;
|
|||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Model\UserItem;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Network\HTTPException\BadRequestException;
|
||||
|
@ -2170,24 +2169,21 @@ function api_statuses_mentions($type)
|
|||
|
||||
$start = max(0, ($page - 1) * $count);
|
||||
|
||||
$query = "`gravity` IN (?, ?) AND `id` IN (SELECT `iid` FROM `user-item`
|
||||
WHERE (`hidden` IS NULL OR NOT `hidden`) AND
|
||||
`uid` = ? AND `notification-type` & ? != 0
|
||||
AND `iid` > ?";
|
||||
$query = "`gravity` IN (?, ?) AND `uri-id` IN
|
||||
(SELECT `uri-id` FROM `post-user-notification` WHERE `uid` = ? AND `notification-type` & ? != 0 ORDER BY `uri-id`)
|
||||
AND (`uid` = 0 OR (`uid` = ? AND NOT `global`)) AND `id` > ?";
|
||||
|
||||
$condition = [GRAVITY_PARENT, GRAVITY_COMMENT, api_user(),
|
||||
UserItem::NOTIF_EXPLICIT_TAGGED | UserItem::NOTIF_IMPLICIT_TAGGED |
|
||||
UserItem::NOTIF_THREAD_COMMENT | UserItem::NOTIF_DIRECT_COMMENT |
|
||||
UserItem::NOTIF_DIRECT_THREAD_COMMENT,
|
||||
$since_id];
|
||||
Post\UserNotification::NOTIF_EXPLICIT_TAGGED | Post\UserNotification::NOTIF_IMPLICIT_TAGGED |
|
||||
Post\UserNotification::NOTIF_THREAD_COMMENT | Post\UserNotification::NOTIF_DIRECT_COMMENT |
|
||||
Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT,
|
||||
api_user(), $since_id];
|
||||
|
||||
if ($max_id > 0) {
|
||||
$query .= " AND `iid` <= ?";
|
||||
$query .= " AND `id` <= ?";
|
||||
$condition[] = $max_id;
|
||||
}
|
||||
|
||||
$query .= ")";
|
||||
|
||||
array_unshift($condition, $query);
|
||||
|
||||
$params = ['order' => ['id' => true], 'limit' => [$start, $count]];
|
||||
|
|
|
@ -32,7 +32,6 @@ use Friendica\Model\Item;
|
|||
use Friendica\Model\Notification;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Model\UserItem;
|
||||
use Friendica\Protocol\Activity;
|
||||
|
||||
/**
|
||||
|
@ -149,9 +148,8 @@ function notification($params)
|
|||
}
|
||||
|
||||
if ($params['type'] == Notification\Type::COMMENT || $params['type'] == Notification\Type::TAG_SELF) {
|
||||
$thread = Post::selectFirstThreadForUser($params['uid'], ['ignored'], ['iid' => $parent_id, 'deleted' => false]);
|
||||
if (DBA::isResult($thread) && $thread['ignored']) {
|
||||
Logger::log('Thread ' . $parent_id . ' will be ignored', Logger::DEBUG);
|
||||
if (Post\ThreadUser::getIgnored($parent_uri_id, $params['uid'])) {
|
||||
Logger::info('Thread is ignored', ['parent' => $parent_id, 'parent-uri-id' => $parent_uri_id]);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -593,32 +591,39 @@ function notification($params)
|
|||
/**
|
||||
* Checks for users who should be notified
|
||||
*
|
||||
* @param int $itemid ID of the item for which the check should be done
|
||||
* @param int $uri_id URI ID of the item for which the check should be done
|
||||
* @param int $uid User ID of the item
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function check_user_notification($itemid) {
|
||||
// fetch all users with notifications
|
||||
$useritems = DBA::select('user-item', ['uid', 'notification-type'], ['iid' => $itemid]);
|
||||
while ($useritem = DBA::fetch($useritems)) {
|
||||
check_item_notification($itemid, $useritem['uid'], $useritem['notification-type']);
|
||||
function check_user_notification(int $uri_id, int $uid) {
|
||||
$condition = ['uri-id' => $uri_id];
|
||||
|
||||
// fetch all users with notifications on public posts
|
||||
if ($uid != 0) {
|
||||
$condition['uid'] = $uid;
|
||||
}
|
||||
DBA::close($useritems);
|
||||
|
||||
$usernotifications = DBA::select('post-user-notification', ['uri-id', 'uid', 'notification-type'], $condition);
|
||||
while ($usernotification = DBA::fetch($usernotifications)) {
|
||||
check_item_notification($usernotification['uri-id'], $usernotification['uid'], $usernotification['notification-type']);
|
||||
}
|
||||
DBA::close($usernotifications);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for item related notifications and sends them
|
||||
*
|
||||
* @param int $itemid ID of the item for which the check should be done
|
||||
* @param int $uri_id URI ID of the item for which the check should be done
|
||||
* @param int $uid User ID
|
||||
* @param int $notification_type Notification bits
|
||||
* @return bool
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function check_item_notification($itemid, $uid, $notification_type) {
|
||||
function check_item_notification(int $uri_id, int $uid, int $notification_type) {
|
||||
$fields = ['id', 'uri-id', 'mention', 'parent', 'parent-uri-id', 'thr-parent-id',
|
||||
'title', 'body', 'author-link', 'author-name', 'author-avatar', 'author-id',
|
||||
'gravity', 'guid', 'parent-uri', 'uri', 'contact-id', 'network'];
|
||||
$condition = ['id' => $itemid, 'deleted' => false];
|
||||
$condition = ['uri-id' => $uri_id, 'uid' => $uid, 'deleted' => false];
|
||||
$item = Post::selectFirstForUser($uid, $fields, $condition);
|
||||
if (!DBA::isResult($item)) {
|
||||
return false;
|
||||
|
@ -638,19 +643,19 @@ function check_item_notification($itemid, $uid, $notification_type) {
|
|||
$params['link'] = DI::baseUrl() . '/display/' . urlencode($item['guid']);
|
||||
|
||||
// Set the activity flags
|
||||
$params['activity']['explicit_tagged'] = ($notification_type & UserItem::NOTIF_EXPLICIT_TAGGED);
|
||||
$params['activity']['implicit_tagged'] = ($notification_type & UserItem::NOTIF_IMPLICIT_TAGGED);
|
||||
$params['activity']['origin_comment'] = ($notification_type & UserItem::NOTIF_DIRECT_COMMENT);
|
||||
$params['activity']['origin_thread'] = ($notification_type & UserItem::NOTIF_THREAD_COMMENT);
|
||||
$params['activity']['thread_comment'] = ($notification_type & UserItem::NOTIF_COMMENT_PARTICIPATION);
|
||||
$params['activity']['thread_activity'] = ($notification_type & UserItem::NOTIF_ACTIVITY_PARTICIPATION);
|
||||
$params['activity']['explicit_tagged'] = ($notification_type & Post\UserNotification::NOTIF_EXPLICIT_TAGGED);
|
||||
$params['activity']['implicit_tagged'] = ($notification_type & Post\UserNotification::NOTIF_IMPLICIT_TAGGED);
|
||||
$params['activity']['origin_comment'] = ($notification_type & Post\UserNotification::NOTIF_DIRECT_COMMENT);
|
||||
$params['activity']['origin_thread'] = ($notification_type & Post\UserNotification::NOTIF_THREAD_COMMENT);
|
||||
$params['activity']['thread_comment'] = ($notification_type & Post\UserNotification::NOTIF_COMMENT_PARTICIPATION);
|
||||
$params['activity']['thread_activity'] = ($notification_type & Post\UserNotification::NOTIF_ACTIVITY_PARTICIPATION);
|
||||
|
||||
// Tagging a user in a direct post (first comment level) means a direct comment
|
||||
if ($params['activity']['explicit_tagged'] && ($notification_type & UserItem::NOTIF_DIRECT_THREAD_COMMENT)) {
|
||||
if ($params['activity']['explicit_tagged'] && ($notification_type & Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT)) {
|
||||
$params['activity']['origin_comment'] = true;
|
||||
}
|
||||
|
||||
if ($notification_type & UserItem::NOTIF_SHARED) {
|
||||
if ($notification_type & Post\UserNotification::NOTIF_SHARED) {
|
||||
$params['type'] = Notification\Type::SHARE;
|
||||
$params['verb'] = Activity::POST;
|
||||
|
||||
|
@ -667,22 +672,22 @@ function check_item_notification($itemid, $uid, $notification_type) {
|
|||
$params['item'] = $parent_item;
|
||||
}
|
||||
}
|
||||
} elseif ($notification_type & UserItem::NOTIF_EXPLICIT_TAGGED) {
|
||||
} elseif ($notification_type & Post\UserNotification::NOTIF_EXPLICIT_TAGGED) {
|
||||
$params['type'] = Notification\Type::TAG_SELF;
|
||||
$params['verb'] = Activity::TAG;
|
||||
} elseif ($notification_type & UserItem::NOTIF_IMPLICIT_TAGGED) {
|
||||
} elseif ($notification_type & Post\UserNotification::NOTIF_IMPLICIT_TAGGED) {
|
||||
$params['type'] = Notification\Type::COMMENT;
|
||||
$params['verb'] = Activity::POST;
|
||||
} elseif ($notification_type & UserItem::NOTIF_THREAD_COMMENT) {
|
||||
} elseif ($notification_type & Post\UserNotification::NOTIF_THREAD_COMMENT) {
|
||||
$params['type'] = Notification\Type::COMMENT;
|
||||
$params['verb'] = Activity::POST;
|
||||
} elseif ($notification_type & UserItem::NOTIF_DIRECT_COMMENT) {
|
||||
} elseif ($notification_type & Post\UserNotification::NOTIF_DIRECT_COMMENT) {
|
||||
$params['type'] = Notification\Type::COMMENT;
|
||||
$params['verb'] = Activity::POST;
|
||||
} elseif ($notification_type & UserItem::NOTIF_COMMENT_PARTICIPATION) {
|
||||
} elseif ($notification_type & Post\UserNotification::NOTIF_COMMENT_PARTICIPATION) {
|
||||
$params['type'] = Notification\Type::COMMENT;
|
||||
$params['verb'] = Activity::POST;
|
||||
} elseif ($notification_type & UserItem::NOTIF_ACTIVITY_PARTICIPATION) {
|
||||
} elseif ($notification_type & Post\UserNotification::NOTIF_ACTIVITY_PARTICIPATION) {
|
||||
$params['type'] = Notification\Type::COMMENT;
|
||||
$params['verb'] = Activity::POST;
|
||||
} else {
|
||||
|
|
|
@ -79,7 +79,8 @@ class DBStructure
|
|||
}
|
||||
|
||||
$old_tables = ['fserver', 'gcign', 'gcontact', 'gcontact-relation', 'gfollower' ,'glink', 'item-delivery-data',
|
||||
'item-activity', 'item-content', 'item_id', 'poll', 'poll_result', 'queue', 'retriever_rule', 'sign', 'spam', 'term'];
|
||||
'item-activity', 'item-content', 'item_id', 'participation', 'poll', 'poll_result', 'queue', 'retriever_rule',
|
||||
'sign', 'spam', 'term', 'user-item'];
|
||||
|
||||
$tables = DBA::selectToArray(['INFORMATION_SCHEMA' => 'TABLES'], ['TABLE_NAME'],
|
||||
['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_TYPE' => 'BASE TABLE']);
|
||||
|
|
|
@ -31,7 +31,6 @@ use Friendica\Model\Photo;
|
|||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Post\Category;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Model\UserItem;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
|
@ -168,7 +167,7 @@ class PostUpdate
|
|||
}
|
||||
|
||||
/**
|
||||
* update user-item data with notifications
|
||||
* update user notification data
|
||||
*
|
||||
* @return bool "true" when the job is done
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
|
@ -188,7 +187,7 @@ class PostUpdate
|
|||
$rows = 0;
|
||||
$condition = ["`id` > ?", $id];
|
||||
$params = ['order' => ['id'], 'limit' => 10000];
|
||||
$items = DBA::select('item', ['id'], $condition, $params);
|
||||
$items = DBA::select('item', ['id', 'uri-id', 'uid'], $condition, $params);
|
||||
|
||||
if (DBA::errorNo() != 0) {
|
||||
Logger::error('Database error', ['no' => DBA::errorNo(), 'message' => DBA::errorMessage()]);
|
||||
|
@ -198,7 +197,7 @@ class PostUpdate
|
|||
while ($item = DBA::fetch($items)) {
|
||||
$id = $item['id'];
|
||||
|
||||
UserItem::setNotification($item['id']);
|
||||
Post\UserNotification::setNotification($item['uri-id'], $item['uid']);
|
||||
|
||||
++$rows;
|
||||
}
|
||||
|
|
|
@ -77,9 +77,9 @@ class Status extends BaseFactory
|
|||
$userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes(
|
||||
Post::exists(['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::LIKE)]),
|
||||
Post::exists(['thr-parent-id' => $uriId, 'uid' => $uid, 'origin' => true, 'gravity' => GRAVITY_ACTIVITY, 'vid' => Verb::getID(Activity::ANNOUNCE)]),
|
||||
DBA::exists('thread', ['iid' => $item['id'], 'uid' => $item['uid'], 'ignored' => true]),
|
||||
Post\ThreadUser::getIgnored($uriId, $item['uid']),
|
||||
(bool)$item['starred'],
|
||||
DBA::exists('user-item', ['iid' => $item['id'], 'uid' => $item['uid'], 'pinned' => true])
|
||||
Post\ThreadUser::getPinned($uriId, $item['uid'])
|
||||
);
|
||||
|
||||
$sensitive = DBA::exists('tag-view', ['uri-id' => $uriId, 'name' => 'nsfw']);
|
||||
|
|
|
@ -31,7 +31,6 @@ use Friendica\Core\Session;
|
|||
use Friendica\Core\System;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\DI;
|
||||
|
@ -99,14 +98,6 @@ class Item
|
|||
'author-id', 'author-link', 'owner-link', 'contact-uid',
|
||||
'signed_text', 'network'];
|
||||
|
||||
// Field list for "post-content" table that is mixed with the item table
|
||||
const MIXED_CONTENT_FIELDLIST = ['title', 'content-warning', 'body', 'location',
|
||||
'coord', 'app', 'rendered-hash', 'rendered-html', 'verb',
|
||||
'object-type', 'object', 'target-type', 'target', 'plink'];
|
||||
|
||||
// Field list for "post-content" table that is not present in the "item" table
|
||||
const CONTENT_FIELDLIST = ['language', 'raw-body'];
|
||||
|
||||
// All fields in the item table
|
||||
const ITEM_FIELDLIST = ['id', 'uid', 'parent', 'uri', 'parent-uri', 'thr-parent',
|
||||
'guid', 'uri-id', 'parent-uri-id', 'thr-parent-id', 'vid',
|
||||
|
@ -121,6 +112,22 @@ class Item
|
|||
'author-id', 'author-link', 'author-name', 'author-avatar', 'author-network',
|
||||
'owner-id', 'owner-link', 'owner-name', 'owner-avatar', 'causer-id'];
|
||||
|
||||
// Item fiels that still are in use
|
||||
const USED_FIELDLIST = ['id', 'parent', 'guid', 'uri', 'uri-id', 'parent-uri', 'parent-uri-id',
|
||||
'thr-parent', 'thr-parent-id', 'created', 'edited', 'commented', 'received', 'changed',
|
||||
'gravity', 'network', 'owner-id', 'author-id', 'causer-id', 'vid', 'extid', 'post-type',
|
||||
'global', 'private', 'visible', 'moderated', 'deleted', 'uid', 'contact-id',
|
||||
'wall', 'origin', 'pubmail', 'starred', 'unseen', 'mention', 'forum_mode', 'psid',
|
||||
'event-id', 'type', 'bookmark'];
|
||||
|
||||
// Legacy item fields that aren't stored any more in the item table
|
||||
const LEGACY_FIELDLIST = ['uri-hash', 'iaid', 'icid', 'attach',
|
||||
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'postopts',
|
||||
'resource-id', 'inform', 'file', 'location', 'coord', 'tag', 'plink',
|
||||
'title', 'content-warning', 'body', 'app', 'verb', 'object-type', 'object',
|
||||
'target-type', 'target', 'author-name', 'author-link', 'author-avatar',
|
||||
'owner-name', 'owner-link', 'owner-avatar', 'rendered-hash', 'rendered-html'];
|
||||
|
||||
// List of all verbs that don't need additional content data.
|
||||
// Never reorder or remove entries from this list. Just add new ones at the end, if needed.
|
||||
const ACTIVITIES = [
|
||||
|
@ -133,49 +140,6 @@ class Item
|
|||
const PRIVATE = 1;
|
||||
const UNLISTED = 2;
|
||||
|
||||
const TABLES = ['item', 'user-item', 'post-content', 'post-delivery-data', 'diaspora-interaction'];
|
||||
|
||||
private static function getItemFields()
|
||||
{
|
||||
$definition = DBStructure::definition('', false);
|
||||
|
||||
$postfields = [];
|
||||
foreach (self::TABLES as $table) {
|
||||
$postfields[$table] = array_keys($definition[$table]['fields']);
|
||||
}
|
||||
|
||||
return $postfields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pinned state of an item
|
||||
*
|
||||
* @param integer $iid Item ID
|
||||
* @param integer $uid User ID
|
||||
* @param boolean $pinned Pinned state
|
||||
*/
|
||||
public static function setPinned(int $iid, int $uid, bool $pinned)
|
||||
{
|
||||
DBA::update('user-item', ['pinned' => $pinned], ['iid' => $iid, 'uid' => $uid], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pinned state
|
||||
*
|
||||
* @param integer $iid Item ID
|
||||
* @param integer $uid User ID
|
||||
*
|
||||
* @return boolean pinned state
|
||||
*/
|
||||
public static function getPinned(int $iid, int $uid)
|
||||
{
|
||||
$useritem = DBA::selectFirst('user-item', ['pinned'], ['iid' => $iid, 'uid' => $uid]);
|
||||
if (!DBA::isResult($useritem)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)$useritem['pinned'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update existing item entries
|
||||
*
|
||||
|
@ -285,12 +249,9 @@ class Item
|
|||
Post\User::update($item['uri-id'], $uid, ['hidden' => true], true);
|
||||
}
|
||||
|
||||
// "Deleting" global items just means hiding them
|
||||
if ($item['uid'] == 0) {
|
||||
DBA::update('user-item', ['hidden' => true], ['iid' => $item['id'], 'uid' => $uid], true);
|
||||
} elseif ($item['uid'] == $uid) {
|
||||
if ($item['uid'] == $uid) {
|
||||
self::markForDeletionById($item['id'], PRIORITY_HIGH);
|
||||
} else {
|
||||
} elseif ($item['uid'] != 0) {
|
||||
Logger::log('Wrong ownership. Not deleting item ' . $item['id']);
|
||||
}
|
||||
}
|
||||
|
@ -393,12 +354,6 @@ class Item
|
|||
}
|
||||
} elseif ($item['uid'] != 0) {
|
||||
Post\User::update($item['uri-id'], $item['uid'], ['hidden' => true]);
|
||||
|
||||
// When we delete just our local user copy of an item, we have to set a marker to hide it
|
||||
$global_item = Post::selectFirst(['id'], ['uri-id' => $item['uri-id'], 'uid' => 0, 'deleted' => false]);
|
||||
if (DBA::isResult($global_item)) {
|
||||
DBA::update('user-item', ['hidden' => true], ['iid' => $global_item['id'], 'uid' => $item['uid']], true);
|
||||
}
|
||||
}
|
||||
|
||||
Logger::info('Item has been marked for deletion.', ['id' => $item_id]);
|
||||
|
@ -755,8 +710,6 @@ class Item
|
|||
|
||||
public static function insert($item, $notify = false, $dontcache = false)
|
||||
{
|
||||
$structure = self::getItemFields();
|
||||
|
||||
$orig_item = $item;
|
||||
|
||||
$priority = PRIORITY_HIGH;
|
||||
|
@ -952,26 +905,11 @@ class Item
|
|||
|
||||
// Update the contact relations
|
||||
Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']);
|
||||
|
||||
unset($item['parent_origin']);
|
||||
} else {
|
||||
$parent_id = 0;
|
||||
$parent_origin = $item['origin'];
|
||||
}
|
||||
|
||||
// We don't store the causer link, only the id
|
||||
unset($item['causer-link']);
|
||||
|
||||
// We don't store these fields anymore in the item table
|
||||
unset($item['author-link']);
|
||||
unset($item['author-name']);
|
||||
unset($item['author-avatar']);
|
||||
unset($item['author-network']);
|
||||
|
||||
unset($item['owner-link']);
|
||||
unset($item['owner-name']);
|
||||
unset($item['owner-avatar']);
|
||||
|
||||
$item['parent-uri-id'] = ItemURI::getIdByURI($item['parent-uri']);
|
||||
$item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']);
|
||||
|
||||
|
@ -994,14 +932,10 @@ class Item
|
|||
$item['edit'] = false;
|
||||
$item['parent'] = $parent_id;
|
||||
Hook::callAll('post_local', $item);
|
||||
unset($item['edit']);
|
||||
} else {
|
||||
Hook::callAll('post_remote', $item);
|
||||
}
|
||||
|
||||
// Set after the insert because top-level posts are self-referencing
|
||||
unset($item['parent']);
|
||||
|
||||
if (!empty($item['cancel'])) {
|
||||
Logger::log('post cancelled by addon.');
|
||||
return 0;
|
||||
|
@ -1020,15 +954,6 @@ class Item
|
|||
$item['deny_gid']
|
||||
);
|
||||
|
||||
unset($item['allow_cid']);
|
||||
unset($item['allow_gid']);
|
||||
unset($item['deny_cid']);
|
||||
unset($item['deny_gid']);
|
||||
|
||||
// This array field is used to trigger some automatic reactions
|
||||
// It is mainly used in the "post_local" hook.
|
||||
unset($item['api_source']);
|
||||
|
||||
if ($item['verb'] == Activity::ANNOUNCE) {
|
||||
self::setOwnerforResharedItem($item);
|
||||
}
|
||||
|
@ -1040,10 +965,6 @@ class Item
|
|||
// Check for hashtags in the body and repair or add hashtag links
|
||||
$item['body'] = self::setHashtags($item['body']);
|
||||
|
||||
if (!empty($item['attach'])) {
|
||||
Post\Media::insertFromAttachment($item['uri-id'], $item['attach']);
|
||||
}
|
||||
|
||||
// Fill the cache field
|
||||
self::putInCache($item);
|
||||
|
||||
|
@ -1053,40 +974,27 @@ class Item
|
|||
$notify_type = Delivery::POST;
|
||||
}
|
||||
|
||||
// Filling item related side tables
|
||||
if (!empty($item['attach'])) {
|
||||
Post\Media::insertFromAttachment($item['uri-id'], $item['attach']);
|
||||
}
|
||||
|
||||
if (!in_array($item['verb'], self::ACTIVITIES)) {
|
||||
Post\Content::insert($item['uri-id'], $item);
|
||||
}
|
||||
|
||||
$body = $item['body'];
|
||||
$verb = $item['verb'];
|
||||
|
||||
// We just remove everything that is content
|
||||
foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
|
||||
unset($item[$field]);
|
||||
}
|
||||
|
||||
unset($item['activity']);
|
||||
|
||||
// Filling item related side tables
|
||||
|
||||
// Diaspora signature
|
||||
if (!empty($item['diaspora_signed_text'])) {
|
||||
DBA::replace('diaspora-interaction', ['uri-id' => $item['uri-id'], 'interaction' => $item['diaspora_signed_text']]);
|
||||
}
|
||||
|
||||
unset($item['diaspora_signed_text']);
|
||||
|
||||
// Attached file links
|
||||
if (!empty($item['file'])) {
|
||||
Post\Category::storeTextByURIId($item['uri-id'], $item['uid'], $item['file']);
|
||||
}
|
||||
|
||||
unset($item['file']);
|
||||
|
||||
// Delivery relevant data
|
||||
$delivery_data = Post\DeliveryData::extractFields($item);
|
||||
unset($item['postopts']);
|
||||
unset($item['inform']);
|
||||
|
||||
if (!empty($item['origin']) || !empty($item['wall']) || !empty($delivery_data['postopts']) || !empty($delivery_data['inform'])) {
|
||||
Post\DeliveryData::insert($item['uri-id'], $delivery_data);
|
||||
|
@ -1094,33 +1002,38 @@ class Item
|
|||
|
||||
// Store tags from the body if this hadn't been handled previously in the protocol classes
|
||||
if (!Tag::existsForPost($item['uri-id'])) {
|
||||
Tag::storeFromBody($item['uri-id'], $body);
|
||||
Tag::storeFromBody($item['uri-id'], $item['body']);
|
||||
}
|
||||
|
||||
$id = Post\User::insert($item['uri-id'], $item['uid'], $item);
|
||||
if ($id) {
|
||||
// Remove all fields that aren't part of the item table
|
||||
foreach ($item as $field => $value) {
|
||||
if (!in_array($field, $structure['item'])) {
|
||||
unset($item[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
$condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'network' => $item['network']];
|
||||
if (Post::exists($condition)) {
|
||||
Logger::notice('Item is already inserted - aborting', $condition);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$result = DBA::insert('item', $item);
|
||||
|
||||
// When the item was successfully stored we fetch the ID of the item.
|
||||
$current_post = DBA::lastInsertId();
|
||||
} else {
|
||||
if (!$id) {
|
||||
Logger::notice('Post-User is already inserted - aborting', ['uid' => $item['uid'], 'uri-id' => $item['uri-id']]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($item['gravity'] == GRAVITY_PARENT) {
|
||||
Post\ThreadUser::insert($item['uri-id'], $item['uid'], $item);
|
||||
}
|
||||
|
||||
$condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'network' => $item['network']];
|
||||
if (Post::exists($condition)) {
|
||||
Logger::notice('Item is already inserted - aborting', $condition);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Remove all fields that aren't part of the item table
|
||||
$table_fields = DBStructure::getFieldsForTable('item', $item);
|
||||
|
||||
// We remove all legacy fields that now are stored in other tables
|
||||
foreach (self::LEGACY_FIELDLIST as $field) {
|
||||
unset($table_fields[$field]);
|
||||
}
|
||||
|
||||
$result = DBA::insert('item', $table_fields);
|
||||
|
||||
// When the item was successfully stored we fetch the ID of the item.
|
||||
$current_post = DBA::lastInsertId();
|
||||
|
||||
if (empty($current_post) || !DBA::isResult($result)) {
|
||||
// On failure store the data into a spool file so that the "SpoolPost" worker can try again later.
|
||||
Logger::warning('Could not store item. it will be spooled', ['result' => $result, 'id' => $current_post]);
|
||||
|
@ -1146,7 +1059,7 @@ class Item
|
|||
$update_commented = in_array($item['gravity'], [GRAVITY_PARENT, GRAVITY_COMMENT]);
|
||||
} else {
|
||||
// Update when it isn't a follow or tag verb
|
||||
$update_commented = !in_array($verb, [Activity::FOLLOW, Activity::TAG]);
|
||||
$update_commented = !in_array($item['verb'], [Activity::FOLLOW, Activity::TAG]);
|
||||
}
|
||||
|
||||
if ($update_commented) {
|
||||
|
@ -1191,9 +1104,10 @@ class Item
|
|||
|
||||
self::updateContact($item);
|
||||
|
||||
UserItem::setNotification($current_post);
|
||||
Post\UserNotification::setNotification($item['uri-id'], $item['uid']);
|
||||
|
||||
check_user_notification($current_post);
|
||||
check_user_notification($item['uri-id'], $item['uid']);
|
||||
//check_user_notification($current_post);
|
||||
|
||||
// Distribute items to users who subscribed to their tags
|
||||
self::distributeByTags($item);
|
||||
|
|
|
@ -192,7 +192,7 @@ class Post
|
|||
$selected = array_merge(['author-addr', 'author-nick', 'owner-addr', 'owner-nick', 'causer-addr', 'causer-nick',
|
||||
'causer-network', 'photo', 'name-date', 'uri-date', 'avatar-date', 'thumb', 'dfrn-id',
|
||||
'parent-guid', 'parent-network', 'parent-author-id', 'parent-author-link', 'parent-author-name',
|
||||
'parent-author-network', 'signed_text'], Item::DISPLAY_FIELDLIST, Item::ITEM_FIELDLIST, Item::CONTENT_FIELDLIST);
|
||||
'parent-author-network', 'signed_text', 'language', 'raw-body'], Item::DISPLAY_FIELDLIST, Item::ITEM_FIELDLIST);
|
||||
|
||||
if ($view == 'post-thread-view') {
|
||||
$selected = array_merge($selected, ['ignored', 'iid']);
|
||||
|
@ -258,7 +258,7 @@ class Post
|
|||
AND (NOT `causer-blocked` OR `causer-id` = ?) AND NOT `contact-blocked`
|
||||
AND ((NOT `contact-readonly` AND NOT `contact-pending` AND (`contact-rel` IN (?, ?)))
|
||||
OR `self` OR `gravity` != ? OR `contact-uid` = ?)
|
||||
AND NOT EXISTS (SELECT `iid` FROM `user-item` WHERE `hidden` AND `iid` = `id` AND `uid` = ?)
|
||||
AND NOT EXISTS (SELECT `uri-id` FROM `post-user` WHERE `hidden` AND `uri-id` = `" . $view . "`.`uri-id` AND `uid` = ?)
|
||||
AND NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `author-id` AND `blocked`)
|
||||
AND NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `owner-id` AND `blocked`)
|
||||
AND NOT EXISTS (SELECT `cid` FROM `user-contact` WHERE `uid` = ? AND `cid` = `author-id` AND `ignored` AND `gravity` = ?)
|
||||
|
@ -272,7 +272,7 @@ class Post
|
|||
unset($selected['pinned']);
|
||||
$selected = array_flip($selected);
|
||||
|
||||
$select_string = "(SELECT `pinned` FROM `user-item` WHERE `iid` = `" . $view . "`.`id` AND uid=`" . $view . "`.`uid`) AS `pinned`, ";
|
||||
$select_string = "(SELECT `pinned` FROM `post-thread-user` WHERE `uri-id` = `" . $view . "`.`uri-id` AND uid=`" . $view . "`.`uid`) AS `pinned`, ";
|
||||
}
|
||||
|
||||
$select_string .= implode(', ', array_map([DBA::class, 'quoteIdentifier'], $selected));
|
||||
|
@ -344,32 +344,6 @@ class Post
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single record from the starting post in the item table and returns it in an associative array
|
||||
*
|
||||
* @param integer $uid User ID
|
||||
* @param array $selected
|
||||
* @param array $condition
|
||||
* @param array $params
|
||||
* @return bool|array
|
||||
* @throws \Exception
|
||||
* @see DBA::select
|
||||
*/
|
||||
public static function selectFirstThreadForUser($uid, array $selected = [], array $condition = [], $params = [])
|
||||
{
|
||||
$params['limit'] = 1;
|
||||
|
||||
$result = self::selectThreadForUser($uid, $selected, $condition, $params);
|
||||
|
||||
if (is_bool($result)) {
|
||||
return $result;
|
||||
} else {
|
||||
$row = self::fetch($result);
|
||||
DBA::close($result);
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select pinned rows from the item table for a given user
|
||||
*
|
||||
|
@ -383,24 +357,24 @@ class Post
|
|||
*/
|
||||
public static function selectPinned(int $uid, array $selected = [], array $condition = [], $params = [])
|
||||
{
|
||||
$useritems = DBA::select('user-item', ['iid'], ['uid' => $uid, 'pinned' => true]);
|
||||
if (!DBA::isResult($useritems)) {
|
||||
return $useritems;
|
||||
$postthreaduser = DBA::select('post-thread-user', ['uri-id'], ['uid' => $uid, 'pinned' => true]);
|
||||
if (!DBA::isResult($postthreaduser)) {
|
||||
return $postthreaduser;
|
||||
}
|
||||
|
||||
|
||||
$pinned = [];
|
||||
while ($useritem = DBA::fetch($useritems)) {
|
||||
$pinned[] = $useritem['iid'];
|
||||
while ($useritem = DBA::fetch($postthreaduser)) {
|
||||
$pinned[] = $useritem['uri-id'];
|
||||
}
|
||||
DBA::close($useritems);
|
||||
DBA::close($postthreaduser);
|
||||
|
||||
if (empty($pinned)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$condition = DBA::mergeConditions(['iid' => $pinned], $condition);
|
||||
$condition = DBA::mergeConditions(['uri-id' => $pinned, 'uid' => $uid, 'gravity' => GRAVITY_PARENT], $condition);
|
||||
|
||||
return self::selectThreadForUser($uid, $selected, $condition, $params);
|
||||
return self::selectForUser($uid, $selected, $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -431,6 +405,8 @@ class Post
|
|||
unset($fields['parent-uri']);
|
||||
unset($fields['parent-uri-id']);
|
||||
|
||||
$thread_condition = DBA::mergeConditions($condition, ['gravity' => GRAVITY_PARENT]);
|
||||
|
||||
// To ensure the data integrity we do it in an transaction
|
||||
DBA::transaction();
|
||||
|
||||
|
@ -472,34 +448,44 @@ class Post
|
|||
$affected = max($affected, DBA::affectedRows());
|
||||
}
|
||||
|
||||
$update_fields = DBStructure::getFieldsForTable('thread', $fields);
|
||||
$update_fields = DBStructure::getFieldsForTable('post-thread-user', $fields);
|
||||
if (!empty($update_fields)) {
|
||||
$rows = DBA::selectToArray('post-view', ['id'], $condition);
|
||||
$ids = array_column($rows, 'id');
|
||||
if (!DBA::update('thread', $update_fields, ['iid' => $ids])) {
|
||||
$rows = DBA::selectToArray('post-view', ['post-user-id'], $thread_condition);
|
||||
$thread_puids = array_column($rows, 'post-user-id');
|
||||
|
||||
$post_thread_condition = DBA::collapseCondition(['id' => $thread_puids]);
|
||||
|
||||
$post_thread_condition[0] = "EXISTS(SELECT `id` FROM `post-user` WHERE " .
|
||||
$post_thread_condition[0] . " AND `uri-id` = `post-thread-user`.`uri-id` AND `uid` = `post-thread-user`.`uid`)";
|
||||
if (!DBA::update('post-thread-user', $update_fields, $post_thread_condition)) {
|
||||
DBA::rollback();
|
||||
Logger::notice('Updating thread failed', ['fields' => $update_fields, 'condition' => $condition]);
|
||||
Logger::notice('Updating post-thread-user failed', ['fields' => $update_fields, 'condition' => $condition]);
|
||||
return false;
|
||||
}
|
||||
$affected = max($affected, DBA::affectedRows());
|
||||
}
|
||||
|
||||
$item_fields = ['guid', 'type', 'wall', 'gravity', 'extid', 'created', 'edited', 'commented', 'received', 'changed',
|
||||
'resource-id', 'post-type', 'private', 'pubmail', 'moderated', 'visible', 'starred', 'bookmark',
|
||||
'unseen', 'deleted', 'origin', 'forum_mode', 'mention', 'global', 'network', 'vid', 'psid',
|
||||
'contact-id', 'author-id', 'owner-id', 'causer-id', 'event-id'];
|
||||
$update_fields = DBStructure::getFieldsForTable('thread', $fields);
|
||||
if (!empty($update_fields)) {
|
||||
$rows = DBA::selectToArray('post-view', ['id'], $thread_condition);
|
||||
$ids = array_column($rows, 'id');
|
||||
if (!DBA::update('thread', $update_fields, ['iid' => $ids])) {
|
||||
DBA::rollback();
|
||||
Logger::notice('Updating thread failed', ['fields' => $update_fields, 'condition' => $thread_condition]);
|
||||
return false;
|
||||
}
|
||||
$affected = max($affected, DBA::affectedRows());
|
||||
}
|
||||
|
||||
$update_fields = [];
|
||||
foreach ($item_fields as $field) {
|
||||
foreach (Item::USED_FIELDLIST as $field) {
|
||||
if (array_key_exists($field, $fields)) {
|
||||
$update_fields[$field] = $fields[$field];
|
||||
}
|
||||
}
|
||||
if (!empty($update_fields)) {
|
||||
if (empty($ids)) {
|
||||
$rows = DBA::selectToArray('post-view', ['id'], $condition, []);
|
||||
$ids = array_column($rows, 'id');
|
||||
}
|
||||
$rows = DBA::selectToArray('post-view', ['id'], $condition, []);
|
||||
$ids = array_column($rows, 'id');
|
||||
if (!DBA::update('item', $update_fields, ['id' => $ids])) {
|
||||
DBA::rollback();
|
||||
Logger::notice('Updating item failed', ['fields' => $update_fields, 'condition' => $condition]);
|
||||
|
|
153
src/Model/Post/ThreadUser.php
Normal file
153
src/Model/Post/ThreadUser.php
Normal file
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2020, Friendica
|
||||
*
|
||||
* @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 \BadMethodCallException;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\DBStructure;
|
||||
|
||||
class ThreadUser
|
||||
{
|
||||
/**
|
||||
* Insert a new URI user entry
|
||||
*
|
||||
* @param integer $uri_id
|
||||
* @param integer $uid
|
||||
* @param array $fields
|
||||
* @return bool success
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function insert(int $uri_id, int $uid, array $data = [])
|
||||
{
|
||||
if (empty($uri_id)) {
|
||||
throw new BadMethodCallException('Empty URI_id');
|
||||
}
|
||||
|
||||
$fields = DBStructure::getFieldsForTable('post-thread-user', $data);
|
||||
|
||||
// Additionally assign the key fields
|
||||
$fields['uri-id'] = $uri_id;
|
||||
$fields['uid'] = $uid;
|
||||
|
||||
return DBA::insert('post-thread-user', $fields, Database::INSERT_IGNORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a URI user entry
|
||||
*
|
||||
* @param integer $uri_id
|
||||
* @param integer $uid
|
||||
* @param array $data
|
||||
* @param bool $insert_if_missing
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function update(int $uri_id, int $uid, array $data = [], bool $insert_if_missing = false)
|
||||
{
|
||||
if (empty($uri_id)) {
|
||||
throw new BadMethodCallException('Empty URI_id');
|
||||
}
|
||||
|
||||
$fields = DBStructure::getFieldsForTable('post-thread-user', $data);
|
||||
|
||||
// Remove the key fields
|
||||
unset($fields['uri-id']);
|
||||
unset($fields['uid']);
|
||||
|
||||
if (empty($fields)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return DBA::update('post-thread-user', $fields, ['uri-id' => $uri_id, 'uid' => $uid], $insert_if_missing ? true : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a row from the post-thread-user table
|
||||
*
|
||||
* @param array $conditions Field condition(s)
|
||||
* @param array $options
|
||||
* - cascade: If true we delete records in other tables that depend on the one we're deleting through
|
||||
* relations (default: true)
|
||||
*
|
||||
* @return boolean was the delete successful?
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function delete(array $conditions, array $options = [])
|
||||
{
|
||||
return DBA::delete('post-thread-user', $conditions, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uri_id
|
||||
* @param int $uid
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getIgnored(int $uri_id, int $uid)
|
||||
{
|
||||
$threaduser = DBA::selectFirst('post-thread-user', ['ignored'], ['uri-id' => $uri_id, 'uid' => $uid]);
|
||||
if (empty($threaduser)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)$threaduser['ignored'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uri_id
|
||||
* @param int $uid
|
||||
* @param int $ignored
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function setIgnored(int $uri_id, int $uid, int $ignored)
|
||||
{
|
||||
DBA::update('post-thread-user', ['ignored' => $ignored], ['uri-id' => $uri_id, 'uid' => $uid], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uri_id
|
||||
* @param int $uid
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getPinned(int $uri_id, int $uid)
|
||||
{
|
||||
$threaduser = DBA::selectFirst('post-thread-user', ['pinned'], ['uri-id' => $uri_id, 'uid' => $uid]);
|
||||
if (empty($threaduser)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)$threaduser['pinned'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uri_id
|
||||
* @param int $uid
|
||||
* @param int $pinned
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function setPinned(int $uri_id, int $uid, int $pinned)
|
||||
{
|
||||
DBA::update('post-thread-user', ['pinned' => $pinned], ['uri-id' => $uri_id, 'uid' => $uid], true);
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ use Friendica\Database\DBStructure;
|
|||
class User
|
||||
{
|
||||
/**
|
||||
* Insert a new URI user entry
|
||||
* Insert a new post user entry
|
||||
*
|
||||
* @param integer $uri_id
|
||||
* @param integer $uid
|
||||
|
@ -66,7 +66,7 @@ class User
|
|||
}
|
||||
|
||||
/**
|
||||
* Update a URI user entry
|
||||
* Update a post user entry
|
||||
*
|
||||
* @param integer $uri_id
|
||||
* @param integer $uid
|
||||
|
|
|
@ -19,17 +19,23 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Model;
|
||||
namespace Friendica\Model\Post;
|
||||
|
||||
use \BadMethodCallException;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Util\Strings;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Protocol\Activity;
|
||||
|
||||
class UserItem
|
||||
|
||||
class UserNotification
|
||||
{
|
||||
// Notification types
|
||||
const NOTIF_NONE = 0;
|
||||
|
@ -42,18 +48,89 @@ class UserItem
|
|||
const NOTIF_DIRECT_THREAD_COMMENT = 64;
|
||||
const NOTIF_SHARED = 128;
|
||||
|
||||
|
||||
/**
|
||||
* Insert a new user notification entry
|
||||
*
|
||||
* @param integer $uri_id
|
||||
* @param integer $uid
|
||||
* @param array $fields
|
||||
* @return bool success
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function insert(int $uri_id, int $uid, array $data = [])
|
||||
{
|
||||
if (empty($uri_id)) {
|
||||
throw new BadMethodCallException('Empty URI_id');
|
||||
}
|
||||
|
||||
$fields = DBStructure::getFieldsForTable('post-user-notification', $data);
|
||||
|
||||
// Additionally assign the key fields
|
||||
$fields['uri-id'] = $uri_id;
|
||||
$fields['uid'] = $uid;
|
||||
|
||||
return DBA::insert('post-user-notification', $fields, Database::INSERT_IGNORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a user notification entry
|
||||
*
|
||||
* @param integer $uri_id
|
||||
* @param integer $uid
|
||||
* @param array $data
|
||||
* @param bool $insert_if_missing
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function update(int $uri_id, int $uid, array $data = [], bool $insert_if_missing = false)
|
||||
{
|
||||
if (empty($uri_id)) {
|
||||
throw new BadMethodCallException('Empty URI_id');
|
||||
}
|
||||
|
||||
$fields = DBStructure::getFieldsForTable('post-user-notification', $data);
|
||||
|
||||
// Remove the key fields
|
||||
unset($fields['uri-id']);
|
||||
unset($fields['uid']);
|
||||
|
||||
if (empty($fields)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return DBA::update('post-user-notification', $fields, ['uri-id' => $uri_id, 'uid' => $uid], $insert_if_missing ? true : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a row from the post-user-notification table
|
||||
*
|
||||
* @param array $conditions Field condition(s)
|
||||
* @param array $options
|
||||
* - cascade: If true we delete records in other tables that depend on the one we're deleting through
|
||||
* relations (default: true)
|
||||
*
|
||||
* @return boolean was the delete successful?
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function delete(array $conditions, array $options = [])
|
||||
{
|
||||
return DBA::delete('post-user-notification', $conditions, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an item for notifications and sets the "notification-type" field
|
||||
* @ToDo:
|
||||
* - Check for mentions in posts with "uid=0" where the user hadn't interacted before
|
||||
*
|
||||
* @param int $iid Item ID
|
||||
* @param int $uri_id URI ID
|
||||
* @param int $uid user ID
|
||||
*/
|
||||
public static function setNotification(int $iid)
|
||||
public static function setNotification(int $uri_id, int $uid)
|
||||
{
|
||||
$fields = ['id', 'uri-id', 'parent-uri-id', 'uid', 'body', 'parent', 'gravity',
|
||||
'private', 'contact-id', 'thr-parent', 'parent-uri', 'author-id', 'verb'];
|
||||
$item = Post::selectFirst($fields, ['id' => $iid, 'origin' => false]);
|
||||
'private', 'contact-id', 'thr-parent', 'parent-uri-id', 'parent-uri', 'author-id', 'verb'];
|
||||
$item = Post::selectFirst($fields, ['uri-id' => $uri_id, 'uid' => $uid, 'origin' => false]);
|
||||
if (!DBA::isResult($item)) {
|
||||
return;
|
||||
}
|
||||
|
@ -73,7 +150,7 @@ class UserItem
|
|||
// Add every user who participated so far in this thread
|
||||
// This can only happen with participations on global items. (means: uid = 0)
|
||||
$users = DBA::p("SELECT DISTINCT(`contact-uid`) AS `uid` FROM `post-view`
|
||||
WHERE `contact-uid` != 0 AND `parent` IN (SELECT `parent` FROM `post-view` WHERE `id` = ?)", $iid);
|
||||
WHERE `contact-uid` != 0 AND `parent-uri-id` = ? AND `uid` = ?", $item['parent-uri-id'], $uid);
|
||||
while ($user = DBA::fetch($users)) {
|
||||
$uids[] = $user['uid'];
|
||||
}
|
||||
|
@ -92,8 +169,7 @@ class UserItem
|
|||
*/
|
||||
private static function setNotificationForUser(array $item, int $uid)
|
||||
{
|
||||
$thread = Post::selectFirstThreadForUser($uid, ['ignored'], ['iid' => $item['parent'], 'deleted' => false]);
|
||||
if (!empty($thread['ignored'])) {
|
||||
if (Post\ThreadUser::getIgnored($item['parent-uri-id'], $uid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -153,11 +229,11 @@ class UserItem
|
|||
return;
|
||||
}
|
||||
|
||||
Logger::info('Set notification', ['iid' => $item['id'], 'uid' => $uid, 'notification-type' => $notification_type]);
|
||||
Logger::info('Set notification', ['iid' => $item['id'], 'uri-id' => $item['uri-id'], 'uid' => $uid, 'notification-type' => $notification_type]);
|
||||
|
||||
$fields = ['notification-type' => $notification_type];
|
||||
Post\User::update($item['uri-id'], $uid, $fields);
|
||||
DBA::update('user-item', $fields, ['iid' => $item['id'], 'uid' => $uid], true);
|
||||
self::update($item['uri-id'], $uid, $fields, true);
|
||||
}
|
||||
|
||||
/**
|
|
@ -49,27 +49,17 @@ class Ignore extends BaseModule
|
|||
|
||||
$dba = DI::dba();
|
||||
|
||||
$thread = Post::selectFirstThreadForUser(local_user(), ['uid', 'ignored'], ['iid' => $itemId]);
|
||||
$thread = Post::selectFirst(['uri-id', 'uid'], ['id' => $itemId, 'gravity' => GRAVITY_PARENT]);
|
||||
if (!$dba->isResult($thread)) {
|
||||
throw new HTTPException\NotFoundException();
|
||||
}
|
||||
|
||||
// Numeric values are needed for the json output further below
|
||||
$ignored = !empty($thread['ignored']) ? 0 : 1;
|
||||
$ignored = !Post\ThreadUser::getIgnored($thread['uri-id'], local_user());
|
||||
|
||||
switch ($thread['uid'] ?? 0) {
|
||||
// if the thread is from the current user
|
||||
case local_user():
|
||||
$dba->update('thread', ['ignored' => $ignored], ['iid' => $itemId]);
|
||||
break;
|
||||
// 0 (null will get transformed to 0) => it's a public post
|
||||
case 0:
|
||||
$dba->update('user-item', ['ignored' => $ignored], ['iid' => $itemId, 'uid' => local_user()], true);
|
||||
break;
|
||||
// Throws a BadRequestException and not a ForbiddenException on purpose
|
||||
// Avoids harvesting existing, but forbidden IIDs (security issue)
|
||||
default:
|
||||
throw new HTTPException\BadRequestException();
|
||||
if (in_array($thread['uid'], [0, local_user()])) {
|
||||
Post\ThreadUser::setIgnored($thread['uri-id'], local_user(), $ignored);
|
||||
} else {
|
||||
throw new HTTPException\BadRequestException();
|
||||
}
|
||||
|
||||
// See if we've been passed a return path to redirect to
|
||||
|
|
|
@ -24,8 +24,9 @@ namespace Friendica\Module\Item;
|
|||
use Friendica\BaseModule;
|
||||
use Friendica\Core\Session;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Network\HTTPException;
|
||||
|
||||
/**
|
||||
|
@ -47,9 +48,18 @@ class Pin extends BaseModule
|
|||
|
||||
$itemId = intval($parameters['id']);
|
||||
|
||||
$pinned = !Item::getPinned($itemId, local_user());
|
||||
$item = Post::selectFirst(['uri-id', 'uid'], ['id' => $itemId]);
|
||||
if (!DBA::isResult($item)) {
|
||||
throw new HTTPException\NotFoundException();
|
||||
}
|
||||
|
||||
Item::setPinned($itemId, local_user(), $pinned);
|
||||
if (!in_array($item['uid'], [0, local_user()])) {
|
||||
throw new HttpException\ForbiddenException($l10n->t('Access denied.'));
|
||||
}
|
||||
|
||||
$pinned = !Post\ThreadUser::getPinned($item['uri-id'], local_user());
|
||||
|
||||
Post\ThreadUser::setPinned($item['uri-id'], local_user(), $pinned);
|
||||
|
||||
// See if we've been passed a return path to redirect to
|
||||
$return_path = $_REQUEST['return'] ?? '';
|
||||
|
|
|
@ -307,17 +307,15 @@ class Post
|
|||
|
||||
if ($this->isToplevel()) {
|
||||
if(local_user()) {
|
||||
$thread = PostModel::selectFirstThreadForUser(local_user(), ['ignored'], ['iid' => $item['id']]);
|
||||
if (DBA::isResult($thread)) {
|
||||
$ignore = [
|
||||
'do' => DI::l10n()->t("ignore thread"),
|
||||
'undo' => DI::l10n()->t("unignore thread"),
|
||||
'toggle' => DI::l10n()->t("toggle ignore status"),
|
||||
'classdo' => $thread['ignored'] ? "hidden" : "",
|
||||
'classundo' => $thread['ignored'] ? "" : "hidden",
|
||||
'ignored' => DI::l10n()->t('ignored'),
|
||||
];
|
||||
}
|
||||
$ignored = PostModel\ThreadUser::getIgnored($item['uri-id'], local_user());
|
||||
$ignore = [
|
||||
'do' => DI::l10n()->t("ignore thread"),
|
||||
'undo' => DI::l10n()->t("unignore thread"),
|
||||
'toggle' => DI::l10n()->t("toggle ignore status"),
|
||||
'classdo' => $ignored ? "hidden" : "",
|
||||
'classundo' => $ignored ? "" : "hidden",
|
||||
'ignored' => DI::l10n()->t('ignored'),
|
||||
];
|
||||
|
||||
if ($conv->getProfileOwner() == local_user() && ($item['uid'] != 0)) {
|
||||
if ($origin) {
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
use Friendica\Database\DBA;
|
||||
|
||||
if (!defined('DB_UPDATE_VERSION')) {
|
||||
define('DB_UPDATE_VERSION', 1396);
|
||||
define('DB_UPDATE_VERSION', 1397);
|
||||
}
|
||||
|
||||
return [
|
||||
|
@ -750,7 +750,6 @@ return [
|
|||
"guid" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "A unique identifier for this item"],
|
||||
"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 item uri"],
|
||||
"uri-hash" => ["type" => "varchar(80)", "not null" => "1", "default" => "", "comment" => "RIPEMD-128 hash from uri"],
|
||||
"parent" => ["type" => "int unsigned", "relation" => ["item" => "id"], "comment" => "item.id of the parent to this item if it is a reply of some form; otherwise this must be set to the id of this item"],
|
||||
"parent-uri" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "uri of the top-level parent to this item"],
|
||||
"parent-uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table that contains the top-level parent uri"],
|
||||
|
@ -774,21 +773,26 @@ return [
|
|||
"visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"moderated" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"deleted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item has been deleted"],
|
||||
// User specific fields. Eventually they will move to user-item
|
||||
// Part of "post-user". Will be deprecated in a later step
|
||||
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner id which owns this copy of the item"],
|
||||
"contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "contact.id"],
|
||||
"wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "This item was posted to the wall of uid"],
|
||||
"origin" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item originated at this site"],
|
||||
"pubmail" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"starred" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item has been favourited"],
|
||||
"unseen" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => "item has not been seen"],
|
||||
"mention" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "The owner of this item was mentioned in it"],
|
||||
"forum_mode" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"origin" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item originated at this site"],
|
||||
"psid" => ["type" => "int unsigned", "foreign" => ["permissionset" => "id", "on delete" => "restrict"], "comment" => "ID of the permission set of this post"],
|
||||
// Part of "post-thread-user". Will be deprecated in a later step
|
||||
"starred" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item has been favourited"],
|
||||
"wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "This item was posted to the wall of uid"],
|
||||
"pubmail" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"forum_mode" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
// It has to be decided whether these fields belong to the user or the structure
|
||||
"resource-id" => ["type" => "varchar(32)", "not null" => "1", "default" => "", "comment" => "Used to link other tables to items, it identifies the linked resource (e.g. photo) and if set must also set resource_type"],
|
||||
"event-id" => ["type" => "int unsigned", "relation" => ["event" => "id"], "comment" => "Used to link to the event.id"],
|
||||
// Check deprecation status
|
||||
"type" => ["type" => "varchar(20)", "comment" => ""],
|
||||
"bookmark" => ["type" => "boolean", "comment" => ""],
|
||||
"mention" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "The owner of this item was mentioned in it"],
|
||||
// Deprecated fields. Will be removed in upcoming versions
|
||||
"resource-id" => ["type" => "varchar(32)", "comment" => "Deprecated"],
|
||||
"uri-hash" => ["type" => "varchar(80)", "comment" => "Deprecated"],
|
||||
"iaid" => ["type" => "int unsigned", "comment" => "Deprecated"],
|
||||
"icid" => ["type" => "int unsigned", "comment" => "Deprecated"],
|
||||
"attach" => ["type" => "mediumtext", "comment" => "Deprecated"],
|
||||
|
@ -798,8 +802,6 @@ return [
|
|||
"deny_gid" => ["type" => "mediumtext", "comment" => "Deprecated"],
|
||||
"postopts" => ["type" => "text", "comment" => "Deprecated"],
|
||||
"inform" => ["type" => "mediumtext", "comment" => "Deprecated"],
|
||||
"type" => ["type" => "varchar(20)", "comment" => "Deprecated"],
|
||||
"bookmark" => ["type" => "boolean", "comment" => "Deprecated"],
|
||||
"file" => ["type" => "mediumtext", "comment" => "Deprecated"],
|
||||
"location" => ["type" => "varchar(255)", "comment" => "Deprecated"],
|
||||
"coord" => ["type" => "varchar(255)", "comment" => "Deprecated"],
|
||||
|
@ -1029,20 +1031,6 @@ return [
|
|||
"created" => ["created"],
|
||||
]
|
||||
],
|
||||
"participation" => [
|
||||
"comment" => "Storage for participation messages from Diaspora",
|
||||
"fields" => [
|
||||
"iid" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item" => "id"], "comment" => ""],
|
||||
"server" => ["type" => "varchar(60)", "not null" => "1", "primary" => "1", "comment" => ""],
|
||||
"cid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["contact" => "id"], "comment" => ""],
|
||||
"fid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["fcontact" => "id"], "comment" => ""],
|
||||
],
|
||||
"indexes" => [
|
||||
"PRIMARY" => ["iid", "server"],
|
||||
"cid" => ["cid"],
|
||||
"fid" => ["fid"]
|
||||
]
|
||||
],
|
||||
"pconfig" => [
|
||||
"comment" => "personal (per user) configuration storage",
|
||||
"fields" => [
|
||||
|
@ -1193,6 +1181,25 @@ return [
|
|||
"cid" => ["cid"]
|
||||
]
|
||||
],
|
||||
"post-thread-user" => [
|
||||
"comment" => "Thread related data per user",
|
||||
"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"],
|
||||
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "primary" => "1", "foreign" => ["user" => "uid"], "comment" => "Owner id which owns this copy of the item"],
|
||||
"pinned" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "The thread is pinned on the profile page"],
|
||||
"starred" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"ignored" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Ignore updates for this thread"],
|
||||
"wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "This item was posted to the wall of uid"],
|
||||
"pubmail" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
"forum_mode" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""]
|
||||
],
|
||||
"indexes" => [
|
||||
"PRIMARY" => ["uid", "uri-id"],
|
||||
"uid_wall" => ["uid", "wall"],
|
||||
"uid_pinned" => ["uid", "pinned"],
|
||||
"uri-id" => ["uri-id"],
|
||||
]
|
||||
],
|
||||
"post-user" => [
|
||||
"comment" => "User specific post data",
|
||||
"fields" => [
|
||||
|
@ -1215,6 +1222,18 @@ return [
|
|||
"psid" => ["psid"],
|
||||
],
|
||||
],
|
||||
"post-user-notification" => [
|
||||
"comment" => "User post notifications",
|
||||
"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"],
|
||||
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "primary" => "1", "foreign" => ["user" => "uid"], "comment" => "Owner id which owns this copy of the item"],
|
||||
"notification-type" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
],
|
||||
"indexes" => [
|
||||
"PRIMARY" => ["uid", "uri-id"],
|
||||
"uri-id" => ["uri-id"],
|
||||
],
|
||||
],
|
||||
"process" => [
|
||||
"comment" => "Currently running system processes",
|
||||
"fields" => [
|
||||
|
@ -1474,22 +1493,6 @@ return [
|
|||
"cid" => ["cid"],
|
||||
]
|
||||
],
|
||||
"user-item" => [
|
||||
"comment" => "User specific item data",
|
||||
"fields" => [
|
||||
"iid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "primary" => "1", "foreign" => ["item" => "id"], "comment" => "Item id"],
|
||||
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "primary" => "1", "foreign" => ["user" => "uid"], "comment" => "User id"],
|
||||
"hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Marker to hide an item from the user"],
|
||||
"ignored" => ["type" => "boolean", "comment" => "Ignore this thread if set"],
|
||||
"pinned" => ["type" => "boolean", "comment" => "The item is pinned on the profile page"],
|
||||
"notification-type" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
|
||||
],
|
||||
"indexes" => [
|
||||
"PRIMARY" => ["uid", "iid"],
|
||||
"uid_pinned" => ["uid", "pinned"],
|
||||
"iid_uid" => ["iid", "uid"]
|
||||
]
|
||||
],
|
||||
"worker-ipc" => [
|
||||
"comment" => "Inter process communication between the frontend and the worker",
|
||||
"fields" => [
|
||||
|
|
|
@ -395,13 +395,13 @@
|
|||
"query" => "FROM `item`
|
||||
INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent`
|
||||
STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
|
||||
LEFT JOIN `user-item` ON `user-item`.`iid` = `item`.`id` AND `user-item`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `post-user` ON `post-user`.`uri-id` = `item`.`uri-id` AND `post-user`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `thread`.`uid` AND `author`.`cid` = `thread`.`author-id`
|
||||
LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `thread`.`uid` AND `owner`.`cid` = `thread`.`owner-id`
|
||||
LEFT JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `thread`.`owner-id`
|
||||
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
|
||||
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
|
||||
AND (`user-item`.`hidden` IS NULL OR NOT `user-item`.`hidden`)
|
||||
AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`)
|
||||
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
|
||||
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)"
|
||||
],
|
||||
|
@ -424,13 +424,13 @@
|
|||
"query" => "FROM `thread`
|
||||
STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
|
||||
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
|
||||
LEFT JOIN `user-item` ON `user-item`.`iid` = `item`.`id` AND `user-item`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `post-user` ON `post-user`.`uri-id` = `item`.`uri-id` AND `post-user`.`uid` = `thread`.`uid`
|
||||
LEFT JOIN `user-contact` AS `author` ON `author`.`uid` = `thread`.`uid` AND `author`.`cid` = `thread`.`author-id`
|
||||
LEFT JOIN `user-contact` AS `owner` ON `owner`.`uid` = `thread`.`uid` AND `owner`.`cid` = `thread`.`owner-id`
|
||||
LEFT JOIN `contact` AS `ownercontact` ON `ownercontact`.`id` = `thread`.`owner-id`
|
||||
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
|
||||
AND (NOT `contact`.`readonly` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`)
|
||||
AND (`user-item`.`hidden` IS NULL OR NOT `user-item`.`hidden`)
|
||||
AND (`post-user`.`hidden` IS NULL OR NOT `post-user`.`hidden`)
|
||||
AND (`author`.`blocked` IS NULL OR NOT `author`.`blocked`)
|
||||
AND (`owner`.`blocked` IS NULL OR NOT `owner`.`blocked`)"
|
||||
],
|
||||
|
|
53
update.php
53
update.php
|
@ -466,7 +466,7 @@ function pre_update_1364()
|
|||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("DELETE FROM `user-item` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
|
||||
if (DBStructure::existsTable('user-item') && !DBA::e("DELETE FROM `user-item` WHERE NOT `uid` IN (SELECT `uid` FROM `user`)")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
|
@ -490,10 +490,6 @@ function pre_update_1364()
|
|||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("DELETE FROM `participation` WHERE NOT `cid` IN (SELECT `id` FROM `contact`)")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("DELETE FROM `profile_check` WHERE NOT `cid` IN (SELECT `id` FROM `contact`)")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
@ -502,10 +498,6 @@ function pre_update_1364()
|
|||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("DELETE FROM `participation` WHERE NOT `fid` IN (SELECT `id` FROM `fcontact`)")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("DELETE FROM `group_member` WHERE NOT `gid` IN (SELECT `id` FROM `group`)")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
@ -514,11 +506,7 @@ function pre_update_1364()
|
|||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("DELETE FROM `participation` WHERE NOT `iid` IN (SELECT `id` FROM `item`)")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("DELETE FROM `user-item` WHERE NOT `iid` IN (SELECT `id` FROM `item`)")) {
|
||||
if (DBStructure::existsTable('user-item') && !DBA::e("DELETE FROM `user-item` WHERE NOT `iid` IN (SELECT `id` FROM `item`)")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
|
@ -686,7 +674,7 @@ function update_1395()
|
|||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBA::e("INSERT INTO `post-user`(`uri-id`, `uid`, `hidden`, `notification-type`)
|
||||
if (DBStructure::existsTable('user-item') && !DBA::e("INSERT INTO `post-user`(`uri-id`, `uid`, `hidden`, `notification-type`)
|
||||
SELECT `uri-id`, `user-item`.`uid`, `hidden`,`notification-type` FROM `user-item`
|
||||
INNER JOIN `item` ON `item`.`id` = `user-item`.`iid`
|
||||
ON DUPLICATE KEY UPDATE `hidden` = `user-item`.`hidden`, `notification-type` = `user-item`.`notification-type`")) {
|
||||
|
@ -713,4 +701,37 @@ function update_1396()
|
|||
return Update::FAILED;
|
||||
}
|
||||
return Update::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
function update_1397()
|
||||
{
|
||||
if (!DBA::e("INSERT INTO `post-user-notification`(`uri-id`, `uid`, `notification-type`)
|
||||
SELECT `uri-id`, `uid`, `notification-type` FROM `post-user` WHERE `notification-type` != 0
|
||||
ON DUPLICATE KEY UPDATE `uri-id` = `post-user`.`uri-id`, `uid` = `post-user`.`uid`, `notification-type` = `post-user`.`notification-type`")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBStructure::existsTable('user-item')) {
|
||||
return Update::SUCCESS;
|
||||
}
|
||||
|
||||
if (!DBA::e("INSERT INTO `post-user-notification`(`uri-id`, `uid`, `notification-type`)
|
||||
SELECT `uri-id`, `user-item`.`uid`, `notification-type` FROM `user-item`
|
||||
INNER JOIN `item` ON `item`.`id` = `user-item`.`iid` WHERE `notification-type` != 0
|
||||
ON DUPLICATE KEY UPDATE `notification-type` = `user-item`.`notification-type`")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
if (!DBStructure::existsTable('thread')) {
|
||||
return Update::SUCCESS;
|
||||
}
|
||||
|
||||
if (!DBA::e("INSERT IGNORE INTO `post-thread-user`(`uri-id`, `uid`, `pinned`, `starred`, `ignored`, `wall`, `pubmail`, `forum_mode`)
|
||||
SELECT `thread`.`uri-id`, `thread`.`uid`, `user-item`.`pinned`, `thread`.`starred`,
|
||||
`thread`.`ignored`, `thread`.`wall`, `thread`.`pubmail`, `thread`.`forum_mode`
|
||||
FROM `thread` LEFT JOIN `user-item` ON `user-item`.`iid` = `thread`.`iid`")) {
|
||||
return Update::FAILED;
|
||||
}
|
||||
|
||||
return Update::SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue