Display featured posts for contacts
This commit is contained in:
		
					parent
					
						
							
								8669f12176
							
						
					
				
			
			
				commit
				
					
						75bc4eccb7
					
				
			
		
					 21 changed files with 172 additions and 118 deletions
				
			
		
							
								
								
									
										20
									
								
								database.sql
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								database.sql
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
-- ------------------------------------------
 | 
			
		||||
-- Friendica 2022.05-dev (Siberian Iris)
 | 
			
		||||
-- DB_UPDATE_VERSION 1456
 | 
			
		||||
-- DB_UPDATE_VERSION 1457
 | 
			
		||||
-- ------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1284,7 +1284,7 @@ CREATE TABLE IF NOT EXISTS `post-thread-user` (
 | 
			
		|||
	`changed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date that something in the conversation changed, indicating clients should fetch the conversation again',
 | 
			
		||||
	`commented` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
 | 
			
		||||
	`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',
 | 
			
		||||
	`pinned` boolean NOT NULL DEFAULT '0' COMMENT 'deprecated',
 | 
			
		||||
	`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',
 | 
			
		||||
| 
						 | 
				
			
			@ -1309,7 +1309,6 @@ CREATE TABLE IF NOT EXISTS `post-thread-user` (
 | 
			
		|||
	 INDEX `commented` (`commented`),
 | 
			
		||||
	 INDEX `uid_received` (`uid`,`received`),
 | 
			
		||||
	 INDEX `uid_wall_received` (`uid`,`wall`,`received`),
 | 
			
		||||
	 INDEX `uid_pinned` (`uid`,`pinned`),
 | 
			
		||||
	 INDEX `uid_commented` (`uid`,`commented`),
 | 
			
		||||
	 INDEX `uid_starred` (`uid`,`starred`),
 | 
			
		||||
	 INDEX `uid_mention` (`uid`,`mention`),
 | 
			
		||||
| 
						 | 
				
			
			@ -1621,7 +1620,6 @@ CREATE VIEW `post-user-view` AS SELECT
 | 
			
		|||
	`post-thread-user`.`pubmail` AS `pubmail`,
 | 
			
		||||
	`post-user`.`visible` AS `visible`,
 | 
			
		||||
	`post-thread-user`.`starred` AS `starred`,
 | 
			
		||||
	`post-thread-user`.`pinned` AS `pinned`,
 | 
			
		||||
	`post-user`.`unseen` AS `unseen`,
 | 
			
		||||
	`post-user`.`deleted` AS `deleted`,
 | 
			
		||||
	`post-user`.`origin` AS `origin`,
 | 
			
		||||
| 
						 | 
				
			
			@ -1783,7 +1781,6 @@ CREATE VIEW `post-thread-user-view` AS SELECT
 | 
			
		|||
	`post-thread-user`.`ignored` AS `ignored`,
 | 
			
		||||
	`post-user`.`visible` AS `visible`,
 | 
			
		||||
	`post-thread-user`.`starred` AS `starred`,
 | 
			
		||||
	`post-thread-user`.`pinned` AS `pinned`,
 | 
			
		||||
	`post-thread-user`.`unseen` AS `unseen`,
 | 
			
		||||
	`post-user`.`deleted` AS `deleted`,
 | 
			
		||||
	`post-thread-user`.`origin` AS `origin`,
 | 
			
		||||
| 
						 | 
				
			
			@ -2169,6 +2166,19 @@ CREATE VIEW `category-view` AS SELECT
 | 
			
		|||
	FROM `post-category`
 | 
			
		||||
			LEFT JOIN `tag` ON `post-category`.`tid` = `tag`.`id`;
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- VIEW collection-view
 | 
			
		||||
--
 | 
			
		||||
DROP VIEW IF EXISTS `collection-view`;
 | 
			
		||||
CREATE VIEW `collection-view` AS SELECT 
 | 
			
		||||
	`post-collection`.`uri-id` AS `uri-id`,
 | 
			
		||||
	`post-collection`.`type` AS `type`,
 | 
			
		||||
	`post`.`author-id` AS `cid`,
 | 
			
		||||
	`post`.`received` AS `received`,
 | 
			
		||||
	`post`.`created` AS `created`
 | 
			
		||||
	FROM `post-collection`
 | 
			
		||||
			INNER JOIN `post` ON `post-collection`.`uri-id` = `post`.`uri-id`;
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- VIEW tag-view
 | 
			
		||||
--
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ Fields
 | 
			
		|||
| changed      | Date that something in the conversation changed, indicating clients should fetch the conversation again | datetime           | NO   |     | 0001-01-01 00:00:00 |       |
 | 
			
		||||
| commented    |                                                                                                         | datetime           | NO   |     | 0001-01-01 00:00:00 |       |
 | 
			
		||||
| uid          | Owner id which owns this copy of the item                                                               | mediumint unsigned | NO   | PRI | 0                   |       |
 | 
			
		||||
| pinned       | The thread is pinned on the profile page                                                                | boolean            | NO   |     | 0                   |       |
 | 
			
		||||
| pinned       | deprecated                                                                                              | boolean            | NO   |     | 0                   |       |
 | 
			
		||||
| starred      |                                                                                                         | boolean            | NO   |     | 0                   |       |
 | 
			
		||||
| ignored      | Ignore updates for this thread                                                                          | boolean            | NO   |     | 0                   |       |
 | 
			
		||||
| wall         | This item was posted to the wall of uid                                                                 | boolean            | NO   |     | 0                   |       |
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,6 @@ Indexes
 | 
			
		|||
| commented         | commented           |
 | 
			
		||||
| uid_received      | uid, received       |
 | 
			
		||||
| uid_wall_received | uid, wall, received |
 | 
			
		||||
| uid_pinned        | uid, pinned         |
 | 
			
		||||
| uid_commented     | uid, commented      |
 | 
			
		||||
| uid_starred       | uid, starred        |
 | 
			
		||||
| uid_mention       | uid, mention        |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -639,6 +639,12 @@ class Conversation
 | 
			
		|||
						$title = '';
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (!empty($item['featured'])) {
 | 
			
		||||
						$pinned = $this->l10n->t('Pinned item');
 | 
			
		||||
					} else {
 | 
			
		||||
						$pinned = '';
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					$tmp_item = [
 | 
			
		||||
						'template'             => $tpl,
 | 
			
		||||
						'id'                   => ($preview ? 'P0' : $item['id']),
 | 
			
		||||
| 
						 | 
				
			
			@ -680,6 +686,7 @@ class Conversation
 | 
			
		|||
						'owner_photo'          => $this->baseURL->remove(Contact::getAvatarUrlForUrl($item['owner-link'], $item['uid'], Proxy::SIZE_THUMB)),
 | 
			
		||||
						'plink'                => ItemModel::getPlink($item),
 | 
			
		||||
						'edpost'               => false,
 | 
			
		||||
						'pinned'               => $pinned,
 | 
			
		||||
						'isstarred'            => 'unstarred',
 | 
			
		||||
						'star'                 => false,
 | 
			
		||||
						'drop'                 => $drop,
 | 
			
		||||
| 
						 | 
				
			
			@ -931,7 +938,7 @@ class Conversation
 | 
			
		|||
		$condition = DBA::mergeConditions($condition,
 | 
			
		||||
			["`uid` IN (0, ?) AND (`vid` != ? OR `vid` IS NULL)", $uid, Verb::getID(Activity::FOLLOW)]);
 | 
			
		||||
 | 
			
		||||
		$thread_items = Post::selectForUser($uid, array_merge(ItemModel::DISPLAY_FIELDLIST, ['pinned', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params);
 | 
			
		||||
		$thread_items = Post::selectForUser($uid, array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params);
 | 
			
		||||
 | 
			
		||||
		$items = [];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1135,7 +1142,9 @@ class Conversation
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (stristr($order, 'pinned_received')) {
 | 
			
		||||
			usort($parents, [$this, 'sortThrPinnedReceived']);
 | 
			
		||||
			usort($parents, [$this, 'sortThrFeaturedReceived']);
 | 
			
		||||
		} elseif (stristr($order, 'pinned_commented')) {
 | 
			
		||||
			usort($parents, [$this, 'sortThrFeaturedCommented']);
 | 
			
		||||
		} elseif (stristr($order, 'received')) {
 | 
			
		||||
			usort($parents, [$this, 'sortThrReceived']);
 | 
			
		||||
		} elseif (stristr($order, 'commented')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1174,23 +1183,41 @@ class Conversation
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * usort() callback to sort item arrays by pinned and the received key
 | 
			
		||||
	 * usort() callback to sort item arrays by featured and the received key
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $a
 | 
			
		||||
	 * @param array $b
 | 
			
		||||
	 * @return int
 | 
			
		||||
	 */
 | 
			
		||||
	private function sortThrPinnedReceived(array $a, array $b)
 | 
			
		||||
	private function sortThrFeaturedReceived(array $a, array $b)
 | 
			
		||||
	{
 | 
			
		||||
		if ($b['pinned'] && !$a['pinned']) {
 | 
			
		||||
		if ($b['featured'] && !$a['featured']) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		} elseif (!$b['pinned'] && $a['pinned']) {
 | 
			
		||||
		} elseif (!$b['featured'] && $a['featured']) {
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return strcmp($b['received'], $a['received']);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * usort() callback to sort item arrays by featured and the received key
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $a
 | 
			
		||||
	 * @param array $b
 | 
			
		||||
	 * @return int
 | 
			
		||||
	 */
 | 
			
		||||
	private function sortThrFeaturedCommented(array $a, array $b)
 | 
			
		||||
	{
 | 
			
		||||
		if ($b['featured'] && !$a['featured']) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		} elseif (!$b['featured'] && $a['featured']) {
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return strcmp($b['commented'], $a['commented']);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * usort() callback to sort item arrays by the received key
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ class Status extends BaseFactory
 | 
			
		|||
	public function createFromUriId(int $uriId, $uid = 0): \Friendica\Object\Api\Mastodon\Status
 | 
			
		||||
	{
 | 
			
		||||
		$fields = ['uri-id', 'uid', 'author-id', 'author-link', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning',
 | 
			
		||||
			'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity'];
 | 
			
		||||
			'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured'];
 | 
			
		||||
		$item = Post::selectFirst($fields, ['uri-id' => $uriId, 'uid' => [0, $uid]], ['order' => ['uid' => true]]);
 | 
			
		||||
		if (!$item) {
 | 
			
		||||
			$mail = DBA::selectFirst('mail', ['id'], ['uri-id' => $uriId, 'uid' => $uid]);
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +125,7 @@ class Status extends BaseFactory
 | 
			
		|||
			]),
 | 
			
		||||
			Post\ThreadUser::getIgnored($uriId, $uid),
 | 
			
		||||
			(bool)($item['starred'] && ($item['gravity'] == GRAVITY_PARENT)),
 | 
			
		||||
			Post\ThreadUser::getPinned($uriId, $uid)
 | 
			
		||||
			$item['featured']
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		$sensitive   = $this->dba->exists('tag-view', ['uri-id' => $uriId, 'name' => 'nsfw', 'type' => TagModel::HASHTAG]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ use Friendica\DI;
 | 
			
		|||
use Friendica\Network\HTTPException;
 | 
			
		||||
use Friendica\Network\Probe;
 | 
			
		||||
use Friendica\Protocol\Activity;
 | 
			
		||||
use Friendica\Protocol\ActivityPub;
 | 
			
		||||
use Friendica\Util\DateTimeFormat;
 | 
			
		||||
use Friendica\Util\Images;
 | 
			
		||||
use Friendica\Util\Network;
 | 
			
		||||
| 
						 | 
				
			
			@ -1455,11 +1456,26 @@ class Contact
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if ($thread_mode) {
 | 
			
		||||
			$items = Post::toArray(Post::selectForUser(local_user(), ['uri-id', 'gravity', 'parent-uri-id', 'thr-parent-id', 'author-id'], $condition, $params));
 | 
			
		||||
			$items = Post::toArray(Post::selectForUser(local_user(), ['uri-id'], $condition, $params));
 | 
			
		||||
 | 
			
		||||
			$o .= DI::conversation()->create($items, 'contacts', $update, false, 'commented', local_user());
 | 
			
		||||
			if ($pager->getStart() == 0) {
 | 
			
		||||
				$cdata = Contact::getPublicAndUserContactID($cid, local_user());
 | 
			
		||||
				$pinned = DBA::selectToArray('collection-view', ['uri-id'], ['cid' => $cdata['public']]);
 | 
			
		||||
				$items = array_merge($items, $pinned);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$o .= DI::conversation()->create($items, 'contacts', $update, false, 'pinned_commented', local_user());
 | 
			
		||||
		} else {
 | 
			
		||||
			$items = Post::toArray(Post::selectForUser(local_user(), Item::DISPLAY_FIELDLIST, $condition, $params));
 | 
			
		||||
			$fields = array_merge(Item::DISPLAY_FIELDLIST, ['featured']);
 | 
			
		||||
			$items = Post::toArray(Post::selectForUser(local_user(), $fields, $condition, $params));
 | 
			
		||||
 | 
			
		||||
			if ($pager->getStart() == 0) {
 | 
			
		||||
				$cdata = Contact::getPublicAndUserContactID($cid, local_user());
 | 
			
		||||
				$condition = ["`uri-id` IN (SELECT `uri-id` FROM `collection-view` WHERE `cid` = ?)", $cdata['public']];
 | 
			
		||||
				$pinned = Post::toArray(Post::selectForUser(local_user(), $fields, $condition, $params));
 | 
			
		||||
				//$items = $pinned;
 | 
			
		||||
				$items = array_merge($pinned, $items);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$o .= DI::conversation()->create($items, 'contact-posts', $update);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -2252,6 +2268,10 @@ class Contact
 | 
			
		|||
		$new_pubkey = $ret['pubkey'] ?? '';
 | 
			
		||||
 | 
			
		||||
		if ($uid == 0) {
 | 
			
		||||
			if ($ret['network'] == Protocol::ACTIVITYPUB) {
 | 
			
		||||
				ActivityPub\Processor::fetchFeaturedPosts($ret['url']);
 | 
			
		||||
			}
 | 
			
		||||
	
 | 
			
		||||
			$ret['last-item'] = Probe::getLastUpdate($ret);
 | 
			
		||||
			Logger::info('Fetched last item', ['id' => $id, 'probed_url' => $ret['url'], 'last-item' => $ret['last-item'], 'callstack' => System::callstack(20)]);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -488,39 +488,6 @@ class Post
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Select pinned rows from the post-thread-user table for a given user
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param integer $uid       User ID
 | 
			
		||||
	 * @param array   $selected  Array of selected fields, empty for all
 | 
			
		||||
	 * @param array   $condition Array of fields for condition
 | 
			
		||||
	 * @param array   $params    Array of several parameters
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return boolean|object
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function selectPinned(int $uid, array $selected = [], array $condition = [], $params = [])
 | 
			
		||||
	{
 | 
			
		||||
		$postthreaduser = DBA::select('post-thread-user', ['uri-id'], ['uid' => $uid, 'pinned' => true]);
 | 
			
		||||
		if (!DBA::isResult($postthreaduser)) {
 | 
			
		||||
			return $postthreaduser;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$pinned = [];
 | 
			
		||||
		while ($useritem = DBA::fetch($postthreaduser)) {
 | 
			
		||||
			$pinned[] = $useritem['uri-id'];
 | 
			
		||||
		}
 | 
			
		||||
		DBA::close($postthreaduser);
 | 
			
		||||
 | 
			
		||||
		if (empty($pinned)) {
 | 
			
		||||
			return [];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$condition = DBA::mergeConditions(['uri-id' => $pinned, 'uid' => $uid, 'gravity' => GRAVITY_PARENT], $condition);
 | 
			
		||||
 | 
			
		||||
		return self::selectForUser($uid, $selected, $condition, $params);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Update existing post entries
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,31 +123,4 @@ class ThreadUser
 | 
			
		|||
	{
 | 
			
		||||
		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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ class Statuses extends BaseApi
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if ($request['pinned']) {
 | 
			
		||||
			$condition = DBA::mergeConditions($condition, ['pinned' => true]);
 | 
			
		||||
			$condition = DBA::mergeConditions($condition, ['featured' => true]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($request['exclude_replies']) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,11 +46,7 @@ class Pin extends BaseApi
 | 
			
		|||
			DI::mstdnError()->RecordNotFound();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($item['gravity'] != GRAVITY_PARENT) {
 | 
			
		||||
			DI::mstdnError()->UnprocessableEntity(DI::l10n()->t('Only starting posts can be pinned'));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Post\ThreadUser::setPinned($this->parameters['id'], $uid, true);
 | 
			
		||||
		Post\Collection::add($this->parameters['id'], Post\Collection::FEATURED);
 | 
			
		||||
 | 
			
		||||
		System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid)->toArray());
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,11 +46,7 @@ class Unpin extends BaseApi
 | 
			
		|||
			DI::mstdnError()->RecordNotFound();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($item['gravity'] != GRAVITY_PARENT) {
 | 
			
		||||
			DI::mstdnError()->UnprocessableEntity(DI::l10n()->t('Only starting posts can be pinned'));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Post\ThreadUser::setPinned($this->parameters['id'], $uid, false);
 | 
			
		||||
		Post\Collection::remove($this->parameters['id'], Post\Collection::FEATURED);
 | 
			
		||||
 | 
			
		||||
		System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid)->toArray());
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ class Pin extends BaseModule
 | 
			
		|||
 | 
			
		||||
		$itemId = intval($this->parameters['id']);
 | 
			
		||||
 | 
			
		||||
		$item = Post::selectFirst(['uri-id', 'uid'], ['id' => $itemId]);
 | 
			
		||||
		$item = Post::selectFirst(['uri-id', 'uid', 'featured'], ['id' => $itemId]);
 | 
			
		||||
		if (!DBA::isResult($item)) {
 | 
			
		||||
			throw new HTTPException\NotFoundException();
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -57,9 +57,13 @@ class Pin extends BaseModule
 | 
			
		|||
			throw new HttpException\ForbiddenException($l10n->t('Access denied.'));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$pinned = !Post\ThreadUser::getPinned($item['uri-id'], local_user());
 | 
			
		||||
		$pinned = !$item['featured'];
 | 
			
		||||
 | 
			
		||||
		Post\ThreadUser::setPinned($item['uri-id'], local_user(), $pinned);
 | 
			
		||||
		if ($pinned) {
 | 
			
		||||
			Post\Collection::add($item['uri-id'], Post\Collection::FEATURED);
 | 
			
		||||
		} else {
 | 
			
		||||
			Post\Collection::remove($item['uri-id'], Post\Collection::FEATURED);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// See if we've been passed a return path to redirect to
 | 
			
		||||
		$return_path = $_REQUEST['return'] ?? '';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ use Friendica\Core\Protocol;
 | 
			
		|||
use Friendica\Core\Session;
 | 
			
		||||
use Friendica\Database\DBA;
 | 
			
		||||
use Friendica\DI;
 | 
			
		||||
use Friendica\Model\Contact;
 | 
			
		||||
use Friendica\Model\Item;
 | 
			
		||||
use Friendica\Model\Post;
 | 
			
		||||
use Friendica\Model\Post\Category;
 | 
			
		||||
| 
						 | 
				
			
			@ -207,20 +208,8 @@ class Status extends BaseProfile
 | 
			
		|||
		$items = Post::toArray($items_stmt);
 | 
			
		||||
 | 
			
		||||
		if ($pager->getStart() == 0 && !empty($profile['uid'])) {
 | 
			
		||||
			$condition = ['private' => [Item::PUBLIC, Item::UNLISTED]];
 | 
			
		||||
			$remote_user = Session::getRemoteContactID($profile['uid']);
 | 
			
		||||
			if (!empty($remote_user)) {
 | 
			
		||||
				$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $profile['uid']);
 | 
			
		||||
				if (!empty($permissionSets)) {
 | 
			
		||||
					$condition = ['psid' => array_merge($permissionSets->column('id'),
 | 
			
		||||
							[DI::permissionSet()->selectPublicForUser($profile['uid'])->id])];
 | 
			
		||||
				}
 | 
			
		||||
			} elseif ($profile['uid'] == local_user()) {
 | 
			
		||||
				$condition = [];
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$pinned_items = Post::selectPinned($profile['uid'], ['uri-id', 'pinned'], $condition);
 | 
			
		||||
			$pinned = Post::toArray($pinned_items);
 | 
			
		||||
			$pcid = Contact::getPublicIdByUserId($profile['uid']);
 | 
			
		||||
			$pinned = DBA::selectToArray('collection-view', [], ['cid' => $pcid]);
 | 
			
		||||
			$items = array_merge($items, $pinned);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -231,7 +231,7 @@ class Post
 | 
			
		|||
 | 
			
		||||
		$origin = $item['origin'] || $item['parent-origin'];
 | 
			
		||||
 | 
			
		||||
		if ($item['pinned']) {
 | 
			
		||||
		if (!empty($item['featured'])) {
 | 
			
		||||
			$pinned = DI::l10n()->t('Pinned item');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -343,14 +343,14 @@ class Post
 | 
			
		|||
 | 
			
		||||
				if ($conv->getProfileOwner() == local_user() && ($item['uid'] != 0)) {
 | 
			
		||||
					if ($origin) {
 | 
			
		||||
						$ispinned = ($item['pinned'] ? 'pinned' : 'unpinned');
 | 
			
		||||
						$ispinned = ($item['featured'] ? 'pinned' : 'unpinned');
 | 
			
		||||
 | 
			
		||||
						$pin = [
 | 
			
		||||
							'do'        => DI::l10n()->t('Pin'),
 | 
			
		||||
							'undo'      => DI::l10n()->t('Unpin'),
 | 
			
		||||
							'toggle'    => DI::l10n()->t('Toggle pin status'),
 | 
			
		||||
							'classdo'   => $item['pinned'] ? 'hidden' : '',
 | 
			
		||||
							'classundo' => $item['pinned'] ? '' : 'hidden',
 | 
			
		||||
							'classdo'   => $item['featured'] ? 'hidden' : '',
 | 
			
		||||
							'classundo' => $item['featured'] ? '' : 'hidden',
 | 
			
		||||
							'pinned'   => DI::l10n()->t('Pinned'),
 | 
			
		||||
						];
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -977,6 +977,54 @@ class Processor
 | 
			
		|||
		return Mail::insert($msg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Fetch featured posts from a contact with the given url
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $url 
 | 
			
		||||
	 * @return void 
 | 
			
		||||
	 */
 | 
			
		||||
	public static function fetchFeaturedPosts(string $url)
 | 
			
		||||
	{
 | 
			
		||||
		Logger::info('Fetch featured posts', ['contact' => $url]);
 | 
			
		||||
 | 
			
		||||
		$apcontact = APContact::getByURL($url);
 | 
			
		||||
		if (empty($apcontact['featured'])) {
 | 
			
		||||
			Logger::info('Contact does not have a featured collection', ['contact' => $url]);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$featured = ActivityPub::fetchItems($apcontact['featured']);
 | 
			
		||||
		if (empty($featured)) {
 | 
			
		||||
			Logger::info('Contact does not have featured posts', ['contact' => $url]);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$new = 0;
 | 
			
		||||
		$old = 0;
 | 
			
		||||
 | 
			
		||||
		foreach ($featured as $post) {
 | 
			
		||||
			if (empty($post['id'])) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			$id = Item::fetchByLink($post['id']);
 | 
			
		||||
			if (!empty($id)) {
 | 
			
		||||
				$item = Post::selectFirst(['uri-id', 'featured'], ['id' => $id]);
 | 
			
		||||
				if (!empty($item['uri-id'])) {
 | 
			
		||||
					if (!$item['featured']) {
 | 
			
		||||
						Post\Collection::add($item['uri-id'], Post\Collection::FEATURED);
 | 
			
		||||
						Logger::debug('Added featured post', ['uri-id' => $item['uri-id'], 'contact' => $url]);
 | 
			
		||||
						$new++;
 | 
			
		||||
					} else {
 | 
			
		||||
						Logger::debug('Post already had been featured', ['uri-id' => $item['uri-id'], 'contact' => $url]);
 | 
			
		||||
						$old++;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Logger::info('Fetched featured posts', ['new' => $new, 'old' => $old, 'contact' => $url]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Fetches missing posts
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -225,9 +225,11 @@ class ExpirePosts
 | 
			
		|||
			$uris = DBA::select('item-uri', ['id'], ["`id` IN
 | 
			
		||||
				(SELECT `uri-id` FROM `post-thread` WHERE `received` < ?
 | 
			
		||||
					AND NOT `uri-id` IN (SELECT `uri-id` FROM `post-thread-user`
 | 
			
		||||
						WHERE (`mention` OR `starred` OR `wall` OR `pinned`) AND `uri-id` = `post-thread`.`uri-id`)
 | 
			
		||||
						WHERE (`mention` OR `starred` OR `wall`) AND `uri-id` = `post-thread`.`uri-id`)
 | 
			
		||||
					AND NOT `uri-id` IN (SELECT `uri-id` FROM `post-category`
 | 
			
		||||
						WHERE `uri-id` = `post-thread`.`uri-id`)
 | 
			
		||||
					AND NOT `uri-id` IN (SELECT `uri-id` FROM `post-collection`
 | 
			
		||||
						WHERE `uri-id` = `post-thread`.`uri-id`)
 | 
			
		||||
					AND NOT `uri-id` IN (SELECT `uri-id` FROM `post-media`
 | 
			
		||||
						WHERE `uri-id` = `post-thread`.`uri-id`)
 | 
			
		||||
					AND NOT `uri-id` IN (SELECT `parent-uri-id` FROM `post-user` INNER JOIN `contact` ON `contact`.`id` = `contact-id` AND `notify_new_posts`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@
 | 
			
		|||
use Friendica\Database\DBA;
 | 
			
		||||
 | 
			
		||||
if (!defined('DB_UPDATE_VERSION')) {
 | 
			
		||||
	define('DB_UPDATE_VERSION', 1456);
 | 
			
		||||
	define('DB_UPDATE_VERSION', 1457);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
| 
						 | 
				
			
			@ -1308,7 +1308,7 @@ return [
 | 
			
		|||
			"changed" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date that something in the conversation changed, indicating clients should fetch the conversation again"],
 | 
			
		||||
			"commented" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
 | 
			
		||||
			"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"],
 | 
			
		||||
			"pinned" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "deprecated"],
 | 
			
		||||
			"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"],
 | 
			
		||||
| 
						 | 
				
			
			@ -1335,7 +1335,6 @@ return [
 | 
			
		|||
			"commented" => ["commented"],
 | 
			
		||||
			"uid_received" => ["uid", "received"],
 | 
			
		||||
			"uid_wall_received" => ["uid", "wall", "received"],
 | 
			
		||||
			"uid_pinned" => ["uid", "pinned"],
 | 
			
		||||
			"uid_commented" => ["uid", "commented"],
 | 
			
		||||
			"uid_starred" => ["uid", "starred"],
 | 
			
		||||
			"uid_mention" => ["uid", "mention"],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,7 +86,6 @@
 | 
			
		|||
			"pubmail" => ["post-thread-user", "pubmail"],
 | 
			
		||||
			"visible" => ["post-user", "visible"],
 | 
			
		||||
			"starred" => ["post-thread-user", "starred"],
 | 
			
		||||
			"pinned" => ["post-thread-user", "pinned"],
 | 
			
		||||
			"unseen" => ["post-user", "unseen"],
 | 
			
		||||
			"deleted" => ["post-user", "deleted"],
 | 
			
		||||
			"origin" => ["post-user", "origin"],
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +245,6 @@
 | 
			
		|||
			"ignored" => ["post-thread-user", "ignored"],
 | 
			
		||||
			"visible" => ["post-user", "visible"],
 | 
			
		||||
			"starred" => ["post-thread-user", "starred"],
 | 
			
		||||
			"pinned" => ["post-thread-user", "pinned"],
 | 
			
		||||
			"unseen" => ["post-thread-user", "unseen"],
 | 
			
		||||
			"deleted" => ["post-user", "deleted"],
 | 
			
		||||
			"origin" => ["post-thread-user", "origin"],
 | 
			
		||||
| 
						 | 
				
			
			@ -627,6 +625,17 @@
 | 
			
		|||
		"query" => "FROM `post-category`
 | 
			
		||||
			LEFT JOIN `tag` ON `post-category`.`tid` = `tag`.`id`"
 | 
			
		||||
	],
 | 
			
		||||
	"collection-view" => [
 | 
			
		||||
		"fields" => [
 | 
			
		||||
			"uri-id" => ["post-collection", "uri-id"],
 | 
			
		||||
			"type" => ["post-collection", "type"],
 | 
			
		||||
			"cid" => ["post", "author-id"],
 | 
			
		||||
			"received" => ["post", "received"],
 | 
			
		||||
			"created" => ["post", "created"],
 | 
			
		||||
		],
 | 
			
		||||
		"query" => "FROM `post-collection`
 | 
			
		||||
			INNER JOIN `post` ON `post-collection`.`uri-id` = `post`.`uri-id`"
 | 
			
		||||
	],
 | 
			
		||||
	"tag-view" => [
 | 
			
		||||
		"fields" => [
 | 
			
		||||
			"uri-id" => ["post-tag", "uri-id"],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								update.php
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								update.php
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1097,3 +1097,14 @@ function update_1451()
 | 
			
		|||
 | 
			
		||||
	return Update::SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function update_1457()
 | 
			
		||||
{
 | 
			
		||||
	$pinned = DBA::select('post-thread-user', ['uri-id'], ['pinned' => true]);
 | 
			
		||||
	while ($post = DBA::fetch($pinned)) {
 | 
			
		||||
		Post\Collection::add($post['uri-id'], Post\Collection::FEATURED);
 | 
			
		||||
	}
 | 
			
		||||
	DBA::close($pinned);
 | 
			
		||||
 | 
			
		||||
	return Update::SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,8 +28,7 @@
 | 
			
		|||
		</div>
 | 
			
		||||
		<div class="wall-item-author">
 | 
			
		||||
				<a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}">{{$item.name}}</span></a>
 | 
			
		||||
				<div class="wall-item-ago"  id="wall-item-ago-{{$item.id}}" title="{{$item.localtime}}">{{$item.ago}}</div>
 | 
			
		||||
				
 | 
			
		||||
				<div class="wall-item-ago" id="wall-item-ago-{{$item.id}}"><time class="dt-published" title="{{$item.localtime}}" datetime="{{$item.utc}}">{{$item.ago}}</time><span class="pinned">{{$item.pinned}}</span></div>				
 | 
			
		||||
		</div>			
 | 
			
		||||
		<div class="wall-item-content" id="wall-item-content-{{$item.id}}">
 | 
			
		||||
			<div class="wall-item-title" id="wall-item-title-{{$item.id}}" dir="auto">{{$item.title}}</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,10 @@
 | 
			
		|||
								<a href="{{$item.plink.orig}}">
 | 
			
		||||
									<time class="time" title="{{$item.localtime}}" data-toggle="tooltip" datetime="{{$item.utc}}">{{$item.ago}}</time>
 | 
			
		||||
								</a>
 | 
			
		||||
								{{if $item.pinned}}
 | 
			
		||||
									• <i class="fa fa-thumb-tack" aria-hidden="true" title="{{$item.pinned}}"></i>
 | 
			
		||||
									<span class="sr-only">{{$item.pinned}}</span>
 | 
			
		||||
								{{/if}}
 | 
			
		||||
							</small>
 | 
			
		||||
						</div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@
 | 
			
		|||
			<span class="wall-item-ago">
 | 
			
		||||
				{{if $item.plink}}<a class="link" title="{{$item.plink.title}}" href="{{$item.plink.href}}" style="color: #999">{{$item.ago}}</a>{{else}} {{$item.ago}} {{/if}}
 | 
			
		||||
				{{if $item.lock}}<span class="fakelink" style="color: #999" onclick="lockview(event, 'item', {{$item.id}});">{{$item.lock}}</span> {{/if}}
 | 
			
		||||
				<span class="pinned">{{$item.pinned}}</span>
 | 
			
		||||
			</span>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="wall-item-content">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue