From 05136d44e03798f55542ca335ed4be65326c64b9 Mon Sep 17 00:00:00 2001 From: easd Date: Mon, 1 Oct 2018 22:27:32 +0700 Subject: [PATCH 01/26] create Controller\Album --- Listener.php | 6 ++++++ XFMG/Controller/Album.php | 15 +++++++++++++ XFMG/Data/Modules.php | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 XFMG/Controller/Album.php create mode 100644 XFMG/Data/Modules.php diff --git a/Listener.php b/Listener.php index 3de31e0c..c7c4f2ed 100644 --- a/Listener.php +++ b/Listener.php @@ -42,6 +42,12 @@ public static function appSetup($app) if (!empty($addOnCache['XFRM'])) { $extension->addClassExtension('Xfrocks\Api\Data\Modules', 'Xfrocks\Api\XFRM\Data\Modules'); } + + $addOnCache = $container['addon.cache']; + $extension = $app->extension(); + if (!empty($addOnCache['XFMG'])) { + $extension->addClassExtension('Xfrocks\Api\Data\Modules', 'Xfrocks\Api\XFMG\Data\Modules'); + } } /** diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php new file mode 100644 index 00000000..a2ce4081 --- /dev/null +++ b/XFMG/Controller/Album.php @@ -0,0 +1,15 @@ +api(['hello' => 'world']); + } +} diff --git a/XFMG/Data/Modules.php b/XFMG/Data/Modules.php new file mode 100644 index 00000000..a41c9fdd --- /dev/null +++ b/XFMG/Data/Modules.php @@ -0,0 +1,44 @@ +addController( + 'Xfrocks\Api\XFMG\Controller\Album', + 'albums', + ':int/' + ); + + $this->register('album', 2018100101); + } + + /** + * @param AbstractController $controller + * @return array + */ + public function getDataForApiIndex($controller) + { + $data = parent::getDataForApiIndex($controller); + + $app = $controller->app(); + $apiRouter = $app->router('api'); + $data['links']['albums'] = $apiRouter->buildLink('albums'); + + return $data; + } +} + +if (false) { + // phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses + // phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps + class XFCP_Modules extends \Xfrocks\Api\Data\Modules + { + } +} From a9397bc21ae5812ad324e5fb625b3880b91ecb6c Mon Sep 17 00:00:00 2001 From: datbth Date: Sat, 1 Dec 2018 13:39:45 +0700 Subject: [PATCH 02/26] add actionIndex and actionSingle for albums --- XFMG/Controller/Album.php | 69 ++++++++++++++++++++++++++++++++++++++- XFMG/Transform/Album.php | 58 ++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 XFMG/Transform/Album.php diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index a2ce4081..54ae619c 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -5,11 +5,78 @@ use XF\Mvc\ParameterBag; use Xfrocks\Api\Controller\AbstractController; +use Xfrocks\Api\Util\PageNav; class Album extends AbstractController { public function actionGetIndex(ParameterBag $params) { - return $this->api(['hello' => 'world']); + if ($params->album_id) { + return $this->actionSingle($params->album_id); + } + + $params = $this->params() + ->defineOrder([ + 'natural' => ['create_date', 'asc'], + 'natural_reverse' => ['create_date', 'desc'], + 'album_last_update_date' => ['last_update_date', 'asc'], + 'album_last_update_date_reverse' => ['last_update_date', 'desc'], + 'album_rating' => ['rating_avg', 'asc'], + 'album_rating_reverse' => ['rating_avg', 'desc'], + 'album_comment_count' => ['comment_count', 'asc'], + 'album_comment_count_reverse' => ['comment_count', 'desc'], + ]) + ->definePageNav(); + + /** @var \XFMG\Finder\Album $finder */ + $finder = $this->finder('XFMG:Album'); + $params->sortFinder($finder); + $params->limitFinderByPage($finder); + + $total = $finder->total(); + $albums = $total > 0 ? $this->transformFinderLazily($finder) : []; + + $data = [ + 'albums' => $albums, + 'albums_total' => $total + ]; + + PageNav::addLinksToData($data, $params, $total, 'albums'); + + return $this->api($data); + } + + protected function actionSingle($albumId) + { + $album = $this->assertViewableAlbum($albumId); + + $data = [ + 'album' => $this->transformEntityLazily($album) + ]; + + return $this->api($data); + } + + /** + * @param int $albumId + * @param array $extraWith + * @return \XFMG\Entity\Album + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertViewableAlbum($albumId, array $extraWith = []) + { + /** @var \XFMG\Entity\Album $album */ + $album = $this->assertRecordExists( + 'XFMG:Album', + $albumId, + $extraWith, + 'xfmg_requested_album_not_found' + ); + + if (!$album->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $album; } } diff --git a/XFMG/Transform/Album.php b/XFMG/Transform/Album.php new file mode 100644 index 00000000..1c7500b6 --- /dev/null +++ b/XFMG/Transform/Album.php @@ -0,0 +1,58 @@ +getSource(); + + $links = [ + self::LINK_PERMALINK => $this->buildPublicLink('media/albums', $album), + ]; + + return $links; + } + + public function getMappings($context) + { + return [ + 'album_id' => self::KEY_ID, + 'category_id' => self::KEY_CATEGORY_ID, + 'title' => self::KEY_TITLE, + 'description' => self::KEY_DESCRIPTION, + 'user_id' => self::KEY_USER_ID, + 'username' => self::KEY_USERNAME, + 'media_count' => self::KEY_MEDIA_COUNT, + 'likes' => self::KEY_LIKE_COUNT, + 'comment_count' => self::KEY_COMMENT_COUNT, + 'rating_count' => self::KEY_RATING_COUNT, + 'rating_avg' => self::KEY_RATING, + ]; + } +} \ No newline at end of file From 7af96ed29f4f921344330825af22d74929ab5714 Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 2 Dec 2018 13:44:22 +0700 Subject: [PATCH 03/26] added Api controller for media --- XFMG/Controller/Media.php | 80 ++++++++++++++++++++++++++ XFMG/Data/Modules.php | 16 ++++-- XFMG/Transform/MediaItem.php | 108 +++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 XFMG/Controller/Media.php create mode 100644 XFMG/Transform/MediaItem.php diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php new file mode 100644 index 00000000..a23807de --- /dev/null +++ b/XFMG/Controller/Media.php @@ -0,0 +1,80 @@ +media_id) { + return $this->actionSingle($params->media_id); + } + + $params = $this->params() + ->defineOrder([ + 'natural' => ['media_date', 'asc'], + 'natural_reverse' => ['media_date', 'desc'], + 'media_rating' => ['rating_avg', 'asc'], + 'media_rating_reverse' => ['rating_avg', 'desc'], + 'media_comment_count' => ['comment_count', 'asc'], + 'media_comment_count_reverse' => ['comment_count', 'desc'], + ]) + ->definePageNav(); + + /** @var \XFMG\Finder\MediaItem $finder */ + $finder = $this->finder('XFMG:MediaItem'); + $params->sortFinder($finder); + $params->limitFinderByPage($finder); + + $total = $finder->total(); + $items = $total > 0 ? $this->transformFinderLazily($finder) : []; + + $data = [ + 'items' => $items, + 'items_total' => $total + ]; + + PageNav::addLinksToData($data, $params, $total, 'items'); + + return $this->api($data); + } + + protected function actionSingle($itemId) + { + $item = $this->assertViewableItem($itemId); + + $data = [ + 'item' => $this->transformEntityLazily($item) + ]; + + return $this->api($data); + } + + /** + * @param int $mediaId + * @param array $extraWith + * @return \XFMG\Entity\MediaItem + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertViewableItem($mediaId, array $extraWith = []) + { + /** @var \XFMG\Entity\MediaItem $item */ + $item = $this->assertRecordExists( + 'XFMG:MediaItem', + $mediaId, + $extraWith, + 'xfmg_requested_media_item_not_found' + ); + + if (!$item->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $item; + } +} diff --git a/XFMG/Data/Modules.php b/XFMG/Data/Modules.php index a41c9fdd..d4346c02 100644 --- a/XFMG/Data/Modules.php +++ b/XFMG/Data/Modules.php @@ -10,13 +10,20 @@ public function __construct() { parent::__construct(); + $this->addController( + 'Xfrocks\Api\XFMG\Controller\Media', + 'media', + ':int/' + ); $this->addController( 'Xfrocks\Api\XFMG\Controller\Album', - 'albums', - ':int/' + 'media', + 'albums/:int/', + null, + 'albums' ); - $this->register('album', 2018100101); + $this->register('xfmg', 2018100101); } /** @@ -29,7 +36,8 @@ public function getDataForApiIndex($controller) $app = $controller->app(); $apiRouter = $app->router('api'); - $data['links']['albums'] = $apiRouter->buildLink('albums'); + $data['links']['media'] = $apiRouter->buildLink('media'); + $data['links']['media/albums'] = $apiRouter->buildLink('media/albums'); return $data; } diff --git a/XFMG/Transform/MediaItem.php b/XFMG/Transform/MediaItem.php new file mode 100644 index 00000000..f163c74b --- /dev/null +++ b/XFMG/Transform/MediaItem.php @@ -0,0 +1,108 @@ +getParentSourceValue('media_id'); + } + + return null; + } + + public function attachmentCollectLinks($context, array &$links) + { + $item = $context->getParentSource(); + $links[self::ATTACHMENT__LINK_MEDIA] = $this->buildApiLink('media', $item); + } + + public function attachmentCollectPermissions($context, array &$permissions) + { + } + + public function attachmentGetMappings($context, array &$mappings) + { + $mappings[] = self::ATTACHMENT__DYNAMIC_KEY_ID; + } + + public function calculateDynamicValue($context, $key) + { + /** @var \XFMG\Entity\MediaItem $item */ + $item = $context->getSource(); + switch ($key) { + case self::DYNAMIC_KEY_ATTACHMENT: + if (!$item->Attachment) { + return null; + } + + return $this->transformer->transformEntityRelation($context, $key, $item, 'Attachment'); + } + return null; + } + + public function collectLinks($context) + { + /** @var \XFMG\Entity\MediaItem $item */ + $item = $context->getSource(); + + $links = [ + self::LINK_PERMALINK => $this->buildPublicLink('media', $item), + ]; + + return $links; + } + + public function getMappings($context) + { + return [ + 'media_id' => self::KEY_ID, + 'media_type' => self::KEY_MEDIA_TYPE, + 'title' => self::KEY_TITLE, + 'description' => self::KEY_DESCRIPTION, + 'album_id' => self::KEY_ALBUM_ID, + 'user_id' => self::KEY_USER_ID, + 'username' => self::KEY_USERNAME, + 'media_date' => self::KEY_MEDIA_DATE, + 'last_edit_date' => self::KEY_LAST_EDIT_DATE, + 'likes' => self::KEY_LIKE_COUNT, + 'comment_count' => self::KEY_COMMENT_COUNT, + 'rating_count' => self::KEY_RATING_COUNT, + 'rating_avg' => self::KEY_RATING, + + self::DYNAMIC_KEY_ATTACHMENT, + ]; + } +} From e9ac7148a5210c8de5b7f0549fa8a046c6e29e32 Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 2 Dec 2018 13:44:55 +0700 Subject: [PATCH 04/26] include date fields for albums --- XFMG/Transform/Album.php | 2 ++ _output/templates/_metadata.json | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/XFMG/Transform/Album.php b/XFMG/Transform/Album.php index 1c7500b6..7f512370 100644 --- a/XFMG/Transform/Album.php +++ b/XFMG/Transform/Album.php @@ -48,6 +48,8 @@ public function getMappings($context) 'description' => self::KEY_DESCRIPTION, 'user_id' => self::KEY_USER_ID, 'username' => self::KEY_USERNAME, + 'create_date' => self::KEY_CREATE_DATE, + 'last_update_date' => self::KEY_LAST_UPDATE_DATE, 'media_count' => self::KEY_MEDIA_COUNT, 'likes' => self::KEY_LIKE_COUNT, 'comment_count' => self::KEY_COMMENT_COUNT, diff --git a/_output/templates/_metadata.json b/_output/templates/_metadata.json index b650a088..58f3208d 100644 --- a/_output/templates/_metadata.json +++ b/_output/templates/_metadata.json @@ -5,18 +5,18 @@ "hash": "0e5d7f1abae08a24192f5de9ccaa93e1" }, "admin/bdapi_entity_delete.html": { - "version_id": 2000015, - "version_string": "2.0.0 Alpha 5", + "version_id": 2000031, + "version_string": "2.0.0 Beta 1", "hash": "6b4d4c43aec7949d705dd36d09a53a34" }, "admin/bdapi_entity_edit.html": { - "version_id": 2000015, - "version_string": "2.0.0 Alpha 5", + "version_id": 2000031, + "version_string": "2.0.0 Beta 1", "hash": "de660feaf87fef084cf1385e462941e5" }, "admin/bdapi_entity_list.html": { - "version_id": 2000015, - "version_string": "2.0.0 Alpha 5", + "version_id": 2000031, + "version_string": "2.0.0 Beta 1", "hash": "fcaa4500cbacc33f1a01cf5a82bc0359" }, "admin/bdapi_log_view.html": { From 109d1e360ea13a3a37bf7fce4d91a5596b335f9e Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 2 Dec 2018 21:59:55 +0700 Subject: [PATCH 05/26] add actionPostIndex for media --- Controller/Conversation.php | 2 +- Controller/ConversationMessage.php | 2 +- Controller/Post.php | 2 +- Controller/Thread.php | 2 +- ControllerPlugin/Attachment.php | 12 ++++ XFMG/Controller/Media.php | 100 +++++++++++++++++++++++++++++ 6 files changed, 116 insertions(+), 4 deletions(-) diff --git a/Controller/Conversation.php b/Controller/Conversation.php index f1ae54f6..9b8258cc 100644 --- a/Controller/Conversation.php +++ b/Controller/Conversation.php @@ -115,7 +115,7 @@ public function actionPostAttachments() $attachmentPlugin = $this->plugin('Xfrocks\Api:Attachment'); $tempHash = $attachmentPlugin->getAttachmentTempHash($contentData); - return $attachmentPlugin->doUpload($tempHash, 'conversation_message', $contentData); + return $attachmentPlugin->doUploadAndRespond($tempHash, 'conversation_message', $contentData); } protected function assertViewableConversation($conversationId, array $extraWith = []) diff --git a/Controller/ConversationMessage.php b/Controller/ConversationMessage.php index 76a417b1..7f488ec4 100644 --- a/Controller/ConversationMessage.php +++ b/Controller/ConversationMessage.php @@ -208,7 +208,7 @@ public function actionPostAttachments() $attachmentPlugin = $this->plugin('Xfrocks\Api:Attachment'); $tempHash = $attachmentPlugin->getAttachmentTempHash($context); - return $attachmentPlugin->doUpload($tempHash, 'conversation_message', $context); + return $attachmentPlugin->doUploadAndRespond($tempHash, 'conversation_message', $context); } public function actionPostReport(ParameterBag $params) diff --git a/Controller/Post.php b/Controller/Post.php index 354a00a1..cc3089fa 100644 --- a/Controller/Post.php +++ b/Controller/Post.php @@ -278,7 +278,7 @@ public function actionPostAttachments() $attachmentPlugin = $this->plugin('Xfrocks\Api:Attachment'); $tempHash = $attachmentPlugin->getAttachmentTempHash($context); - return $attachmentPlugin->doUpload($tempHash, 'post', $context); + return $attachmentPlugin->doUploadAndRespond($tempHash, 'post', $context); } public function actionGetLikes(ParameterBag $params) diff --git a/Controller/Thread.php b/Controller/Thread.php index 9d4f4f5c..c6286c35 100644 --- a/Controller/Thread.php +++ b/Controller/Thread.php @@ -203,7 +203,7 @@ public function actionPostAttachments() $attachmentPlugin = $this->plugin('Xfrocks\Api:Attachment'); $tempHash = $attachmentPlugin->getAttachmentTempHash($context); - return $attachmentPlugin->doUpload($tempHash, 'post', $context); + return $attachmentPlugin->doUploadAndRespond($tempHash, 'post', $context); } public function actionGetFollowers(ParameterBag $params) diff --git a/ControllerPlugin/Attachment.php b/ControllerPlugin/Attachment.php index 12a0f2b5..c78292f8 100644 --- a/ControllerPlugin/Attachment.php +++ b/ControllerPlugin/Attachment.php @@ -45,7 +45,15 @@ public function doUpload($hash, $contentType, $context, $formField = 'file') if (!$attachment) { throw $this->controller->exception($this->controller->noPermission($error)); } + return $attachment; + } + + public function doUploadAndRespond($hash, $contentType, $context, $formField = 'file') + { + $attachment = $this->doUpload($hash, $contentType, $context, $formField); + /** @var AbstractController $controller */ + $controller = $this->controller; $lazyTransformer = $controller->transformEntityLazily($attachment); $lazyTransformer->addCallbackPreTransform(function ($context) use ($hash) { /** @var TransformContext $context */ @@ -80,6 +88,10 @@ public function getAttachmentTempHash(array $contentData = []) $prefix = sprintf('message%d', $contentData['message_id']); } elseif (!empty($contentData['conversation_id'])) { $prefix = sprintf('conversation%d', $contentData['conversation_id']); + } elseif (!empty($contentData['media_album_id'])) { + $prefix = sprintf('media_album%d', $contentData['media_album_id']); + } elseif (!empty($contentData['media_category_id'])) { + $prefix = sprintf('media_category%d', $contentData['media_category_id']); } /** @var Session $session */ diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index a23807de..7aa60e59 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -55,6 +55,106 @@ protected function actionSingle($itemId) return $this->api($data); } + public function actionPostIndex() + { + $params = $this + ->params() + ->define('album_id', 'uint', 'id of the target album') + ->define('category_id', 'uint', 'id of the target category') + ->define('title', 'str', 'title of the new media') + ->define('description', 'str', 'description of the new media') + ->defineAttachmentHash() + ->defineFile('file', 'binary data of the attachment'); + + if (!empty($params['album_id'])) { + $container = $this->assertViewableAlbum($params['album_id']); + $context = ['media_album_id' => $params['album_id']]; + } else if (!empty($params['category_id'])) { + $container = $this->assertViewableCategory($params['category_id']); + $context = ['media_category_id' => $params['category_id']]; + } else { + return $this->noPermission(); + } + + if (!$container->canAddMedia($error)) { + return $this->noPermission($error); + } + + /** @var \Xfrocks\Api\ControllerPlugin\Attachment $attachmentPlugin */ + $attachmentPlugin = $this->plugin('Xfrocks\Api:Attachment'); + $tempHash = $attachmentPlugin->getAttachmentTempHash($context); + $attachment = $attachmentPlugin->doUpload($tempHash, 'xfmg_media', $context); + + /** @var \XFMG\Entity\MediaTemp $tempMedia */ + $mediaTemp = $this->em()->findOne('XFMG:MediaTemp', ['attachment_id' => $attachment->attachment_id]); + + /** @var \XFMG\Service\Media\Creator $creator */ + $creator = $this->service('XFMG:Media\Creator', $mediaTemp); + $creator->setContainer($container); + $creator->setTitle($params['title'], $params['description']); + $creator->setAttachment($attachment->attachment_id, $attachment->temp_hash); + + $creator->checkForSpam(); + + if (!$creator->validate($errors)) { + return $this->error($errors); + } + + /** @var \XFMG\Entity\MediaItem $item */ + $item = $creator->save(); + + // Clear entity cache + $this->em()->detachEntity($item); + $this->em()->detachEntity($attachment); + + return $this->actionSingle($item->media_id); + } + /** + * @param int $albumId + * @param array $extraWith + * @return \XFMG\Entity\Album + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertViewableAlbum($albumId, array $extraWith = []) + { + /** @var \XFMG\Entity\Album $album */ + $album = $this->assertRecordExists( + 'XFMG:Album', + $albumId, + $extraWith, + 'xfmg_requested_album_not_found' + ); + + if (!$album->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $album; + } + + /** + * @param int $categoryId + * @param array $extraWith + * @return \XFMG\Entity\Category + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertViewableCategory($categoryId, array $extraWith = []) + { + /** @var \XFMG\Entity\Category $category */ + $category = $this->assertRecordExists( + 'XFMG:Category', + $categoryId, + $extraWith, + 'xfmg_requested_category_not_found' + ); + + if (!$category->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $category; + } + /** * @param int $mediaId * @param array $extraWith From c081fc3008d49898ed64f8def26c648e1224eaa8 Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 2 Dec 2018 22:10:52 +0700 Subject: [PATCH 06/26] add data to Transform/MediaItem --- XFMG/Transform/MediaItem.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/XFMG/Transform/MediaItem.php b/XFMG/Transform/MediaItem.php index f163c74b..e2f19dee 100644 --- a/XFMG/Transform/MediaItem.php +++ b/XFMG/Transform/MediaItem.php @@ -15,12 +15,14 @@ class MediaItem extends AbstractHandler implements AttachmentParent { const ATTACHMENT__DYNAMIC_KEY_ID = 'media_id'; const ATTACHMENT__LINK_MEDIA = 'media'; + const ATTACHMENT__LINK_THUMBNAIL = 'thumbnail'; const KEY_ID = 'media_id'; const KEY_MEDIA_TYPE = 'media_type'; const KEY_ALBUM_ID = 'album_id'; const KEY_TITLE = 'title'; const KEY_DESCRIPTION = 'description'; + const KEY_EXIF_DATA = 'exif_data'; const KEY_MEDIA_DATE = 'media_date'; const KEY_LAST_EDIT_DATE = 'last_edit_date'; const KEY_USER_ID = 'user_id'; @@ -31,6 +33,8 @@ class MediaItem extends AbstractHandler implements AttachmentParent const KEY_RATING = 'rating'; const KEY_COMMENT_COUNT = 'comment_count'; + const LINK_ALBUM = 'album'; + const DYNAMIC_KEY_ATTACHMENT = 'attachment'; public function attachmentCalculateDynamicValue($context, $key) @@ -45,8 +49,10 @@ public function attachmentCalculateDynamicValue($context, $key) public function attachmentCollectLinks($context, array &$links) { + /** @var \XFMG\Entity\MediaItem $item */ $item = $context->getParentSource(); $links[self::ATTACHMENT__LINK_MEDIA] = $this->buildApiLink('media', $item); + $links[self::ATTACHMENT__LINK_THUMBNAIL] = $item->getCurrentThumbnailUrl(); } public function attachmentCollectPermissions($context, array &$permissions) @@ -80,6 +86,7 @@ public function collectLinks($context) $links = [ self::LINK_PERMALINK => $this->buildPublicLink('media', $item), + self::LINK_ALBUM => $this->buildPublicLink('media/albums', $item), ]; return $links; @@ -92,6 +99,7 @@ public function getMappings($context) 'media_type' => self::KEY_MEDIA_TYPE, 'title' => self::KEY_TITLE, 'description' => self::KEY_DESCRIPTION, + 'exif_data' => self::KEY_EXIF_DATA, 'album_id' => self::KEY_ALBUM_ID, 'user_id' => self::KEY_USER_ID, 'username' => self::KEY_USERNAME, From 84344a58f355b5a173607737f7ccad71b9440ea3 Mon Sep 17 00:00:00 2001 From: datbth Date: Mon, 3 Dec 2018 20:23:12 +0700 Subject: [PATCH 07/26] fix routing --- XFMG/Data/Modules.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/XFMG/Data/Modules.php b/XFMG/Data/Modules.php index d4346c02..6160ba8d 100644 --- a/XFMG/Data/Modules.php +++ b/XFMG/Data/Modules.php @@ -10,11 +10,6 @@ public function __construct() { parent::__construct(); - $this->addController( - 'Xfrocks\Api\XFMG\Controller\Media', - 'media', - ':int/' - ); $this->addController( 'Xfrocks\Api\XFMG\Controller\Album', 'media', @@ -22,6 +17,11 @@ public function __construct() null, 'albums' ); + $this->addController( + 'Xfrocks\Api\XFMG\Controller\Media', + 'media', + ':int/' + ); $this->register('xfmg', 2018100101); } From 111af99b4b7315345b7b27ce1a29a0668b23ca2b Mon Sep 17 00:00:00 2001 From: datbth Date: Mon, 3 Dec 2018 20:23:22 +0700 Subject: [PATCH 08/26] add actionPutIndex for albums --- XFMG/Controller/Album.php | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index 54ae619c..50a03aa3 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -57,6 +57,48 @@ protected function actionSingle($albumId) return $this->api($data); } + public function actionPutIndex(ParameterBag $params) + { + $album = $this->assertViewableAlbum($params->album_id); + if (!$album->canEdit($error)) + { + return $this->noPermission($error); + } + + $params = $this->params() + ->define('title', 'str', 'new title of the album') + ->define('description', 'str', 'new description of the album') + ->define('view_privacy', 'str', 'public, members, or private', 'public') + ->define('view_users', 'str', 'specific users who can view this album', null) + ->define('add_privacy', 'str', 'public, members, or private', 'private') + ->define('add_users', 'str', 'specific users who can add media to this album', null) + ; + $title = $params['title']; + $description = $params['description']; + + /** @var \XFMG\Service\Album\Editor $editor */ + $editor = $this->service('XFMG:Album\Editor', $album); + + if (!empty($title) && !empty($description)) { + $editor->setTitle($title, $description); + } + if ($album->canChangePrivacy()) + { + $editor->setViewPrivacy($params['view_privacy'], $params['view_users']); + $editor->setAddPrivacy($params['add_privacy'], $params['add_users']); + } + + $editor->checkForSpam(); + + if (!$editor->validate($errors)) + { + return $this->error($errors); + } + $editor->save(); + + return $this->actionSingle($album->album_id); + } + /** * @param int $albumId * @param array $extraWith From 153a5a34a2046eceb5ac850eede6eaa963226233 Mon Sep 17 00:00:00 2001 From: datbth Date: Mon, 3 Dec 2018 20:50:59 +0700 Subject: [PATCH 09/26] add actionPostIndex for albums --- XFMG/Controller/Album.php | 83 +++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index 50a03aa3..cd2ad32a 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -57,6 +57,45 @@ protected function actionSingle($albumId) return $this->api($data); } + public function actionPostIndex(ParameterBag $params) + { + /** @var \XFMG\XF\Entity\User $visitor */ + $visitor = \XF::visitor(); + if (!$visitor->canCreateAlbum()) + { + return $this->noPermission(); + } + + $params = $this->defineAlbumParams() + ->define('category_id', 'uint', 'category of the new album') + ; + + /** @var \XFMG\Service\Album\Creator $creator */ + $creator = $this->service('XFMG:Album\Creator'); + + if (!empty($params['category_id'])) { + $category = $this->assertViewableCategory($params['category_id']); + if (!$category->canCreateAlbum()) + { + return $this->noPermission(); + } + $creator->setCategory($category); + } + $creator->setTitle($params['title'], $params['description']); + $creator->setViewPrivacy($params['view_privacy'], $params['view_users']); + $creator->setAddPrivacy($params['add_privacy'], $params['add_users']); + + $creator->checkForSpam(); + + if (!$creator->validate($errors)) + { + return $this->error($errors); + } + $album = $creator->save(); + + return $this->actionSingle($album->album_id); + } + public function actionPutIndex(ParameterBag $params) { $album = $this->assertViewableAlbum($params->album_id); @@ -65,14 +104,7 @@ public function actionPutIndex(ParameterBag $params) return $this->noPermission($error); } - $params = $this->params() - ->define('title', 'str', 'new title of the album') - ->define('description', 'str', 'new description of the album') - ->define('view_privacy', 'str', 'public, members, or private', 'public') - ->define('view_users', 'str', 'specific users who can view this album', null) - ->define('add_privacy', 'str', 'public, members, or private', 'private') - ->define('add_users', 'str', 'specific users who can add media to this album', null) - ; + $params = $this->defineAlbumParams(); $title = $params['title']; $description = $params['description']; @@ -121,4 +153,39 @@ protected function assertViewableAlbum($albumId, array $extraWith = []) return $album; } + + /** + * @param int $categoryId + * @param array $extraWith + * @return \XFMG\Entity\Category + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertViewableCategory($categoryId, array $extraWith = []) + { + /** @var \XFMG\Entity\Category $category */ + $category = $this->assertRecordExists( + 'XFMG:Category', + $categoryId, + $extraWith, + 'xfmg_requested_category_not_found' + ); + + if (!$category->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $category; + } + + protected function defineAlbumParams() + { + return $this->params() + ->define('title', 'str', 'new title of the album') + ->define('description', 'str', 'new description of the album') + ->define('view_privacy', 'str', 'public, members, or private', 'public') + ->define('view_users', 'str', 'specific users who can view this album', null) + ->define('add_privacy', 'str', 'public, members, or private', 'private') + ->define('add_users', 'str', 'specific users who can add media to this album', null) + ; + } } From 475373ca6eba9e80938165d8ace9184983d67548 Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 20:39:46 +0700 Subject: [PATCH 10/26] refactor getAttachmentTempHash to not require param attachment_hash --- ControllerPlugin/Attachment.php | 5 ++--- XFMG/Controller/Media.php | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ControllerPlugin/Attachment.php b/ControllerPlugin/Attachment.php index c78292f8..70002b0b 100644 --- a/ControllerPlugin/Attachment.php +++ b/ControllerPlugin/Attachment.php @@ -72,10 +72,9 @@ public function getAttachmentTempHash(array $contentData = []) $params = $controller->params(); $prefix = ''; - $inputHash = $params['attachment_hash']; - if (!empty($inputHash)) { - $prefix = sprintf('hash%s', $inputHash); + if (!empty($params['attachment_hash'])) { + $prefix = sprintf('hash%s', $params['attachment_hash']); } elseif (!empty($contentData['post_id'])) { $prefix = sprintf('post%d', $contentData['post_id']); } elseif (!empty($contentData['thread_id'])) { diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index 7aa60e59..da8326ed 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -63,7 +63,6 @@ public function actionPostIndex() ->define('category_id', 'uint', 'id of the target category') ->define('title', 'str', 'title of the new media') ->define('description', 'str', 'description of the new media') - ->defineAttachmentHash() ->defineFile('file', 'binary data of the attachment'); if (!empty($params['album_id'])) { From 1501ad13dea4f90cb826df499534b2e73d1a1139 Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 20:50:25 +0700 Subject: [PATCH 11/26] add actionPutIndex for media --- XFMG/Controller/Media.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index da8326ed..64230b08 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -108,6 +108,33 @@ public function actionPostIndex() return $this->actionSingle($item->media_id); } + + public function actionPutIndex(ParameterBag $params) + { + $item = $this->assertViewableItem($params->media_id); + if (!$item->canEdit($error)) { + return $this->noPermission($error); + } + + $params = $this->params() + ->define('title', 'str', 'title of the new media') + ->define('description', 'str', 'description of the new media'); + + /** @var \XFMG\Service\Media\Editor $editor */ + $editor = $this->service('XFMG:Media\Editor', $item); + $editor->setTitle($params['title'], $params['description']); + $editor->checkForSpam(); + + if (!$editor->validate($errors)) + { + return $this->error($errors); + } + /** @var \XFMG\Entity\MediaItem $item */ + $item = $editor->save(); + + return $this->actionSingle($item->media_id); + } + /** * @param int $albumId * @param array $extraWith From c66accb697965e178616f2abafc6bed9726cc52c Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:20:53 +0700 Subject: [PATCH 12/26] add actionDeleteIndex for albums --- XFMG/Controller/Album.php | 17 +++++++++++++++++ XFMG/Transform/Album.php | 15 +++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index cd2ad32a..264cd504 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -131,6 +131,23 @@ public function actionPutIndex(ParameterBag $params) return $this->actionSingle($album->album_id); } + public function actionDeleteIndex(ParameterBag $params) + { + $album = $this->assertViewableAlbum($params->album_id); + if (!$album->canDelete('soft', $error)) + { + return $this->noPermission($error); + } + + /** @var \XFMG\Service\Album\Deleter $deleter */ + $deleter = $this->service('XFMG:Album\Deleter', $album); + $deleter->delete('soft'); + + $this->em()->detachEntity($album); + + return $this->actionSingle($album->album_id); + } + /** * @param int $albumId * @param array $extraWith diff --git a/XFMG/Transform/Album.php b/XFMG/Transform/Album.php index 7f512370..ff00f0cc 100644 --- a/XFMG/Transform/Album.php +++ b/XFMG/Transform/Album.php @@ -27,6 +27,19 @@ class Album extends AbstractHandler const KEY_RATING = 'rating'; const KEY_COMMENT_COUNT = 'comment_count'; + const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; + + public function calculateDynamicValue($context, $key) + { + /** @var \XFMG\Entity\Album $album */ + $album = $context->getSource(); + switch ($key) { + case self::DYNAMIC_KEY_IS_DELETED: + return $album->album_state == 'deleted'; + } + return null; + } + public function collectLinks($context) { /** @var \XFMG\Entity\Album $album */ @@ -55,6 +68,8 @@ public function getMappings($context) 'comment_count' => self::KEY_COMMENT_COUNT, 'rating_count' => self::KEY_RATING_COUNT, 'rating_avg' => self::KEY_RATING, + + self::DYNAMIC_KEY_IS_DELETED, ]; } } \ No newline at end of file From 227980afe46e9d522d3eaed7d710a1b37d26760b Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:27:13 +0700 Subject: [PATCH 13/26] add some filters for album listing --- XFMG/Controller/Album.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index 264cd504..4b3eb27b 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -5,6 +5,7 @@ use XF\Mvc\ParameterBag; use Xfrocks\Api\Controller\AbstractController; +use Xfrocks\Api\Data\Params; use Xfrocks\Api\Util\PageNav; class Album extends AbstractController @@ -16,6 +17,8 @@ public function actionGetIndex(ParameterBag $params) } $params = $this->params() + ->define('category_id', 'int', '', -1) + ->define('user_id', 'uint') ->defineOrder([ 'natural' => ['create_date', 'asc'], 'natural_reverse' => ['create_date', 'desc'], @@ -30,6 +33,7 @@ public function actionGetIndex(ParameterBag $params) /** @var \XFMG\Finder\Album $finder */ $finder = $this->finder('XFMG:Album'); + $this->applyFilters($finder, $params); $params->sortFinder($finder); $params->limitFinderByPage($finder); @@ -205,4 +209,14 @@ protected function defineAlbumParams() ->define('add_users', 'str', 'specific users who can add media to this album', null) ; } + + protected function applyFilters(\XFMG\Finder\Album $finder, Params $params) + { + if ($params['category_id'] > -1) { + $finder->inCategory($params['category_id']); + } + if ($params['user_id'] > 0) { + $finder->byUser($params['user_id']); + } + } } From 08c7e5d16143d79f87ead66f4cc35dd93377fa36 Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:34:01 +0700 Subject: [PATCH 14/26] add actionDeleteIndex for media --- XFMG/Controller/Media.php | 15 +++++++++++++++ XFMG/Transform/MediaItem.php | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index 64230b08..c82094b0 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -135,6 +135,21 @@ public function actionPutIndex(ParameterBag $params) return $this->actionSingle($item->media_id); } + public function actionDeleteIndex(ParameterBag $params) + { + $item = $this->assertViewableItem($params->media_id); + if (!$item->canDelete('soft', $error)) + { + return $this->noPermission($error); + } + + /** @var \XFMG\Service\Media\Deleter $deleter */ + $deleter = $this->service('XFMG:Media\Deleter', $item); + $deleter->delete('soft'); + + return $this->actionSingle($item->media_id); + } + /** * @param int $albumId * @param array $extraWith diff --git a/XFMG/Transform/MediaItem.php b/XFMG/Transform/MediaItem.php index e2f19dee..25f6154c 100644 --- a/XFMG/Transform/MediaItem.php +++ b/XFMG/Transform/MediaItem.php @@ -36,6 +36,7 @@ class MediaItem extends AbstractHandler implements AttachmentParent const LINK_ALBUM = 'album'; const DYNAMIC_KEY_ATTACHMENT = 'attachment'; + const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; public function attachmentCalculateDynamicValue($context, $key) { @@ -75,6 +76,8 @@ public function calculateDynamicValue($context, $key) } return $this->transformer->transformEntityRelation($context, $key, $item, 'Attachment'); + case self::DYNAMIC_KEY_IS_DELETED: + return $item->media_state == 'deleted'; } return null; } @@ -111,6 +114,7 @@ public function getMappings($context) 'rating_avg' => self::KEY_RATING, self::DYNAMIC_KEY_ATTACHMENT, + self::DYNAMIC_KEY_IS_DELETED, ]; } } From 9a93e43ee315447b85f0ab9019bc9bea63b58156 Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:34:25 +0700 Subject: [PATCH 15/26] remove unnecessary detachEntity in album controller --- XFMG/Controller/Album.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index 4b3eb27b..e4d11cfa 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -147,8 +147,6 @@ public function actionDeleteIndex(ParameterBag $params) $deleter = $this->service('XFMG:Album\Deleter', $album); $deleter->delete('soft'); - $this->em()->detachEntity($album); - return $this->actionSingle($album->album_id); } From e4cccd9740526a783bae14a1cb52d445e9dbf84f Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:43:18 +0700 Subject: [PATCH 16/26] refactor controllers --- XFMG/Controller/AbstractController.php | 79 ++++++++++++++++++++++++++ XFMG/Controller/Album.php | 48 +--------------- XFMG/Controller/Media.php | 77 ++----------------------- 3 files changed, 84 insertions(+), 120 deletions(-) create mode 100644 XFMG/Controller/AbstractController.php diff --git a/XFMG/Controller/AbstractController.php b/XFMG/Controller/AbstractController.php new file mode 100644 index 00000000..377d6072 --- /dev/null +++ b/XFMG/Controller/AbstractController.php @@ -0,0 +1,79 @@ +assertRecordExists( + 'XFMG:Album', + $albumId, + $extraWith, + 'xfmg_requested_album_not_found' + ); + + if (!$album->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $album; + } + + /** + * @param int $categoryId + * @param array $extraWith + * @return \XFMG\Entity\Category + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertViewableCategory($categoryId, array $extraWith = []) + { + /** @var \XFMG\Entity\Category $category */ + $category = $this->assertRecordExists( + 'XFMG:Category', + $categoryId, + $extraWith, + 'xfmg_requested_category_not_found' + ); + + if (!$category->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $category; + } + + /** + * @param int $mediaId + * @param array $extraWith + * @return \XFMG\Entity\MediaItem + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertViewableMediaItem($mediaId, array $extraWith = []) + { + /** @var \XFMG\Entity\MediaItem $item */ + $item = $this->assertRecordExists( + 'XFMG:MediaItem', + $mediaId, + $extraWith, + 'xfmg_requested_media_item_not_found' + ); + + if (!$item->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $item; + } +} \ No newline at end of file diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index e4d11cfa..949ec0e4 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -3,8 +3,8 @@ namespace Xfrocks\Api\XFMG\Controller; +use AbstractController; use XF\Mvc\ParameterBag; -use Xfrocks\Api\Controller\AbstractController; use Xfrocks\Api\Data\Params; use Xfrocks\Api\Util\PageNav; @@ -150,52 +150,6 @@ public function actionDeleteIndex(ParameterBag $params) return $this->actionSingle($album->album_id); } - /** - * @param int $albumId - * @param array $extraWith - * @return \XFMG\Entity\Album - * @throws \XF\Mvc\Reply\Exception - */ - protected function assertViewableAlbum($albumId, array $extraWith = []) - { - /** @var \XFMG\Entity\Album $album */ - $album = $this->assertRecordExists( - 'XFMG:Album', - $albumId, - $extraWith, - 'xfmg_requested_album_not_found' - ); - - if (!$album->canView($error)) { - throw $this->exception($this->noPermission($error)); - } - - return $album; - } - - /** - * @param int $categoryId - * @param array $extraWith - * @return \XFMG\Entity\Category - * @throws \XF\Mvc\Reply\Exception - */ - protected function assertViewableCategory($categoryId, array $extraWith = []) - { - /** @var \XFMG\Entity\Category $category */ - $category = $this->assertRecordExists( - 'XFMG:Category', - $categoryId, - $extraWith, - 'xfmg_requested_category_not_found' - ); - - if (!$category->canView($error)) { - throw $this->exception($this->noPermission($error)); - } - - return $category; - } - protected function defineAlbumParams() { return $this->params() diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index c82094b0..bb97f030 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -3,8 +3,8 @@ namespace Xfrocks\Api\XFMG\Controller; +use AbstractController; use XF\Mvc\ParameterBag; -use Xfrocks\Api\Controller\AbstractController; use Xfrocks\Api\Util\PageNav; class Media extends AbstractController @@ -46,7 +46,7 @@ public function actionGetIndex(ParameterBag $params) protected function actionSingle($itemId) { - $item = $this->assertViewableItem($itemId); + $item = $this->assertViewableMediaItem($itemId); $data = [ 'item' => $this->transformEntityLazily($item) @@ -111,7 +111,7 @@ public function actionPostIndex() public function actionPutIndex(ParameterBag $params) { - $item = $this->assertViewableItem($params->media_id); + $item = $this->assertViewableMediaItem($params->media_id); if (!$item->canEdit($error)) { return $this->noPermission($error); } @@ -137,7 +137,7 @@ public function actionPutIndex(ParameterBag $params) public function actionDeleteIndex(ParameterBag $params) { - $item = $this->assertViewableItem($params->media_id); + $item = $this->assertViewableMediaItem($params->media_id); if (!$item->canDelete('soft', $error)) { return $this->noPermission($error); @@ -149,73 +149,4 @@ public function actionDeleteIndex(ParameterBag $params) return $this->actionSingle($item->media_id); } - - /** - * @param int $albumId - * @param array $extraWith - * @return \XFMG\Entity\Album - * @throws \XF\Mvc\Reply\Exception - */ - protected function assertViewableAlbum($albumId, array $extraWith = []) - { - /** @var \XFMG\Entity\Album $album */ - $album = $this->assertRecordExists( - 'XFMG:Album', - $albumId, - $extraWith, - 'xfmg_requested_album_not_found' - ); - - if (!$album->canView($error)) { - throw $this->exception($this->noPermission($error)); - } - - return $album; - } - - /** - * @param int $categoryId - * @param array $extraWith - * @return \XFMG\Entity\Category - * @throws \XF\Mvc\Reply\Exception - */ - protected function assertViewableCategory($categoryId, array $extraWith = []) - { - /** @var \XFMG\Entity\Category $category */ - $category = $this->assertRecordExists( - 'XFMG:Category', - $categoryId, - $extraWith, - 'xfmg_requested_category_not_found' - ); - - if (!$category->canView($error)) { - throw $this->exception($this->noPermission($error)); - } - - return $category; - } - - /** - * @param int $mediaId - * @param array $extraWith - * @return \XFMG\Entity\MediaItem - * @throws \XF\Mvc\Reply\Exception - */ - protected function assertViewableItem($mediaId, array $extraWith = []) - { - /** @var \XFMG\Entity\MediaItem $item */ - $item = $this->assertRecordExists( - 'XFMG:MediaItem', - $mediaId, - $extraWith, - 'xfmg_requested_media_item_not_found' - ); - - if (!$item->canView($error)) { - throw $this->exception($this->noPermission($error)); - } - - return $item; - } } From fa936f4e870ede718cc6f6ff60f3f95798a84581 Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:53:28 +0700 Subject: [PATCH 17/26] fix AbstractController --- XFMG/Controller/AbstractController.php | 2 ++ XFMG/Controller/Album.php | 1 - XFMG/Controller/Media.php | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/XFMG/Controller/AbstractController.php b/XFMG/Controller/AbstractController.php index 377d6072..ab631178 100644 --- a/XFMG/Controller/AbstractController.php +++ b/XFMG/Controller/AbstractController.php @@ -6,6 +6,8 @@ * Time: 21:39 */ +namespace Xfrocks\Api\XFMG\Controller; + abstract class AbstractController extends \Xfrocks\Api\Controller\AbstractController { /** diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index 949ec0e4..c0c78c5d 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -3,7 +3,6 @@ namespace Xfrocks\Api\XFMG\Controller; -use AbstractController; use XF\Mvc\ParameterBag; use Xfrocks\Api\Data\Params; use Xfrocks\Api\Util\PageNav; diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index bb97f030..394c90aa 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -3,7 +3,6 @@ namespace Xfrocks\Api\XFMG\Controller; -use AbstractController; use XF\Mvc\ParameterBag; use Xfrocks\Api\Util\PageNav; From d8538116d84e1b6d0cce23b71574a20d6ea0770c Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:54:39 +0700 Subject: [PATCH 18/26] add like actions for album --- XFMG/Controller/Album.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index c0c78c5d..08088940 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -149,6 +149,42 @@ public function actionDeleteIndex(ParameterBag $params) return $this->actionSingle($album->album_id); } + public function actionPostLikes(ParameterBag $params) + { + $album = $this->assertViewableAlbum($params->album_id); + if (!$album->canLike($error)) { + return $this->noPermission($error); + } + + $visitor = \XF::visitor(); + if (empty($album->Likes[$visitor->user_id])) { + /** @var \XF\Repository\LikedContent $likeRepo */ + $likeRepo = $this->repository('XF:LikedContent'); + $contentType = $album->getEntityContentType(); + $likeRepo->toggleLike($contentType, $album->album_id, $visitor); + } + + return $this->message(\XF::phrase('changes_saved')); + } + + public function actionDeleteLikes(ParameterBag $params) + { + $album = $this->assertViewableAlbum($params->album_id); + if (!$album->canLike($error)) { + return $this->noPermission($error); + } + + $visitor = \XF::visitor(); + if (!empty($album->Likes[$visitor->user_id])) { + /** @var \XF\Repository\LikedContent $likeRepo */ + $likeRepo = $this->repository('XF:LikedContent'); + $contentType = $album->getEntityContentType(); + $likeRepo->toggleLike($contentType, $album->album_id, $visitor); + } + + return $this->message(\XF::phrase('changes_saved')); + } + protected function defineAlbumParams() { return $this->params() From cb7f4a36d79f923adaa459890c0b976817bfc0ab Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 21:57:03 +0700 Subject: [PATCH 19/26] add like actions for media --- XFMG/Controller/Media.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index 394c90aa..505eed24 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -148,4 +148,40 @@ public function actionDeleteIndex(ParameterBag $params) return $this->actionSingle($item->media_id); } + + public function actionPostLikes(ParameterBag $params) + { + $item = $this->assertViewableMediaItem($params->media_id); + if (!$item->canLike($error)) { + return $this->noPermission($error); + } + + $visitor = \XF::visitor(); + if (empty($item->Likes[$visitor->user_id])) { + /** @var \XF\Repository\LikedContent $likeRepo */ + $likeRepo = $this->repository('XF:LikedContent'); + $contentType = $item->getEntityContentType(); + $likeRepo->toggleLike($contentType, $item->media_id, $visitor); + } + + return $this->message(\XF::phrase('changes_saved')); + } + + public function actionDeleteLikes(ParameterBag $params) + { + $item = $this->assertViewableMediaItem($params->media_id); + if (!$item->canLike($error)) { + return $this->noPermission($error); + } + + $visitor = \XF::visitor(); + if (!empty($item->Likes[$visitor->user_id])) { + /** @var \XF\Repository\LikedContent $likeRepo */ + $likeRepo = $this->repository('XF:LikedContent'); + $contentType = $item->getEntityContentType(); + $likeRepo->toggleLike($contentType, $item->media_id, $visitor); + } + + return $this->message(\XF::phrase('changes_saved')); + } } From 638f7a115fe8e46cfae2c8caded557d5f52bc941 Mon Sep 17 00:00:00 2001 From: datbth Date: Wed, 5 Dec 2018 22:03:20 +0700 Subject: [PATCH 20/26] add is_liked field to Transform\Album and Transform\Media --- XFMG/Transform/Album.php | 4 ++++ XFMG/Transform/MediaItem.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/XFMG/Transform/Album.php b/XFMG/Transform/Album.php index ff00f0cc..1f6bc030 100644 --- a/XFMG/Transform/Album.php +++ b/XFMG/Transform/Album.php @@ -27,6 +27,7 @@ class Album extends AbstractHandler const KEY_RATING = 'rating'; const KEY_COMMENT_COUNT = 'comment_count'; + const DYNAMIC_KEY_IS_LIKED = 'is_liked'; const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; public function calculateDynamicValue($context, $key) @@ -34,6 +35,8 @@ public function calculateDynamicValue($context, $key) /** @var \XFMG\Entity\Album $album */ $album = $context->getSource(); switch ($key) { + case self::DYNAMIC_KEY_IS_LIKED: + return $album->isLiked(); case self::DYNAMIC_KEY_IS_DELETED: return $album->album_state == 'deleted'; } @@ -69,6 +72,7 @@ public function getMappings($context) 'rating_count' => self::KEY_RATING_COUNT, 'rating_avg' => self::KEY_RATING, + self::DYNAMIC_KEY_IS_LIKED, self::DYNAMIC_KEY_IS_DELETED, ]; } diff --git a/XFMG/Transform/MediaItem.php b/XFMG/Transform/MediaItem.php index 25f6154c..39fc9ebe 100644 --- a/XFMG/Transform/MediaItem.php +++ b/XFMG/Transform/MediaItem.php @@ -36,6 +36,7 @@ class MediaItem extends AbstractHandler implements AttachmentParent const LINK_ALBUM = 'album'; const DYNAMIC_KEY_ATTACHMENT = 'attachment'; + const DYNAMIC_KEY_IS_LIKED = 'is_liked'; const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; public function attachmentCalculateDynamicValue($context, $key) @@ -76,6 +77,8 @@ public function calculateDynamicValue($context, $key) } return $this->transformer->transformEntityRelation($context, $key, $item, 'Attachment'); + case self::DYNAMIC_KEY_IS_LIKED: + return $item->isLiked(); case self::DYNAMIC_KEY_IS_DELETED: return $item->media_state == 'deleted'; } @@ -114,6 +117,7 @@ public function getMappings($context) 'rating_avg' => self::KEY_RATING, self::DYNAMIC_KEY_ATTACHMENT, + self::DYNAMIC_KEY_IS_LIKED, self::DYNAMIC_KEY_IS_DELETED, ]; } From a3d27f3654719b79a7ceb83983ecd2ea3ec1e5a0 Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 9 Dec 2018 10:31:47 +0700 Subject: [PATCH 21/26] implement follow APIs for albums --- XFMG/Controller/Album.php | 47 +++++++++++++++++++++++++++++++++++++++ XFMG/Transform/Album.php | 4 ++++ 2 files changed, 51 insertions(+) diff --git a/XFMG/Controller/Album.php b/XFMG/Controller/Album.php index 08088940..82707b2e 100644 --- a/XFMG/Controller/Album.php +++ b/XFMG/Controller/Album.php @@ -96,6 +96,12 @@ public function actionPostIndex(ParameterBag $params) } $album = $creator->save(); + $creator->sendNotifications(); + + /** @var \XFMG\Repository\AlbumWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:AlbumWatch'); + $watchRepo->autoWatchAlbum($album, \XF::visitor(), true); + return $this->actionSingle($album->album_id); } @@ -185,6 +191,47 @@ public function actionDeleteLikes(ParameterBag $params) return $this->message(\XF::phrase('changes_saved')); } + public function actionPostFollowers(ParameterBag $params) + { + $album = $this->assertViewableAlbum($params->album_id); + if (!$album->canWatch($error)) { + return $this->noPermission($error); + } + + $params = $this->params() + ->define('notify_on', 'str', 'comment|media|media_comment', 'media_comment') + ->define('send_alert', 'bool', '', true) + ->define('send_email', 'bool', '', true) + ; + + $action = 'watch'; + $config = [ + 'notify_on' => $params['notify_on'], + 'send_alert' => $params['send_alert'], + 'send_email' => $params['send_email'], + ]; + $visitor = \XF::visitor(); + + /** @var \XFMG\Repository\AlbumWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:AlbumWatch'); + $watchRepo->setWatchState($album, $visitor, $action, $config); + + return $this->message(\XF::phrase('changes_saved')); + } + + public function actionDeleteFollowers(ParameterBag $params) + { + $album = $this->assertViewableAlbum($params->album_id); + + $visitor = \XF::visitor(); + + /** @var \XFMG\Repository\AlbumWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:AlbumWatch'); + $watchRepo->setWatchState($album, $visitor, 'delete'); + + return $this->message(\XF::phrase('changes_saved')); + } + protected function defineAlbumParams() { return $this->params() diff --git a/XFMG/Transform/Album.php b/XFMG/Transform/Album.php index 1f6bc030..4e772085 100644 --- a/XFMG/Transform/Album.php +++ b/XFMG/Transform/Album.php @@ -28,6 +28,7 @@ class Album extends AbstractHandler const KEY_COMMENT_COUNT = 'comment_count'; const DYNAMIC_KEY_IS_LIKED = 'is_liked'; + const DYNAMIC_KEY_IS_FOLLOWED = 'is_followed'; const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; public function calculateDynamicValue($context, $key) @@ -37,6 +38,8 @@ public function calculateDynamicValue($context, $key) switch ($key) { case self::DYNAMIC_KEY_IS_LIKED: return $album->isLiked(); + case self::DYNAMIC_KEY_IS_FOLLOWED: + return !empty($album->Watch[\XF::visitor()->user_id]); case self::DYNAMIC_KEY_IS_DELETED: return $album->album_state == 'deleted'; } @@ -73,6 +76,7 @@ public function getMappings($context) 'rating_avg' => self::KEY_RATING, self::DYNAMIC_KEY_IS_LIKED, + self::DYNAMIC_KEY_IS_FOLLOWED, self::DYNAMIC_KEY_IS_DELETED, ]; } From 0ef09b1640d0eeeb532c8e79bf8c077c99fc01a0 Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 9 Dec 2018 10:41:11 +0700 Subject: [PATCH 22/26] implement follow APIs for media --- XFMG/Controller/Media.php | 44 ++++++++++++++++++++++++++++++++++++ XFMG/Transform/MediaItem.php | 4 ++++ 2 files changed, 48 insertions(+) diff --git a/XFMG/Controller/Media.php b/XFMG/Controller/Media.php index 505eed24..7dbc033e 100644 --- a/XFMG/Controller/Media.php +++ b/XFMG/Controller/Media.php @@ -101,6 +101,10 @@ public function actionPostIndex() /** @var \XFMG\Entity\MediaItem $item */ $item = $creator->save(); + /** @var \XFMG\Repository\MediaWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:MediaWatch'); + $watchRepo->autoWatchMediaItem($item, \XF::visitor(), true); + // Clear entity cache $this->em()->detachEntity($item); $this->em()->detachEntity($attachment); @@ -184,4 +188,44 @@ public function actionDeleteLikes(ParameterBag $params) return $this->message(\XF::phrase('changes_saved')); } + + public function actionPostFollowers(ParameterBag $params) + { + $item = $this->assertViewableMediaItem($params->media_id); + if (!$item->canWatch($error)) { + return $this->noPermission($error); + } + + $params = $this->params() + ->define('send_alert', 'bool', '', true) + ->define('send_email', 'bool', '', true) + ; + + $action = 'watch'; + $config = [ + 'notify_on' => 'comment', + 'send_alert' => $params['send_alert'], + 'send_email' => $params['send_email'], + ]; + $visitor = \XF::visitor(); + + /** @var \XFMG\Repository\MediaWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:MediaWatch'); + $watchRepo->setWatchState($item, $visitor, $action, $config); + + return $this->message(\XF::phrase('changes_saved')); + } + + public function actionDeleteFollowers(ParameterBag $params) + { + $item = $this->assertViewableMediaItem($params->media_id); + + $visitor = \XF::visitor(); + + /** @var \XFMG\Repository\MediaWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:MediaWatch'); + $watchRepo->setWatchState($item, $visitor, 'delete'); + + return $this->message(\XF::phrase('changes_saved')); + } } diff --git a/XFMG/Transform/MediaItem.php b/XFMG/Transform/MediaItem.php index 39fc9ebe..5f7ac9c8 100644 --- a/XFMG/Transform/MediaItem.php +++ b/XFMG/Transform/MediaItem.php @@ -37,6 +37,7 @@ class MediaItem extends AbstractHandler implements AttachmentParent const DYNAMIC_KEY_ATTACHMENT = 'attachment'; const DYNAMIC_KEY_IS_LIKED = 'is_liked'; + const DYNAMIC_KEY_IS_FOLLOWED = 'is_followed'; const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; public function attachmentCalculateDynamicValue($context, $key) @@ -79,6 +80,8 @@ public function calculateDynamicValue($context, $key) return $this->transformer->transformEntityRelation($context, $key, $item, 'Attachment'); case self::DYNAMIC_KEY_IS_LIKED: return $item->isLiked(); + case self::DYNAMIC_KEY_IS_FOLLOWED: + return !empty($item->Watch[\XF::visitor()->user_id]); case self::DYNAMIC_KEY_IS_DELETED: return $item->media_state == 'deleted'; } @@ -118,6 +121,7 @@ public function getMappings($context) self::DYNAMIC_KEY_ATTACHMENT, self::DYNAMIC_KEY_IS_LIKED, + self::DYNAMIC_KEY_IS_FOLLOWED, self::DYNAMIC_KEY_IS_DELETED, ]; } From 09979fe41e0f9085d62b82773e5174a79caad93a Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 9 Dec 2018 10:46:27 +0700 Subject: [PATCH 23/26] add links to API response for album and media --- XFMG/Transform/Album.php | 3 +++ XFMG/Transform/MediaItem.php | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/XFMG/Transform/Album.php b/XFMG/Transform/Album.php index 4e772085..bc18f664 100644 --- a/XFMG/Transform/Album.php +++ b/XFMG/Transform/Album.php @@ -53,6 +53,9 @@ public function collectLinks($context) $links = [ self::LINK_PERMALINK => $this->buildPublicLink('media/albums', $album), + self::LINK_DETAIL => $this->buildApiLink('media/albums', $album), + self::LINK_LIKES => $this->buildApiLink('media/albums/likes', $album), + self::LINK_FOLLOWERS => $this->buildApiLink('media/albums/followers', $album), ]; return $links; diff --git a/XFMG/Transform/MediaItem.php b/XFMG/Transform/MediaItem.php index 5f7ac9c8..d482552a 100644 --- a/XFMG/Transform/MediaItem.php +++ b/XFMG/Transform/MediaItem.php @@ -95,7 +95,10 @@ public function collectLinks($context) $links = [ self::LINK_PERMALINK => $this->buildPublicLink('media', $item), - self::LINK_ALBUM => $this->buildPublicLink('media/albums', $item), + self::LINK_DETAIL => $this->buildApiLink('media', $item), + self::LINK_LIKES => $this->buildApiLink('media/likes', $item), + self::LINK_FOLLOWERS => $this->buildApiLink('media/followers', $item), + self::LINK_ALBUM => $this->buildPublicLink('media', $item), ]; return $links; From da7a60299f5317fbda56244aace25ef48e014160 Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 9 Dec 2018 11:28:28 +0700 Subject: [PATCH 24/26] add permissions data to API response for albums and media --- XFMG/Transform/Album.php | 20 ++++++++++++++++++++ XFMG/Transform/MediaItem.php | 22 ++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/XFMG/Transform/Album.php b/XFMG/Transform/Album.php index bc18f664..b5565b80 100644 --- a/XFMG/Transform/Album.php +++ b/XFMG/Transform/Album.php @@ -31,6 +31,9 @@ class Album extends AbstractHandler const DYNAMIC_KEY_IS_FOLLOWED = 'is_followed'; const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; + const PERM_ADD_MEDIA = 'add_media'; + const PERM_COMMENT = 'comment'; + public function calculateDynamicValue($context, $key) { /** @var \XFMG\Entity\Album $album */ @@ -46,6 +49,23 @@ public function calculateDynamicValue($context, $key) return null; } + public function collectPermissions($context) + { + /** @var \XFMG\Entity\Album $album */ + $album = $context->getSource(); + + $permissions = [ + self::PERM_DELETE => $album->canDelete(), + self::PERM_EDIT => $album->canEdit(), + self::PERM_LIKE => $album->canLike(), + self::PERM_FOLLOW => $album->canWatch(), + self::PERM_ADD_MEDIA => $album->canAddMedia(), + self::PERM_COMMENT => $album->canAddComment(), + ]; + + return $permissions; + } + public function collectLinks($context) { /** @var \XFMG\Entity\Album $album */ diff --git a/XFMG/Transform/MediaItem.php b/XFMG/Transform/MediaItem.php index d482552a..51a0eada 100644 --- a/XFMG/Transform/MediaItem.php +++ b/XFMG/Transform/MediaItem.php @@ -33,13 +33,15 @@ class MediaItem extends AbstractHandler implements AttachmentParent const KEY_RATING = 'rating'; const KEY_COMMENT_COUNT = 'comment_count'; - const LINK_ALBUM = 'album'; - const DYNAMIC_KEY_ATTACHMENT = 'attachment'; const DYNAMIC_KEY_IS_LIKED = 'is_liked'; const DYNAMIC_KEY_IS_FOLLOWED = 'is_followed'; const DYNAMIC_KEY_IS_DELETED = 'is_deleted'; + const LINK_ALBUM = 'album'; + + const PERM_COMMENT = 'comment'; + public function attachmentCalculateDynamicValue($context, $key) { switch ($key) { @@ -104,6 +106,22 @@ public function collectLinks($context) return $links; } + public function collectPermissions($context) + { + /** @var \XFMG\Entity\MediaItem $item */ + $item = $context->getSource(); + + $permissions = [ + self::PERM_DELETE => $item->canDelete(), + self::PERM_EDIT => $item->canEdit(), + self::PERM_LIKE => $item->canLike(), + self::PERM_FOLLOW => $item->canWatch(), + self::PERM_COMMENT => $item->canAddComment(), + ]; + + return $permissions; + } + public function getMappings($context) { return [ From 9bbccf1d9709d19f07f98f8c8702e163cc9d5fff Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 9 Dec 2018 12:11:04 +0700 Subject: [PATCH 25/26] add basic APIs for comments --- XFMG/Controller/Comment.php | 231 ++++++++++++++++++++++++++++++++++++ XFMG/Data/Modules.php | 7 ++ XFMG/Transform/Comment.php | 104 ++++++++++++++++ 3 files changed, 342 insertions(+) create mode 100644 XFMG/Controller/Comment.php create mode 100644 XFMG/Transform/Comment.php diff --git a/XFMG/Controller/Comment.php b/XFMG/Controller/Comment.php new file mode 100644 index 00000000..af09359b --- /dev/null +++ b/XFMG/Controller/Comment.php @@ -0,0 +1,231 @@ +comment_id) { + return $this->actionSingle($params->comment_id); + } + + $params = $this->params() + ->define('media_id', 'int', '') + ->define('album_id', 'int', '') + ->defineOrder([ + 'natural' => ['comment_date', 'asc'], + 'natural_reverse' => ['comment_date', 'desc'], + ]) + ->definePageNav(); + + $content = $this->assertViewableContent($params); + + /** @var \XFMG\Finder\Comment $finder */ + $finder = $this->finder('XFMG:Comment'); + $finder->forContent($content); + $params->sortFinder($finder); + $params->limitFinderByPage($finder); + + $total = $finder->total(); + $comments = $total > 0 ? $this->transformFinderLazily($finder) : []; + + $data = [ + 'comments' => $comments, + 'comments_total' => $total + ]; + + PageNav::addLinksToData($data, $params, $total, 'comments'); + + return $this->api($data); + } + + protected function actionSingle($commentId) + { + $comment = $this->assertViewableComment($commentId); + + $data = [ + 'comment' => $this->transformEntityLazily($comment) + ]; + + return $this->api($data); + } + + public function actionPostIndex(ParameterBag $params) + { + $params = $this->params() + ->define('media_id', 'int', '') + ->define('album_id', 'int', '') + ->define('message', 'str', 'comment message') + ; + + $content = $this->assertViewableAndCommentableContent($params); + + /** @var \XFMG\Service\Comment\Creator $creator */ + $creator = $this->service('XFMG:Comment\Creator', $content); + $creator->setMessage($params['message']); + $creator->checkForSpam(); + + if (!$creator->validate($errors)) + { + return $this->error($errors); + } + /** @var \XFMG\Entity\Comment $comment */ + $comment = $creator->save(); + + $this->finalizeCommentCreate($creator); + + return $this->actionSingle($comment->comment_id); + } + + public function actionPutIndex(ParameterBag $params) + { + $comment = $this->assertViewableComment($params->comment_id); + if (!$comment->canEdit($error)) { + return $this->noPermission($error); + } + + $params = $this->params() + ->define('message', 'str', 'comment message') + ; + + /** @var \XFMG\Service\Comment\Editor $editor */ + $editor = $this->service('XFMG:Comment\Editor', $comment); + $editor->setMessage($params['message']); + $editor->checkForSpam(); + + if (!$editor->validate($errors)) + { + return $this->error($errors); + } + /** @var \XFMG\Entity\Comment $comment */ + $comment = $editor->save(); + + return $this->actionSingle($comment->comment_id); + } + + public function actionDeleteIndex(ParameterBag $params) + { + $comment = $this->assertViewableComment($params->comment_id); + if (!$comment->canDelete('soft', $error)) { + return $this->noPermission($error); + } + + /** @var \XFMG\Service\Comment\Deleter $deleter */ + $deleter = $this->service('XFMG:Comment\Deleter', $comment); + $deleter->delete('soft'); + + return $this->actionSingle($comment->comment_id); + } + + public function actionPostLikes(ParameterBag $params) + { + $comment = $this->assertViewableComment($params->comment_id); + if (!$comment->canLike($error)) { + return $this->noPermission($error); + } + + if (!$comment->isLiked()) { + /** @var \XF\Repository\LikedContent $likeRepo */ + $likeRepo = $this->repository('XF:LikedContent'); + $contentType = $comment->getEntityContentType(); + $likeRepo->toggleLike($contentType, $comment->comment_id, \XF::visitor()); + } + + return $this->message(\XF::phrase('changes_saved')); + } + + public function actionDeleteLikes(ParameterBag $params) + { + $comment = $this->assertViewableComment($params->comment_id); + if (!$comment->canLike($error)) { + return $this->noPermission($error); + } + + if ($comment->isLiked()) { + /** @var \XF\Repository\LikedContent $likeRepo */ + $likeRepo = $this->repository('XF:LikedContent'); + $contentType = $comment->getEntityContentType(); + $likeRepo->toggleLike($contentType, $comment->comment_id, \XF::visitor()); + } + + return $this->message(\XF::phrase('changes_saved')); + } + + protected function finalizeCommentCreate(\XFMG\Service\Comment\Creator $creator) + { + $creator->sendNotifications(); + + $content = $creator->getContent(); + $content->draft_comment->delete(); + + $visitor = \XF::visitor(); + + if ($visitor->user_id != $content->user_id) + { + if ($content->content_type == 'xfmg_media') + { + /** @var \XFMG\Repository\MediaWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:MediaWatch'); + $watchRepo->autoWatchMediaItem($content, $visitor); + } + else + { + /** @var \XFMG\Repository\AlbumWatch $watchRepo */ + $watchRepo = $this->repository('XFMG:AlbumWatch'); + $watchRepo->autoWatchAlbum($content, $visitor); + } + } + } + + protected function assertViewableContent(Params $params) + { + if ($params['media_id'] > 0) { + $content = $this->assertViewableMediaItem($params['media_id']); + } elseif ($params['album_id'] > 0) { + $content = $this->assertViewableAlbum($params['album_id']); + } else { + throw $this->exception($this->noPermission()); + } + if (!$content->canViewComments($error)) { + throw $this->exception($this->noPermission($error)); + } + return $content; + } + + protected function assertViewableAndCommentableContent(Params $params) + { + $content = $this->assertViewableContent($params); + if (!$content->canAddComment($error)) { + throw $this->exception($this->noPermission($error)); + } + return $content; + } + + protected function assertViewableComment($commentId, array $extraWith = []) + { + /** @var \XFMG\Entity\Comment $comment */ + $comment = $this->assertRecordExists( + 'XFMG:Comment', + $commentId, + $extraWith, + 'xfmg_requested_comment_not_found' + ); + + if (!$comment->canView($error)) { + throw $this->exception($this->noPermission($error)); + } + + return $comment; + } +} diff --git a/XFMG/Data/Modules.php b/XFMG/Data/Modules.php index 6160ba8d..241fa537 100644 --- a/XFMG/Data/Modules.php +++ b/XFMG/Data/Modules.php @@ -17,6 +17,13 @@ public function __construct() null, 'albums' ); + $this->addController( + 'Xfrocks\Api\XFMG\Controller\Comment', + 'media', + 'comments/:int/', + null, + 'comments' + ); $this->addController( 'Xfrocks\Api\XFMG\Controller\Media', 'media', diff --git a/XFMG/Transform/Comment.php b/XFMG/Transform/Comment.php new file mode 100644 index 00000000..2a1867ef --- /dev/null +++ b/XFMG/Transform/Comment.php @@ -0,0 +1,104 @@ +getSource(); + + switch ($key) { + case self::DYNAMIC_KEY_BODY_HTML: + return $this->renderBbCodeHtml($key, $comment->message, $comment); + case self::DYNAMIC_KEY_BODY_PLAIN: + return $this->renderBbCodePlainText($comment->message); + case self::DYNAMIC_KEY_IS_DELETED: + return $comment->comment_state === 'deleted'; + case self::DYNAMIC_KEY_IS_IGNORED: + if (!\XF::visitor()->user_id) { + return false; + } + + return $comment->isIgnored(); + case self::DYNAMIC_KEY_IS_LIKED: + return $comment->isLiked(); + } + + return null; + } + + public function collectPermissions($context) + { + /** @var \XFMG\Entity\Comment $comment */ + $comment = $context->getSource(); + + $permissions = [ + self::PERM_DELETE => $comment->canDelete(), + self::PERM_EDIT => $comment->canEdit(), + self::PERM_LIKE => $comment->canLike(), + ]; + + return $permissions; + } + + public function collectLinks($context) + { + /** @var \XFMG\Entity\Comment $comment */ + $comment = $context->getSource(); + + $links = [ + self::LINK_DETAIL => $this->buildApiLink('media/comments', $comment), + self::LINK_LIKES => $this->buildApiLink('media/comments/likes', $comment), + ]; + + return $links; + } + + public function getMappings($context) + { + return [ + 'comment_id' => self::KEY_ID, + 'content_id' => self::KEY_CONTENT_ID, + 'content_type' => self::KEY_CONTENT_TYPE, + 'message' => self::KEY_BODY, + 'comment_date' => self::KEY_COMMENT_DATE, + 'last_edit_date' => self::KEY_LAST_EDIT_DATE, + 'user_id' => self::KEY_USER_ID, + 'username' => self::KEY_USERNAME, + 'likes' => self::KEY_LIKE_COUNT, + + self::DYNAMIC_KEY_BODY_HTML, + self::DYNAMIC_KEY_BODY_PLAIN, + self::DYNAMIC_KEY_IS_DELETED, + self::DYNAMIC_KEY_IS_LIKED, + ]; + } +} From 30af829a64e3a5bd5fc1e551f5889c724d115804 Mon Sep 17 00:00:00 2001 From: datbth Date: Sun, 9 Dec 2018 12:14:57 +0700 Subject: [PATCH 26/26] revert changes in _output/templates/_metadata.json --- _output/templates/_metadata.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_output/templates/_metadata.json b/_output/templates/_metadata.json index 58f3208d..b650a088 100644 --- a/_output/templates/_metadata.json +++ b/_output/templates/_metadata.json @@ -5,18 +5,18 @@ "hash": "0e5d7f1abae08a24192f5de9ccaa93e1" }, "admin/bdapi_entity_delete.html": { - "version_id": 2000031, - "version_string": "2.0.0 Beta 1", + "version_id": 2000015, + "version_string": "2.0.0 Alpha 5", "hash": "6b4d4c43aec7949d705dd36d09a53a34" }, "admin/bdapi_entity_edit.html": { - "version_id": 2000031, - "version_string": "2.0.0 Beta 1", + "version_id": 2000015, + "version_string": "2.0.0 Alpha 5", "hash": "de660feaf87fef084cf1385e462941e5" }, "admin/bdapi_entity_list.html": { - "version_id": 2000031, - "version_string": "2.0.0 Beta 1", + "version_id": 2000015, + "version_string": "2.0.0 Alpha 5", "hash": "fcaa4500cbacc33f1a01cf5a82bc0359" }, "admin/bdapi_log_view.html": {