localisation and refactoring
Signed-off-by: dartcafe <github@dartcafe.de>
This commit is contained in:
Родитель
efa6b84d3f
Коммит
75dfad8b22
|
@ -26,9 +26,9 @@ namespace OCA\Polls\Command\Share;
|
|||
use OC\Core\Command\Base;
|
||||
use OCA\Polls\Db\Poll;
|
||||
use OCA\Polls\Exceptions\ShareAlreadyExistsException;
|
||||
use OCA\Polls\Model\UserGroup\Email;
|
||||
use OCA\Polls\Model\UserGroup\Group;
|
||||
use OCA\Polls\Model\UserGroup\User;
|
||||
use OCA\Polls\Model\Group\Group;
|
||||
use OCA\Polls\Model\User\Email;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
|
|
@ -26,11 +26,11 @@ namespace OCA\Polls\Command\Share;
|
|||
use OC\Core\Command\Base;
|
||||
use OCA\Polls\Db\Poll;
|
||||
use OCA\Polls\Db\Share;
|
||||
use OCA\Polls\Model\UserGroup\Contact;
|
||||
use OCA\Polls\Model\UserGroup\Email;
|
||||
use OCA\Polls\Model\UserGroup\GenericUser;
|
||||
use OCA\Polls\Model\UserGroup\Group;
|
||||
use OCA\Polls\Model\UserGroup\User;
|
||||
use OCA\Polls\Model\Group\Group;
|
||||
use OCA\Polls\Model\User\Contact;
|
||||
use OCA\Polls\Model\User\Email;
|
||||
use OCA\Polls\Model\User\GenericUser;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace OCA\Polls\Controller;
|
||||
|
||||
use OCA\Polls\Model\Acl;
|
||||
use OCA\Polls\Service\CommentService;
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
|
@ -32,12 +33,17 @@ class CommentApiController extends BaseApiController {
|
|||
/** @var CommentService */
|
||||
private $commentService;
|
||||
|
||||
/** @var Acl */
|
||||
private $acl;
|
||||
|
||||
public function __construct(
|
||||
string $appName,
|
||||
Acl $acl,
|
||||
IRequest $request,
|
||||
CommentService $commentService
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->acl = $acl;
|
||||
$this->commentService = $commentService;
|
||||
}
|
||||
|
||||
|
@ -48,7 +54,9 @@ class CommentApiController extends BaseApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function list(int $pollId): JSONResponse {
|
||||
return $this->response(fn () => ['comments' => $this->commentService->list($pollId)]);
|
||||
return $this->response(fn () => [
|
||||
'comments' => $this->commentService->list($$this->acl->setPollId($pollId))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +66,9 @@ class CommentApiController extends BaseApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function add(int $pollId, string $message): JSONResponse {
|
||||
return $this->response(fn () => ['comment' => $this->commentService->add($message, $pollId)]);
|
||||
return $this->response(fn () => [
|
||||
'comment' => $this->commentService->add($message, $this->acl->setPollId($pollId, Acl::PERMISSION_COMMENT_ADD))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,6 +78,10 @@ class CommentApiController extends BaseApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function delete(int $commentId): JSONResponse {
|
||||
return $this->responseDeleteTolerant(fn () => ['comment' => $this->commentService->delete($commentId)]);
|
||||
$comment = $this->commentService->get($commentId);
|
||||
|
||||
return $this->responseDeleteTolerant(fn () => [
|
||||
'comment' => $this->commentService->delete($comment, $this->acl->setPollId($comment->getPollId()))
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace OCA\Polls\Controller;
|
||||
|
||||
use OCA\Polls\Model\Acl;
|
||||
use OCA\Polls\Service\CommentService;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IRequest;
|
||||
|
@ -33,13 +34,18 @@ class CommentController extends BaseController {
|
|||
/** @var CommentService */
|
||||
private $commentService;
|
||||
|
||||
/** @var Acl */
|
||||
private $acl;
|
||||
|
||||
public function __construct(
|
||||
string $appName,
|
||||
Acl $acl,
|
||||
ISession $session,
|
||||
IRequest $request,
|
||||
CommentService $commentService
|
||||
) {
|
||||
parent::__construct($appName, $request, $session);
|
||||
$this->acl = $acl;
|
||||
$this->commentService = $commentService;
|
||||
}
|
||||
|
||||
|
@ -48,7 +54,9 @@ class CommentController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function list(int $pollId): JSONResponse {
|
||||
return $this->response(fn () => ['comments' => $this->commentService->list($pollId)]);
|
||||
return $this->response(fn () => [
|
||||
'comments' => $this->commentService->list($this->acl->setPollId($pollId))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +64,9 @@ class CommentController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function add(int $pollId, string $message): JSONResponse {
|
||||
return $this->response(fn () => ['comment' => $this->commentService->add($message, $pollId)]);
|
||||
return $this->response(fn () => [
|
||||
'comment' => $this->commentService->add($message, $this->acl->setPollId($pollId, Acl::PERMISSION_COMMENT_ADD))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,6 +74,10 @@ class CommentController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function delete(int $commentId): JSONResponse {
|
||||
return $this->responseDeleteTolerant(fn () => ['comment' => $this->commentService->delete($commentId)]);
|
||||
$comment = $this->commentService->get($commentId);
|
||||
|
||||
return $this->responseDeleteTolerant(fn () => [
|
||||
'comment' => $this->commentService->delete($comment, $this->acl->setPollId($comment->getPollId()))
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,10 +83,11 @@ class PollController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function get(int $pollId): JSONResponse {
|
||||
$this->acl->setPollId($pollId);
|
||||
$poll = $this->pollService->get($pollId);
|
||||
$this->acl->setPoll($poll);
|
||||
return $this->response(fn () => [
|
||||
'acl' => $this->acl,
|
||||
'poll' => $this->acl->getPoll(),
|
||||
'poll' => $poll,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -117,7 +118,7 @@ class PollController extends BaseController {
|
|||
public function sendConfirmation(int $pollId): JSONResponse {
|
||||
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
|
||||
return $this->response(fn () => [
|
||||
'confirmations' => $this->mailService->sendConfirmation($pollId),
|
||||
'confirmations' => $this->mailService->sendConfirmations($pollId),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function getPoll(string $token): JSONResponse {
|
||||
$this->acl->setToken($token);
|
||||
|
||||
return $this->response(fn () => [
|
||||
'acl' => $this->acl,
|
||||
'poll' => $this->pollService->get($this->acl->getPollId()),
|
||||
|
@ -144,9 +145,8 @@ class PublicController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function watchPoll(string $token, ?int $offset): JSONResponse {
|
||||
$pollId = $this->acl->setToken($token)->getPollId();
|
||||
return $this->responseLong(fn () => [
|
||||
'updates' => $this->watchService->watchUpdates($pollId, $offset)
|
||||
'updates' => $this->watchService->watchUpdates($this->acl->setToken($token)->getPollId(), $offset)
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -162,25 +162,16 @@ class PublicController extends BaseController {
|
|||
], $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Comments
|
||||
* @NoAdminRequired
|
||||
* @PublicPage
|
||||
*/
|
||||
public function getComments(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'comments' => $this->commentService->list(null, $token)
|
||||
], $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get votes
|
||||
* @NoAdminRequired
|
||||
* @PublicPage
|
||||
*/
|
||||
public function getVotes(string $token): JSONResponse {
|
||||
$this->acl->setToken($token);
|
||||
|
||||
return $this->response(fn () => [
|
||||
'votes' => $this->voteService->list(null, $token)
|
||||
'votes' => $this->voteService->list(null, $this->acl)
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -191,7 +182,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function deleteUser(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'deleted' => $this->voteService->delete(null, null, $token)
|
||||
'deleted' => $this->voteService->delete(null, null, $this->acl->setToken($token, Acl::PERMISSION_VOTE_EDIT))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -202,7 +193,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function getOptions(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'options' => $this->optionService->list(null, $token)
|
||||
'options' => $this->optionService->list(null, $this->acl->setToken($token))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -213,7 +204,13 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function addOption(string $token, int $timestamp = 0, string $text = '', int $duration = 0): JSONResponse {
|
||||
return $this->responseCreate(fn () => [
|
||||
'option' => $this->optionService->add(null, $timestamp, $text, $duration, $token)
|
||||
'option' => $this->optionService->add(
|
||||
null,
|
||||
$timestamp,
|
||||
$text,
|
||||
$duration,
|
||||
$this->acl->setToken($token, Acl::PERMISSION_OPTIONS_ADD)
|
||||
)
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -224,18 +221,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function deleteOption(string $token, int $optionId): JSONResponse {
|
||||
return $this->responseDeleteTolerant(fn () => [
|
||||
'option' => $this->optionService->delete($optionId, $token)
|
||||
], $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription status
|
||||
* @PublicPage
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function getSubscription(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'subscribed' => $this->subscriptionService->get(null, $token)
|
||||
'option' => $this->optionService->delete($optionId, $this->acl->setToken($token, Acl::PERMISSION_POLL_VIEW))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -246,7 +232,18 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function setVote(int $optionId, string $setTo, string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'vote' => $this->voteService->set($optionId, $setTo, $token)
|
||||
'vote' => $this->voteService->set($optionId, $setTo, $this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD))
|
||||
], $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Comments
|
||||
* @NoAdminRequired
|
||||
* @PublicPage
|
||||
*/
|
||||
public function getComments(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'comments' => $this->commentService->list($this->acl->setToken($token))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -257,7 +254,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function addComment(string $token, string $message): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'comment' => $this->commentService->add($message, null, $token)
|
||||
'comment' => $this->commentService->add($message, $this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -267,8 +264,20 @@ class PublicController extends BaseController {
|
|||
* @PublicPage
|
||||
*/
|
||||
public function deleteComment(int $commentId, string $token): JSONResponse {
|
||||
$comment = $this->commentService->get($commentId);
|
||||
return $this->responseDeleteTolerant(fn () => [
|
||||
'comment' => $this->commentService->delete($commentId, $token)
|
||||
'comment' => $this->commentService->delete($comment, $this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD))
|
||||
], $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription status
|
||||
* @PublicPage
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function getSubscription(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'subscribed' => $this->subscriptionService->get($this->acl->setToken($token))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -279,7 +288,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function subscribe(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'subscribed' => $this->subscriptionService->set(true, null, $token)
|
||||
'subscribed' => $this->subscriptionService->set(true, $this->acl->setToken($token))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -290,7 +299,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function unsubscribe(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'subscribed' => $this->subscriptionService->set(false, null, $token)
|
||||
'subscribed' => $this->subscriptionService->set(false, $this->acl->setToken($token))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -303,7 +312,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function validatePublicUsername(string $userName, string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'result' => $this->systemService->validatePublicUsername($userName, $token), 'name' => $userName
|
||||
'result' => $this->systemService->validatePublicUsername($userName, $this->shareService->get($token)), 'name' => $userName
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -325,7 +334,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function setDisplayName(string $token, string $displayName): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'share' => $this->shareService->setDisplayname($token, $displayName)
|
||||
'share' => $this->shareService->setDisplayname($this->shareService->get($token), $displayName)
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -337,7 +346,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function setEmailAddress(string $token, string $emailAddress = ''): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'share' => $this->shareService->setEmailAddress($token, $emailAddress, true)
|
||||
'share' => $this->shareService->setEmailAddress($this->shareService->get($token), $emailAddress, true)
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -348,7 +357,7 @@ class PublicController extends BaseController {
|
|||
*/
|
||||
public function deleteEmailAddress(string $token): JSONResponse {
|
||||
return $this->response(fn () => [
|
||||
'share' => $this->shareService->deleteEmailAddress($token)
|
||||
'share' => $this->shareService->deleteEmailAddress($this->shareService->get($token))
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
@ -358,9 +367,11 @@ class PublicController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
* @PublicPage
|
||||
*/
|
||||
public function register(string $token, string $userName, string $emailAddress = ''): JSONResponse {
|
||||
public function register(string $token, string $userName, string $emailAddress = '', string $timeZone = ''): JSONResponse {
|
||||
$language = explode(',', $this->request->getHeader('Accept-Language'))[0];
|
||||
|
||||
return $this->responseCreate(fn () => [
|
||||
'share' => $this->shareService->register($token, $userName, $emailAddress)
|
||||
'share' => $this->shareService->register($this->shareService->get($token), $userName, $emailAddress, $language, $language, $timeZone)
|
||||
], $token);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,6 @@ class ShareController extends BaseController {
|
|||
|
||||
/**
|
||||
* List shares
|
||||
*
|
||||
* @NoAdminRequired
|
||||
*
|
||||
* @return JSONResponse
|
||||
|
@ -100,16 +99,36 @@ class ShareController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function setEmailAddress(string $token, string $emailAddress = ''): JSONResponse {
|
||||
return $this->response(fn () => ['share' => $this->shareService->setEmailAddress($token, $emailAddress)]);
|
||||
return $this->response(fn () => [
|
||||
'share' => $this->shareService->setEmailAddress($this->shareService->get($token),
|
||||
$emailAddress)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a personal share from a public share
|
||||
* or update an email share with the username
|
||||
* @deprecated not used?
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function register(string $token, string $userName, string $emailAddress = ''): JSONResponse {
|
||||
return $this->responseCreate(fn () => ['share' => $this->shareService->register($token, $userName, $emailAddress)]);
|
||||
public function register(
|
||||
string $token,
|
||||
string $userName,
|
||||
string $emailAddress = '',
|
||||
string $timeZone = ''
|
||||
): JSONResponse {
|
||||
$language = explode(',', $this->request->getHeader('Accept-Language'))[0];
|
||||
|
||||
return $this->responseCreate(fn () =>
|
||||
['share' => $this->shareService->register(
|
||||
$this->shareService->get($token),
|
||||
$userName,
|
||||
$emailAddress,
|
||||
$language,
|
||||
$language,
|
||||
$timeZone
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
namespace OCA\Polls\Controller;
|
||||
|
||||
use OCA\Polls\Exceptions\Exception;
|
||||
use OCA\Polls\Model\Acl;
|
||||
use OCA\Polls\Service\SubscriptionService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
|
@ -35,13 +36,17 @@ class SubscriptionApiController extends BaseApiController {
|
|||
/** @var SubscriptionService */
|
||||
private $subscriptionService;
|
||||
|
||||
/** @var Acl */
|
||||
private $acl;
|
||||
|
||||
public function __construct(
|
||||
string $appName,
|
||||
Acl $acl,
|
||||
SubscriptionService $subscriptionService,
|
||||
IRequest $request
|
||||
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->acl = $acl;
|
||||
$this->subscriptionService = $subscriptionService;
|
||||
}
|
||||
|
||||
|
@ -53,7 +58,7 @@ class SubscriptionApiController extends BaseApiController {
|
|||
*/
|
||||
public function get(int $pollId): JSONResponse {
|
||||
try {
|
||||
$this->subscriptionService->get($pollId, '');
|
||||
$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);
|
||||
|
@ -70,7 +75,7 @@ class SubscriptionApiController extends BaseApiController {
|
|||
*/
|
||||
public function subscribe(int $pollId): JSONResponse {
|
||||
try {
|
||||
$this->subscriptionService->set(true, $pollId, '');
|
||||
$this->subscriptionService->set(true, $this->acl->setPollId($pollId));
|
||||
return new JSONResponse(['status' => 'Subscribed to poll ' . $pollId], Http::STATUS_OK);
|
||||
} catch (Exception $e) {
|
||||
return new JSONResponse(['message' => $e->getMessage()], $e->getStatus());
|
||||
|
@ -85,7 +90,7 @@ class SubscriptionApiController extends BaseApiController {
|
|||
*/
|
||||
public function unsubscribe(int $pollId): JSONResponse {
|
||||
try {
|
||||
$this->subscriptionService->set(false, $pollId, '');
|
||||
$this->subscriptionService->set(false, $this->acl->setPollId($pollId));
|
||||
return new JSONResponse(['status' => 'Unsubscribed from poll ' . $pollId], Http::STATUS_OK);
|
||||
} catch (Exception $e) {
|
||||
return new JSONResponse(['message' => $e->getMessage()], $e->getStatus());
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace OCA\Polls\Controller;
|
||||
|
||||
use OCA\Polls\Model\Acl;
|
||||
use OCA\Polls\Service\SubscriptionService;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IRequest;
|
||||
|
@ -33,13 +34,18 @@ class SubscriptionController extends BaseController {
|
|||
/** @var SubscriptionService */
|
||||
private $subscriptionService;
|
||||
|
||||
/** @var Acl */
|
||||
private $acl;
|
||||
|
||||
public function __construct(
|
||||
string $appName,
|
||||
Acl $acl,
|
||||
ISession $session,
|
||||
IRequest $request,
|
||||
SubscriptionService $subscriptionService
|
||||
) {
|
||||
parent::__construct($appName, $request, $session);
|
||||
$this->acl = $acl;
|
||||
$this->subscriptionService = $subscriptionService;
|
||||
}
|
||||
|
||||
|
@ -48,7 +54,9 @@ class SubscriptionController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function get(int $pollId): JSONResponse {
|
||||
return $this->response(fn () => ['subscribed' => $this->subscriptionService->get($pollId)]);
|
||||
return $this->response(fn () => [
|
||||
'subscribed' => $this->subscriptionService->get($this->acl->setPollId($pollId))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +64,9 @@ class SubscriptionController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function subscribe(int $pollId): JSONResponse {
|
||||
return $this->response(fn () => ['subscribed' => $this->subscriptionService->set(true, $pollId, '')]);
|
||||
return $this->response(fn () => [
|
||||
'subscribed' => $this->subscriptionService->set(true, $this->acl->setPollId($pollId))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,6 +74,8 @@ class SubscriptionController extends BaseController {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
public function unsubscribe(int $pollId): JSONResponse {
|
||||
return $this->response(fn () => ['subscribed' => $this->subscriptionService->set(false, $pollId, '')]);
|
||||
return $this->response(fn () => [
|
||||
'subscribed' => $this->subscriptionService->set(false, $this->acl->setPollId($pollId))
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
|
||||
namespace OCA\Polls\Db;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use JsonSerializable;
|
||||
|
||||
use OCA\Polls\Helper\Container;
|
||||
|
@ -32,6 +36,7 @@ use OCP\AppFramework\Db\Entity;
|
|||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\IL10N;
|
||||
|
||||
/**
|
||||
* @method int getId()
|
||||
|
@ -145,6 +150,7 @@ class Option extends Entity implements JsonSerializable {
|
|||
];
|
||||
}
|
||||
|
||||
|
||||
public function getPollOptionText(): string {
|
||||
if ($this->getTimestamp() && $this->getDuration()) {
|
||||
return date('c', $this->getTimestamp()) . ' - ' . date('c', $this->getTimestamp() + $this->getDuration());
|
||||
|
@ -197,13 +203,7 @@ class Option extends Entity implements JsonSerializable {
|
|||
if (!strncmp($this->getOwner(), 'deleted_', 8)) {
|
||||
return 'Deleted User';
|
||||
}
|
||||
// if ($this->getOwner() === '') {
|
||||
// return '';
|
||||
// }
|
||||
// return $this->getOwnerIsNoUser()
|
||||
// ? $this->getOwner()
|
||||
// : $this->userManager->get($this->getOwner())->getDisplayName();
|
||||
|
||||
|
||||
if ($this->getOwnerIsNoUser()) {
|
||||
try {
|
||||
$share = $this->shareMapper->findByPollAndUser($this->getPollId(), $this->getOwner());
|
||||
|
@ -215,7 +215,68 @@ class Option extends Entity implements JsonSerializable {
|
|||
return $this->userManager->get($this->getOwner())->getDisplayName();
|
||||
}
|
||||
|
||||
public function getDateStringLocalized(DateTimeZone $timeZone, IL10N $l10n) {
|
||||
$mutableFrom = DateTime::createFromImmutable($this->getDateObjectFrom($timeZone));
|
||||
$mutableTo = DateTime::createFromImmutable($this->getDateObjectTo($timeZone));
|
||||
$dayLongSecond = new DateInterval('PT1S');
|
||||
$sameDay = $this->getDateObjectFrom($timeZone)->format('Y-m-d') === $this->getDateObjectTo($timeZone)->format('Y-m-d');
|
||||
|
||||
// If duration is zero, the option represents a moment with day and time
|
||||
if ($this->getDuration() === 0) {
|
||||
return $l10n->l('datetime', $mutableFrom);
|
||||
}
|
||||
|
||||
$dateTimeFrom = $l10n->l('datetime', $mutableFrom);
|
||||
$dateTimeTo = $l10n->l('datetime', $mutableTo);
|
||||
|
||||
// If the option spans over on or more whole days, the option represents only the days without time
|
||||
// adjust the end by substracting a second, to represent the last moment at the day and not the first moment of the following day
|
||||
// which is calculated by adding the duration
|
||||
if ($this->getDaylong($timeZone)) {
|
||||
$dateTimeFrom = $l10n->l('date', $mutableFrom);
|
||||
$dateTimeTo = $l10n->l('date', $mutableTo->sub($dayLongSecond));
|
||||
// if start and end day are identiacal, just return the start day
|
||||
if ($dateTimeFrom === $dateTimeTo) {
|
||||
return $dateTimeFrom;
|
||||
}
|
||||
}
|
||||
|
||||
if ($sameDay) {
|
||||
$dateTimeTo = $dateTimeTo = $l10n->l('time', $mutableTo);
|
||||
}
|
||||
|
||||
return $dateTimeFrom . ' - ' . $dateTimeTo;
|
||||
}
|
||||
|
||||
private function getOwnerIsNoUser(): bool {
|
||||
return !$this->userManager->get($this->getOwner()) instanceof IUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check, if the date option spans one or more whole days (from 00:00 to 24:00)
|
||||
*/
|
||||
private function getDaylong(DateTimeZone $timeZone = null): bool {
|
||||
$from = $this->getDateObjectFrom($timeZone);
|
||||
$to = $this->getDateObjectTo($timeZone);
|
||||
$dateInterval = $from->diff($to);
|
||||
|
||||
if (
|
||||
$this->getDuration() > 0
|
||||
&& $from->format('H') === '00'
|
||||
&& $dateInterval->h + $dateInterval->i + $dateInterval->h === 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getDateObjectFrom(DateTimeZone $timeZone): DateTimeImmutable {
|
||||
$dateTime = (new DateTimeImmutable())->setTimestamp($this->getTimestamp());
|
||||
return $dateTime->setTimezone($timeZone);
|
||||
}
|
||||
|
||||
private function getDateObjectTo(DateTimeZone $timeZone): DateTimeImmutable {
|
||||
$dateTime = (new DateTimeImmutable())->setTimestamp($this->getTimestamp() + $this->getDuration());
|
||||
return $dateTime->setTimezone($timeZone);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ namespace OCA\Polls\Db;
|
|||
use JsonSerializable;
|
||||
use OCA\Polls\Exceptions\NoDeadLineException;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\UserGroup\User;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
|
@ -326,10 +325,6 @@ class Poll extends Entity implements JsonSerializable {
|
|||
: $this->owner;
|
||||
}
|
||||
|
||||
public function getOwnerUserObject(): User {
|
||||
return new User($this->owner);
|
||||
}
|
||||
|
||||
private function setMiscSettingsArray(array $value) : void {
|
||||
$this->setMiscSettings(json_encode($value));
|
||||
}
|
||||
|
|
|
@ -27,10 +27,8 @@ use JsonSerializable;
|
|||
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\IURLGenerator;
|
||||
use OCA\Polls\Model\UserGroup\UserBase;
|
||||
use OCA\Polls\Model\Settings\AppSettings;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Service\UserService;
|
||||
|
||||
/**
|
||||
* @method int getId()
|
||||
|
@ -126,15 +124,11 @@ class Share extends Entity implements JsonSerializable {
|
|||
/** @var AppSettings */
|
||||
protected $appSettings;
|
||||
|
||||
/** @var UserService */
|
||||
protected $userService;
|
||||
|
||||
public function __construct() {
|
||||
$this->addType('pollId', 'int');
|
||||
$this->addType('invitationSent', 'int');
|
||||
$this->addType('reminderSent', 'int');
|
||||
$this->urlGenerator = Container::queryClass(IURLGenerator::class);
|
||||
$this->userService = Container::queryClass(UserService::class);
|
||||
$this->appSettings = new AppSettings;
|
||||
}
|
||||
|
||||
|
@ -164,6 +158,27 @@ class Share extends Entity implements JsonSerializable {
|
|||
$this->setMiscSettingsByKey('publicPollEmail', $value);
|
||||
}
|
||||
|
||||
public function getTimeZoneName() : ?string {
|
||||
return $this->getMiscSettingsArray()['timeZone'] ?? '';
|
||||
}
|
||||
|
||||
public function setTimeZoneName(string $value) : void {
|
||||
$this->setMiscSettingsByKey('timeZone', $value);
|
||||
}
|
||||
|
||||
public function getLanguage(): ?string {
|
||||
return $this->getMiscSettingsArray()['language'] ?? '';
|
||||
}
|
||||
|
||||
// Fallback for now; use language as locale
|
||||
public function getLocale(): ?string {
|
||||
return $this->getLanguage();
|
||||
}
|
||||
|
||||
public function setLanguage(string $value) : void {
|
||||
$this->setMiscSettingsByKey('language', $value);
|
||||
}
|
||||
|
||||
public function getURL(): string {
|
||||
if (in_array($this->type, [self::TYPE_USER, self::TYPE_ADMIN, self::TYPE_GROUP], true)) {
|
||||
return $this->urlGenerator->linkToRouteAbsolute(
|
||||
|
@ -191,15 +206,6 @@ class Share extends Entity implements JsonSerializable {
|
|||
return $this->userId;
|
||||
}
|
||||
|
||||
public function getUserObject(): UserBase {
|
||||
return $this->userService->getUser(
|
||||
$this->type,
|
||||
$this->userId,
|
||||
$this->displayName,
|
||||
$this->emailAddress
|
||||
);
|
||||
}
|
||||
|
||||
public function getRichObjectString(): array {
|
||||
return [
|
||||
'type' => 'highlight',
|
||||
|
|
|
@ -31,6 +31,7 @@ use OCA\Polls\Db\Poll;
|
|||
use OCA\Polls\Db\Share;
|
||||
use OCA\Polls\Db\Vote;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Service\UserService;
|
||||
use OCP\IUserSession;
|
||||
|
||||
abstract class BaseEvent extends Event {
|
||||
|
@ -55,12 +56,16 @@ abstract class BaseEvent extends Event {
|
|||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
||||
/** @var UserService */
|
||||
protected $userService;
|
||||
|
||||
public function __construct(
|
||||
$eventObject
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->eventObject = $eventObject;
|
||||
$this->poll = Container::queryPoll($this->getPollId());
|
||||
$this->userService = Container::queryClass(UserService::class);
|
||||
$this->userSession = Container::queryClass(IUserSession::class);
|
||||
|
||||
$this->activitySubjectParams['pollTitle'] = [
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
namespace OCA\Polls\Event;
|
||||
|
||||
use OCA\Polls\Db\Share;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
|
||||
abstract class ShareEvent extends BaseEvent {
|
||||
public const ADD = 'share_add';
|
||||
|
@ -38,16 +39,23 @@ abstract class ShareEvent extends BaseEvent {
|
|||
/** @var Share */
|
||||
private $share;
|
||||
|
||||
/** @var UserBase */
|
||||
protected $sharee;
|
||||
|
||||
public function __construct(Share $share) {
|
||||
parent::__construct($share);
|
||||
$this->activityObject = 'poll';
|
||||
$this->log = false;
|
||||
$this->share = $share;
|
||||
$this->activitySubjectParams['shareType'] = $this->share->getRichObjectString();
|
||||
$this->activitySubjectParams['sharee'] = $this->share->getUserObject()->getRichObjectString();
|
||||
$this->activitySubjectParams['sharee'] = $this->getSharee()->getRichObjectString();
|
||||
}
|
||||
|
||||
public function getShare(): Share {
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
protected function getSharee() : UserBase {
|
||||
return $this->userService->getUserFromShare($this->share);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,10 @@ class Acl implements JsonSerializable {
|
|||
/**
|
||||
* load share via token and than call setShare
|
||||
*/
|
||||
public function setToken(string $token = '', string $permission = self::PERMISSION_POLL_VIEW, ?int $pollIdToValidate = null): Acl {
|
||||
public function setToken(string $token = '',
|
||||
string $permission = self::PERMISSION_POLL_VIEW,
|
||||
?int $pollIdToValidate = null
|
||||
): Acl {
|
||||
try {
|
||||
$this->share = $this->shareMapper->findByToken($token);
|
||||
|
||||
|
@ -134,6 +137,10 @@ class Acl implements JsonSerializable {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getShare() : Share {
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
public function setPollId(?int $pollId = 0, string $permission = self::PERMISSION_POLL_VIEW): Acl {
|
||||
try {
|
||||
$this->poll = $this->pollMapper->find($pollId);
|
||||
|
@ -145,6 +152,10 @@ class Acl implements JsonSerializable {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setPoll(Poll $poll) {
|
||||
$this->poll = $poll;
|
||||
}
|
||||
|
||||
public function getToken(): string {
|
||||
return strval($this->share->getToken());
|
||||
}
|
||||
|
@ -161,10 +172,18 @@ class Acl implements JsonSerializable {
|
|||
return $this->getIsLoggedIn() ? $this->userSession->getUser()->getUID() : $this->share->getUserId();
|
||||
}
|
||||
|
||||
public function validateUserId(string $userId): void {
|
||||
public function validateUserId(string $userId): bool {
|
||||
if ($this->getUserId() !== $userId) {
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validatePollId(int $pollId): bool {
|
||||
if ($this->getPollId() !== $pollId) {
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getIsOwner(): bool {
|
||||
|
@ -441,10 +460,10 @@ class Acl implements JsonSerializable {
|
|||
|
||||
private function validateShareAccess(): void {
|
||||
if ($this->getIsLoggedIn() && !$this->getIsShareValidForUsers()) {
|
||||
throw new NotAuthorizedException('Share type "' . $this->share->getType() . '"only valid for guests');
|
||||
throw new NotAuthorizedException('Share type "' . $this->share->getType() . '" is only valid for guests');
|
||||
}
|
||||
if (!$this->getIsShareValidForGuests()) {
|
||||
throw new NotAuthorizedException('Share type "' . $this->share->getType() . '"only valid for registered users');
|
||||
throw new NotAuthorizedException('Share type "' . $this->share->getType() . '" is only valid for registered users');
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,16 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\Group;
|
||||
|
||||
use OCA\Circles\Api\v1\Circles;
|
||||
use OCA\Circles\Model\Circle as CirclesCircle;
|
||||
use OCA\Polls\Exceptions\CirclesNotEnabledException;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\User\Contact;
|
||||
use OCA\Polls\Model\User\Email;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
|
||||
class Circle extends UserBase {
|
||||
public const TYPE = 'circle';
|
||||
|
@ -40,7 +44,7 @@ class Circle extends UserBase {
|
|||
) {
|
||||
parent::__construct($id, self::TYPE);
|
||||
$this->icon = self::ICON;
|
||||
$this->description = Container::getL10N()->t('Circle');
|
||||
$this->description = $this->l10n->t('Circle');
|
||||
$this->richObjectType = 'circle';
|
||||
|
||||
if (self::isEnabled()) {
|
|
@ -21,10 +21,12 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\Group;
|
||||
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Exceptions\ContactsNotEnabledExceptions;
|
||||
use OCA\Polls\Model\User\Contact;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use OCP\Contacts\IManager as IContactsManager;
|
||||
|
||||
class ContactGroup extends UserBase {
|
||||
|
@ -36,7 +38,7 @@ class ContactGroup extends UserBase {
|
|||
) {
|
||||
parent::__construct($id, self::TYPE);
|
||||
$this->icon = self::ICON;
|
||||
$this->description = Container::getL10N()->t('Contact group');
|
||||
$this->description = $this->l10n->t('Contact group');
|
||||
$this->richObjectType = 'addressbook-contact';
|
||||
|
||||
if (!self::isEnabled()) {
|
|
@ -21,9 +21,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\Group;
|
||||
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IGroup;
|
||||
|
||||
|
@ -39,7 +41,7 @@ class Group extends UserBase {
|
|||
) {
|
||||
parent::__construct($id, self::TYPE);
|
||||
$this->icon = self::ICON;
|
||||
$this->description = Container::getL10N()->t('Group');
|
||||
$this->description = $this->l10n->t('Group');
|
||||
$this->richObjectType = 'user-group';
|
||||
|
||||
$this->group = Container::queryClass(IGroupManager::class)->get($this->id);
|
|
@ -24,25 +24,25 @@
|
|||
|
||||
namespace OCA\Polls\Model\Mail;
|
||||
|
||||
use OCA\Polls\Db\OptionMapper;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Db\Option;
|
||||
use OCA\Polls\Db\Poll;
|
||||
|
||||
class ConfirmationMail extends MailBase {
|
||||
private const TEMPLATE_CLASS = 'polls.Confirmation';
|
||||
|
||||
/** @var OptionMapper */
|
||||
protected $optionMapper;
|
||||
/** @var Option[] */
|
||||
protected $confirmedOptions;
|
||||
|
||||
public function __construct(
|
||||
string $recipientId,
|
||||
int $pollId
|
||||
) {
|
||||
parent::__construct($recipientId, $pollId);
|
||||
$this->optionMapper = Container::queryClass(OptionMapper::class);
|
||||
$this->confirmedOptions = $this->optionMapper->findConfirmed($pollId);
|
||||
}
|
||||
|
||||
protected function getSubject(): string {
|
||||
return $this->l10n->t('Poll "%s" has been closed', $this->poll->getTitle());
|
||||
return $this->l10n->t('Poll "%s" - Confirmation', $this->poll->getTitle());
|
||||
}
|
||||
|
||||
protected function getFooter(): string {
|
||||
|
@ -56,20 +56,32 @@ class ConfirmationMail extends MailBase {
|
|||
$this->l10n->t('{owner} wants to inform you about the final result of the poll "{title}"')
|
||||
));
|
||||
|
||||
$confirmedOptions = $this->optionMapper->findConfirmed($this->poll->getId());
|
||||
$countConfirmed = count($confirmedOptions);
|
||||
|
||||
$this->emailTemplate->addBodyText(
|
||||
$this->l10n->n('Confirmed option:', 'Confirmed options:', $countConfirmed)
|
||||
$this->l10n->n('Confirmed option:', 'Confirmed options:', count($this->confirmedOptions))
|
||||
);
|
||||
|
||||
foreach ($confirmedOptions as $option) {
|
||||
$this->emailTemplate->addBodyListItem(
|
||||
$option->getPollOptionText()
|
||||
foreach ($this->confirmedOptions as $option) {
|
||||
if ($this->poll->getType() === Poll::TYPE_DATE) {
|
||||
$this->emailTemplate->addBodyListItem($option->getDateStringLocalized($this->recipient->getTimeZone(), $this->l10n));
|
||||
} else {
|
||||
$this->emailTemplate->addBodyListItem($option->getPollOptionText());
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->poll->getType() === Poll::TYPE_DATE) {
|
||||
$this->emailTemplate->addBodyText(
|
||||
$this->l10n->t('The used time zone is "%s", based on the detected time zone at your registration time. To view the times in your current time zone, enter the poll by clicking the button below.', $this->recipient->getTimeZoneName())
|
||||
);
|
||||
}
|
||||
|
||||
$this->emailTemplate->addBodyText($this->getRichDescription(), $this->poll->getDescription());
|
||||
// $this->emailTemplate->addBodyText(
|
||||
// $this->l10n->t('Used languageCode is %1$s, %2$s, %3$s', [$this->l10n->getLanguageCode(), $this->l10n->getLocaleCode(), $this->transFactory->localeExists($this->l10n->getLanguageCode())])
|
||||
// );
|
||||
|
||||
if ($this->poll->getDescription()) {
|
||||
$this->emailTemplate->addBodyText($this->getRichDescription(), $this->poll->getDescription());
|
||||
}
|
||||
|
||||
$this->addButtonToPoll();
|
||||
|
||||
$this->emailTemplate->addBodyText($this->l10n->t('This link gives you personal access to the poll named above. Press the button above or copy the following link and add it in your browser\'s location bar:'));
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
|
||||
namespace OCA\Polls\Model\Mail;
|
||||
|
||||
use OCA\Polls\Db\OptionMapper;
|
||||
use OCA\Polls\Db\Poll;
|
||||
use OCA\Polls\Exceptions\InvalidEmailAddress;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\Settings\AppSettings;
|
||||
use OCA\Polls\Model\UserGroup\UserBase;
|
||||
use OCA\Polls\Model\UserGroup\User;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCA\Polls\Service\UserService;
|
||||
use OCP\IL10N;
|
||||
use OCP\L10N\IFactory;
|
||||
|
@ -61,7 +62,10 @@ abstract class MailBase {
|
|||
|
||||
/** @var IMailer */
|
||||
protected $mailer;
|
||||
|
||||
|
||||
/** @var OptionMapper */
|
||||
protected $optionMapper;
|
||||
|
||||
/** @var User */
|
||||
protected $owner;
|
||||
|
||||
|
@ -88,9 +92,9 @@ abstract class MailBase {
|
|||
$this->appSettings = Container::queryClass(AppSettings::class);
|
||||
$this->logger = Container::queryClass(LoggerInterface::class);
|
||||
$this->mailer = Container::queryClass(IMailer::class);
|
||||
$this->optionMapper = Container::queryClass(OptionMapper::class);
|
||||
$this->transFactory = Container::queryClass(IFactory::class);
|
||||
$this->userService = Container::queryClass(UserService::class);
|
||||
|
||||
$this->poll = $this->getPoll($pollId);
|
||||
$this->recipient = $this->getUser($recipientId);
|
||||
$this->url = $url ?? $this->poll->getVoteUrl();
|
||||
|
@ -114,7 +118,7 @@ abstract class MailBase {
|
|||
}
|
||||
|
||||
protected function initializeClass(): void {
|
||||
$this->owner = $this->poll->getOwnerUserObject();
|
||||
$this->owner = $this->getUser($this->poll->getOwner());
|
||||
|
||||
if ($this->recipient->getIsNoUser()) {
|
||||
$this->url = $this->getShareURL();
|
||||
|
@ -122,9 +126,8 @@ abstract class MailBase {
|
|||
|
||||
$this->l10n = $this->transFactory->get(
|
||||
'polls',
|
||||
$this->recipient->getLanguage()
|
||||
? $this->recipient->getLanguage()
|
||||
: $this->owner->getLanguage()
|
||||
$this->recipient->getLanguageCode() ? $this->recipient->getLanguageCode() : $this->owner->getLanguageCode(),
|
||||
$this->recipient->getLocaleCode()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -201,7 +204,7 @@ abstract class MailBase {
|
|||
return $legal;
|
||||
}
|
||||
|
||||
protected function getUser(string $userId) : UserBase {
|
||||
protected function getUser(string $userId) : ?UserBase {
|
||||
return $this->userService->evaluateUser($userId, $this->poll->getId());
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
namespace OCA\Polls\Model\Settings;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Polls\Model\UserGroup\Group;
|
||||
use OCA\Polls\Model\Group\Group;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\User;
|
||||
|
||||
class Admin extends User {
|
||||
public const TYPE = 'admin';
|
|
@ -21,11 +21,12 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\User;
|
||||
|
||||
use OCA\Polls\Exceptions\MultipleContactsFound;
|
||||
use OCA\Polls\Exceptions\ContactsNotEnabledExceptions;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use OCP\Contacts\IManager as IContactsManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
@ -44,7 +45,7 @@ class Contact extends UserBase {
|
|||
) {
|
||||
parent::__construct($id, self::TYPE);
|
||||
$this->icon = self::ICON;
|
||||
$this->description = Container::getL10N()->t('Contact');
|
||||
$this->description = $this->l10n->t('Contact');
|
||||
$this->richObjectType = 'addressbook-contact';
|
||||
|
||||
$this->logger = Container::queryClass(LoggerInterface::class);
|
||||
|
@ -120,7 +121,7 @@ class Contact extends UserBase {
|
|||
array_unshift($description, $this->getEmailAddress());
|
||||
}
|
||||
|
||||
return count($description) ? implode(", ", $description) : Container::getL10N()->t('Contact');
|
||||
return count($description) ? implode(", ", $description) : $this->l10n->t('Contact');
|
||||
}
|
||||
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\User;
|
||||
|
||||
use OCP\IUserSession;
|
||||
use OCA\Polls\Helper\Container;
|
|
@ -22,9 +22,9 @@
|
|||
*/
|
||||
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\User;
|
||||
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
|
||||
class Email extends UserBase {
|
||||
public const TYPE = 'email';
|
||||
|
@ -33,13 +33,15 @@ class Email extends UserBase {
|
|||
public function __construct(
|
||||
string $id,
|
||||
string $displayName = '',
|
||||
string $emailAddress = ''
|
||||
string $emailAddress = '',
|
||||
string $languageCode = ''
|
||||
) {
|
||||
parent::__construct($id, self::TYPE);
|
||||
$this->icon = self::ICON;
|
||||
$this->description = $emailAddress ? $emailAddress : Container::getL10N()->t('External Email');
|
||||
$this->description = $emailAddress ? $emailAddress : $this->l10n->t('External Email');
|
||||
$this->richObjectType = 'email';
|
||||
|
||||
$this->languageCode = $languageCode;
|
||||
$this->emailAddress = $emailAddress ? $emailAddress : $id;
|
||||
$this->displayName = $displayName ? $displayName : $this->displayName;
|
||||
}
|
|
@ -22,9 +22,9 @@
|
|||
*/
|
||||
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\User;
|
||||
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
|
||||
class GenericUser extends UserBase {
|
||||
public const TYPE = 'external';
|
||||
|
@ -35,19 +35,20 @@ class GenericUser extends UserBase {
|
|||
string $id,
|
||||
string $type = self::TYPE,
|
||||
string $displayName = '',
|
||||
string $emailAddress = ''
|
||||
string $emailAddress = '',
|
||||
string $languageCode = '',
|
||||
string $localeCode = '',
|
||||
string $timeZoneName = ''
|
||||
) {
|
||||
parent::__construct($id, $type);
|
||||
parent::__construct($id, $type, $displayName, $emailAddress, $languageCode, $localeCode, $timeZoneName);
|
||||
|
||||
$this->icon = self::ICON_DEFAULT;
|
||||
$this->description = Container::getL10N()->t('External user');
|
||||
$this->description = $this->l10n->t('External user');
|
||||
$this->richObjectType = 'guest';
|
||||
|
||||
if ($type === UserBase::TYPE_PUBLIC) {
|
||||
$this->icon = self::ICON_PUBLIC;
|
||||
$this->description = Container::getL10N()->t('Public link');
|
||||
$this->description = $this->l10n->t('Public link');
|
||||
}
|
||||
|
||||
$this->displayName = $displayName;
|
||||
$this->emailAddress = $emailAddress;
|
||||
}
|
||||
}
|
|
@ -21,11 +21,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model\User;
|
||||
|
||||
use DateTimeZone;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\Settings\AppSettings;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUser;
|
||||
|
@ -51,14 +51,15 @@ class User extends UserBase {
|
|||
parent::__construct($id, $type);
|
||||
$this->icon = self::ICON;
|
||||
$this->isNoUser = false;
|
||||
$this->description = Container::getL10N()->t('User');
|
||||
$this->description = $this->l10n->t('User');
|
||||
|
||||
$this->config = Container::queryClass(IConfig::class);
|
||||
$this->user = Container::queryClass(IUserManager::class)->get($this->id);
|
||||
$this->displayName = $this->user->getDisplayName();
|
||||
$this->emailAddress = $this->user->getEmailAddress();
|
||||
$this->language = $this->config->getUserValue($this->id, 'core', 'lang');
|
||||
$this->locale = $this->config->getUserValue($this->id, 'core', 'locale');
|
||||
$this->languageCode = $this->config->getUserValue($this->id, 'core', 'lang');
|
||||
$this->localeCode = $this->config->getUserValue($this->id, 'core', 'locale');
|
||||
$this->timeZoneName = $this->config->getUserValue($this->id, 'core', 'timezone');
|
||||
$this->appSettings = new AppSettings;
|
||||
}
|
||||
|
||||
|
@ -73,14 +74,6 @@ class User extends UserBase {
|
|||
return '';
|
||||
}
|
||||
|
||||
public function getTimeZone(): DateTimeZone {
|
||||
$tz = $this->config->getUserValue($this->getId(), 'core', 'timezone');
|
||||
if ($tz) {
|
||||
return new DateTimeZone($tz);
|
||||
}
|
||||
return new DateTimeZone($this->timezone->getTimeZone()->getName());
|
||||
}
|
||||
|
||||
public function getDescription(): string {
|
||||
if ($this->getEmailAddress()) {
|
||||
return $this->getEmailAddress();
|
|
@ -21,11 +21,18 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Model\UserGroup;
|
||||
namespace OCA\Polls\Model;
|
||||
|
||||
use DateTimeZone;
|
||||
use OCP\IL10N;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\Group\Circle;
|
||||
use OCA\Polls\Model\Group\ContactGroup;
|
||||
use OCA\Polls\Model\User\Admin;
|
||||
use OCA\Polls\Model\User\Contact;
|
||||
use OCA\Polls\Model\User\Email;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCA\Polls\Model\Group\Group;
|
||||
use OCP\Collaboration\Collaborators\ISearch;
|
||||
use OCP\Share\IShare;
|
||||
use OCP\IDateTimeZone;
|
||||
|
@ -47,7 +54,7 @@ class UserBase implements \JsonSerializable {
|
|||
protected $richObjectType = 'user';
|
||||
|
||||
/** @var IL10N */
|
||||
private $l10n;
|
||||
protected $l10n;
|
||||
|
||||
/** @var string */
|
||||
protected $id;
|
||||
|
@ -65,10 +72,10 @@ class UserBase implements \JsonSerializable {
|
|||
protected $emailAddress = null;
|
||||
|
||||
/** @var string */
|
||||
protected $language = '';
|
||||
protected $languageCode = '';
|
||||
|
||||
/** @var string */
|
||||
protected $locale = '';
|
||||
protected $localeCode = '';
|
||||
|
||||
/** @var string */
|
||||
protected $organisation = '';
|
||||
|
@ -83,7 +90,10 @@ class UserBase implements \JsonSerializable {
|
|||
protected $categories = [];
|
||||
|
||||
/** @var IDateTimeZone */
|
||||
protected $timezone;
|
||||
protected $timeZone;
|
||||
|
||||
/** @var string */
|
||||
protected $timeZoneName;
|
||||
|
||||
/** @var IUserSession */
|
||||
protected $userSession;
|
||||
|
@ -93,21 +103,23 @@ class UserBase implements \JsonSerializable {
|
|||
string $type,
|
||||
string $displayName = '',
|
||||
string $emailAddress = '',
|
||||
string $language = '',
|
||||
string $locale = ''
|
||||
string $languageCode = '',
|
||||
string $localeCode = '',
|
||||
string $timeZoneName = ''
|
||||
) {
|
||||
$this->icon = 'icon-share';
|
||||
|
||||
$this->l10n = Container::getL10N();
|
||||
$this->timezone = Container::queryClass(IDateTimeZone::class);
|
||||
$this->timeZone = Container::queryClass(IDateTimeZone::class);
|
||||
$this->userSession = Container::queryClass(IUserSession::class);
|
||||
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
$this->displayName = $displayName;
|
||||
$this->emailAddress = $emailAddress;
|
||||
$this->language = $language;
|
||||
$this->locale = $locale;
|
||||
$this->timeZoneName = $timeZoneName;
|
||||
$this->localeCode = $localeCode;
|
||||
$this->languageCode = $languageCode;
|
||||
}
|
||||
|
||||
public function getId(): string {
|
||||
|
@ -122,16 +134,27 @@ class UserBase implements \JsonSerializable {
|
|||
return $this->type;
|
||||
}
|
||||
|
||||
public function getLanguage(): string {
|
||||
return $this->language;
|
||||
public function getLanguageCode(): string {
|
||||
return $this->languageCode;
|
||||
}
|
||||
|
||||
public function getLocaleCode(): string {
|
||||
if (!$this->localeCode) {
|
||||
return $this->languageCode;
|
||||
}
|
||||
|
||||
return $this->localeCode;
|
||||
}
|
||||
|
||||
public function getTimeZone(): DateTimeZone {
|
||||
return new DateTimeZone($this->timezone->getTimeZone()->getName());
|
||||
if ($this->timeZoneName) {
|
||||
return new DateTimeZone($this->timeZoneName);
|
||||
}
|
||||
return new DateTimeZone($this->timeZone->getTimeZone()->getName());
|
||||
}
|
||||
|
||||
public function getLocale(): string {
|
||||
return $this->locale;
|
||||
public function getTimeZoneName(): string {
|
||||
return $this->timeZoneName;
|
||||
}
|
||||
|
||||
public function getDisplayName(): string {
|
||||
|
@ -196,14 +219,14 @@ class UserBase implements \JsonSerializable {
|
|||
return $this->emailAddress;
|
||||
}
|
||||
|
||||
public function setLanguage(string $language): string {
|
||||
$this->language = $language;
|
||||
return $this->language;
|
||||
public function setLanguageCode(string $languageCode): string {
|
||||
$this->languageCode = $languageCode;
|
||||
return $this->languageCode;
|
||||
}
|
||||
|
||||
public function setLocale(string $locale): string {
|
||||
$this->locale = $locale;
|
||||
return $this->locale;
|
||||
public function setLocaleCode(string $localeCode): string {
|
||||
$this->localeCode = $localeCode;
|
||||
return $this->localeCode;
|
||||
}
|
||||
|
||||
public function setOrganisation(string $organisation): string {
|
||||
|
@ -283,7 +306,9 @@ class UserBase implements \JsonSerializable {
|
|||
'displayName' => $this->getDisplayName(),
|
||||
'organisation' => $this->getOrganisation(),
|
||||
'emailAddress' => $this->getEmailAddressMasked(),
|
||||
'language' => $this->getLanguage(),
|
||||
'languageCode' => $this->getLanguageCode(),
|
||||
'localeCode' => $this->getLocaleCode(),
|
||||
'timeZone' => $this->getTimeZoneName(),
|
||||
'desc' => $this->getDescription(),
|
||||
'subtitle' => $this->getDescription(),
|
||||
'icon' => $this->getIcon(),
|
|
@ -32,7 +32,7 @@ use DateTimeZone;
|
|||
use OCA\Polls\Db\OptionMapper;
|
||||
use OCA\Polls\Db\Preferences;
|
||||
use OCA\Polls\Model\CalendarEvent;
|
||||
use OCA\Polls\Model\UserGroup\CurrentUser;
|
||||
use OCA\Polls\Model\User\CurrentUser;
|
||||
use OCP\Calendar\ICalendar;
|
||||
use OCP\Calendar\IManager as CalendarManager;
|
||||
use OCP\Util;
|
||||
|
|
|
@ -68,21 +68,15 @@ class CommentService {
|
|||
* @return Comment[]
|
||||
*
|
||||
*/
|
||||
public function listFlat(?int $pollId, string $token = '') : array {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token);
|
||||
} else {
|
||||
$this->acl->setPollId($pollId);
|
||||
}
|
||||
private function listFlat(Acl $acl) : array {
|
||||
$comments = $this->commentMapper->findByPoll($acl->getPollId());
|
||||
|
||||
$comments = $this->commentMapper->findByPoll($this->acl->getPollId());
|
||||
|
||||
if (!$this->acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
|
||||
$this->anonymizer->set($this->acl->getPollId(), $this->acl->getUserId());
|
||||
if (!$acl->getIsAllowed(Acl::PERMISSION_POLL_USERNAMES_VIEW)) {
|
||||
$this->anonymizer->set($acl->getPollId(), $acl->getUserId());
|
||||
$this->anonymizer->anonymize($comments);
|
||||
} elseif (!$this->acl->getIsLoggedIn()) {
|
||||
} elseif (!$acl->getIsLoggedIn()) {
|
||||
// if participant is not logged in avoid leaking user ids
|
||||
AnonymizeService::replaceUserId($comments, $this->acl->getUserId());
|
||||
AnonymizeService::replaceUserId($comments, $acl->getUserId());
|
||||
}
|
||||
|
||||
return $comments;
|
||||
|
@ -92,8 +86,8 @@ class CommentService {
|
|||
* Get comments
|
||||
* Read all comments of a poll based on the poll id and return list as array
|
||||
*/
|
||||
public function list(?int $pollId, string $token = ''): array {
|
||||
$comments = $this->listFlat($pollId, $token);
|
||||
public function list(Acl $acl): array {
|
||||
$comments = $this->listFlat($acl);
|
||||
$timeTolerance = 5 * 60; // treat comments within 5 minutes as one comment
|
||||
$groupedComments = [];
|
||||
|
||||
|
@ -116,15 +110,16 @@ class CommentService {
|
|||
/**
|
||||
* Add comment
|
||||
*/
|
||||
public function add(string $message, ?int $pollId = null, ?string $token = null): Comment {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD);
|
||||
} else {
|
||||
$this->acl->setPollId($pollId, Acl::PERMISSION_COMMENT_ADD);
|
||||
}
|
||||
public function get(int $commentId): Comment {
|
||||
return $this->commentMapper->find($commentId);
|
||||
}
|
||||
/**
|
||||
* Add comment
|
||||
*/
|
||||
public function add(string $message, Acl $acl): Comment {
|
||||
$this->comment = new Comment();
|
||||
$this->comment->setPollId($this->acl->getPollId());
|
||||
$this->comment->setUserId($this->acl->getUserId());
|
||||
$this->comment->setPollId($acl->getPollId());
|
||||
$this->comment->setUserId($acl->getUserId());
|
||||
$this->comment->setComment($message);
|
||||
$this->comment->setTimestamp(time());
|
||||
$this->comment = $this->commentMapper->insert($this->comment);
|
||||
|
@ -137,23 +132,16 @@ class CommentService {
|
|||
/**
|
||||
* Delete comment
|
||||
*/
|
||||
public function delete(int $commentId, string $token = ''): Comment {
|
||||
$this->comment = $this->commentMapper->find($commentId);
|
||||
public function delete(Comment $comment, Acl $acl): Comment {
|
||||
$acl->validatePollId($comment->getPollId());
|
||||
|
||||
if ($token) {
|
||||
$this->acl->setToken($token, Acl::PERMISSION_COMMENT_ADD, $this->comment->getPollId());
|
||||
} else {
|
||||
$this->acl->setPollId($this->comment->getPollId());
|
||||
if (!$acl->getIsOwner()) {
|
||||
$acl->validateUserId($comment->getUserId());
|
||||
}
|
||||
|
||||
if (!$this->acl->getIsOwner()) {
|
||||
$this->acl->validateUserId($this->comment->getUserId());
|
||||
}
|
||||
$this->commentMapper->delete($comment);
|
||||
$this->eventDispatcher->dispatchTyped(new CommentDeleteEvent($comment));
|
||||
|
||||
$this->commentMapper->delete($this->comment);
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new CommentDeleteEvent($this->comment));
|
||||
|
||||
return $this->comment;
|
||||
return $comment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ use OCA\Polls\Model\Mail\ConfirmationMail;
|
|||
use OCA\Polls\Model\Mail\InvitationMail;
|
||||
use OCA\Polls\Model\Mail\NotificationMail;
|
||||
use OCA\Polls\Model\Mail\ReminderMail;
|
||||
use OCA\Polls\Model\UserGroup\UserBase;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class MailService {
|
||||
|
@ -130,7 +130,7 @@ class MailService {
|
|||
$sentMails = [];
|
||||
$abortedMails = [];
|
||||
|
||||
foreach ($share->getUserObject()->getMembers() as $recipient) {
|
||||
foreach ($this->userService->getUserFromShare($share)->getMembers() as $recipient) {
|
||||
$invitation = new InvitationMail($recipient->getId(), $share);
|
||||
|
||||
try {
|
||||
|
@ -162,18 +162,20 @@ class MailService {
|
|||
}
|
||||
}
|
||||
|
||||
public function sendConfirmation($pollId): array {
|
||||
/**
|
||||
* Send a confirmation mail for the poll to all participants
|
||||
*/
|
||||
public function sendConfirmations($pollId): array {
|
||||
$sentMails = [];
|
||||
$abortedMails = [];
|
||||
|
||||
$participants = $this->userService->getParticipants($pollId);
|
||||
foreach ($participants as $participant) {
|
||||
if ($this->sendConfirmationToParticipant($participant, $pollId)) {
|
||||
if ($this->sendConfirmationMail($participant, $pollId)) {
|
||||
$sentMails[] = $participant->getDisplayName();
|
||||
} else {
|
||||
$abortedMails[] = $participant->getDisplayName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return [
|
||||
|
@ -195,11 +197,8 @@ class MailService {
|
|||
}
|
||||
}
|
||||
|
||||
private function sendConfirmationToParticipant(UserBase $participant, int $pollId) : bool {
|
||||
$confirmation = new ConfirmationMail(
|
||||
$participant->getId(),
|
||||
$pollId
|
||||
);
|
||||
private function sendConfirmationMail(UserBase $participant, int $pollId) : bool {
|
||||
$confirmation = new ConfirmationMail($participant->getId(), $pollId);
|
||||
|
||||
try {
|
||||
$confirmation->send();
|
||||
|
@ -209,11 +208,12 @@ class MailService {
|
|||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error sending confirmation to ' . json_encode($participant));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function sendAutoReminderToRecipients(Share $share, Poll $poll) {
|
||||
foreach ($share->getUserObject()->getMembers() as $recipient) {
|
||||
foreach ($this->userService->getUserFromShare($share)->getMembers() as $recipient) {
|
||||
$reminder = new ReminderMail(
|
||||
$recipient->getId(),
|
||||
$poll->getId()
|
||||
|
|
|
@ -39,6 +39,7 @@ use OCA\Polls\Event\PollOptionReorderedEvent;
|
|||
use OCA\Polls\Exceptions\DuplicateEntryException;
|
||||
use OCA\Polls\Exceptions\InvalidPollTypeException;
|
||||
use OCA\Polls\Exceptions\InvalidOptionPropertyException;
|
||||
use OCA\Polls\Exceptions\NotAuthorizedException;
|
||||
use OCA\Polls\Model\Acl;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\DB\Exception;
|
||||
|
@ -105,9 +106,9 @@ class OptionService {
|
|||
*
|
||||
* @psalm-return array<array-key, Option>
|
||||
*/
|
||||
public function list(?int $pollId, ?string $token = null): array {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token);
|
||||
public function list(?int $pollId, ?Acl $acl = null): array {
|
||||
if ($acl) {
|
||||
$this->acl = $acl;
|
||||
} else {
|
||||
$this->acl->setPollId($pollId);
|
||||
}
|
||||
|
@ -159,9 +160,9 @@ class OptionService {
|
|||
*
|
||||
* @return Option
|
||||
*/
|
||||
public function add(?int $pollId, int $timestamp = 0, string $pollOptionText = '', ?int $duration = 0, string $token = ''): Option {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token, Acl::PERMISSION_OPTIONS_ADD);
|
||||
public function add(?int $pollId, int $timestamp = 0, string $pollOptionText = '', ?int $duration = 0, ?Acl $acl = null): Option {
|
||||
if ($acl) {
|
||||
$this->acl = $acl;
|
||||
} else {
|
||||
$this->acl->setPollId($pollId, Acl::PERMISSION_OPTIONS_ADD);
|
||||
}
|
||||
|
@ -234,15 +235,19 @@ class OptionService {
|
|||
*
|
||||
* @return Option
|
||||
*/
|
||||
public function delete(int $optionId, string $token = ''): Option {
|
||||
public function delete(int $optionId, ?Acl $acl = null): Option {
|
||||
$this->option = $this->optionMapper->find($optionId);
|
||||
|
||||
if ($token) {
|
||||
$this->acl->setToken($token, Acl::PERMISSION_POLL_VIEW, $this->option->getPollId());
|
||||
if ($acl) {
|
||||
$this->acl = $acl;
|
||||
} else {
|
||||
$this->acl->setPollId($this->option->getPollId());
|
||||
}
|
||||
|
||||
if ($this->option->getPollId() !== $this->acl->getPollid()) {
|
||||
throw new NotAuthorizedException();
|
||||
}
|
||||
|
||||
if ($this->option->getOwner() !== $this->acl->getUserId()) {
|
||||
$this->acl->request(Acl::PERMISSION_POLL_EDIT);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
namespace OCA\Polls\Service;
|
||||
|
||||
use OCA\Polls\Db\PollMapper;
|
||||
use OCA\Polls\Db\ShareMapper;
|
||||
use OCA\Polls\Db\Share;
|
||||
use OCA\Polls\Event\ShareChangedDisplayNameEvent;
|
||||
|
@ -39,7 +38,7 @@ use OCA\Polls\Exceptions\ShareAlreadyExistsException;
|
|||
use OCA\Polls\Exceptions\NotFoundException;
|
||||
use OCA\Polls\Exceptions\InvalidUsernameException;
|
||||
use OCA\Polls\Model\Acl;
|
||||
use OCA\Polls\Model\UserGroup\UserBase;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
|
@ -49,6 +48,8 @@ use OCP\Security\ISecureRandom;
|
|||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ShareService {
|
||||
// Define user types, which can carry locale informations
|
||||
public const SHARE_ALLOW_LOCALE = [UserBase::TYPE_EXTERNAL, UserBase::TYPE_CONTACT];
|
||||
|
||||
/** @var Acl */
|
||||
private $acl;
|
||||
|
@ -68,9 +69,6 @@ class ShareService {
|
|||
/** @var NotificationService */
|
||||
private $notificationService;
|
||||
|
||||
/** @var PollMapper */
|
||||
private $pollMapper;
|
||||
|
||||
/** @var ShareMapper */
|
||||
private $shareMapper;
|
||||
|
||||
|
@ -104,7 +102,6 @@ class ShareService {
|
|||
IUserSession $userSession,
|
||||
ShareMapper $shareMapper,
|
||||
SystemService $systemService,
|
||||
PollMapper $pollMapper,
|
||||
Share $share,
|
||||
MailService $mailService,
|
||||
Acl $acl,
|
||||
|
@ -118,7 +115,6 @@ class ShareService {
|
|||
$this->secureRandom = $secureRandom;
|
||||
$this->shareMapper = $shareMapper;
|
||||
$this->systemService = $systemService;
|
||||
$this->pollMapper = $pollMapper;
|
||||
$this->share = $share;
|
||||
$this->mailService = $mailService;
|
||||
$this->acl = $acl;
|
||||
|
@ -147,61 +143,8 @@ class ShareService {
|
|||
return $this->shares;
|
||||
}
|
||||
|
||||
private function sortByCategory() : void {
|
||||
$sortedShares = [];
|
||||
foreach (Share::TYPE_SORT_ARRAY as $shareType) {
|
||||
$filteredShares = array_filter($this->shares, function ($share) use ($shareType) {
|
||||
return $share->getType() === $shareType;
|
||||
});
|
||||
$sortedShares = array_merge($sortedShares, $filteredShares);
|
||||
}
|
||||
$this->shares = $sortedShares;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if share type is allowed to be used in a public poll
|
||||
* or is accessibale for use by the current user
|
||||
*/
|
||||
private function validateShareType() : void {
|
||||
$currentUser = $this->userService->getCurrentUser();
|
||||
|
||||
switch ($this->share->getType()) {
|
||||
case Share::TYPE_PUBLIC:
|
||||
// public shares are always valid
|
||||
break;
|
||||
case Share::TYPE_USER:
|
||||
if ($this->share->getUserId() !== $currentUser->getId()) {
|
||||
// share is not valid for user
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
break;
|
||||
case Share::TYPE_ADMIN:
|
||||
if ($this->share->getUserId() !== $currentUser->getId()) {
|
||||
// share is not valid for user
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
break;
|
||||
case Share::TYPE_GROUP:
|
||||
if (!$currentUser->getIsLoggedIn()) {
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
|
||||
if (!$this->groupManager->isInGroup($this->share->getUserId(), $this->userId)) {
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
break;
|
||||
case Share::TYPE_EMAIL:
|
||||
break;
|
||||
case Share::TYPE_EXTERNAL:
|
||||
break;
|
||||
default:
|
||||
$this->logger->alert(json_encode('invalid share type ' . $this->share->getType()));
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get share by token
|
||||
* Get share by token for accessing the poll
|
||||
*/
|
||||
public function get(string $token, bool $validateShareType = false): Share {
|
||||
try {
|
||||
|
@ -212,15 +155,15 @@ class ShareService {
|
|||
} catch (DoesNotExistException $e) {
|
||||
throw new NotFoundException('Token ' . $token . ' does not exist');
|
||||
}
|
||||
// Allow users entering the poll with a public share access
|
||||
|
||||
// Exception: logged in user accesses the poll via public share link
|
||||
if ($this->share->getType() === Share::TYPE_PUBLIC && $this->userSession->isLoggedIn()) {
|
||||
try {
|
||||
// Test if the user has already access.
|
||||
// Check, if he is already authorized for this poll
|
||||
$this->acl->setPollId($this->share->getPollId());
|
||||
} catch (NotAuthorizedException $e) {
|
||||
// If he is not authorized until now, createNewShare a new personal share for this user.
|
||||
// Return the created share
|
||||
// If he is not authorized for this poll, create a personal share
|
||||
// for this user and return the created share instead of the public share
|
||||
return $this->createNewShare(
|
||||
$this->share->getPollId(),
|
||||
$this->userService->getUser(Share::TYPE_USER, $this->userSession->getUser()->getUID()),
|
||||
|
@ -232,9 +175,7 @@ class ShareService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get share by token
|
||||
*
|
||||
* @return Share
|
||||
* Flag invitation of this share as sent
|
||||
*/
|
||||
public function setInvitationSent(string $token): Share {
|
||||
$share = $this->shareMapper->findByToken($token);
|
||||
|
@ -242,71 +183,6 @@ class ShareService {
|
|||
return $this->shareMapper->update($share);
|
||||
}
|
||||
|
||||
/**
|
||||
* crate a new share
|
||||
*
|
||||
* @return Share
|
||||
*/
|
||||
private function createNewShare(int $pollId, UserBase $userGroup, bool $preventInvitation = false): Share {
|
||||
$preventInvitation = $userGroup->getType() === UserBase::TYPE_PUBLIC ?: $preventInvitation;
|
||||
$token = $this->secureRandom->generate(
|
||||
16,
|
||||
ISecureRandom::CHAR_DIGITS .
|
||||
ISecureRandom::CHAR_LOWER .
|
||||
ISecureRandom::CHAR_UPPER
|
||||
);
|
||||
|
||||
$this->share = new Share();
|
||||
$this->share->setToken($token);
|
||||
$this->share->setPollId($pollId);
|
||||
|
||||
// Convert user type contact to share type email
|
||||
if ($userGroup->getType() === UserBase::TYPE_CONTACT) {
|
||||
$this->share->setType(Share::TYPE_EMAIL);
|
||||
$this->share->setUserId($userGroup->getEmailAddress());
|
||||
} else {
|
||||
$this->share->setType($userGroup->getType());
|
||||
$this->share->setUserId($userGroup->getType() === UserBase::TYPE_PUBLIC ? $token : $userGroup->getPublicId());
|
||||
}
|
||||
|
||||
$this->share->setInvitationSent($preventInvitation ? time() : 0);
|
||||
$this->share->setDisplayName($userGroup->getDisplayName());
|
||||
$this->share->setEmailAddress($userGroup->getEmailAddress());
|
||||
|
||||
$this->share = $this->shareMapper->insert($this->share);
|
||||
|
||||
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add share
|
||||
*
|
||||
* @return Share
|
||||
*/
|
||||
public function add(int $pollId, string $type, string $userId = '', string $displayName = '', string $emailAddress = ''): Share {
|
||||
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
|
||||
|
||||
if ($type === UserBase::TYPE_PUBLIC) {
|
||||
$this->acl->request(ACL::PERMISSION_PUBLIC_SHARES);
|
||||
} else {
|
||||
try {
|
||||
$this->shareMapper->findByPollAndUser($pollId, $userId);
|
||||
throw new ShareAlreadyExistsException;
|
||||
} catch (MultipleObjectsReturnedException $e) {
|
||||
throw new ShareAlreadyExistsException;
|
||||
} catch (DoesNotExistException $e) {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
|
||||
$this->createNewShare($pollId, $this->userService->getUser($type, $userId, $displayName, $emailAddress));
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new ShareCreateEvent($this->share));
|
||||
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change share type
|
||||
*/
|
||||
|
@ -343,29 +219,23 @@ class ShareService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set emailAddress of personal share
|
||||
* Set emailAddress of personal public share
|
||||
*
|
||||
* @return Share
|
||||
*/
|
||||
public function setEmailAddress(string $token, string $emailAddress, bool $emptyIsValid = false): Share {
|
||||
try {
|
||||
$this->share = $this->shareMapper->findByToken($token);
|
||||
} catch (DoesNotExistException $e) {
|
||||
throw new NotFoundException('Token ' . $token . ' does not exist');
|
||||
}
|
||||
|
||||
if ($this->share->getType() === Share::TYPE_EXTERNAL) {
|
||||
public function setEmailAddress(Share $share, string $emailAddress, bool $emptyIsValid = false): Share {
|
||||
if ($share->getType() === Share::TYPE_EXTERNAL) {
|
||||
$this->systemService->validateEmailAddress($emailAddress, $emptyIsValid);
|
||||
$this->share->setEmailAddress($emailAddress);
|
||||
$share->setEmailAddress($emailAddress);
|
||||
// TODO: Send confirmation
|
||||
$this->share = $this->shareMapper->update($this->share);
|
||||
$share = $this->shareMapper->update($share);
|
||||
} else {
|
||||
throw new InvalidShareTypeException('Email address can only be set in external shares.');
|
||||
}
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new ShareChangedEmailEvent($this->share));
|
||||
$this->eventDispatcher->dispatchTyped(new ShareChangedEmailEvent($share));
|
||||
|
||||
return $this->share;
|
||||
return $share;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -373,15 +243,11 @@ class ShareService {
|
|||
*
|
||||
* @return Share
|
||||
*/
|
||||
public function setDisplayName(string $token, string $displayName): Share {
|
||||
try {
|
||||
$this->share = $this->shareMapper->findByToken($token);
|
||||
} catch (DoesNotExistException $e) {
|
||||
throw new NotFoundException('Token ' . $token . ' does not exist');
|
||||
}
|
||||
public function setDisplayName(Share $share, string $displayName): Share {
|
||||
$this->share = $share;
|
||||
|
||||
if ($this->share->getType() === Share::TYPE_EXTERNAL) {
|
||||
$this->systemService->validatePublicUsername($displayName, $token);
|
||||
$this->systemService->validatePublicUsername($displayName, $this->share);
|
||||
$this->share->setDisplayName($displayName);
|
||||
// TODO: Send confirmation
|
||||
$this->share = $this->shareMapper->update($this->share);
|
||||
|
@ -395,85 +261,58 @@ class ShareService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete emailAddress of personal share
|
||||
*
|
||||
* @return Share
|
||||
* Delete emailAddress of the personal share
|
||||
*/
|
||||
public function deleteEmailAddress(string $token): Share {
|
||||
try {
|
||||
$this->share = $this->shareMapper->findByToken($token);
|
||||
} catch (DoesNotExistException $e) {
|
||||
throw new NotFoundException('Token ' . $token . ' does not exist');
|
||||
}
|
||||
|
||||
if ($this->share->getType() === Share::TYPE_EXTERNAL) {
|
||||
$this->share->setEmailAddress('');
|
||||
return $this->shareMapper->update($this->share);
|
||||
public function deleteEmailAddress(Share $share): Share {
|
||||
if ($share->getType() === Share::TYPE_EXTERNAL) {
|
||||
$share->setEmailAddress('');
|
||||
return $this->shareMapper->update($share);
|
||||
} else {
|
||||
throw new InvalidShareTypeException('Email address can only be set in external shares.');
|
||||
}
|
||||
}
|
||||
|
||||
private function generatePublicUserId(string $token, string $prefix = 'ex_'): string {
|
||||
$publicUserId = '';
|
||||
|
||||
while ($publicUserId === '') {
|
||||
$publicUserId = $prefix . $this->secureRandom->generate(
|
||||
8,
|
||||
ISecureRandom::CHAR_DIGITS .
|
||||
ISecureRandom::CHAR_LOWER .
|
||||
ISecureRandom::CHAR_UPPER
|
||||
);
|
||||
|
||||
try {
|
||||
// make sure, the user id is unique
|
||||
$this->systemService->validatePublicUsername($publicUserId, $token);
|
||||
} catch (InvalidUsernameException $th) {
|
||||
$publicUserId = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $publicUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a personal share from a public share
|
||||
* or update an email share with the username
|
||||
*
|
||||
* @return Share
|
||||
*/
|
||||
public function register(string $token, string $userName, string $emailAddress = ''): Share {
|
||||
try {
|
||||
$this->share = $this->shareMapper->findByToken($token);
|
||||
$poll = $this->pollMapper->find($this->share->getPollId());
|
||||
} catch (DoesNotExistException $e) {
|
||||
throw new NotFoundException('Token ' . $token . ' does not exist');
|
||||
}
|
||||
|
||||
$this->systemService->validatePublicUsername($userName, $token);
|
||||
public function register(
|
||||
Share $share,
|
||||
string $userName,
|
||||
string $emailAddress = '',
|
||||
string $language = '',
|
||||
string $locale = '',
|
||||
string $timeZone = ''
|
||||
): Share {
|
||||
$this->share = $share;
|
||||
$this->systemService->validatePublicUsername($userName, $this->share);
|
||||
|
||||
if ($this->share->getPublicPollEmail() !== Share::EMAIL_DISABLED) {
|
||||
$this->systemService->validateEmailAddress($emailAddress, $this->share->getPublicPollEmail() !== Share::EMAIL_MANDATORY);
|
||||
}
|
||||
|
||||
$userId = $this->generatePublicUserId($token);
|
||||
|
||||
$userId = $this->generatePublicUserId();
|
||||
|
||||
if ($this->share->getType() === Share::TYPE_PUBLIC) {
|
||||
// Create new external share for user, who entered the poll via public link,
|
||||
// prevent invtation sending, when no email address is given
|
||||
$this->createNewShare(
|
||||
$this->share->getPollId(),
|
||||
$this->userService->getUser(Share::TYPE_EXTERNAL, $userId, $userName, $emailAddress),
|
||||
!$emailAddress
|
||||
$this->userService->getUser(Share::TYPE_EXTERNAL, $userId, $userName, $emailAddress, $language, $locale, $timeZone),
|
||||
!$emailAddress,
|
||||
$timeZone
|
||||
);
|
||||
$this->eventDispatcher->dispatchTyped(new ShareRegistrationEvent($this->share));
|
||||
} elseif ($this->share->getType() === Share::TYPE_EMAIL
|
||||
|| $this->share->getType() === Share::TYPE_CONTACT) {
|
||||
$this->userService->getUser(Share::TYPE_EXTERNAL, $userId, $userName, $emailAddress, $language, $locale, $timeZone);
|
||||
|
||||
// Convert email and contact shares to external share, if user registers
|
||||
$this->share->setType(Share::TYPE_EXTERNAL);
|
||||
$this->share->setUserId($userId);
|
||||
$this->share->setDisplayName($userName);
|
||||
$this->share->setTimeZoneName($timeZone);
|
||||
$this->share->setLanguage($language);
|
||||
|
||||
// prepare for resending invitation to new email address
|
||||
if ($emailAddress !== $this->share->getEmailAddress()) {
|
||||
|
@ -527,11 +366,199 @@ class ShareService {
|
|||
// $sentResult = ['sentMails' => [new User($share->getuserId())]];
|
||||
// $this->shareService->setInvitationSent($token);
|
||||
} elseif ($share->getType() === Share::TYPE_GROUP) {
|
||||
foreach ($share->getUserObject()->getMembers() as $member) {
|
||||
foreach ($this->userService->getUserFromShare($share)->getMembers() as $member) {
|
||||
$this->notificationService->sendInvitation($share->getPollId(), $member->getId());
|
||||
}
|
||||
}
|
||||
|
||||
return $this->mailService->sendInvitation($token);
|
||||
}
|
||||
|
||||
private function generatePublicUserId(string $prefix = 'ex_'): string {
|
||||
$publicUserId = '';
|
||||
|
||||
while ($publicUserId === '') {
|
||||
$publicUserId = $prefix . $this->secureRandom->generate(
|
||||
8,
|
||||
ISecureRandom::CHAR_DIGITS .
|
||||
ISecureRandom::CHAR_LOWER .
|
||||
ISecureRandom::CHAR_UPPER
|
||||
);
|
||||
|
||||
try {
|
||||
// make sure, the user id is unique
|
||||
$this->systemService->validatePublicUsername($publicUserId, $this->share);
|
||||
} catch (InvalidUsernameException $th) {
|
||||
$publicUserId = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $publicUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert this share to personal public (aka external) share
|
||||
*/
|
||||
private function convertToExternal(
|
||||
UserBase $userGroup
|
||||
): void {
|
||||
$this->share->setType(Share::TYPE_EXTERNAL);
|
||||
$this->share->setUserId($userGroup->getPublicId());
|
||||
$this->share->setDisplayName($userGroup->getDisplayName());
|
||||
$this->share->setTimeZoneName($userGroup->getTimeZoneName());
|
||||
$this->share->setLanguage($userGroup->getLanguageCode());
|
||||
|
||||
// prepare for resending invitation to new email address
|
||||
if ($userGroup->getEmailAddress() !== $this->share->getEmailAddress()) {
|
||||
$this->share->setInvitationSent(0);
|
||||
}
|
||||
$this->share->setEmailAddress($userGroup->getEmailAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add share
|
||||
*
|
||||
* @return Share
|
||||
*/
|
||||
public function add(
|
||||
int $pollId,
|
||||
string $type,
|
||||
string $userId = '',
|
||||
string $displayName = '',
|
||||
string $emailAddress = ''
|
||||
): Share {
|
||||
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
|
||||
|
||||
if ($type === UserBase::TYPE_PUBLIC) {
|
||||
$this->acl->request(Acl::PERMISSION_PUBLIC_SHARES);
|
||||
} else {
|
||||
try {
|
||||
$this->shareMapper->findByPollAndUser($pollId, $userId);
|
||||
throw new ShareAlreadyExistsException;
|
||||
} catch (MultipleObjectsReturnedException $e) {
|
||||
throw new ShareAlreadyExistsException;
|
||||
} catch (DoesNotExistException $e) {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
|
||||
$this->createNewShare($pollId, $this->userService->getUser($type, $userId, $displayName, $emailAddress));
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new ShareCreateEvent($this->share));
|
||||
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
private function sortByCategory(): void {
|
||||
$sortedShares = [];
|
||||
foreach (Share::TYPE_SORT_ARRAY as $shareType) {
|
||||
$filteredShares = array_filter($this->shares, function ($share) use ($shareType) {
|
||||
return $share->getType() === $shareType;
|
||||
});
|
||||
$sortedShares = array_merge($sortedShares, $filteredShares);
|
||||
}
|
||||
$this->shares = $sortedShares;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if share type is allowed to be used in a public poll
|
||||
* or is accessibale for use by the current user
|
||||
*/
|
||||
private function validateShareType(): void {
|
||||
$currentUser = $this->userService->getCurrentUser();
|
||||
|
||||
switch ($this->share->getType()) {
|
||||
case Share::TYPE_PUBLIC:
|
||||
// public shares are always valid
|
||||
break;
|
||||
case Share::TYPE_USER:
|
||||
if ($this->share->getUserId() !== $currentUser->getId()) {
|
||||
// share is not valid for user
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
break;
|
||||
case Share::TYPE_ADMIN:
|
||||
if ($this->share->getUserId() !== $currentUser->getId()) {
|
||||
// share is not valid for user
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
break;
|
||||
case Share::TYPE_GROUP:
|
||||
if (!$currentUser->getIsLoggedIn()) {
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
|
||||
if (!$this->groupManager->isInGroup($this->share->getUserId(), $this->userId)) {
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
break;
|
||||
case Share::TYPE_EMAIL:
|
||||
break;
|
||||
case Share::TYPE_EXTERNAL:
|
||||
break;
|
||||
default:
|
||||
$this->logger->alert(json_encode('invalid share type ' . $this->share->getType()));
|
||||
throw new NotAuthorizedException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* crate a new share
|
||||
*/
|
||||
private function createNewShare(
|
||||
int $pollId,
|
||||
UserBase $userGroup,
|
||||
bool $preventInvitation = false,
|
||||
string $timeZone = ''
|
||||
): Share {
|
||||
$preventInvitation = $userGroup->getType() === UserBase::TYPE_PUBLIC ?: $preventInvitation;
|
||||
$token = $this->secureRandom->generate(
|
||||
16,
|
||||
ISecureRandom::CHAR_DIGITS .
|
||||
ISecureRandom::CHAR_LOWER .
|
||||
ISecureRandom::CHAR_UPPER
|
||||
);
|
||||
|
||||
$this->share = new Share();
|
||||
$this->share->setToken($token);
|
||||
$this->share->setPollId($pollId);
|
||||
$this->share->setType($userGroup->getType());
|
||||
$this->share->setDisplayName($userGroup->getDisplayName());
|
||||
$this->share->setInvitationSent($preventInvitation ? time() : 0);
|
||||
$this->share->setEmailAddress($userGroup->getEmailAddress());
|
||||
$this->share->setUserId($userGroup->getPublicId());
|
||||
|
||||
if (
|
||||
$userGroup->getType() === UserBase::TYPE_USER
|
||||
|| $userGroup->getType() === UserBase::TYPE_ADMIN
|
||||
) {
|
||||
$this->share = $this->shareMapper->insert($this->share);
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
if ($userGroup->getType() === UserBase::TYPE_PUBLIC) {
|
||||
$this->share->setUserId($token);
|
||||
|
||||
$this->share = $this->shareMapper->insert($this->share);
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
// Convert user type contact to share type email
|
||||
if ($userGroup->getType() === UserBase::TYPE_CONTACT) {
|
||||
$this->share->setType(Share::TYPE_EMAIL);
|
||||
$this->share->setUserId($userGroup->getEmailAddress());
|
||||
$this->share = $this->shareMapper->insert($this->share);
|
||||
return $this->share;
|
||||
}
|
||||
|
||||
// user is created from public share. Store locale information for
|
||||
// usage in server side actions, i.e. scheduled emails
|
||||
if ($userGroup->getType() === UserBase::TYPE_EXTERNAL) {
|
||||
$this->share->setLanguage($userGroup->getLanguageCode());
|
||||
$this->share->setTimeZoneName($timeZone);
|
||||
}
|
||||
|
||||
$this->share = $this->shareMapper->insert($this->share);
|
||||
return $this->share;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,15 +46,9 @@ class SubscriptionService {
|
|||
$this->acl = $acl;
|
||||
}
|
||||
|
||||
public function get(?int $pollId = null, ?string $token = null): bool {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token);
|
||||
} else {
|
||||
$this->acl->setPollId($pollId);
|
||||
}
|
||||
|
||||
public function get(Acl $acl): bool {
|
||||
try {
|
||||
$this->subscriptionMapper->findByPollAndUser($this->acl->getPollId(), $this->acl->getUserId());
|
||||
$this->subscriptionMapper->findByPollAndUser($acl->getPollId(), $acl->getUserId());
|
||||
// Subscription exists
|
||||
return true;
|
||||
} catch (DoesNotExistException $e) {
|
||||
|
@ -62,30 +56,17 @@ class SubscriptionService {
|
|||
}
|
||||
}
|
||||
|
||||
public function add(int $pollId, string $userId): void {
|
||||
$subscription = new Subscription();
|
||||
$subscription->setPollId($pollId);
|
||||
$subscription->setUserId($userId);
|
||||
$this->subscriptionMapper->insert($subscription);
|
||||
}
|
||||
|
||||
public function set(bool $subscribed, ?int $pollId = null, ?string $token = null): bool {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token);
|
||||
} else {
|
||||
$this->acl->setPollId($pollId);
|
||||
}
|
||||
|
||||
public function set(bool $subscribed, Acl $acl): bool {
|
||||
if (!$subscribed) {
|
||||
try {
|
||||
$subscription = $this->subscriptionMapper->findByPollAndUser($this->acl->getPollId(), $this->acl->getUserId());
|
||||
$subscription = $this->subscriptionMapper->findByPollAndUser($acl->getPollId(), $acl->getUserId());
|
||||
$this->subscriptionMapper->delete($subscription);
|
||||
} catch (DoesNotExistException $e) {
|
||||
// catch silently (assume already unsubscribed)
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$this->add($this->acl->getPollId(), $this->acl->getUserId());
|
||||
$this->add($acl->getPollId(), $acl->getUserId());
|
||||
} catch (UniqueConstraintViolationException $e) {
|
||||
// deprecated NC22
|
||||
// catch silently (assume already subscribed)
|
||||
|
@ -98,4 +79,11 @@ class SubscriptionService {
|
|||
}
|
||||
return $subscribed;
|
||||
}
|
||||
|
||||
private function add(int $pollId, string $userId): void {
|
||||
$subscription = new Subscription();
|
||||
$subscription->setPollId($pollId);
|
||||
$subscription->setUserId($userId);
|
||||
$this->subscriptionMapper->insert($subscription);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,19 +23,19 @@
|
|||
|
||||
namespace OCA\Polls\Service;
|
||||
|
||||
use OCA\Polls\Db\Share;
|
||||
use OCA\Polls\Db\ShareMapper;
|
||||
use OCA\Polls\Db\VoteMapper;
|
||||
use OCA\Polls\Exceptions\TooShortException;
|
||||
use OCA\Polls\Exceptions\InvalidUsernameException;
|
||||
use OCA\Polls\Exceptions\InvalidEmailAddress;
|
||||
use OCA\Polls\Exceptions\NotAuthorizedException;
|
||||
use OCA\Polls\Helper\Container;
|
||||
use OCA\Polls\Model\UserGroup\Circle;
|
||||
use OCA\Polls\Model\UserGroup\Contact;
|
||||
use OCA\Polls\Model\UserGroup\ContactGroup;
|
||||
use OCA\Polls\Model\UserGroup\Email;
|
||||
use OCA\Polls\Model\UserGroup\Group;
|
||||
use OCA\Polls\Model\UserGroup\User;
|
||||
use OCA\Polls\Model\Group\Circle;
|
||||
use OCA\Polls\Model\User\Contact;
|
||||
use OCA\Polls\Model\Group\ContactGroup;
|
||||
use OCA\Polls\Model\User\Email;
|
||||
use OCA\Polls\Model\Group\Group;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCP\IUserManager;
|
||||
|
||||
class SystemService {
|
||||
|
@ -144,14 +144,7 @@ class SystemService {
|
|||
*
|
||||
* @return true
|
||||
*/
|
||||
public function validatePublicUsername(string $userName, string $token): bool {
|
||||
try {
|
||||
$share = $this->shareMapper->findByToken($token);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotAuthorizedException('Token invalid');
|
||||
}
|
||||
|
||||
|
||||
public function validatePublicUsername(string $userName, Share $share): bool {
|
||||
if (!$userName) {
|
||||
throw new TooShortException('Username must not be empty');
|
||||
}
|
||||
|
|
|
@ -23,19 +23,20 @@
|
|||
|
||||
namespace OCA\Polls\Service;
|
||||
|
||||
use OCA\Polls\Db\Share;
|
||||
use OCA\Polls\Db\ShareMapper;
|
||||
use OCA\Polls\Db\VoteMapper;
|
||||
use OCA\Polls\Exceptions\Exception;
|
||||
use OCA\Polls\Exceptions\InvalidShareTypeException;
|
||||
use OCA\Polls\Model\UserGroup\Admin;
|
||||
use OCA\Polls\Model\UserGroup\Circle;
|
||||
use OCA\Polls\Model\UserGroup\Contact;
|
||||
use OCA\Polls\Model\UserGroup\ContactGroup;
|
||||
use OCA\Polls\Model\UserGroup\Email;
|
||||
use OCA\Polls\Model\UserGroup\GenericUser;
|
||||
use OCA\Polls\Model\UserGroup\Group;
|
||||
use OCA\Polls\Model\UserGroup\User;
|
||||
use OCA\Polls\Model\UserGroup\UserBase;
|
||||
use OCA\Polls\Model\User\Admin;
|
||||
use OCA\Polls\Model\Group\Circle;
|
||||
use OCA\Polls\Model\Group\ContactGroup;
|
||||
use OCA\Polls\Model\User\Contact;
|
||||
use OCA\Polls\Model\User\Email;
|
||||
use OCA\Polls\Model\User\GenericUser;
|
||||
use OCA\Polls\Model\Group\Group;
|
||||
use OCA\Polls\Model\User\User;
|
||||
use OCA\Polls\Model\UserBase;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\Collaboration\Collaborators\ISearch;
|
||||
use OCP\ISession;
|
||||
|
@ -81,55 +82,58 @@ class UserService {
|
|||
|
||||
/**
|
||||
* getCurrentUser - Get current user from userbase or from share in public polls
|
||||
* @return Admin|Circle|Contact|ContactGroup|Email|GenericUser|Group|User
|
||||
*/
|
||||
|
||||
public function getCurrentUser() {
|
||||
public function getCurrentUser() : UserBase {
|
||||
// If there is a valid user session, get current user from session
|
||||
if ($this->userSession->getUser()) {
|
||||
return $this->getUserFromShare($this->userSession->getUser()->getUID());
|
||||
return new User($this->userSession->getUser()->getUID());
|
||||
}
|
||||
|
||||
// Retrieve token and get current user from share
|
||||
$token = $this->session->get('publicPollToken');
|
||||
|
||||
if ($token) {
|
||||
return $this->getUserFromShare($token);
|
||||
$share = $this->shareMapper->findByToken($token);
|
||||
return $this->getUserFromShare($share);
|
||||
}
|
||||
|
||||
throw new DoesNotExistException('User not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluateUser - Get user by name; and poll in case of a share user of the particulair poll
|
||||
* evaluateUser - Get user by name and poll in case of a share user of the particulair poll
|
||||
*/
|
||||
|
||||
public function evaluateUser(string $userId, int $pollId = 0): ?UserBase {
|
||||
// if a user with this name exists, return from the user base
|
||||
$user = $this->userManager->get($userId);
|
||||
if ($user) {
|
||||
return new User($userId);
|
||||
}
|
||||
// Otherwise get it from a share that belongs to the poll and return the share user
|
||||
try {
|
||||
$share = $this->shareMapper->findByPollAndUser($pollId, $userId);
|
||||
return $this->getUser(
|
||||
$share->getType(),
|
||||
$share->getUserId(),
|
||||
$share->getDisplayName(),
|
||||
$share->getEmailAddress()
|
||||
);
|
||||
return $this->getUserFromShare($share);
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get participans of a poll as array of users
|
||||
* @return Admin|Circle|Contact|ContactGroup|Email|GenericUser|Group|User
|
||||
* Get participans of a poll as array of user objects
|
||||
* @return array<array-key, mixed>
|
||||
*/
|
||||
public function getParticipants($pollId) : array {
|
||||
$users = [];
|
||||
// get the distict list of usernames from the votes
|
||||
$participants = $this->voteMapper->findParticipantsByPoll($pollId);
|
||||
|
||||
foreach ($participants as &$participant) {
|
||||
$user = $this->evaluateUser($participant->getUserId(), $pollId);
|
||||
if ($user) {
|
||||
// replace every entry with a user object
|
||||
$users[] = $this->evaluateUser($participant->getUserId(), $pollId);
|
||||
}
|
||||
}
|
||||
|
@ -140,19 +144,21 @@ class UserService {
|
|||
* Create user from share
|
||||
* @return Admin|Circle|Contact|ContactGroup|Email|GenericUser|Group|User
|
||||
*/
|
||||
public function getUserFromShare(string $token) {
|
||||
$share = $this->shareMapper->findByToken($token);
|
||||
public function getUserFromShare(Share $share) : UserBase {
|
||||
return $this->getUser(
|
||||
$share->getType(),
|
||||
$share->getUserId(),
|
||||
$share->getDisplayName(),
|
||||
$share->getEmailAddress()
|
||||
$share->getEmailAddress(),
|
||||
$share->getLanguage(),
|
||||
$share->getLocale(),
|
||||
$share->getTimeZoneName()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* search all possible sharees - use ISearch to respect autocomplete restrictions
|
||||
* get a list of user objects from the backend matching the query string
|
||||
*/
|
||||
public function search(string $query = ''): array {
|
||||
$items = [];
|
||||
|
@ -162,6 +168,7 @@ class UserService {
|
|||
IShare::TYPE_EMAIL
|
||||
];
|
||||
if (Circle::isEnabled() && class_exists('\OCA\Circles\ShareByCircleProvider')) {
|
||||
// Add circles to the search, if app is enabled
|
||||
$types[] = IShare::TYPE_CIRCLE;
|
||||
}
|
||||
|
||||
|
@ -199,10 +206,10 @@ class UserService {
|
|||
}
|
||||
|
||||
/**
|
||||
* create a new user object
|
||||
* create a new user object based on $type
|
||||
* @return Circle|Contact|ContactGroup|Email|GenericUser|Group|User|Admin
|
||||
*/
|
||||
public function getUser(string $type, string $id, string $displayName = '', string $emailAddress = ''): UserBase {
|
||||
public function getUser(string $type, string $id, string $displayName = '', string $emailAddress = '', ?string $language = '', string $locale = '', string $timeZoneName = ''): UserBase {
|
||||
switch ($type) {
|
||||
case Group::TYPE:
|
||||
return new Group($id);
|
||||
|
@ -217,11 +224,11 @@ class UserService {
|
|||
case Admin::TYPE:
|
||||
return new Admin($id);
|
||||
case Email::TYPE:
|
||||
return new Email($id, $displayName, $emailAddress);
|
||||
return new Email($id, $displayName, $emailAddress, $language);
|
||||
case UserBase::TYPE_PUBLIC:
|
||||
return new GenericUser($id, UserBase::TYPE_PUBLIC);
|
||||
case UserBase::TYPE_EXTERNAL:
|
||||
return new GenericUser($id, UserBase::TYPE_EXTERNAL, $displayName, $emailAddress);
|
||||
return new GenericUser($id, UserBase::TYPE_EXTERNAL, $displayName, $emailAddress, $language, $locale, $timeZoneName);
|
||||
default:
|
||||
throw new InvalidShareTypeException('Invalid user type (' . $type . ')');
|
||||
}
|
||||
|
|
|
@ -74,9 +74,9 @@ class VoteService {
|
|||
*
|
||||
* @return Vote[]
|
||||
*/
|
||||
public function list(?int $pollId, string $token = '') : array {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token);
|
||||
public function list(?int $pollId, ?Acl $acl = null) : array {
|
||||
if ($acl) {
|
||||
$this->acl = $acl;
|
||||
} else {
|
||||
$this->acl->setPollId($pollId);
|
||||
}
|
||||
|
@ -119,11 +119,12 @@ class VoteService {
|
|||
/**
|
||||
* Set vote
|
||||
*/
|
||||
public function set(int $optionId, string $setTo, string $token = ''): ?Vote {
|
||||
public function set(int $optionId, string $setTo, ?Acl $acl = null): ?Vote {
|
||||
$option = $this->optionMapper->find($optionId);
|
||||
|
||||
if ($token) {
|
||||
$this->acl->setToken($token, Acl::PERMISSION_VOTE_EDIT, $option->getPollId());
|
||||
if ($acl) {
|
||||
$this->acl = $acl; // ->setToken($token, Acl::PERMISSION_VOTE_EDIT, $option->getPollId());
|
||||
// $this->acl->setToken($token, Acl::PERMISSION_VOTE_EDIT, $option->getPollId());
|
||||
} else {
|
||||
$this->acl->setPollId($option->getPollId(), Acl::PERMISSION_VOTE_EDIT);
|
||||
}
|
||||
|
@ -161,9 +162,9 @@ class VoteService {
|
|||
/**
|
||||
* Remove user from poll
|
||||
*/
|
||||
public function delete(?int $pollId, ?string $userId, string $token = ''): string {
|
||||
if ($token) {
|
||||
$this->acl->setToken($token, Acl::PERMISSION_VOTE_EDIT);
|
||||
public function delete(?int $pollId, ?string $userId, ?Acl $acl = null): string {
|
||||
if ($acl) {
|
||||
$this->acl = $acl;
|
||||
$userId = $this->acl->getUserId();
|
||||
$pollId = $this->acl->getPollId();
|
||||
} else {
|
||||
|
|
|
@ -89,6 +89,7 @@ const actions = {
|
|||
headers: { Accept: 'application/json' },
|
||||
userName: payload.userName,
|
||||
emailAddress: payload.emailAddress,
|
||||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
})
|
||||
|
||||
if (payload.saveCookie && context.state.type === 'public') {
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<div v-if="acl.allowAddOptions && proposalsOpen && !closed" class="area__proposal">
|
||||
<OptionProposals />
|
||||
</div>
|
||||
<div class="area__confirmation">
|
||||
<div v-if="showConfirmationMail" class="area__confirmation">
|
||||
<ActionSendConfirmedOptions />
|
||||
</div>
|
||||
|
||||
|
@ -135,8 +135,13 @@ export default {
|
|||
proposalsOpen: 'poll/proposalsOpen',
|
||||
countHiddenParticipants: 'poll/countHiddenParticipants',
|
||||
safeTable: 'poll/safeTable',
|
||||
confirmedOptions: 'options/confirmed',
|
||||
}),
|
||||
|
||||
showConfirmationMail() {
|
||||
return this.acl.isOwner && this.closed && this.confirmedOptions.length > 0
|
||||
},
|
||||
|
||||
/* eslint-disable-next-line vue/no-unused-properties */
|
||||
windowTitle() {
|
||||
return `${t('polls', 'Polls')} - ${this.poll.title}`
|
||||
|
|
Загрузка…
Ссылка в новой задаче