diff --git a/appinfo/routes.php b/appinfo/routes.php index fcf0748d0..320e67bcb 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -120,15 +120,16 @@ ['name' => 'preferences#get_calendars', 'url' => '/calendars', 'verb' => 'GET'], // REST-API calls + ['name' => 'base_api#preflighted_cors', 'url' => '/api/v1.0/{path}', 'verb' => 'OPTIONS', 'requirements' => array('path' => '.+')], ['name' => 'poll_api#list', 'url' => '/api/v1.0/polls', 'verb' => 'GET'], ['name' => 'poll_api#transfer_polls', 'url' => '/api/v1.0/polls/transfer/{sourceUser}/{destinationUser}', 'verb' => 'PUT'], + ['name' => 'poll_api#transfer_poll', 'url' => '/api/v1.0/poll/{pollId}/transfer/{destinationUser}', 'verb' => 'PUT'], ['name' => 'poll_api#add', 'url' => '/api/v1.0/poll', 'verb' => 'POST'], ['name' => 'poll_api#get', 'url' => '/api/v1.0/poll/{pollId}', 'verb' => 'GET'], ['name' => 'poll_api#update', 'url' => '/api/v1.0/poll/{pollId}', 'verb' => 'PUT'], ['name' => 'poll_api#delete', 'url' => '/api/v1.0/poll/{pollId}', 'verb' => 'DELETE'], - ['name' => 'poll_api#switchDeleted', 'url' => '/api/v1.0/poll/{pollId}/switchdeleted', 'verb' => 'PUT'], + ['name' => 'poll_api#toggleArchive', 'url' => '/api/v1.0/poll/{pollId}/toggleArchive', 'verb' => 'PUT'], ['name' => 'poll_api#clone', 'url' => '/api/v1.0/poll/{pollId}/clone', 'verb' => 'POST'], - ['name' => 'poll_api#trash', 'url' => '/api/v1.0/poll/{pollId}/trash', 'verb' => 'POST'], ['name' => 'poll_api#get_participants_email_addresses', 'url' => '/api/v1.0/poll/{pollId}/addresses', 'verb' => 'GET'], ['name' => 'poll_api#enum', 'url' => '/api/v1.0/enum/poll', 'verb' => 'GET'], @@ -140,20 +141,20 @@ ['name' => 'option_api#confirm', 'url' => '/api/v1.0/option/{optionId}/confirm', 'verb' => 'PUT'], ['name' => 'vote_api#list', 'url' => '/api/v1.0/poll/{pollId}/votes', 'verb' => 'GET'], - ['name' => 'vote_api#set', 'url' => '/api/v1.0/vote', 'verb' => 'POST'], + ['name' => 'vote_api#set', 'url' => '/api/v1.0/option/{optionId}/vote/{answer}', 'verb' => 'PUT'], ['name' => 'share_api#list', 'url' => '/api/v1.0/poll/{pollId}/shares', 'verb' => 'GET'], ['name' => 'share_api#get', 'url' => '/api/v1.0/share/{token}', 'verb' => 'GET'], - ['name' => 'share_api#add', 'url' => '/api/v1.0/share', 'verb' => 'POST'], + ['name' => 'share_api#add', 'url' => '/api/v1.0/poll/{pollId}/share/{type}', 'verb' => 'POST'], ['name' => 'share_api#delete', 'url' => '/api/v1.0/share/{token}', 'verb' => 'DELETE'], - ['name' => 'share_api#sendInvitation', 'url' => '/api/v1.0/share/send/{token}', 'verb' => 'POST'], + ['name' => 'share_api#sendInvitation', 'url' => '/api/v1.0/share/send/{token}', 'verb' => 'PUT'], ['name' => 'subscription_api#get', 'url' => '/api/v1.0/poll/{pollId}/subscription', 'verb' => 'GET'], ['name' => 'subscription_api#subscribe', 'url' => '/api/v1.0/poll/{pollId}/subscription', 'verb' => 'PUT'], ['name' => 'subscription_api#unsubscribe', 'url' => '/api/v1.0/poll/{pollId}/subscription', 'verb' => 'DELETE'], ['name' => 'comment_api#list', 'url' => '/api/v1.0/poll/{pollId}/comments', 'verb' => 'GET'], - ['name' => 'comment_api#add', 'url' => '/api/v1.0/comment', 'verb' => 'POST'], + ['name' => 'comment_api#add', 'url' => '/api/v1.0/poll/{pollId}/comment', 'verb' => 'POST'], ['name' => 'comment_api#delete', 'url' => '/api/v1.0/comment/{commentId}', 'verb' => 'DELETE'], ] diff --git a/lib/Controller/CommentApiController.php b/lib/Controller/CommentApiController.php index ce94fa667..0d39ad5f9 100644 --- a/lib/Controller/CommentApiController.php +++ b/lib/Controller/CommentApiController.php @@ -46,7 +46,7 @@ public function __construct( */ public function list(int $pollId): JSONResponse { return $this->response(fn () => [ - 'comments' => $this->commentService->list($$this->acl->setPollId($pollId)) + 'comments' => $this->commentService->list($this->acl->setPollId($pollId)) ]); } @@ -56,9 +56,9 @@ public function list(int $pollId): JSONResponse { * @CORS * @NoCSRFRequired */ - public function add(int $pollId, string $message): JSONResponse { + public function add(int $pollId, string $comment): JSONResponse { return $this->response(fn () => [ - 'comment' => $this->commentService->add($message, $this->acl->setPollId($pollId, Acl::PERMISSION_COMMENT_ADD)) + 'comment' => $this->commentService->add($comment, $this->acl->setPollId($pollId, Acl::PERMISSION_COMMENT_ADD)) ]); } @@ -69,10 +69,13 @@ public function add(int $pollId, string $message): JSONResponse { * @NoCSRFRequired */ public function delete(int $commentId): JSONResponse { - $comment = $this->commentService->get($commentId); - return $this->responseDeleteTolerant(fn () => [ - 'comment' => $this->commentService->delete($comment, $this->acl->setPollId($comment->getPollId())) + 'comment' => $this->deleteComment($commentId) ]); } + + private function deleteComment($commentId) { + $comment = $this->commentService->get($commentId); + return $this->commentService->delete($comment, $this->acl->setPollId($comment->getPollId())); + } } diff --git a/lib/Controller/PollApiController.php b/lib/Controller/PollApiController.php index eb3c879c3..9246b5d9c 100644 --- a/lib/Controller/PollApiController.php +++ b/lib/Controller/PollApiController.php @@ -157,13 +157,30 @@ public function clone(int $pollId): JSONResponse { } /** - * Clone poll + * Transfer all polls from one user to another (change owner of poll) + * @CORS + * @NoCSRFRequired + * @param string $sourceUser User to transfer polls from + * @param string $destinationUser User to transfer polls to + */ + public function transferPolls(string $sourceUser, string $destinationUser): JSONResponse { + try { + return new JSONResponse(['transferred' => $this->pollService->transferPolls($sourceUser, $destinationUser)], Http::STATUS_CREATED); + } catch (Exception $e) { + return new JSONResponse(['message' => $e->getMessage()], $e->getStatus()); + } + } + + /** + * Transfer singe poll to another user (change owner of poll) * @CORS * @NoCSRFRequired + * @param int $pollId Poll to transfer + * @param string $destinationUser User to transfer the poll to */ - public function transferPolls(string $sourceUser, string $targetUser): JSONResponse { + public function transferPoll(int $pollId, string $destinationUser): JSONResponse { try { - return new JSONResponse(['transferred' => $this->pollService->transferPolls($sourceUser, $targetUser)], Http::STATUS_CREATED); + return new JSONResponse(['transferred' => $this->pollService->transferPoll($pollId, $destinationUser)], Http::STATUS_CREATED); } catch (Exception $e) { return new JSONResponse(['message' => $e->getMessage()], $e->getStatus()); } diff --git a/lib/Controller/ShareController.php b/lib/Controller/ShareController.php index 8eed1cbae..d2b01fc79 100644 --- a/lib/Controller/ShareController.php +++ b/lib/Controller/ShareController.php @@ -57,8 +57,8 @@ public function list(int $pollId): JSONResponse { * Add share * @NoAdminRequired */ - public function add(int $pollId, string $type, string $userId = '', string $displayName = ''): JSONResponse { - return $this->responseCreate(fn () => ['share' => $this->shareService->add($pollId, $type, $userId, $displayName)]); + public function add(int $pollId, string $type, string $userId = '', string $displayName = '', string $emailAddress = ''): JSONResponse { + return $this->responseCreate(fn () => ['share' => $this->shareService->add($pollId, $type, $userId, $displayName, $emailAddress)]); } /** diff --git a/lib/Controller/SubscriptionApiController.php b/lib/Controller/SubscriptionApiController.php index 863c498f5..c393cc29d 100644 --- a/lib/Controller/SubscriptionApiController.php +++ b/lib/Controller/SubscriptionApiController.php @@ -26,7 +26,6 @@ use OCA\Polls\Exceptions\Exception; use OCA\Polls\Model\Acl; use OCA\Polls\Service\SubscriptionService; -use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; @@ -49,10 +48,10 @@ public function __construct( */ public function get(int $pollId): JSONResponse { try { - $this->subscriptionService->get($this->acl->setPollId($pollId)); - return new JSONResponse(['status' => 'Subscribed to poll ' . $pollId], Http::STATUS_OK); - } catch (DoesNotExistException $e) { - return new JSONResponse(['status' => 'Not subscribed to poll ' . $pollId], Http::STATUS_NOT_FOUND); + return new JSONResponse([ + 'pollId' => $pollId, + 'subscribed' => $this->subscriptionService->get($this->acl->setPollId($pollId)), + ], Http::STATUS_OK); } catch (Exception $e) { return new JSONResponse(['message' => $e->getMessage()], $e->getStatus()); } @@ -67,7 +66,10 @@ public function get(int $pollId): JSONResponse { public function subscribe(int $pollId): JSONResponse { try { $this->subscriptionService->set(true, $this->acl->setPollId($pollId)); - return new JSONResponse(['status' => 'Subscribed to poll ' . $pollId], Http::STATUS_OK); + return new JSONResponse([ + 'pollId' => $pollId, + 'subscribed' => $this->subscriptionService->get($this->acl->setPollId($pollId)), + ], Http::STATUS_OK); } catch (Exception $e) { return new JSONResponse(['message' => $e->getMessage()], $e->getStatus()); } @@ -82,7 +84,10 @@ public function subscribe(int $pollId): JSONResponse { public function unsubscribe(int $pollId): JSONResponse { try { $this->subscriptionService->set(false, $this->acl->setPollId($pollId)); - return new JSONResponse(['status' => 'Unsubscribed from poll ' . $pollId], Http::STATUS_OK); + return new JSONResponse([ + 'pollId' => $pollId, + 'subscribed' => $this->subscriptionService->get($this->acl->setPollId($pollId)), + ], Http::STATUS_OK); } catch (Exception $e) { return new JSONResponse(['message' => $e->getMessage()], $e->getStatus()); } diff --git a/lib/Controller/VoteApiController.php b/lib/Controller/VoteApiController.php index dd188c22a..c90fab4d0 100644 --- a/lib/Controller/VoteApiController.php +++ b/lib/Controller/VoteApiController.php @@ -61,9 +61,9 @@ public function list(int $pollId): JSONResponse { * @CORS * @NoCSRFRequired */ - public function set(int $optionId, string $setTo): JSONResponse { + public function set(int $optionId, string $answer): JSONResponse { try { - return new JSONResponse(['vote' => $this->voteService->set($optionId, $setTo)], Http::STATUS_OK); + return new JSONResponse(['vote' => $this->voteService->set($optionId, $answer)], Http::STATUS_OK); } catch (DoesNotExistException $e) { return new JSONResponse(['error' => 'Option or poll not found'], Http::STATUS_NOT_FOUND); } catch (Exception $e) { diff --git a/lib/Service/OptionService.php b/lib/Service/OptionService.php index 80a3172fc..ee021c9dc 100644 --- a/lib/Service/OptionService.php +++ b/lib/Service/OptionService.php @@ -250,7 +250,7 @@ public function confirm(int $optionId): Option { return $this->option; } - private function getModifiedDateOption(Option $option, DateTimeZone $timeZone, int $step, string $unit) { + private function getModifiedDateOption(Option $option, DateTimeZone $timeZone, int $step, string $unit): array { $from = (new DateTime()) ->setTimestamp($option->getTimestamp()) ->setTimezone($timeZone) @@ -266,10 +266,6 @@ private function getModifiedDateOption(Option $option, DateTimeZone $timeZone, i ]; } - private function cloneOption() { - return clone $this->option; - } - /** * Make a sequence of date poll options * diff --git a/lib/Service/PollService.php b/lib/Service/PollService.php index c49379738..1f55275b3 100644 --- a/lib/Service/PollService.php +++ b/lib/Service/PollService.php @@ -183,6 +183,20 @@ public function transferPolls(string $sourceUser, string $targetUser): array { throw new InvalidUsernameException('The user id "' . $targetUser . '" is not valid.'); } + /** + * @return Poll + */ + public function transferPoll(int $pollId, string $targetUser): Poll { + if ($this->userManager->get($targetUser) instanceof IUser) { + $poll = $this->pollMapper->find($pollId); + $poll->setOwner($targetUser); + $this->pollMapper->update($poll); + $this->eventDispatcher->dispatchTyped(new PollOwnerChangeEvent($poll)); + return $poll; + } + throw new InvalidUsernameException('The user id "' . $targetUser . '" is not valid.'); + } + /** * get poll configuration diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php index aab1bb3a2..e24ba02a1 100644 --- a/lib/Service/ShareService.php +++ b/lib/Service/ShareService.php @@ -361,7 +361,7 @@ public function add( string $type, string $userId = '', string $displayName = '', - string $emailAddress = '' + string $emailAddress = '', ): Share { $this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT); diff --git a/src/js/Api/polls.js b/src/js/Api/polls.js index fb32ca4f4..14bf34a4c 100644 --- a/src/js/Api/polls.js +++ b/src/js/Api/polls.js @@ -139,7 +139,7 @@ const polls = { setSubscription(pollId, subscription) { return httpInstance.request({ method: 'PUT', - url: `poll/${pollId}${subscription ? '/unsubscribe' : '/subscribe'}`, + url: `poll/${pollId}${subscription ? '/subscribe' : '/unsubscribe'}`, cancelToken: cancelTokenHandlerObject[this.setSubscription.name].handleRequestCancellation().token, }) }, diff --git a/src/js/store/modules/subscription.js b/src/js/store/modules/subscription.js index 363de6527..74f3e4022 100644 --- a/src/js/store/modules/subscription.js +++ b/src/js/store/modules/subscription.js @@ -68,9 +68,9 @@ const actions = { try { let response = null if (context.rootState.route.name === 'publicVote') { - response = await PublicAPI.setSubscription(context.rootState.route.params.token) + response = await PublicAPI.setSubscription(context.rootState.route.params.token, !context.state.subscribed) } else if (context.rootState.route.name === 'vote') { - response = await PollsAPI.setSubscription(context.rootState.route.params.id) + response = await PollsAPI.setSubscription(context.rootState.route.params.id, !context.state.subscribed) } else { context.commit('reset') return