diff --git a/lib/AP.php b/lib/AP.php index 0efbd998..54c7382d 100644 --- a/lib/AP.php +++ b/lib/AP.php @@ -43,7 +43,7 @@ use OCA\Social\Interfaces\Activity\CreateInterface; use OCA\Social\Interfaces\Activity\DeleteInterface; use OCA\Social\Interfaces\Actor\ServiceInterface; use OCA\Social\Interfaces\Object\FollowInterface; -use OCA\Social\Interfaces\Activity\LikeInterface; +use OCA\Social\Interfaces\Object\LikeInterface; use OCA\Social\Interfaces\Activity\RejectInterface; use OCA\Social\Interfaces\Activity\RemoveInterface; use OCA\Social\Interfaces\Activity\UndoInterface; @@ -63,7 +63,7 @@ use OCA\Social\Model\ActivityPub\Activity\Create; use OCA\Social\Model\ActivityPub\Activity\Delete; use OCA\Social\Model\ActivityPub\Actor\Service; use OCA\Social\Model\ActivityPub\Object\Follow; -use OCA\Social\Model\ActivityPub\Activity\Like; +use OCA\Social\Model\ActivityPub\Object\Like; use OCA\Social\Model\ActivityPub\Activity\Reject; use OCA\Social\Model\ActivityPub\Activity\Remove; use OCA\Social\Model\ActivityPub\Activity\Undo; diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 1e5dacd3..132e0cf3 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -76,6 +76,7 @@ class CoreRequestBuilder { const TABLE_STREAMS = 'social_a2_stream'; const TABLE_HASHTAGS = 'social_a2_hashtags'; const TABLE_FOLLOWS = 'social_a2_follows'; + const TABLE_LIKES = 'social_a2_likes'; const TABLE_CACHE_ACTORS = 'social_a2_cache_actors'; const TABLE_CACHE_DOCUMENTS = 'social_a2_cache_documts'; @@ -200,6 +201,17 @@ class CoreRequestBuilder { } + /** + * Limit the request to the sub-type + * + * @param IQueryBuilder $qb + * @param string $subType + */ + protected function limitToSubType(IQueryBuilder &$qb, string $subType) { + $this->limitToDBField($qb, 'subtype', $subType); + } + + /** * @param IQueryBuilder $qb * @param string $type diff --git a/lib/Db/LikesRequest.php b/lib/Db/LikesRequest.php new file mode 100644 index 00000000..a03b448c --- /dev/null +++ b/lib/Db/LikesRequest.php @@ -0,0 +1,162 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + + +namespace OCA\Social\Db; + + +use daita\MySmallPhpTools\Traits\TArrayTools; +use DateTime; +use Exception; +use OCA\Social\Exceptions\LikeDoesNotExistException; +use OCA\Social\Model\ActivityPub\Object\Like; +use OCP\DB\QueryBuilder\IQueryBuilder; + + +/** + * Class LikesRequest + * + * @package OCA\Social\Db + */ +class LikesRequest extends LikesRequestBuilder { + + + use TArrayTools; + + + /** + * Insert a new Note in the database. + * + * @param Like $like + */ + public function save(Like $like) { + $qb = $this->getLikesInsertSql(); + $qb->setValue('id', $qb->createNamedParameter($like->getId())) + ->setValue('actor_id', $qb->createNamedParameter($like->getActorId())) + ->setValue('type', $qb->createNamedParameter($like->getType())) + ->setValue('object_id', $qb->createNamedParameter($like->getObjectId())); + + try { + $qb->setValue( + 'creation', + $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE) + ); + } catch (Exception $e) { + } + + $this->generatePrimaryKey($qb, $like->getId()); + + $qb->execute(); + } + + + /** + * @param string $actorId + * @param string $objectId + * + * @return Like + * @throws LikeDoesNotExistException + */ + public function getLike(string $actorId, string $objectId): Like { + $qb = $this->getLikesSelectSql(); + $this->limitToActorId($qb, $actorId); + $this->limitToObjectId($qb, $objectId); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + if ($data === false) { + throw new LikeDoesNotExistException(); + } + + return $this->parseLikesSelectSql($data); + } + + + /** + * @param string $objectId + * + * @return int + */ + public function countLikes(string $objectId): int { + $qb = $this->countLikesSelectSql(); + $this->limitToObjectId($qb, $objectId); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + + /** + * @param string $objectId + * + * @return Like[] + */ + public function getByObjectId(string $objectId): array { + $qb = $this->getLikesSelectSql(); + $this->limitToObjectId($qb, $objectId); + $this->leftJoinCacheActors($qb, 'actor_id'); + + $likes = []; + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $likes[] = $this->parseLikesSelectSql($data); + } + $cursor->closeCursor(); + + return $likes; + } + + + /** + * @param Like $like + */ + public function delete(Like $like) { + $qb = $this->getLikesDeleteSql(); + $this->limitToIdString($qb, $like->getId()); + + $qb->execute(); + } + + + /** + * @param string $objectId + */ + public function deleteLikes(string $objectId) { + $qb = $this->getLikesDeleteSql(); + $this->limitToObjectId($qb, $objectId); + + $qb->execute(); + } + +} + diff --git a/lib/Db/LikesRequestBuilder.php b/lib/Db/LikesRequestBuilder.php new file mode 100644 index 00000000..64e83d74 --- /dev/null +++ b/lib/Db/LikesRequestBuilder.php @@ -0,0 +1,146 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + + +namespace OCA\Social\Db; + + +use daita\MySmallPhpTools\Traits\TArrayTools; +use OCA\Social\Exceptions\InvalidResourceException; +use OCA\Social\Model\ActivityPub\Object\Follow; +use OCA\Social\Model\ActivityPub\Object\Like; +use OCP\DB\QueryBuilder\IQueryBuilder; + + +/** + * Class LikesRequestBuilder + * + * @package OCA\Social\Db + */ +class LikesRequestBuilder extends CoreRequestBuilder { + + + use TArrayTools; + + + /** + * Base of the Sql Insert request + * + * @return IQueryBuilder + */ + protected function getLikesInsertSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert(self::TABLE_LIKES); + + return $qb; + } + + + /** + * Base of the Sql Update request + * + * @return IQueryBuilder + */ + protected function getLikesUpdateSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update(self::TABLE_LIKES); + + return $qb; + } + + + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function getLikesSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + + /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->select('l.id', 'l.type', 'l.actor_id', 'l.object_id', 'l.creation') + ->from(self::TABLE_LIKES, 'l'); + + $this->defaultSelectAlias = 'l'; + + return $qb; + } + + + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function countLikesSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') + ->from(self::TABLE_LIKES, 'l'); + + $this->defaultSelectAlias = 'l'; + + return $qb; + } + + + /** + * Base of the Sql Delete request + * + * @return IQueryBuilder + */ + protected function getLikesDeleteSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->delete(self::TABLE_LIKES); + + return $qb; + } + + + /** + * @param array $data + * + * @return Like + */ + protected function parseLikesSelectSql($data): Like { + $like = new Like(); + $like->importFromDatabase($data); + + try { + $actor = $this->parseCacheActorsLeftJoin($data); + $actor->setCompleteDetails(true); + + $like->setActor($actor); + } catch (InvalidResourceException $e) { + } + + return $like; + } + +} + diff --git a/lib/Db/StreamRequest.php b/lib/Db/StreamRequest.php index a32ff935..34081d82 100644 --- a/lib/Db/StreamRequest.php +++ b/lib/Db/StreamRequest.php @@ -214,15 +214,16 @@ class StreamRequest extends StreamRequestBuilder { /** - * @param string $type * @param string $objectId + * @param string $type + * @param string $subType * * @return Stream - * @throws StreamNotFoundException * @throws ItemUnknownException * @throws SocialAppConfigException + * @throws StreamNotFoundException */ - public function getStreamByObjectId(string $objectId, string $type): Stream { + public function getStreamByObjectId(string $objectId, string $type, string $subType = ''): Stream { if ($objectId === '') { throw new StreamNotFoundException('missing objectId'); }; @@ -230,6 +231,7 @@ class StreamRequest extends StreamRequestBuilder { $qb = $this->getStreamSelectSql(); $this->limitToObjectId($qb, $objectId); $this->limitToType($qb, $type); + $this->limitToSubType($qb, $subType); $cursor = $qb->execute(); $data = $cursor->fetch(); @@ -580,6 +582,7 @@ class StreamRequest extends StreamRequestBuilder { $qb = $this->getStreamInsertSql(); $qb->setValue('id', $qb->createNamedParameter($stream->getId())) ->setValue('type', $qb->createNamedParameter($stream->getType())) + ->setValue('subtype', $qb->createNamedParameter($stream->getSubType())) ->setValue('to', $qb->createNamedParameter($stream->getTo())) ->setValue( 'to_array', $qb->createNamedParameter( diff --git a/lib/Exceptions/LikeDoesNotExistException.php b/lib/Exceptions/LikeDoesNotExistException.php new file mode 100644 index 00000000..66e79da3 --- /dev/null +++ b/lib/Exceptions/LikeDoesNotExistException.php @@ -0,0 +1,40 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + + +namespace OCA\Social\Exceptions; + + +use Exception; + + +class LikeDoesNotExistException extends Exception { + +} + diff --git a/lib/Interfaces/Activity/LikeInterface.php b/lib/Interfaces/Activity/LikeInterface.php deleted file mode 100644 index fba4a6e3..00000000 --- a/lib/Interfaces/Activity/LikeInterface.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Interfaces\Activity; - - -use OCA\Social\AP; -use OCA\Social\Exceptions\ItemNotFoundException; -use OCA\Social\Exceptions\ItemUnknownException; -use OCA\Social\Interfaces\IActivityPubInterface; -use OCA\Social\Model\ActivityPub\ACore; -use OCA\Social\Service\MiscService; - - -class LikeInterface implements IActivityPubInterface { - - - /** @var MiscService */ - private $miscService; - - - /** - * LikeService constructor. - * - * @param MiscService $miscService - */ - public function __construct(MiscService $miscService) { - $this->miscService = $miscService; - } - - - /** - * @param ACore $item - */ - public function processIncomingRequest(ACore $item) { - if (!$item->gotObject()) { - return; - } - $object = $item->getObject(); - - try { - $service = AP::$activityPub->getInterfaceForItem($item->getObject()); - $service->activity($item, $object); - } catch (ItemUnknownException $e) { - } - } - - - /** - * @param ACore $item - */ - public function processResult(ACore $item) { - } - - - /** - * @param string $id - * - * @return ACore - * @throws ItemNotFoundException - */ - public function getItemById(string $id): ACore { - throw new ItemNotFoundException(); - } - - - /** - * @param ACore $item - */ - public function save(ACore $item) { - } - - - /** - * @param ACore $item - */ - public function update(ACore $item) { - } - - - /** - * @param ACore $item - */ - public function delete(ACore $item) { - } - - - /** - * @param ACore $item - * @param string $source - */ - public function event(ACore $item, string $source) { - } - - - /** - * @param ACore $activity - * @param ACore $item - */ - public function activity(ACore $activity, ACore $item) { - } -} - diff --git a/lib/Interfaces/Object/AnnounceInterface.php b/lib/Interfaces/Object/AnnounceInterface.php index d45d4864..8c37f042 100644 --- a/lib/Interfaces/Object/AnnounceInterface.php +++ b/lib/Interfaces/Object/AnnounceInterface.php @@ -324,6 +324,7 @@ class AnnounceInterface implements IActivityPubInterface { $notification->setDetailItem('post', $post); $notification->addDetail('accounts', $author->getAccount()); $notification->setAttributedTo($author->getId()) + ->setSubType(Announce::TYPE) ->setId($item->getId() . '/notification') ->setSummary('{accounts} boosted your post') ->setObjectId($item->getId()) diff --git a/lib/Interfaces/Object/FollowInterface.php b/lib/Interfaces/Object/FollowInterface.php index d7f216ea..70326087 100644 --- a/lib/Interfaces/Object/FollowInterface.php +++ b/lib/Interfaces/Object/FollowInterface.php @@ -288,6 +288,7 @@ class FollowInterface implements IActivityPubInterface { $notification->setDetail('account', $follower->getAccount()); $notification->setAttributedTo($follow->getActorId()) ->setId($follow->getId() . '/notification') + ->setSubType(Follow::TYPE) ->setActorId($follower->getId()) ->setSummary('{account} is following you') ->setTo($follow->getObjectId()) diff --git a/lib/Interfaces/Object/LikeInterface.php b/lib/Interfaces/Object/LikeInterface.php new file mode 100644 index 00000000..658955f2 --- /dev/null +++ b/lib/Interfaces/Object/LikeInterface.php @@ -0,0 +1,232 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + + +namespace OCA\Social\Interfaces\Object; + + +use Exception; +use OCA\Social\AP; +use OCA\Social\Db\LikesRequest; +use OCA\Social\Db\StreamRequest; +use OCA\Social\Exceptions\InvalidOriginException; +use OCA\Social\Exceptions\ItemNotFoundException; +use OCA\Social\Exceptions\ItemUnknownException; +use OCA\Social\Exceptions\LikeDoesNotExistException; +use OCA\Social\Exceptions\SocialAppConfigException; +use OCA\Social\Exceptions\StreamNotFoundException; +use OCA\Social\Interfaces\IActivityPubInterface; +use OCA\Social\Interfaces\Internal\SocialAppNotificationInterface; +use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Model\ActivityPub\Activity\Undo; +use OCA\Social\Model\ActivityPub\Actor\Person; +use OCA\Social\Model\ActivityPub\Internal\SocialAppNotification; +use OCA\Social\Model\ActivityPub\Object\Like; +use OCA\Social\Service\CacheActorService; +use OCA\Social\Service\MiscService; + + +/** + * Class LikeInterface + * + * @package OCA\Social\Interfaces\Object + */ +class LikeInterface implements IActivityPubInterface { + + /** @var LikesRequest */ + private $likesRequest; + + /** @var StreamRequest */ + private $streamRequest; + + /** @var CacheActorService */ + private $cacheActorService; + + /** @var MiscService */ + private $miscService; + + + /** + * LikeService constructor. + * + * @param LikesRequest $likesRequest + * @param StreamRequest $streamRequest + * @param CacheActorService $cacheActorService + * @param MiscService $miscService + */ + public function __construct( + LikesRequest $likesRequest, StreamRequest $streamRequest, + CacheActorService $cacheActorService, MiscService $miscService + ) { + $this->likesRequest = $likesRequest; + $this->streamRequest = $streamRequest; + $this->cacheActorService = $cacheActorService; + $this->miscService = $miscService; + } + + + /** + * @param ACore $like + * + * @throws InvalidOriginException + */ + public function processIncomingRequest(ACore $like) { + /** @var Like $like */ + $like->checkOrigin($like->getActorId()); + + try { + $this->likesRequest->getLike($like->getActorId(), $like->getObjectId()); + } catch (LikeDoesNotExistException $e) { + $this->likesRequest->save($like); + + try { + if ($like->hasActor()) { + $actor = $like->getActor(); + } else { + $actor = $this->cacheActorService->getFromId($like->getActorId()); + } + + $this->generateNotification($like, $actor); + } catch (Exception $e) { + } + } + } + + + /** + * @param ACore $item + */ + public function processResult(ACore $item) { + } + + + /** + * @param string $id + * + * @return ACore + * @throws ItemNotFoundException + */ + public function getItemById(string $id): ACore { + throw new ItemNotFoundException(); + } + + + /** + * @param ACore $item + */ + public function save(ACore $item) { + } + + + /** + * @param ACore $item + */ + public function update(ACore $item) { + } + + + /** + * @param ACore $item + */ + public function delete(ACore $item) { + } + + + /** + * @param ACore $item + * @param string $source + */ + public function event(ACore $item, string $source) { + } + + + /** + * @param ACore $activity + * @param ACore $item + * + * @throws InvalidOriginException + */ + public function activity(ACore $activity, ACore $item) { + /** @var Like $item */ + if ($activity->getType() === Undo::TYPE) { + $activity->checkOrigin($item->getId()); + $activity->checkOrigin($item->getActorId()); + $this->likesRequest->delete($item); + } + } + + + /** + * @param Like $like + * @param Person $author + * + * @throws ItemUnknownException + * @throws SocialAppConfigException + */ + private function generateNotification(Like $like, Person $author) { + /** @var SocialAppNotificationInterface $notificationInterface */ + $notificationInterface = + AP::$activityPub->getInterfaceFromType(SocialAppNotification::TYPE); + + try { + $notification = $this->streamRequest->getStreamByObjectId( + $like->getObjectId(), SocialAppNotification::TYPE, Like::TYPE + ); + + $notification->addDetail('accounts', $author->getAccount()); + $notificationInterface->update($notification); + } catch (StreamNotFoundException $e) { + try { + $post = $this->streamRequest->getStreamById($like->getObjectId()); + } catch (StreamNotFoundException $e) { + return; // should not happens. + } + + if (!$post->isLocal()) { + return; + } + + /** @var SocialAppNotification $notification */ + $notification = AP::$activityPub->getItemFromType(SocialAppNotification::TYPE); +// $notification->setDetail('url', ''); + $notification->setDetailItem('post', $post); + $notification->addDetail('accounts', $author->getAccount()); + $notification->setAttributedTo($author->getId()) + ->setSubType(Like::TYPE) + ->setId($like->getObjectId() . '/like') + ->setSummary('{accounts} liked your post') + ->setObjectId($like->getObjectId()) + ->setTo($post->getAttributedTo()) + ->setLocal(true); + + $notificationInterface->save($notification); + } + } +} + diff --git a/lib/Migration/Version0002Date20190628000001.php b/lib/Migration/Version0002Date20190628000001.php index 3e1f8277..999bfdbb 100644 --- a/lib/Migration/Version0002Date20190628000001.php +++ b/lib/Migration/Version0002Date20190628000001.php @@ -32,6 +32,8 @@ namespace OCA\Social\Migration; use Closure; +use Doctrine\DBAL\Schema\SchemaException; +use Doctrine\DBAL\Types\Type; use Exception; use OCP\DB\ISchemaWrapper; use OCP\IDBConnection; @@ -65,11 +67,73 @@ class Version0002Date20190628000001 extends SimpleMigrationStep { * @param array $options * * @return ISchemaWrapper + * @throws SchemaException */ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options ): ISchemaWrapper { /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); + if ($schema->hasTable('social_a2_stream')) { + $table = $schema->getTable('social_a2_stream'); + if (!$table->hasColumn('subtype')) { + $table->addColumn( + 'subtype', Type::STRING, + [ + 'notnull' => false, + 'length' => 31, + ] + ); + } + } + + + if (!$schema->hasTable('social_a2_likes')) { + $table = $schema->createTable('social_a2_likes'); + + $table->addColumn( + 'id', 'string', + [ + 'notnull' => false, + 'length' => 1000 + ] + ); + $table->addColumn( + 'id_prim', 'string', + [ + 'notnull' => false, + 'length' => 128 + ] + ); + $table->addColumn( + 'type', 'string', + [ + 'notnull' => false, + 'length' => 31, + ] + ); + $table->addColumn( + 'actor_id', 'string', + [ + 'notnull' => true, + 'length' => 1000, + ] + ); + $table->addColumn( + 'object_id', 'string', + [ + 'notnull' => true, + 'length' => 1000, + ] + ); + $table->addColumn( + 'creation', 'datetime', + [ + 'notnull' => false, + ] + ); + + $table->setPrimaryKey(['id_prim']); + } return $schema; } diff --git a/lib/Model/ActivityPub/Item.php b/lib/Model/ActivityPub/Item.php index f1438583..add8e14d 100644 --- a/lib/Model/ActivityPub/Item.php +++ b/lib/Model/ActivityPub/Item.php @@ -56,6 +56,9 @@ class Item { /** @var string */ private $type = ''; + /** @var string */ + private $subType = ''; + /** @var string */ private $url = ''; @@ -149,10 +152,27 @@ class Item { * @return Item */ public function setType(string $type): Item { -// if ($type !== '') { $this->type = $type; -// } + return $this; + } + + + + /** + * @return string + */ + public function getSubType(): string { + return $this->subType; + } + + /** + * @param string $type + * + * @return Item + */ + public function setSubType(string $type): Item { + $this->subType = $type; return $this; } @@ -667,6 +687,7 @@ class Item { } + } diff --git a/lib/Model/ActivityPub/Activity/Like.php b/lib/Model/ActivityPub/Object/Like.php similarity index 94% rename from lib/Model/ActivityPub/Activity/Like.php rename to lib/Model/ActivityPub/Object/Like.php index 947f30c4..6118e409 100644 --- a/lib/Model/ActivityPub/Activity/Like.php +++ b/lib/Model/ActivityPub/Object/Like.php @@ -28,7 +28,7 @@ declare(strict_types=1); */ -namespace OCA\Social\Model\ActivityPub\Activity; +namespace OCA\Social\Model\ActivityPub\Object; use JsonSerializable; @@ -38,7 +38,7 @@ use OCA\Social\Model\ActivityPub\ACore; /** * Class Like * - * @package OCA\Social\Model\ActivityPub\Activity + * @package OCA\Social\Model\ActivityPub\Object */ class Like extends ACore implements JsonSerializable {