Replace glob by EventDispatcher
Signed-off-by: Vitor Mattos <vitor@php.rio>
This commit is contained in:
committed by
Julius Härtl
parent
f2b6934ac3
commit
ccd5bce7ea
@@ -1,4 +1,32 @@
|
|||||||
## Implement import
|
## Implement import
|
||||||
|
|
||||||
* Create a new class `lib/Service/Importer/Systems/<ImportName>Service.php` where `<ImportName>` is the name of the source system.
|
* Create a new importer class extending `ABoardImportService`
|
||||||
|
* Create a listener for event `BoardImportGetAllowedEvent` to enable your importer.
|
||||||
|
> You can read more about listeners on [Nextcloud](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html?highlight=event#writing-a-listener) doc.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
class YourCustomImporterListener {
|
||||||
|
public function handle(Event $event): void {
|
||||||
|
if (!($event instanceof BoardImportGetAllowedEvent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$event->getService()->addAllowedImportSystem([
|
||||||
|
'name' => YourCustomImporterService::$name,
|
||||||
|
'class' => YourCustomImporterService::class,
|
||||||
|
'internalName' => 'YourCustomImporter'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
* Register your listener on your `Application` class like this:
|
||||||
|
```php
|
||||||
|
$dispatcher = $this->getContainer()->query(IEventDispatcher::class);
|
||||||
|
$dispatcher->registerEventListener(
|
||||||
|
BoardImportGetAllowedEvent::class,
|
||||||
|
YourCustomImporterListener::class
|
||||||
|
);
|
||||||
|
```
|
||||||
* Use the `lib/Service/Importer/Systems/TrelloJsonService.php` class as inspiration
|
* Use the `lib/Service/Importer/Systems/TrelloJsonService.php` class as inspiration
|
||||||
44
lib/Event/ABoardImportGetAllowedEvent.php
Normal file
44
lib/Event/ABoardImportGetAllowedEvent.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (c) 2021 Vitor Mattos <vitor@php.rio>
|
||||||
|
*
|
||||||
|
* @author Vitor Mattos <vitor@php.rio>
|
||||||
|
*
|
||||||
|
* @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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Deck\Event;
|
||||||
|
|
||||||
|
use OCA\Deck\Service\Importer\BoardImportService;
|
||||||
|
use OCP\EventDispatcher\Event;
|
||||||
|
|
||||||
|
abstract class ABoardImportGetAllowedEvent extends Event {
|
||||||
|
private $service;
|
||||||
|
|
||||||
|
public function __construct(BoardImportService $service) {
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->service = $service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getService(): BoardImportService {
|
||||||
|
return $this->service;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
lib/Event/BoardImportGetAllowedEvent.php
Normal file
29
lib/Event/BoardImportGetAllowedEvent.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (c) 2021 Vitor Mattos <vitor@php.rio>
|
||||||
|
*
|
||||||
|
* @author Vitor Mattos <vitor@php.rio>
|
||||||
|
*
|
||||||
|
* @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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\Deck\Event;
|
||||||
|
|
||||||
|
class BoardImportGetAllowedEvent extends ABoardImportGetAllowedEvent {
|
||||||
|
}
|
||||||
@@ -92,6 +92,8 @@ abstract class ABoardImportService {
|
|||||||
|
|
||||||
abstract public function validateUsers(): void;
|
abstract public function validateUsers(): void;
|
||||||
|
|
||||||
|
abstract public function getJsonSchemaPath(): string;
|
||||||
|
|
||||||
public function updateStack(string $id, Stack $stack): void {
|
public function updateStack(string $id, Stack $stack): void {
|
||||||
$this->stacks[$id] = $stack;
|
$this->stacks[$id] = $stack;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ class BoardImportCommandService extends BoardImportService {
|
|||||||
return $v['message'];
|
return $v['message'];
|
||||||
}, $e->getData()));
|
}, $e->getData()));
|
||||||
$this->getOutput()->writeln('Valid schema:');
|
$this->getOutput()->writeln('Valid schema:');
|
||||||
$schemaPath = __DIR__ . '/fixtures/config-' . $this->getSystem() . '-schema.json';
|
$this->getOutput()->writeln(print_r(file_get_contents($this->getJsonSchemaPath()), true));
|
||||||
$this->getOutput()->writeln(print_r(file_get_contents($schemaPath), true));
|
|
||||||
$this->getInput()->setOption('config', '');
|
$this->getInput()->setOption('config', '');
|
||||||
}
|
}
|
||||||
$this->validateConfig();
|
$this->validateConfig();
|
||||||
|
|||||||
@@ -36,11 +36,16 @@ use OCA\Deck\Db\BoardMapper;
|
|||||||
use OCA\Deck\Db\CardMapper;
|
use OCA\Deck\Db\CardMapper;
|
||||||
use OCA\Deck\Db\LabelMapper;
|
use OCA\Deck\Db\LabelMapper;
|
||||||
use OCA\Deck\Db\StackMapper;
|
use OCA\Deck\Db\StackMapper;
|
||||||
|
use OCA\Deck\Event\BoardImportGetAllowedEvent;
|
||||||
use OCA\Deck\Exceptions\ConflictException;
|
use OCA\Deck\Exceptions\ConflictException;
|
||||||
use OCA\Deck\NotFoundException;
|
use OCA\Deck\NotFoundException;
|
||||||
|
use OCA\Deck\Service\FileService;
|
||||||
|
use OCA\Deck\Service\Importer\Systems\TrelloApiService;
|
||||||
|
use OCA\Deck\Service\Importer\Systems\TrelloJsonService;
|
||||||
use OCP\Comments\IComment;
|
use OCP\Comments\IComment;
|
||||||
use OCP\Comments\ICommentsManager;
|
use OCP\Comments\ICommentsManager;
|
||||||
use OCP\Comments\NotFoundException as CommentNotFoundException;
|
use OCP\Comments\NotFoundException as CommentNotFoundException;
|
||||||
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
use OCP\IUserManager;
|
use OCP\IUserManager;
|
||||||
|
|
||||||
class BoardImportService {
|
class BoardImportService {
|
||||||
@@ -62,6 +67,8 @@ class BoardImportService {
|
|||||||
private $attachmentMapper;
|
private $attachmentMapper;
|
||||||
/** @var ICommentsManager */
|
/** @var ICommentsManager */
|
||||||
private $commentsManager;
|
private $commentsManager;
|
||||||
|
/** @var IEventDispatcher */
|
||||||
|
private $eventDispatcher;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $system = '';
|
private $system = '';
|
||||||
/** @var null|ABoardImportService */
|
/** @var null|ABoardImportService */
|
||||||
@@ -96,7 +103,8 @@ class BoardImportService {
|
|||||||
AssignmentMapper $assignmentMapper,
|
AssignmentMapper $assignmentMapper,
|
||||||
AttachmentMapper $attachmentMapper,
|
AttachmentMapper $attachmentMapper,
|
||||||
CardMapper $cardMapper,
|
CardMapper $cardMapper,
|
||||||
ICommentsManager $commentsManager
|
ICommentsManager $commentsManager,
|
||||||
|
IEventDispatcher $eventDispatcher
|
||||||
) {
|
) {
|
||||||
$this->userManager = $userManager;
|
$this->userManager = $userManager;
|
||||||
$this->boardMapper = $boardMapper;
|
$this->boardMapper = $boardMapper;
|
||||||
@@ -107,6 +115,7 @@ class BoardImportService {
|
|||||||
$this->assignmentMapper = $assignmentMapper;
|
$this->assignmentMapper = $assignmentMapper;
|
||||||
$this->attachmentMapper = $attachmentMapper;
|
$this->attachmentMapper = $attachmentMapper;
|
||||||
$this->commentsManager = $commentsManager;
|
$this->commentsManager = $commentsManager;
|
||||||
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->board = new Board();
|
$this->board = new Board();
|
||||||
$this->disableCommentsEvents();
|
$this->disableCommentsEvents();
|
||||||
}
|
}
|
||||||
@@ -161,29 +170,25 @@ class BoardImportService {
|
|||||||
return $this->system;
|
return $this->system;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addAllowedImportSystem($system): self {
|
||||||
|
$this->allowedSystems[] = $system;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAllowedImportSystems(): array {
|
public function getAllowedImportSystems(): array {
|
||||||
if (!$this->allowedSystems) {
|
if (!$this->allowedSystems) {
|
||||||
$allowedSystems = glob(__DIR__ . '/Systems/*Service.php');
|
$this->addAllowedImportSystem([
|
||||||
$allowedSystems = array_map(function ($filename) {
|
'name' => TrelloApiService::$name,
|
||||||
preg_match('/\/(?<class>(?<system>\w+)Service)\.php$/', $filename, $matches);
|
'class' => TrelloApiService::class,
|
||||||
$className = 'OCA\Deck\Service\Importer\Systems\\'.$matches['class'];
|
'internalName' => 'TrelloApi'
|
||||||
if (!class_exists($className)) {
|
]);
|
||||||
/** @psalm-suppress UnresolvableInclude */
|
$this->addAllowedImportSystem([
|
||||||
require_once $className;
|
'name' => TrelloJsonService::$name,
|
||||||
}
|
'class' => TrelloJsonService::class,
|
||||||
/** @psalm-suppress InvalidPropertyFetch */
|
'internalName' => 'TrelloJson'
|
||||||
$name = $className::$name;
|
]);
|
||||||
if (empty($name)) {
|
|
||||||
$name = lcfirst($matches['system']);
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
'name' => $name,
|
|
||||||
'class' => $className,
|
|
||||||
'internalName' => lcfirst($matches['system'])
|
|
||||||
];
|
|
||||||
}, $allowedSystems);
|
|
||||||
$this->allowedSystems = array_values($allowedSystems);
|
|
||||||
}
|
}
|
||||||
|
$this->eventDispatcher->dispatchTyped(new BoardImportGetAllowedEvent($this));
|
||||||
return $this->allowedSystems;
|
return $this->allowedSystems;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +197,7 @@ class BoardImportService {
|
|||||||
throw new NotFoundException('System to import not found');
|
throw new NotFoundException('System to import not found');
|
||||||
}
|
}
|
||||||
if (!is_object($this->systemInstance)) {
|
if (!is_object($this->systemInstance)) {
|
||||||
$systemClass = 'OCA\\Deck\\Service\\BoardImport' . ucfirst($this->getSystem()) . 'Service';
|
$systemClass = 'OCA\\Deck\\Service\\Importer\\Systems\\' . ucfirst($this->getSystem()) . 'Service';
|
||||||
$this->systemInstance = \OC::$server->get($systemClass);
|
$this->systemInstance = \OC::$server->get($systemClass);
|
||||||
$this->systemInstance->setImportService($this);
|
$this->systemInstance->setImportService($this);
|
||||||
}
|
}
|
||||||
@@ -421,7 +426,7 @@ class BoardImportService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getJsonSchemaPath(): string {
|
public function getJsonSchemaPath(): string {
|
||||||
return __DIR__ . '/fixtures/config-' . $this->getSystem() . '-schema.json';
|
return $this->getImportSystem()->getJsonSchemaPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateOwner(): void {
|
public function validateOwner(): void {
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ class TrelloApiService extends TrelloJsonService {
|
|||||||
parent::bootstrap();
|
parent::bootstrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getJsonSchemaPath(): string {
|
||||||
|
return implode(DIRECTORY_SEPARATOR, [
|
||||||
|
__DIR__,
|
||||||
|
'..',
|
||||||
|
'fixtures',
|
||||||
|
'config-trelloApi-schema.json',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
private function populateActions(): void {
|
private function populateActions(): void {
|
||||||
$data = $this->getImportService()->getData();
|
$data = $this->getImportService()->getData();
|
||||||
$data->actions = $this->doRequest(
|
$data->actions = $this->doRequest(
|
||||||
|
|||||||
@@ -65,6 +65,15 @@ class TrelloJsonService extends ABoardImportService {
|
|||||||
$this->validateUsers();
|
$this->validateUsers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getJsonSchemaPath(): string {
|
||||||
|
return implode(DIRECTORY_SEPARATOR, [
|
||||||
|
__DIR__,
|
||||||
|
'..',
|
||||||
|
'fixtures',
|
||||||
|
'config-trelloJson-schema.json',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function validateUsers(): void {
|
public function validateUsers(): void {
|
||||||
if (empty($this->getImportService()->getConfig('uidRelation'))) {
|
if (empty($this->getImportService()->getConfig('uidRelation'))) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -35,8 +35,10 @@ use OCA\Deck\Db\Label;
|
|||||||
use OCA\Deck\Db\LabelMapper;
|
use OCA\Deck\Db\LabelMapper;
|
||||||
use OCA\Deck\Db\Stack;
|
use OCA\Deck\Db\Stack;
|
||||||
use OCA\Deck\Db\StackMapper;
|
use OCA\Deck\Db\StackMapper;
|
||||||
|
use OCA\Deck\Event\BoardImportGetAllowedEvent;
|
||||||
use OCA\Deck\Service\Importer\Systems\TrelloJsonService;
|
use OCA\Deck\Service\Importer\Systems\TrelloJsonService;
|
||||||
use OCP\Comments\ICommentsManager;
|
use OCP\Comments\ICommentsManager;
|
||||||
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
use OCP\IUserManager;
|
use OCP\IUserManager;
|
||||||
@@ -63,6 +65,8 @@ class BoardImportServiceTest extends \Test\TestCase {
|
|||||||
private $attachmentMapper;
|
private $attachmentMapper;
|
||||||
/** @var ICommentsManager|MockObject */
|
/** @var ICommentsManager|MockObject */
|
||||||
private $commentsManager;
|
private $commentsManager;
|
||||||
|
/** @var IEventDispatcher|MockObject */
|
||||||
|
private $eventDispatcher;
|
||||||
/** @var TrelloJsonService|MockObject */
|
/** @var TrelloJsonService|MockObject */
|
||||||
private $trelloJsonService;
|
private $trelloJsonService;
|
||||||
/** @var BoardImportService|MockObject */
|
/** @var BoardImportService|MockObject */
|
||||||
@@ -77,6 +81,7 @@ class BoardImportServiceTest extends \Test\TestCase {
|
|||||||
$this->assignmentMapper = $this->createMock(AssignmentMapper::class);
|
$this->assignmentMapper = $this->createMock(AssignmentMapper::class);
|
||||||
$this->attachmentMapper = $this->createMock(AttachmentMapper::class);
|
$this->attachmentMapper = $this->createMock(AttachmentMapper::class);
|
||||||
$this->commentsManager = $this->createMock(ICommentsManager::class);
|
$this->commentsManager = $this->createMock(ICommentsManager::class);
|
||||||
|
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
|
||||||
$this->boardImportService = new BoardImportService(
|
$this->boardImportService = new BoardImportService(
|
||||||
$this->userManager,
|
$this->userManager,
|
||||||
$this->boardMapper,
|
$this->boardMapper,
|
||||||
@@ -86,18 +91,33 @@ class BoardImportServiceTest extends \Test\TestCase {
|
|||||||
$this->assignmentMapper,
|
$this->assignmentMapper,
|
||||||
$this->attachmentMapper,
|
$this->attachmentMapper,
|
||||||
$this->cardMapper,
|
$this->cardMapper,
|
||||||
$this->commentsManager
|
$this->commentsManager,
|
||||||
|
$this->eventDispatcher
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->boardImportService->setSystem('trelloJson');
|
$this->boardImportService->setSystem('trelloJson');
|
||||||
|
|
||||||
|
$this->eventDispatcher
|
||||||
|
->method('dispatchTyped')
|
||||||
|
->willReturnCallback(function (BoardImportGetAllowedEvent $event) {
|
||||||
|
$event->getService()->addAllowedImportSystem([
|
||||||
|
'name' => TrelloJsonService::$name,
|
||||||
|
'class' => TrelloJsonService::class,
|
||||||
|
'internalName' => 'trelloJson'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
$data = json_decode(file_get_contents(__DIR__ . '/../../../data/data-trelloJson.json'));
|
$data = json_decode(file_get_contents(__DIR__ . '/../../../data/data-trelloJson.json'));
|
||||||
$this->boardImportService->setData($data);
|
$this->boardImportService->setData($data);
|
||||||
|
|
||||||
$configInstance = json_decode(file_get_contents(__DIR__ . '/../../../data/config-trelloJson.json'));
|
$configFile = __DIR__ . '/../../../data/config-trelloJson.json';
|
||||||
|
$configInstance = json_decode(file_get_contents($configFile));
|
||||||
$this->boardImportService->setConfigInstance($configInstance);
|
$this->boardImportService->setConfigInstance($configInstance);
|
||||||
|
|
||||||
$this->trelloJsonService = $this->createMock(TrelloJsonService::class);
|
$this->trelloJsonService = $this->createMock(TrelloJsonService::class);
|
||||||
|
$this->trelloJsonService
|
||||||
|
->method('getJsonSchemaPath')
|
||||||
|
->willReturn($configFile);
|
||||||
$this->boardImportService->setImportSystem($this->trelloJsonService);
|
$this->boardImportService->setImportSystem($this->trelloJsonService);
|
||||||
|
|
||||||
$owner = $this->createMock(IUser::class);
|
$owner = $this->createMock(IUser::class);
|
||||||
|
|||||||
Reference in New Issue
Block a user