diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index 19f3866cd4..642c9efe83 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -99,7 +99,7 @@ class Status extends BaseFactory public function createFromUriId(int $uriId, int $uid = 0, bool $display_quote = false, bool $reblog = true, bool $in_reply_status = true): \Friendica\Object\Api\Mastodon\Status { $fields = ['uri-id', 'uid', 'author-id', 'causer-id', 'author-uri-id', 'author-link', 'causer-uri-id', 'post-reason', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning', 'question-id', - 'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured', 'has-media', 'quote-uri-id', + 'created', 'edited', 'commented', 'received', 'changed', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured', 'has-media', 'quote-uri-id', 'delivery_queue_count', 'delivery_queue_done','delivery_queue_failed']; $item = Post::selectFirst($fields, ['uri-id' => $uriId, 'uid' => [0, $uid]], ['order' => ['uid' => true]]); if (!$item) { @@ -289,7 +289,7 @@ class Status extends BaseFactory } $delivery_data = new FriendicaDeliveryData($item['delivery_queue_count'], $item['delivery_queue_done'], $item['delivery_queue_failed']); - $friendica = new FriendicaExtension($item['title'], $counts->dislikes, $delivery_data); + $friendica = new FriendicaExtension($item['title'], $item['changed'], $item['commented'], $item['edited'], $item['received'], $counts->dislikes, $delivery_data); return new \Friendica\Object\Api\Mastodon\Status($item, $account, $counts, $userAttributes, $sensitive, $application, $mentions, $tags, $card, $attachments, $in_reply, $reshare, $friendica, $quote, $poll); } @@ -355,7 +355,7 @@ class Status extends BaseFactory $attachments = []; $in_reply = []; $reshare = []; - $friendica = new FriendicaExtension('', 0, new FriendicaDeliveryData(0, 0, 0)); + $friendica = new FriendicaExtension('', null, null, null, null, 0, new FriendicaDeliveryData(0, 0, 0)); return new \Friendica\Object\Api\Mastodon\Status($item, $account, $counts, $userAttributes, $sensitive, $application, $mentions, $tags, $card, $attachments, $in_reply, $reshare, $friendica); } diff --git a/src/Module/Api/Mastodon/Timelines/Home.php b/src/Module/Api/Mastodon/Timelines/Home.php index 797b192407..53ab3d629b 100644 --- a/src/Module/Api/Mastodon/Timelines/Home.php +++ b/src/Module/Api/Mastodon/Timelines/Home.php @@ -89,14 +89,7 @@ class Home extends BaseApi while ($item = Post::fetch($items)) { try { $status = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid, $display_quotes); - switch ($request['friendica_order']) { - case TimelineOrderByTypes::CREATED: - self::setBoundaries($status->createdAtTimestamp()); - break; - case TimelineOrderByTypes::ID: - default: - self::setBoundaries($item['uri-id']); - } + $this->updateBoundaries($status, $item, $request['friendica_order']); $statuses[] = $status; } catch (\Throwable $th) { Logger::info('Post not fetchable', ['uri-id' => $item['uri-id'], 'uid' => $uid, 'error' => $th]); diff --git a/src/Module/BaseApi.php b/src/Module/BaseApi.php index 82f0ad0596..4c16ab20e2 100644 --- a/src/Module/BaseApi.php +++ b/src/Module/BaseApi.php @@ -37,6 +37,7 @@ use Friendica\Model\User; use Friendica\Module\Api\ApiResponse; use Friendica\Module\Special\HTTPException as ModuleHTTPException; use Friendica\Network\HTTPException; +use Friendica\Object\Api\Mastodon\Status; use Friendica\Object\Api\Mastodon\TimelineOrderByTypes; use Friendica\Security\BasicAuth; use Friendica\Security\OAuth; @@ -128,13 +129,7 @@ class BaseApi extends BaseModule $condition = DBA::mergeConditions($condition, ["`uri-id` > ?", intval($request['min_id'])]); } } else { - switch ($requested_order) { - case TimelineOrderByTypes::CREATED: - $order_field = 'created'; - break; - default: - $order_field = 'uri-id'; - } + $order_field = $requested_order; if (!empty($request['max_id'])) { $condition = DBA::mergeConditions($condition, ["`$order_field` < ?", DateTimeFormat::convert($request['max_id'], DateTimeFormat::MYSQL)]); } @@ -163,9 +158,21 @@ class BaseApi extends BaseModule { $requested_order = $request['friendica_order']; switch ($requested_order) { + case TimelineOrderByTypes::CHANGED: + $order_field = 'changed'; + break; case TimelineOrderByTypes::CREATED: $order_field = 'created'; break; + case TimelineOrderByTypes::COMMENTED: + $order_field = 'commented'; + break; + case TimelineOrderByTypes::EDITED: + $order_field = 'edited'; + break; + case TimelineOrderByTypes::RECEIVED: + $order_field = 'received'; + break; case TimelineOrderByTypes::ID: default: $order_field = 'uri-id'; @@ -182,6 +189,44 @@ class BaseApi extends BaseModule return $params; } + protected function updateBoundaries(Status $status, array $post_item, string $order) { + ; + try { + switch ($order) { + case TimelineOrderByTypes::CHANGED: + if (!empty($status->friendicaExtension()->changedAt())){ + self::setBoundaries(new DateTime(DateTimeFormat::utc($status->friendicaExtension()->changedAt(), DateTimeFormat::JSON))); + } + break; + case TimelineOrderByTypes::CREATED: + if (!empty($status->createdAt())){ + self::setBoundaries(new DateTime(DateTimeFormat::utc($status->createdAt(), DateTimeFormat::JSON))); + } + break; + case TimelineOrderByTypes::COMMENTED: + if (!empty($status->friendicaExtension()->commentedAt())){ + self::setBoundaries(new DateTime(DateTimeFormat::utc($status->friendicaExtension()->commentedAt(), DateTimeFormat::JSON))); + } + break; + case TimelineOrderByTypes::EDITED: + if (!empty($status->friendicaExtension()->editedAt())){ + self::setBoundaries(new DateTime(DateTimeFormat::utc($status->friendicaExtension()->editedAt(), DateTimeFormat::JSON))); + } + break; + case TimelineOrderByTypes::RECEIVED: + if (!empty($status->friendicaExtension()->receivedAt())){ + self::setBoundaries(new DateTime(DateTimeFormat::utc($status->friendicaExtension()->receivedAt(), DateTimeFormat::JSON))); + } + break; + case TimelineOrderByTypes::ID: + default: + self::setBoundaries($post_item['uri-id']); + } + } catch (\Exception $e) { + Logger::debug('Error processing page boundary calculation, skipping', ['error' => $e]); + } + } + /** * Processes data from GET requests and sets defaults * diff --git a/src/Object/Api/Mastodon/Status.php b/src/Object/Api/Mastodon/Status.php index e157d44d03..5563981f13 100644 --- a/src/Object/Api/Mastodon/Status.php +++ b/src/Object/Api/Mastodon/Status.php @@ -38,7 +38,7 @@ class Status extends BaseDataTransferObject { /** @var string */ protected $id; - /** @var string (Datetime) */ + /** @var string|null (Datetime) */ protected $created_at; /** @var string|null */ protected $in_reply_to_id = null; @@ -107,8 +107,8 @@ class Status extends BaseDataTransferObject */ public function __construct(array $item, Account $account, Counts $counts, UserAttributes $userAttributes, bool $sensitive, Application $application, array $mentions, array $tags, Card $card, array $attachments, array $in_reply, array $reblog, FriendicaExtension $friendica, array $quote = null, array $poll = null) { - $this->id = (string)$item['uri-id']; - $this->created_at = DateTimeFormat::utc($item['created'], DateTimeFormat::JSON); + $this->id = (string)$item['uri-id']; + $this->created_at = $item['created']; if ($item['gravity'] == Item::GRAVITY_COMMENT) { $this->in_reply_to_id = (string)$item['thr-parent-id']; @@ -155,18 +155,21 @@ class Status extends BaseDataTransferObject } /** - * Returns the current created_at DateTime as an integer timestamp - * @return \DateTime - * @throws \Exception + * Returns the current created_at string or null if not set + * @return \DateTime|null */ - public function createdAtTimestamp(): \DateTime + public function createdAt(): ?string { - $result = new \DateTime($this->created_at); - if (!$result) { - throw new \Exception('Unknown date-time format'); - } + return $this->created_at; + } - return $result; + /** + * Returns the Friendica Extension properties + * @return FriendicaExtension + */ + public function friendicaExtension(): FriendicaExtension + { + return $this->friendica; } /** diff --git a/src/Object/Api/Mastodon/Status/FriendicaExtension.php b/src/Object/Api/Mastodon/Status/FriendicaExtension.php index b2853894ad..3e39c2baa6 100644 --- a/src/Object/Api/Mastodon/Status/FriendicaExtension.php +++ b/src/Object/Api/Mastodon/Status/FriendicaExtension.php @@ -35,6 +35,18 @@ class FriendicaExtension extends BaseDataTransferObject /** @var string */ protected $title; + /** @var string|null (Datetime) */ + protected $changed_at; + + /** @var string|null (Datetime) */ + protected $commented_at; + + /** @var string|null (Datetime) */ + protected $edited_at; + + /** @var string|null (Datetime) */ + protected $received_at; + /** @var FriendicaDeliveryData */ protected $delivery_data; /** @var int */ @@ -47,10 +59,52 @@ class FriendicaExtension extends BaseDataTransferObject * @param int $dislikes_count * @param FriendicaDeliveryData $delivery_data */ - public function __construct(string $title, int $dislikes_count, FriendicaDeliveryData $delivery_data) + public function __construct(string $title, ?string $changed_at, ?string $commented_at, ?string $edited_at, ?string $received_at, + int $dislikes_count, FriendicaDeliveryData $delivery_data) { $this->title = $title; + $this->changed_at = $changed_at; + $this->commented_at = $commented_at; + $this->edited_at = $edited_at; + $this->received_at = $received_at; $this->delivery_data = $delivery_data; $this->dislikes_count = $dislikes_count; } + + /** + * Returns the current changed_at string or null if not set + * @return ?string + */ + public function changedAt(): ?string + { + return $this->changed_at; + } + + /** + * Returns the current commented_at string or null if not set + * @return ?string + */ + public function commentedAt(): ?string + { + return $this->commented_at; + } + + /** + * Returns the current edited_at string or null if not set + * @return ?string + */ + public function editedAt(): ?string + { + return $this->edited_at; + } + + /** + * Returns the current received_at string or null if not set + * @return ?string + */ + public function receivedAt(): ?string + { + return $this->received_at; + } + } diff --git a/src/Object/Api/Mastodon/TimelineOrderByTypes.php b/src/Object/Api/Mastodon/TimelineOrderByTypes.php index 196933c1fe..04fb7cc3b8 100644 --- a/src/Object/Api/Mastodon/TimelineOrderByTypes.php +++ b/src/Object/Api/Mastodon/TimelineOrderByTypes.php @@ -27,6 +27,16 @@ namespace Friendica\Object\Api\Mastodon; */ abstract class TimelineOrderByTypes { - const ID = 'id'; - const CREATED = 'created'; + const CHANGED = 'changed'; + + const CREATED = 'created'; + + const COMMENTED = 'commented'; + + const EDITED = 'edited'; + + const ID = 'id'; + + const RECEIVED = 'received'; + }