initial transfer ownership
Signed-off-by: dartcafe <github@dartcafe.de>
This commit is contained in:
Родитель
f254e9c33f
Коммит
3904d95446
|
@ -39,6 +39,7 @@
|
|||
<command>OCA\Polls\Command\Share\Add</command>
|
||||
<command>OCA\Polls\Command\Share\Remove</command>
|
||||
<command>OCA\Polls\Command\Db\Rebuild</command>
|
||||
<command>OCA\Polls\Command\Poll\TransferOwnership</command>
|
||||
</commands>
|
||||
<settings>
|
||||
<admin-section>OCA\Polls\Settings\AdminSection</admin-section>
|
||||
|
|
|
@ -67,6 +67,8 @@ return [
|
|||
['name' => 'poll#clone', 'url' => '/poll/{pollId}/clone', 'verb' => 'GET'],
|
||||
['name' => 'poll#getParticipantsEmailAddresses', 'url' => '/poll/{pollId}/addresses', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'poll#transfer_polls', 'url' => '/polls/transfer/{sourceUser}/{destinationUser}', 'verb' => 'PUT'],
|
||||
|
||||
['name' => 'option#list', 'url' => '/poll/{pollId}/options', 'verb' => 'GET'],
|
||||
['name' => 'option#add', 'url' => '/option', 'verb' => 'POST'],
|
||||
['name' => 'option#addBulk', 'url' => '/option/bulk', 'verb' => 'POST'],
|
||||
|
@ -118,6 +120,7 @@ return [
|
|||
|
||||
// REST-API calls
|
||||
['name' => 'poll_api#list', 'url' => '/api/v1.0/polls', 'verb' => 'GET'],
|
||||
['name' => 'poll_api#transfer_polls', 'url' => '/api/v1.0/polls/transfer/{sourceUser}/{destinationUser}', 'verb' => 'PUT'],
|
||||
['name' => 'poll_api#add', 'url' => '/api/v1.0/poll', 'verb' => 'POST'],
|
||||
['name' => 'poll_api#get', 'url' => '/api/v1.0/poll/{pollId}', 'verb' => 'GET'],
|
||||
['name' => 'poll_api#update', 'url' => '/api/v1.0/poll/{pollId}', 'verb' => 'PUT'],
|
||||
|
|
|
@ -47,6 +47,7 @@ use OCA\Polls\Event\PollArchivedEvent;
|
|||
use OCA\Polls\Event\PollCreatedEvent;
|
||||
use OCA\Polls\Event\PollDeletedEvent;
|
||||
use OCA\Polls\Event\PollExpiredEvent;
|
||||
use OCA\Polls\Event\PollOwnerChangeEvent;
|
||||
use OCA\Polls\Event\PollRestoredEvent;
|
||||
use OCA\Polls\Event\PollTakeoverEvent;
|
||||
use OCA\Polls\Event\PollUpdatedEvent;
|
||||
|
@ -98,6 +99,7 @@ class Application extends App implements IBootstrap {
|
|||
$context->registerEventListener(PollDeletedEvent::class, PollListener::class);
|
||||
$context->registerEventListener(PollExpiredEvent::class, PollListener::class);
|
||||
$context->registerEventListener(PollRestoredEvent::class, PollListener::class);
|
||||
$context->registerEventListener(PollOwnerChangeEvent::class, PollListener::class);
|
||||
$context->registerEventListener(PollTakeoverEvent::class, PollListener::class);
|
||||
$context->registerEventListener(PollUpdatedEvent::class, PollListener::class);
|
||||
$context->registerEventListener(ShareChangedEmailEvent::class, ShareListener::class);
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @author René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Command\Poll;
|
||||
|
||||
use OCA\Polls\Service\PollService;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
|
||||
class TransferOwnership extends Command {
|
||||
/** @var PollService */
|
||||
private $pollService;
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
public function __construct(
|
||||
IUserManager $userManager,
|
||||
PollService $pollService
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->pollService = $pollService;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
protected function configure(): void {
|
||||
$this
|
||||
->setName('polls:poll:transfer-ownership')
|
||||
->setDescription('Transfer the ownership of one user\'s polls to another user.')
|
||||
->addArgument(
|
||||
'source-user',
|
||||
InputArgument::REQUIRED,
|
||||
'User id to transfer the polls from'
|
||||
)
|
||||
->addArgument(
|
||||
'target-user',
|
||||
InputArgument::REQUIRED,
|
||||
'User id to transfer the polls to'
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
if ($this->requestConfirmation($input, $output)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!$this->userManager->get($input->getArgument('target-user')) instanceof IUser) {
|
||||
$output->writeln('<error> Unknown destination user ' . $input->getArgument('target-user') . '</error>');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$transferredPolls = $this->pollService->transferPolls($input->getArgument('source-user'), $input->getArgument('target-user'));
|
||||
|
||||
if (sizeof($transferredPolls) < 1) {
|
||||
$output->writeln('<info>No polls were transferred from ' . $input->getArgument('source-user') . '</info>');
|
||||
|
||||
} else if (sizeof($transferredPolls) === 1) {
|
||||
$output->writeln('<info>One poll was transferred from ' . $input->getArgument('source-user') . ' to ' . $input->getArgument('target-user') . '</info>');
|
||||
$output->writeln('<info> * ' . $transferredPolls[0]->getId() . ' - ' . $transferredPolls[0]->getTitle() . '</info>');
|
||||
|
||||
} else {
|
||||
$output->writeln('<info>' . sizeof($transferredPolls) . ' polls were transferred from ' . $input->getArgument('source-user') . ' to ' . $input->getArgument('target-user') . '</info>');
|
||||
foreach ($transferredPolls as $poll) {
|
||||
$output->writeln('<info> * ' . $poll->getId() . ' - ' . $poll->getTitle() . '</info>');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function requestConfirmation(InputInterface $input, OutputInterface $output): int {
|
||||
if ($input->isInteractive()) {
|
||||
$helper = $this->getHelper('question');
|
||||
$output->writeln('<comment>This command will change the ownership of all polls of ' . $input->getArgument('source-user') . ' to ' . $input->getArgument('target-user') . '.</comment>');
|
||||
$output->writeln('<comment>NO notifications will be sent to the users.</comment>');
|
||||
$output->writeln('');
|
||||
|
||||
$question = new ConfirmationQuestion('Continue with the transfer (y/n)? [n] ', false);
|
||||
if (!$helper->ask($input, $output, $question)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -168,6 +168,19 @@ class PollApiController extends ApiController {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone poll
|
||||
* @CORS
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function transferPolls(string $sourceUser, string $targetUser): JSONResponse {
|
||||
try {
|
||||
return new JSONResponse(['transferred' => $this->pollService->transferPolls($sourceUser, $targetUser)], Http::STATUS_CREATED);
|
||||
} catch (Exception $e) {
|
||||
return new JSONResponse(['message' => $e->getMessage()], $e->getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect email addresses from particitipants
|
||||
* @NoAdminRequired
|
||||
|
|
|
@ -138,6 +138,13 @@ class PollController extends Controller {
|
|||
return $this->get($pollId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer polls between users
|
||||
*/
|
||||
public function transferPolls(string $sourceUser, string $targetUser): JSONResponse {
|
||||
return $this->response(fn () => $this->pollService->transferPolls($sourceUser, $targetUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect email addresses from particitipants
|
||||
* @NoAdminRequired
|
||||
|
|
|
@ -94,6 +94,18 @@ class PollMapper extends QBMapper {
|
|||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Poll[]
|
||||
*/
|
||||
public function findOwner(string $userId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from($this->getTableName())
|
||||
->where($qb->expr()->eq('owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)));
|
||||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Poll[]
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/*
|
||||
* @copyright Copyright (c) 2021 René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @author René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Event;
|
||||
|
||||
use OCA\Polls\Db\Poll;
|
||||
|
||||
class PollOwnerChangeEvent extends PollEvent {
|
||||
public function __construct(
|
||||
Poll $poll
|
||||
) {
|
||||
parent::__construct($poll);
|
||||
$this->activitySubject = self::OWNER_CHANGE;
|
||||
}
|
||||
}
|
|
@ -26,12 +26,11 @@ namespace OCA\Polls\Event;
|
|||
use OCA\Polls\Notification\Notifier;
|
||||
use OCA\Polls\Db\Poll;
|
||||
|
||||
class PollTakeoverEvent extends PollEvent {
|
||||
class PollTakeoverEvent extends PollOwnerChangeEvent {
|
||||
public function __construct(
|
||||
Poll $poll
|
||||
) {
|
||||
parent::__construct($poll);
|
||||
$this->activitySubject = self::OWNER_CHANGE;
|
||||
}
|
||||
|
||||
public function getNotification(): array {
|
||||
|
|
|
@ -80,6 +80,7 @@ abstract class BaseListener implements IEventListener {
|
|||
|
||||
public function handle(Event $event) : void {
|
||||
$this->event = $event;
|
||||
|
||||
try {
|
||||
$this->checkClass();
|
||||
$this->addLog();
|
||||
|
@ -111,7 +112,6 @@ abstract class BaseListener implements IEventListener {
|
|||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
// add a cron job, if necessary (i.e. for removed users and groups)
|
||||
$this->addCronJob();
|
||||
|
||||
|
|
|
@ -41,11 +41,15 @@ use OCA\Polls\Db\Vote;
|
|||
use OCA\Polls\Event\PollArchivedEvent;
|
||||
use OCA\Polls\Event\PollCreatedEvent;
|
||||
use OCA\Polls\Event\PollDeletedEvent;
|
||||
use OCA\Polls\Event\PollOwnerChangeEvent;
|
||||
use OCA\Polls\Event\PollRestoredEvent;
|
||||
use OCA\Polls\Event\PollTakeoverEvent;
|
||||
use OCA\Polls\Event\PollUpdatedEvent;
|
||||
use OCA\Polls\Exceptions\InvalidUsernameException;
|
||||
use OCA\Polls\Model\Acl;
|
||||
use OCA\Polls\Model\Settings\AppSettings;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
|
||||
class PollService {
|
||||
|
||||
|
@ -54,6 +58,9 @@ class PollService {
|
|||
|
||||
/** @var IEventDispatcher */
|
||||
private $eventDispatcher;
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
@ -87,6 +94,7 @@ class PollService {
|
|||
AppSettings $appSettings,
|
||||
IEventDispatcher $eventDispatcher,
|
||||
IGroupManager $groupManager,
|
||||
IUserManager $userManager,
|
||||
IUserSession $userSession,
|
||||
MailService $mailService,
|
||||
Poll $poll,
|
||||
|
@ -103,6 +111,7 @@ class PollService {
|
|||
$this->poll = $poll;
|
||||
$this->pollMapper = $pollMapper;
|
||||
$this->userId = $UserId;
|
||||
$this->userManager = $userManager;
|
||||
$this->userSession = $userSession;
|
||||
$this->voteMapper = $voteMapper;
|
||||
$this->vote = $vote;
|
||||
|
@ -191,6 +200,20 @@ class PollService {
|
|||
return $this->poll;
|
||||
}
|
||||
|
||||
public function transferPolls(string $sourceUser, string $targetUser) {
|
||||
if ($this->userManager->get($targetUser) instanceof IUser) {
|
||||
$pollsToTransfer = $this->pollMapper->findOwner($sourceUser);
|
||||
foreach ($pollsToTransfer as $poll) {
|
||||
$poll->setOwner($targetUser);
|
||||
$this->pollMapper->update($poll);
|
||||
$this->eventDispatcher->dispatchTyped(new PollOwnerChangeEvent($poll));
|
||||
}
|
||||
return $pollsToTransfer;
|
||||
}
|
||||
throw new InvalidUsernameException('The user id "' . $targetUser . '" is not valid.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get poll configuration
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче