From 8640adaf015719bb2dd49618b778eda7d4245f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D?= Date: Sun, 10 Mar 2024 15:41:35 +0100 Subject: [PATCH] chore(tests): UT for Plugin repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rubén D --- .../Controllers/Plugin/ResetController.php | 8 +- .../web/Controllers/Plugin/ViewController.php | 6 +- .../material-blue/views/plugin/plugin.inc | 6 +- .../Plugin/Models/Plugin.php} | 30 +- .../Plugin/Models/PluginData.php} | 4 +- ...Interface.php => PluginDataRepository.php} | 38 +- ...ataInterface.php => PluginDataService.php} | 8 +- .../Plugin/Ports/PluginManagerInterface.php | 14 +- .../Domain/Plugin/Ports/PluginRepository.php | 109 +++- lib/SP/Domain/Plugin/Services/PluginData.php | 35 +- .../Domain/Plugin/Services/PluginManager.php | 14 +- .../Plugin/Services/PluginOperation.php | 10 +- .../Domain/Plugin/Services/PluginRegister.php | 6 +- .../Domain/Plugin/Services/PluginUpgrader.php | 6 +- .../Plugin/Repositories/Plugin.php | 389 +++++++++++++ .../Repositories/PluginBaseRepository.php | 452 --------------- ...nDataBaseRepository.php => PluginData.php} | 61 +- tests/SPT/Generators/PluginGenerator.php | 50 ++ .../Plugin/Repositories/PluginTest.php | 522 ++++++++++++++++++ 19 files changed, 1167 insertions(+), 601 deletions(-) rename lib/SP/{Infrastructure/Plugin/Repositories/PluginModel.php => Domain/Plugin/Models/Plugin.php} (72%) rename lib/SP/{Infrastructure/Plugin/Repositories/PluginDataModel.php => Domain/Plugin/Models/PluginData.php} (92%) rename lib/SP/Domain/Plugin/Ports/{PluginDataRepositoryInterface.php => PluginDataRepository.php} (80%) rename lib/SP/Domain/Plugin/Ports/{PluginDataInterface.php => PluginDataService.php} (94%) create mode 100644 lib/SP/Infrastructure/Plugin/Repositories/Plugin.php delete mode 100644 lib/SP/Infrastructure/Plugin/Repositories/PluginBaseRepository.php rename lib/SP/Infrastructure/Plugin/Repositories/{PluginDataBaseRepository.php => PluginData.php} (83%) create mode 100644 tests/SPT/Generators/PluginGenerator.php create mode 100644 tests/SPT/Infrastructure/Plugin/Repositories/PluginTest.php diff --git a/app/modules/web/Controllers/Plugin/ResetController.php b/app/modules/web/Controllers/Plugin/ResetController.php index 87836758..9fc9298d 100644 --- a/app/modules/web/Controllers/Plugin/ResetController.php +++ b/app/modules/web/Controllers/Plugin/ResetController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -30,7 +30,7 @@ use JsonException; use SP\Core\Application; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Domain\Plugin\Ports\PluginDataInterface; +use SP\Domain\Plugin\Ports\PluginDataService; use SP\Domain\Plugin\Ports\PluginManagerInterface; use SP\Http\JsonMessage; use SP\Modules\Web\Controllers\ControllerBase; @@ -45,13 +45,13 @@ final class ResetController extends ControllerBase use JsonTrait; private PluginManagerInterface $pluginService; - private PluginDataInterface $pluginDataService; + private PluginDataService $pluginDataService; public function __construct( Application $application, WebControllerHelper $webControllerHelper, PluginManagerInterface $pluginService, - PluginDataInterface $pluginDataService + PluginDataService $pluginDataService ) { parent::__construct($application, $webControllerHelper); diff --git a/app/modules/web/Controllers/Plugin/ViewController.php b/app/modules/web/Controllers/Plugin/ViewController.php index 831c2dad..15d5bed4 100644 --- a/app/modules/web/Controllers/Plugin/ViewController.php +++ b/app/modules/web/Controllers/Plugin/ViewController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -33,10 +33,10 @@ use SP\Core\Events\Event; use SP\Domain\Core\Acl\AclActionsInterface; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Plugin\Models\Plugin; use SP\Domain\Plugin\Ports\PluginManagerInterface; use SP\Http\JsonMessage; use SP\Infrastructure\Common\Repositories\NoSuchItemException; -use SP\Infrastructure\Plugin\Repositories\PluginModel; use SP\Modules\Web\Controllers\ControllerBase; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Mvc\Controller\WebControllerHelper; @@ -116,7 +116,7 @@ final class ViewController extends ControllerBase $pluginData = $pluginId ? $this->pluginService->getById($pluginId) - : new PluginModel(); + : new Plugin(); $pluginInfo = $this->pluginManager->getPlugin($pluginData->getName()); $this->view->assign('plugin', $pluginData); diff --git a/app/modules/web/themes/material-blue/views/plugin/plugin.inc b/app/modules/web/themes/material-blue/views/plugin/plugin.inc index ba7fd8d8..86776ec1 100644 --- a/app/modules/web/themes/material-blue/views/plugin/plugin.inc +++ b/app/modules/web/themes/material-blue/views/plugin/plugin.inc @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -23,7 +23,7 @@ */ /** - * @var PluginModel $plugin + * @var Plugin $plugin * @var PluginInterface $pluginInfo * @var ThemeIconsInterface $icons * @var ConfigDataInterface $configData @@ -33,8 +33,8 @@ use SP\Domain\Config\Ports\ConfigDataInterface; use SP\Domain\Core\UI\ThemeIconsInterface; +use SP\Domain\Plugin\Models\Plugin; use SP\Domain\Plugin\Ports\PluginInterface; -use SP\Infrastructure\Plugin\Repositories\PluginModel; use SP\Mvc\View\TemplateInterface; $plugin = $_getvar('plugin'); diff --git a/lib/SP/Infrastructure/Plugin/Repositories/PluginModel.php b/lib/SP/Domain/Plugin/Models/Plugin.php similarity index 72% rename from lib/SP/Infrastructure/Plugin/Repositories/PluginModel.php rename to lib/SP/Domain/Plugin/Models/Plugin.php index 91f721a7..2166dde3 100644 --- a/lib/SP/Infrastructure/Plugin/Repositories/PluginModel.php +++ b/lib/SP/Domain/Plugin/Models/Plugin.php @@ -22,7 +22,7 @@ * along with sysPass. If not, see . */ -namespace SP\Infrastructure\Plugin\Repositories; +namespace SP\Domain\Plugin\Models; use SP\Domain\Common\Models\ItemWithIdAndNameModel; use SP\Domain\Common\Models\Model; @@ -30,7 +30,7 @@ use SP\Domain\Common\Models\Model; /** * Class PluginModel */ -class PluginModel extends Model implements ItemWithIdAndNameModel +class Plugin extends Model implements ItemWithIdAndNameModel { protected ?int $id = null; protected ?string $name = null; @@ -43,49 +43,23 @@ class PluginModel extends Model implements ItemWithIdAndNameModel return $this->id; } - public function setId(int $id): void - { - $this->id = $id; - } - public function getName(): ?string { return $this->name; } - public function setName(string $name): void - { - $this->name = $name; - } - public function getData(): ?string { return $this->data; } - public function setData(string $data): void - { - $this->data = $data; - } - public function getEnabled(): ?bool { return $this->enabled; } - public function setEnabled(bool $enabled): void - { - $this->enabled = $enabled; - } - - public function getVersionLevel(): ?string { return $this->versionLevel; } - - public function setVersionLevel(string $versionLevel): void - { - $this->versionLevel = $versionLevel; - } } diff --git a/lib/SP/Infrastructure/Plugin/Repositories/PluginDataModel.php b/lib/SP/Domain/Plugin/Models/PluginData.php similarity index 92% rename from lib/SP/Infrastructure/Plugin/Repositories/PluginDataModel.php rename to lib/SP/Domain/Plugin/Models/PluginData.php index acb90b6f..8f2b9885 100644 --- a/lib/SP/Infrastructure/Plugin/Repositories/PluginDataModel.php +++ b/lib/SP/Domain/Plugin/Models/PluginData.php @@ -22,7 +22,7 @@ * along with sysPass. If not, see . */ -namespace SP\Infrastructure\Plugin\Repositories; +namespace SP\Domain\Plugin\Models; use SP\DataModel\EncryptedModel; use SP\Domain\Common\Attributes\Encryptable; @@ -34,7 +34,7 @@ use SP\Domain\Common\Models\SerializedModel; * Class PluginDataModel */ #[Encryptable('data', 'key')] -final class PluginDataModel extends Model implements HydratableModel +final class PluginData extends Model implements HydratableModel { use SerializedModel; use EncryptedModel; diff --git a/lib/SP/Domain/Plugin/Ports/PluginDataRepositoryInterface.php b/lib/SP/Domain/Plugin/Ports/PluginDataRepository.php similarity index 80% rename from lib/SP/Domain/Plugin/Ports/PluginDataRepositoryInterface.php rename to lib/SP/Domain/Plugin/Ports/PluginDataRepository.php index 88907855..56b690e8 100644 --- a/lib/SP/Domain/Plugin/Ports/PluginDataRepositoryInterface.php +++ b/lib/SP/Domain/Plugin/Ports/PluginDataRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -26,22 +26,22 @@ namespace SP\Domain\Plugin\Ports; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Plugin\Models\PluginData as PluginDataModel; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\Plugin\Repositories\PluginDataModel; /** * Class PluginDataRepository * - * @package SP\Infrastructure\Plugin\Repositories + * @template T of PluginDataModel */ -interface PluginDataRepositoryInterface +interface PluginDataRepository { /** * Creates an item * - * @param PluginDataModel $itemData + * @param PluginDataModel $itemData * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -50,7 +50,7 @@ interface PluginDataRepositoryInterface /** * Updates an item * - * @param PluginDataModel $itemData + * @param PluginDataModel $itemData * * @return int * @throws ConstraintException @@ -61,7 +61,7 @@ interface PluginDataRepositoryInterface /** * Deletes an item * - * @param string $id + * @param string $id * * @return int * @throws ConstraintException @@ -72,8 +72,8 @@ interface PluginDataRepositoryInterface /** * Deletes an item * - * @param string $name - * @param int $itemId + * @param string $name + * @param int $itemId * * @return int * @throws ConstraintException @@ -84,9 +84,9 @@ interface PluginDataRepositoryInterface /** * Returns the item for given id * - * @param string $id + * @param string $id * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -95,7 +95,7 @@ interface PluginDataRepositoryInterface /** * Returns all the items * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -104,9 +104,9 @@ interface PluginDataRepositoryInterface /** * Returns all the items for given ids * - * @param string[] $ids + * @param string[] $ids * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -115,7 +115,7 @@ interface PluginDataRepositoryInterface /** * Deletes all the items for given ids * - * @param string[] $ids + * @param string[] $ids * * @return int * @throws ConstraintException @@ -126,10 +126,10 @@ interface PluginDataRepositoryInterface /** * Devuelve los datos de un plugin por su nombre * - * @param string $name - * @param int $itemId + * @param string $name + * @param int $itemId * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ diff --git a/lib/SP/Domain/Plugin/Ports/PluginDataInterface.php b/lib/SP/Domain/Plugin/Ports/PluginDataService.php similarity index 94% rename from lib/SP/Domain/Plugin/Ports/PluginDataInterface.php rename to lib/SP/Domain/Plugin/Ports/PluginDataService.php index 7bec1b5c..eb22dd19 100644 --- a/lib/SP/Domain/Plugin/Ports/PluginDataInterface.php +++ b/lib/SP/Domain/Plugin/Ports/PluginDataService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -29,14 +29,16 @@ use SP\Domain\Common\Services\ServiceException; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\NoSuchPropertyException; use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Plugin\Models\PluginData as PluginDataModel; use SP\Infrastructure\Common\Repositories\NoSuchItemException; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\Plugin\Repositories\PluginDataModel; /** * Class PluginDataInterface + * + * @template T of PluginDataModel */ -interface PluginDataInterface +interface PluginDataService { /** * Creates an item diff --git a/lib/SP/Domain/Plugin/Ports/PluginManagerInterface.php b/lib/SP/Domain/Plugin/Ports/PluginManagerInterface.php index dc7bb7c4..c23c4bf2 100644 --- a/lib/SP/Domain/Plugin/Ports/PluginManagerInterface.php +++ b/lib/SP/Domain/Plugin/Ports/PluginManagerInterface.php @@ -29,9 +29,9 @@ use SP\DataModel\ItemSearchData; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Plugin\Models\Plugin; use SP\Infrastructure\Common\Repositories\NoSuchItemException; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\Plugin\Repositories\PluginModel; /** * Interface PluginManagerInterface @@ -44,7 +44,7 @@ interface PluginManagerInterface * @throws ConstraintException * @throws QueryException */ - public function create(PluginModel $itemData): int; + public function create(Plugin $itemData): int; /** * Updates an item @@ -52,7 +52,7 @@ interface PluginManagerInterface * @throws ConstraintException * @throws QueryException */ - public function update(PluginModel $itemData): int; + public function update(Plugin $itemData): int; /** * Returns the item for given id @@ -61,12 +61,12 @@ interface PluginManagerInterface * @throws QueryException * @throws NoSuchItemException */ - public function getById(int $id): PluginModel; + public function getById(int $id): Plugin; /** * Returns all the items * - * @return PluginModel[] + * @return Plugin[] * @throws ConstraintException * @throws QueryException */ @@ -77,7 +77,7 @@ interface PluginManagerInterface * * @param int[] $ids * - * @return PluginModel[] + * @return Plugin[] * @throws ConstraintException * @throws QueryException */ @@ -119,7 +119,7 @@ interface PluginManagerInterface * @throws ConstraintException * @throws QueryException */ - public function getByName(string $name): PluginModel; + public function getByName(string $name): Plugin; /** * Cambiar el estado del plugin diff --git a/lib/SP/Domain/Plugin/Ports/PluginRepository.php b/lib/SP/Domain/Plugin/Ports/PluginRepository.php index 5407682b..dc1bc3fc 100644 --- a/lib/SP/Domain/Plugin/Ports/PluginRepository.php +++ b/lib/SP/Domain/Plugin/Ports/PluginRepository.php @@ -24,34 +24,84 @@ namespace SP\Domain\Plugin\Ports; +use SP\DataModel\ItemSearchData; use SP\Domain\Common\Ports\Repository; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Plugin\Models\Plugin as PluginModel; use SP\Infrastructure\Database\QueryResult; /** * Class PluginRepository * - * @package SP\Infrastructure\Plugin\Repositories + * @template T of PluginModel */ interface PluginRepository extends Repository { /** - * Devuelve los datos de un plugin por su nombre + * Creates an item * - * @param string $name + * @param PluginModel $plugin * * @return QueryResult * @throws ConstraintException * @throws QueryException */ + public function create(PluginModel $plugin): QueryResult; + + /** + * Updates an item + * + * @param PluginModel $plugin + * + * @return int + * @throws ConstraintException + * @throws QueryException + */ + public function update(PluginModel $plugin): int; + + /** + * Devuelve los datos de un plugin por su nombre + * + * @param string $name + * + * @return QueryResult + * @throws ConstraintException + * @throws QueryException + */ public function getByName(string $name): QueryResult; + /** + * Returns the item for given id + * + * @param int $pluginId + * + * @return QueryResult + */ + public function getById(int $pluginId): QueryResult; + + /** + * Returns all the items + * + * @return QueryResult + */ + public function getAll(): QueryResult; + + /** + * Returns all the items for given ids + * + * @param array $pluginsId + * + * @return QueryResult + */ + public function getByIdBatch(array $pluginsId): QueryResult; + /** * Cambiar el estado del plugin * - * @param int $id - * @param bool $enabled + * @param int $id + * @param bool $enabled * * @return int * @throws ConstraintException @@ -62,8 +112,8 @@ interface PluginRepository extends Repository /** * Cambiar el estado del plugin * - * @param string $name - * @param bool $enabled + * @param string $name + * @param bool $enabled * * @return int * @throws ConstraintException @@ -74,8 +124,8 @@ interface PluginRepository extends Repository /** * Cambiar el estado del plugin * - * @param int $id - * @param bool $available + * @param int $id + * @param bool $available * * @return int * @throws ConstraintException @@ -86,8 +136,8 @@ interface PluginRepository extends Repository /** * Cambiar el estado del plugin * - * @param string $name - * @param bool $available + * @param string $name + * @param bool $available * * @return int * @throws ConstraintException @@ -98,7 +148,7 @@ interface PluginRepository extends Repository /** * Restablecer los datos de un plugin * - * @param int $id Id del plugin + * @param int $id Id del plugin * * @return int * @throws ConstraintException @@ -109,9 +159,42 @@ interface PluginRepository extends Repository /** * Devolver los plugins activados * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ public function getEnabled(): QueryResult; + + /** + * Deletes all the items for given ids + * + * @param array $pluginsId + * + * @return QueryResult + * @throws SPException + * @throws ConstraintException + * @throws QueryException + */ + public function deleteByIdBatch(array $pluginsId): QueryResult; + + /** + * Deletes an item + * + * @param int $id + * + * @return QueryResult + * @throws ConstraintException + * @throws QueryException + */ + public function delete(int $id): QueryResult; + + /** + * Searches for items by a given filter + * + * @param ItemSearchData $itemSearchData + * + * @return QueryResult + */ + public function search(ItemSearchData $itemSearchData): QueryResult; + } diff --git a/lib/SP/Domain/Plugin/Services/PluginData.php b/lib/SP/Domain/Plugin/Services/PluginData.php index f52c5fa2..6e8f56d3 100644 --- a/lib/SP/Domain/Plugin/Services/PluginData.php +++ b/lib/SP/Domain/Plugin/Services/PluginData.php @@ -32,23 +32,22 @@ use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\CryptException; use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SPException; -use SP\Domain\Plugin\Ports\PluginDataInterface; -use SP\Domain\Plugin\Ports\PluginDataRepositoryInterface; +use SP\Domain\Plugin\Ports\PluginDataRepository; +use SP\Domain\Plugin\Ports\PluginDataService; use SP\Infrastructure\Common\Repositories\NoSuchItemException; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\Plugin\Repositories\PluginDataModel; use function SP\__u; /** * Class PluginData */ -final class PluginData extends Service implements PluginDataInterface +final class PluginData extends Service implements PluginDataService { public function __construct( - Application $application, - private readonly PluginDataRepositoryInterface $pluginDataRepository, - private readonly CryptInterface $crypt, + Application $application, + private readonly PluginDataRepository $pluginDataRepository, + private readonly CryptInterface $crypt, ) { parent::__construct($application); } @@ -57,14 +56,14 @@ final class PluginData extends Service implements PluginDataInterface /** * Creates an item * - * @param PluginDataModel $itemData + * @param \SP\Domain\Plugin\Models\PluginData $itemData * @return QueryResult * @throws ConstraintException * @throws CryptException * @throws QueryException * @throws ServiceException */ - public function create(PluginDataModel $itemData): QueryResult + public function create(PluginData $itemData): QueryResult { return $this->pluginDataRepository->create($itemData->encrypt($this->getMasterKeyFromContext(), $this->crypt)); } @@ -72,14 +71,14 @@ final class PluginData extends Service implements PluginDataInterface /** * Updates an item * - * @param PluginDataModel $itemData + * @param \SP\Domain\Plugin\Models\PluginData $itemData * @return int * @throws ConstraintException * @throws CryptException * @throws QueryException * @throws ServiceException */ - public function update(PluginDataModel $itemData): int + public function update(PluginData $itemData): int { return $this->pluginDataRepository->update($itemData->encrypt($this->getMasterKeyFromContext(), $this->crypt)); } @@ -89,14 +88,14 @@ final class PluginData extends Service implements PluginDataInterface * * @param string $name * @param int $id - * @return PluginDataModel + * @return PluginData * @throws ConstraintException * @throws CryptException * @throws NoSuchItemException * @throws QueryException * @throws ServiceException */ - public function getByItemId(string $name, int $id): PluginDataModel + public function getByItemId(string $name, int $id): PluginData { $result = $this->pluginDataRepository->getByItemId($name, $id); @@ -105,7 +104,7 @@ final class PluginData extends Service implements PluginDataInterface } - return $result->getData(PluginDataModel::class) + return $result->getData(PluginData::class) ->decrypt($this->getMasterKeyFromContext(), $this->crypt); } @@ -113,7 +112,7 @@ final class PluginData extends Service implements PluginDataInterface * Returns the item for given id * * @param string $id - * @return PluginDataModel[] + * @return PluginData[] * @throws ConstraintException * @throws CryptException * @throws NoSuchItemException @@ -129,7 +128,7 @@ final class PluginData extends Service implements PluginDataInterface } return array_map( - fn(PluginDataModel $itemData) => $itemData->decrypt($this->getMasterKeyFromContext(), $this->crypt), + fn(PluginData $itemData) => $itemData->decrypt($this->getMasterKeyFromContext(), $this->crypt), $result->getDataAsArray() ); } @@ -137,7 +136,7 @@ final class PluginData extends Service implements PluginDataInterface /** * Returns all the items * - * @return PluginDataModel[] + * @return PluginData[] * @throws ConstraintException * @throws CryptException * @throws QueryException @@ -147,7 +146,7 @@ final class PluginData extends Service implements PluginDataInterface public function getAll(): array { return array_map( - fn(PluginDataModel $itemData) => $itemData->decrypt($this->getMasterKeyFromContext(), $this->crypt), + fn(PluginData $itemData) => $itemData->decrypt($this->getMasterKeyFromContext(), $this->crypt), $this->pluginDataRepository->getAll()->getDataAsArray() ); } diff --git a/lib/SP/Domain/Plugin/Services/PluginManager.php b/lib/SP/Domain/Plugin/Services/PluginManager.php index 909c0f07..aef98d3c 100644 --- a/lib/SP/Domain/Plugin/Services/PluginManager.php +++ b/lib/SP/Domain/Plugin/Services/PluginManager.php @@ -32,27 +32,25 @@ use SP\Domain\Common\Services\ServiceException; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Plugin\Models\Plugin as PluginModel; use SP\Domain\Plugin\Ports\PluginManagerInterface; use SP\Domain\Plugin\Ports\PluginRepository; use SP\Infrastructure\Common\Repositories\NoSuchItemException; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\Plugin\Repositories\PluginBaseRepository; -use SP\Infrastructure\Plugin\Repositories\PluginModel; use function SP\__u; /** * Class PluginManager + * + * @template T of PluginModel */ final class PluginManager extends Service implements PluginManagerInterface { - private PluginBaseRepository $pluginRepository; - public function __construct(Application $application, PluginRepository $pluginRepository) + public function __construct(Application $application, private readonly PluginRepository $pluginRepository) { parent::__construct($application); - - $this->pluginRepository = $pluginRepository; } /** @@ -101,7 +99,7 @@ final class PluginManager extends Service implements PluginManagerInterface /** * Returns all the items * - * @return PluginModel[] + * @return array * @throws ConstraintException * @throws QueryException * @throws SPException @@ -116,7 +114,7 @@ final class PluginManager extends Service implements PluginManagerInterface * * @param int[] $ids * - * @return PluginModel[] + * @return array * @throws ConstraintException * @throws QueryException * @throws SPException diff --git a/lib/SP/Domain/Plugin/Services/PluginOperation.php b/lib/SP/Domain/Plugin/Services/PluginOperation.php index 217c29bd..794608e3 100644 --- a/lib/SP/Domain/Plugin/Services/PluginOperation.php +++ b/lib/SP/Domain/Plugin/Services/PluginOperation.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -29,10 +29,10 @@ use SP\Domain\Common\Services\ServiceException; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\NoSuchPropertyException; use SP\Domain\Core\Exceptions\QueryException; -use SP\Domain\Plugin\Ports\PluginDataInterface; +use SP\Domain\Plugin\Models\PluginData as PluginDataModel; +use SP\Domain\Plugin\Ports\PluginDataService; use SP\Domain\Plugin\Ports\PluginOperationInterface; use SP\Infrastructure\Common\Repositories\NoSuchItemException; -use SP\Infrastructure\Plugin\Repositories\PluginDataModel; /** * Class PluginOperation @@ -40,8 +40,8 @@ use SP\Infrastructure\Plugin\Repositories\PluginDataModel; final class PluginOperation implements PluginOperationInterface { public function __construct( - private readonly PluginDataInterface $pluginDataService, - private readonly string $pluginName + private readonly PluginDataService $pluginDataService, + private readonly string $pluginName ) { } diff --git a/lib/SP/Domain/Plugin/Services/PluginRegister.php b/lib/SP/Domain/Plugin/Services/PluginRegister.php index 6173c540..870877ef 100644 --- a/lib/SP/Domain/Plugin/Services/PluginRegister.php +++ b/lib/SP/Domain/Plugin/Services/PluginRegister.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -30,11 +30,11 @@ use SP\Core\Events\EventMessage; use SP\Domain\Common\Services\Service; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Plugin\Models\Plugin; use SP\Domain\Plugin\Ports\PluginInterface; use SP\Domain\Plugin\Ports\PluginManagerInterface; use SP\Domain\Plugin\Ports\PluginRegisterInterface; use SP\Infrastructure\Common\Repositories\NoSuchItemException; -use SP\Infrastructure\Plugin\Repositories\PluginModel; use function SP\__u; @@ -87,7 +87,7 @@ final class PluginRegister extends Service implements PluginRegisterInterface */ private function register(PluginInterface $plugin): void { - $pluginData = new PluginModel(); + $pluginData = new Plugin(); $pluginData->setName($plugin->getName()); $pluginData->setEnabled(false); diff --git a/lib/SP/Domain/Plugin/Services/PluginUpgrader.php b/lib/SP/Domain/Plugin/Services/PluginUpgrader.php index 29af4cc7..dc6cbc05 100644 --- a/lib/SP/Domain/Plugin/Services/PluginUpgrader.php +++ b/lib/SP/Domain/Plugin/Services/PluginUpgrader.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -30,7 +30,7 @@ use SP\Core\Events\EventMessage; use SP\Domain\Common\Services\Service; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; -use SP\Domain\Plugin\Ports\PluginDataInterface; +use SP\Domain\Plugin\Ports\PluginDataService; use SP\Domain\Plugin\Ports\PluginInterface; use SP\Domain\Plugin\Ports\PluginManagerInterface; use SP\Domain\Plugin\Ports\PluginUpgraderInterface; @@ -48,7 +48,7 @@ final class PluginUpgrader extends Service implements PluginUpgraderInterface public function __construct( Application $application, private readonly PluginManagerInterface $pluginService, - private readonly PluginDataInterface $pluginDataService + private readonly PluginDataService $pluginDataService ) { parent::__construct($application); } diff --git a/lib/SP/Infrastructure/Plugin/Repositories/Plugin.php b/lib/SP/Infrastructure/Plugin/Repositories/Plugin.php new file mode 100644 index 00000000..bde0d3ac --- /dev/null +++ b/lib/SP/Infrastructure/Plugin/Repositories/Plugin.php @@ -0,0 +1,389 @@ +. + */ + +namespace SP\Infrastructure\Plugin\Repositories; + +use SP\DataModel\ItemSearchData; +use SP\Domain\Core\Exceptions\ConstraintException; +use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Plugin\Models\Plugin as PluginModel; +use SP\Domain\Plugin\Ports\PluginRepository; +use SP\Infrastructure\Common\Repositories\BaseRepository; +use SP\Infrastructure\Common\Repositories\RepositoryItemTrait; +use SP\Infrastructure\Database\QueryData; +use SP\Infrastructure\Database\QueryResult; + +use function SP\__u; + +/** + * Class Plugin + * + * @template T of PluginModel + */ +final class Plugin extends BaseRepository implements PluginRepository +{ + use RepositoryItemTrait; + + public const TABLE = 'Plugin'; + + /** + * Creates an item + * + * @param PluginModel $plugin + * + * @return QueryResult + * @throws ConstraintException + * @throws QueryException + */ + public function create(PluginModel $plugin): QueryResult + { + $query = $this->queryFactory + ->newInsert() + ->into(self::TABLE) + ->cols($plugin->toArray(null, ['id'])); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while adding the plugin')); + + return $this->db->doQuery($queryData); + } + + /** + * Updates an item + * + * @param PluginModel $plugin + * + * @return int + * @throws ConstraintException + * @throws QueryException + */ + public function update(PluginModel $plugin): int + { + $query = $this->queryFactory + ->newUpdate() + ->table(self::TABLE) + ->cols($plugin->toArray(null, ['id'])) + ->where('name = :name OR id = :id', ['name' => $plugin->getName(), 'id' => $plugin->getId()]) + ->limit(1); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the plugin')); + + return $this->db->doQuery($queryData)->getAffectedNumRows(); + } + + /** + * Devolver los plugins activados + * + * @return QueryResult + */ + public function getEnabled(): QueryResult + { + $query = $this->queryFactory + ->newSelect() + ->from(self::TABLE) + ->cols(PluginModel::getCols()) + ->where('enabled = 1'); + + $queryData = QueryData::buildWithMapper($query, PluginModel::class); + + return $this->db->doSelect($queryData); + } + + /** + * Returns the item for given id + * + * @param int $pluginId + * + * @return QueryResult + */ + public function getById(int $pluginId): QueryResult + { + $query = $this->queryFactory + ->newSelect() + ->from(self::TABLE) + ->cols(PluginModel::getCols()) + ->where('id = :id') + ->bindValues(['id' => $pluginId]) + ->limit(1); + + $queryData = QueryData::buildWithMapper($query, PluginModel::class); + + return $this->db->doSelect($queryData); + } + + /** + * Returns all the items + * + * @return QueryResult + */ + public function getAll(): QueryResult + { + $query = $this->queryFactory + ->newSelect() + ->from(self::TABLE) + ->cols(PluginModel::getCols()) + ->orderBy(['name']); + + return $this->db->doSelect(QueryData::buildWithMapper($query, PluginModel::class)); + } + + /** + * Returns all the items for given ids + * + * @param array $pluginsId + * + * @return QueryResult + */ + public function getByIdBatch(array $pluginsId): QueryResult + { + $query = $this->queryFactory + ->newSelect() + ->from(self::TABLE) + ->cols(PluginModel::getCols()) + ->where('id IN (:ids)', ['ids' => $pluginsId]) + ->orderBy(['id']); + + $queryData = QueryData::buildWithMapper($query, PluginModel::class); + + return $this->db->doSelect($queryData); + } + + /** + * Deletes all the items for given ids + * + * @param array $pluginsId + * + * @return QueryResult + * @throws SPException + * @throws ConstraintException + * @throws QueryException + */ + public function deleteByIdBatch(array $pluginsId): QueryResult + { + if (count($pluginsId) === 0) { + return new QueryResult(); + } + + $query = $this->queryFactory + ->newDelete() + ->from(self::TABLE) + ->where('id IN (:ids) AND sticky = 0', ['ids' => $pluginsId]); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while deleting the plugins')); + + return $this->db->doQuery($queryData); + } + + /** + * Deletes an item + * + * @param int $id + * + * @return QueryResult + * @throws ConstraintException + * @throws QueryException + */ + public function delete(int $id): QueryResult + { + $query = $this->queryFactory + ->newDelete() + ->from(self::TABLE) + ->where('id = :id', ['id' => $id]) + ->limit(1); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while deleting the plugin')); + + return $this->db->doQuery($queryData); + } + + /** + * Searches for items by a given filter + * + * @param ItemSearchData $itemSearchData + * + * @return QueryResult + */ + public function search(ItemSearchData $itemSearchData): QueryResult + { + $query = $this->queryFactory + ->newSelect() + ->from(self::TABLE) + ->cols(PluginModel::getCols()) + ->orderBy(['name']) + ->limit($itemSearchData->getLimitCount()) + ->offset($itemSearchData->getLimitStart()); + + if (!empty($itemSearchData->getSeachString())) { + $query->where('name LIKE :name'); + + $search = '%' . $itemSearchData->getSeachString() . '%'; + + $query->bindValues(['name' => $search]); + } + + $queryData = QueryData::build($query)->setMapClassName(PluginModel::class); + + return $this->db->doSelect($queryData, true); + } + + /** + * Devuelve los datos de un plugin por su nombre + * + * @param string $name + * + * @return QueryResult + */ + public function getByName(string $name): QueryResult + { + $query = $this->queryFactory + ->newSelect() + ->from(self::TABLE) + ->cols(PluginModel::getCols()) + ->where('name = :name', ['name' => $name]) + ->limit(1); + + $queryData = QueryData::buildWithMapper($query, PluginModel::class); + + return $this->db->doSelect($queryData); + } + + /** + * Cambiar el estado del plugin + * + * @param int $id + * @param bool $enabled + * + * @return int + * @throws ConstraintException + * @throws QueryException + */ + public function toggleEnabled(int $id, bool $enabled): int + { + $query = $this->queryFactory + ->newUpdate() + ->table(self::TABLE) + ->cols(['enabled' => $enabled]) + ->where('id = :id', ['id' => $id]) + ->limit(1); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the plugin')); + + return $this->db->doQuery($queryData)->getAffectedNumRows(); + } + + /** + * Cambiar el estado del plugin + * + * @param string $name + * @param bool $enabled + * + * @return int + * @throws ConstraintException + * @throws QueryException + */ + public function toggleEnabledByName(string $name, bool $enabled): int + { + $query = $this->queryFactory + ->newUpdate() + ->table(self::TABLE) + ->cols(['enabled' => $enabled]) + ->where('name = :name', ['name' => $name]) + ->limit(1); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the plugin')); + + return $this->db->doQuery($queryData)->getAffectedNumRows(); + } + + /** + * Cambiar el estado del plugin + * + * @param int $id + * @param bool $available + * + * @return int + * @throws ConstraintException + * @throws QueryException + */ + public function toggleAvailable(int $id, bool $available): int + { + $query = $this->queryFactory + ->newUpdate() + ->table(self::TABLE) + ->cols(['available' => $available, 'enabled' => 0]) + ->where('id = :id', ['id' => $id]) + ->limit(1); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the plugin')); + + return $this->db->doQuery($queryData)->getAffectedNumRows(); + } + + /** + * Cambiar el estado del plugin + * + * @param string $name + * @param bool $available + * + * @return int + * @throws ConstraintException + * @throws QueryException + */ + public function toggleAvailableByName(string $name, bool $available): int + { + $query = $this->queryFactory + ->newUpdate() + ->table(self::TABLE) + ->cols(['available' => $available, 'enabled' => 0]) + ->where('name = :name', ['name' => $name]) + ->limit(1); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the plugin')); + + return $this->db->doQuery($queryData)->getAffectedNumRows(); + } + + /** + * Restablecer los datos de un plugin + * + * @param int $id Id del plugin + * + * @return int + * @throws ConstraintException + * @throws QueryException + */ + public function resetById(int $id): int + { + $query = $this->queryFactory + ->newUpdate() + ->table(self::TABLE) + ->cols(['data' => null]) + ->where('id = :id', ['id' => $id]) + ->limit(1); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the plugin')); + + return $this->db->doQuery($queryData)->getAffectedNumRows(); + } +} diff --git a/lib/SP/Infrastructure/Plugin/Repositories/PluginBaseRepository.php b/lib/SP/Infrastructure/Plugin/Repositories/PluginBaseRepository.php deleted file mode 100644 index 957d0156..00000000 --- a/lib/SP/Infrastructure/Plugin/Repositories/PluginBaseRepository.php +++ /dev/null @@ -1,452 +0,0 @@ -. - */ - -namespace SP\Infrastructure\Plugin\Repositories; - -use RuntimeException; -use SP\DataModel\Item; -use SP\DataModel\ItemSearchData; -use SP\Domain\Core\Exceptions\ConstraintException; -use SP\Domain\Core\Exceptions\QueryException; -use SP\Domain\Core\Exceptions\SPException; -use SP\Domain\Plugin\Ports\PluginRepository; -use SP\Infrastructure\Common\Repositories\BaseRepository; -use SP\Infrastructure\Common\Repositories\RepositoryItemTrait; -use SP\Infrastructure\Database\QueryData; -use SP\Infrastructure\Database\QueryResult; - -/** - * Class PluginRepository - * - * @package SP\Infrastructure\Plugin\Repositories - */ -final class PluginBaseRepository extends BaseRepository implements PluginRepository -{ - use RepositoryItemTrait; - - /** - * Creates an item - * - * @param PluginModel $itemData - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function create($itemData): QueryResult - { - $query = /** @lang SQL */ - 'INSERT INTO Plugin SET `name` = ?, `data` = ?, enabled = ?, available = ?'; - - $queryData = new QueryData(); - $queryData->setQuery($query); - $queryData->setParams([ - $itemData->getName(), - $itemData->getData(), - $itemData->getEnabled(), - $itemData->getAvailable(), - ]); - $queryData->setOnErrorMessage(__u('Error while adding the plugin')); - - return $this->db->doQuery($queryData); - } - - /** - * Devolver los plugins activados - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function getEnabled(): QueryResult - { - $queryData = new QueryData(); - $queryData->setMapClassName(Item::class); - $queryData->setQuery('SELECT id, `name` FROM Plugin WHERE enabled = 1 ORDER BY id'); - - return $this->db->doSelect($queryData); - } - - /** - * Updates an item - * - * @param PluginModel $itemData - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function update($itemData): int - { - $query = /** @lang SQL */ - 'UPDATE Plugin - SET `name` = ?, - `data` = ?, - enabled = ?, - available = ?, - versionLevel = ? - WHERE `name` = ? OR id = ? LIMIT 1'; - - $queryData = new QueryData(); - $queryData->setQuery($query); - $queryData->setParams([ - $itemData->getName(), - $itemData->getData(), - $itemData->getEnabled(), - $itemData->getAvailable(), - $itemData->getVersionLevel(), - $itemData->getName(), - $itemData->getId(), - ]); - $queryData->setOnErrorMessage(__u('Error while updating the plugin')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } - - /** - * Returns the item for given id - * - * @param int $id - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function getById(int $id): QueryResult - { - $query = /** @lang SQL */ - 'SELECT id, - `name`, - `data`, - enabled, - available, - versionLevel - FROM Plugin - WHERE id = ? LIMIT 1'; - - $queryData = new QueryData(); - $queryData->setMapClassName(PluginModel::class); - $queryData->setQuery($query); - $queryData->addParam($id); - - return $this->db->doSelect($queryData); - } - - /** - * Returns all the items - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function getAll(): QueryResult - { - $query = /** @lang SQL */ - 'SELECT id, - `name`, - enabled, - available, - versionLevel - FROM Plugin - ORDER BY `name`'; - - $queryData = new QueryData(); - $queryData->setMapClassName(PluginModel::class); - $queryData->setQuery($query); - - return $this->db->doSelect($queryData); - } - - /** - * Returns all the items for given ids - * - * @param array $ids - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function getByIdBatch(array $ids): QueryResult - { - if (count($ids) === 0) { - return new QueryResult(); - } - - $query = /** @lang SQL */ - 'SELECT id, - `name`, - enabled, - available, - versionLevel - FROM Plugin - WHERE id IN ('.$this->buildParamsFromArray($ids).') - ORDER BY id'; - - $queryData = new QueryData(); - $queryData->setMapClassName(PluginModel::class); - $queryData->setQuery($query); - $queryData->setParams($ids); - - return $this->db->doSelect($queryData); - } - - /** - * Deletes all the items for given ids - * - * @param array $ids - * - * @return int - * @throws SPException - * @throws ConstraintException - * @throws QueryException - */ - public function deleteByIdBatch(array $ids): int - { - if (count($ids) === 0) { - return 0; - } - - $queryData = new QueryData(); - $queryData->setQuery('DELETE FROM Plugin WHERE id IN ('.$this->buildParamsFromArray($ids).')'); - $queryData->setParams($ids); - $queryData->setOnErrorMessage(__u('Error while deleting the plugins')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } - - /** - * Deletes an item - * - * @param int $id - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function delete(int $id): int - { - $queryData = new QueryData(); - $queryData->setQuery('DELETE FROM Plugin WHERE id = ? LIMIT 1'); - $queryData->addParam($id); - $queryData->setOnErrorMessage(__u('Error while deleting the plugin')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } - - /** - * Checks whether the item is in use or not - * - * @param $id int - * - * @return void - */ - public function checkInUse(int $id): bool - { - throw new RuntimeException('Not implemented'); - } - - /** - * Checks whether the item is duplicated on updating - * - * @param mixed $itemData - * - * @return void - */ - public function checkDuplicatedOnUpdate($itemData): bool - { - throw new RuntimeException('Not implemented'); - } - - /** - * Checks whether the item is duplicated on adding - * - * @param mixed $itemData - * - * @return void - */ - public function checkDuplicatedOnAdd($itemData): bool - { - throw new RuntimeException('Not implemented'); - } - - /** - * Searches for items by a given filter - * - * @param ItemSearchData $itemSearchData - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function search(ItemSearchData $itemSearchData): QueryResult - { - $queryData = new QueryData(); - $queryData->setMapClassName(PluginModel::class); - $queryData->setSelect('id, name, enabled, available, versionLevel'); - $queryData->setFrom('Plugin'); - $queryData->setOrder('name'); - - if (!empty($itemSearchData->getSeachString())) { - $queryData->setWhere('name LIKE ?'); - - $search = '%'.$itemSearchData->getSeachString().'%'; - $queryData->addParam($search); - } - - $queryData->setLimit( - '?,?', - [$itemSearchData->getLimitStart(), $itemSearchData->getLimitCount()] - ); - - return $this->db->doSelect($queryData, true); - } - - /** - * Devuelve los datos de un plugin por su nombre - * - * @param string $name - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function getByName(string $name): QueryResult - { - $query = /** @lang SQL */ - 'SELECT id, - `name`, - `data`, - enabled, - available, - versionLevel - FROM Plugin - WHERE `name` = ? LIMIT 1'; - - $queryData = new QueryData(); - $queryData->setMapClassName(PluginModel::class); - $queryData->setQuery($query); - $queryData->addParam($name); - - return $this->db->doSelect($queryData); - } - - /** - * Cambiar el estado del plugin - * - * @param int $id - * @param bool $enabled - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function toggleEnabled(int $id, bool $enabled): int - { - $queryData = new QueryData(); - $queryData->setQuery('UPDATE Plugin SET enabled = ? WHERE id = ? LIMIT 1'); - $queryData->setParams([(int)$enabled, $id]); - $queryData->setOnErrorMessage(__u('Error while updating the plugin')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } - - /** - * Cambiar el estado del plugin - * - * @param string $name - * @param bool $enabled - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function toggleEnabledByName(string $name, bool $enabled): int - { - $queryData = new QueryData(); - $queryData->setQuery('UPDATE Plugin SET enabled = ? WHERE name = ? LIMIT 1'); - $queryData->setParams([(int)$enabled, $name]); - $queryData->setOnErrorMessage(__u('Error while updating the plugin')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } - - /** - * Cambiar el estado del plugin - * - * @param int $id - * @param bool $available - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function toggleAvailable(int $id, bool $available): int - { - $queryData = new QueryData(); - $queryData->setQuery('UPDATE Plugin SET available = ?, enabled = 0 WHERE id = ? LIMIT 1'); - $queryData->setParams([(int)$available, $id]); - $queryData->setOnErrorMessage(__u('Error while updating the plugin')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } - - /** - * Cambiar el estado del plugin - * - * @param string $name - * @param bool $available - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function toggleAvailableByName(string $name, bool $available): int - { - $queryData = new QueryData(); - $queryData->setQuery('UPDATE Plugin SET available = ?, enabled = 0 WHERE `name` = ? LIMIT 1'); - $queryData->setParams([(int)$available, $name]); - $queryData->setOnErrorMessage(__u('Error while updating the plugin')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } - - /** - * Restablecer los datos de un plugin - * - * @param int $id Id del plugin - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function resetById(int $id): int - { - $queryData = new QueryData(); - $queryData->setQuery('UPDATE Plugin SET `data` = NULL WHERE id = ? LIMIT 1'); - $queryData->addParam($id); - $queryData->setOnErrorMessage(__u('Error while updating the plugin')); - - return $this->db->doQuery($queryData)->getAffectedNumRows(); - } -} diff --git a/lib/SP/Infrastructure/Plugin/Repositories/PluginDataBaseRepository.php b/lib/SP/Infrastructure/Plugin/Repositories/PluginData.php similarity index 83% rename from lib/SP/Infrastructure/Plugin/Repositories/PluginDataBaseRepository.php rename to lib/SP/Infrastructure/Plugin/Repositories/PluginData.php index 2635d84a..8e91404e 100644 --- a/lib/SP/Infrastructure/Plugin/Repositories/PluginDataBaseRepository.php +++ b/lib/SP/Infrastructure/Plugin/Repositories/PluginData.php @@ -26,25 +26,26 @@ namespace SP\Infrastructure\Plugin\Repositories; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; -use SP\Domain\Plugin\Ports\PluginDataRepositoryInterface; +use SP\Domain\Plugin\Models\PluginData as PluginDataModel; +use SP\Domain\Plugin\Ports\PluginDataRepository; use SP\Infrastructure\Common\Repositories\BaseRepository; use SP\Infrastructure\Common\Repositories\RepositoryItemTrait; use SP\Infrastructure\Database\QueryData; use SP\Infrastructure\Database\QueryResult; /** - * Class PluginDataRepository + * Class PluginData * - * @package SP\Infrastructure\Plugin\Repositories + * @template T of PluginDataModel */ -final class PluginDataBaseRepository extends BaseRepository implements PluginDataRepositoryInterface +final class PluginData extends BaseRepository implements PluginDataRepository { use RepositoryItemTrait; /** * Creates an item * - * @param PluginDataModel $itemData + * @param PluginDataModel $itemData * * @return QueryResult * @throws ConstraintException @@ -58,11 +59,11 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat $queryData = new QueryData(); $queryData->setQuery($query); $queryData->setParams([ - $itemData->getName(), - $itemData->getItemId(), - $itemData->getData(), - $itemData->getKey(), - ]); + $itemData->getName(), + $itemData->getItemId(), + $itemData->getData(), + $itemData->getKey(), + ]); $queryData->setOnErrorMessage(__u('Error while adding plugin\'s data')); return $this->db->doQuery($queryData); @@ -71,7 +72,7 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Updates an item * - * @param PluginDataModel $itemData + * @param PluginDataModel $itemData * * @return int * @throws ConstraintException @@ -87,11 +88,11 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat $queryData = new QueryData(); $queryData->setQuery($query); $queryData->setParams([ - $itemData->getData(), - $itemData->getKey(), - $itemData->getName(), - $itemData->getItemId(), - ]); + $itemData->getData(), + $itemData->getKey(), + $itemData->getName(), + $itemData->getItemId(), + ]); $queryData->setOnErrorMessage(__u('Error while updating plugin\'s data')); return $this->db->doQuery($queryData)->getAffectedNumRows(); @@ -100,7 +101,7 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Deletes an item * - * @param string $id + * @param string $id * * @return int * @throws ConstraintException @@ -119,8 +120,8 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Deletes an item * - * @param string $name - * @param int $itemId + * @param string $name + * @param int $itemId * * @return int * @throws ConstraintException @@ -139,9 +140,9 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Returns the item for given id * - * @param string $id + * @param string $id * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -166,7 +167,7 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Returns all the items * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -190,9 +191,9 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Returns all the items for given ids * - * @param string[] $ids + * @param string[] $ids * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -208,7 +209,7 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat `data`, `key` FROM PluginData - WHERE `name` IN ('.$this->buildParamsFromArray($ids).') + WHERE `name` IN (' . $this->buildParamsFromArray($ids) . ') ORDER BY `name`'; $queryData = new QueryData(); @@ -222,7 +223,7 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Deletes all the items for given ids * - * @param string[] $ids + * @param string[] $ids * * @return int * @throws ConstraintException @@ -235,7 +236,7 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat } $queryData = new QueryData(); - $queryData->setQuery('DELETE FROM PluginData WHERE `name` IN ('.$this->buildParamsFromArray($ids).')'); + $queryData->setQuery('DELETE FROM PluginData WHERE `name` IN (' . $this->buildParamsFromArray($ids) . ')'); $queryData->setParams($ids); $queryData->setOnErrorMessage(__u('Error while deleting plugin\'s data')); @@ -245,10 +246,10 @@ final class PluginDataBaseRepository extends BaseRepository implements PluginDat /** * Devuelve los datos de un plugin por su nombre * - * @param string $name - * @param int $itemId + * @param string $name + * @param int $itemId * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ diff --git a/tests/SPT/Generators/PluginGenerator.php b/tests/SPT/Generators/PluginGenerator.php new file mode 100644 index 00000000..5d836619 --- /dev/null +++ b/tests/SPT/Generators/PluginGenerator.php @@ -0,0 +1,50 @@ +. + */ + +namespace SPT\Generators; + +use SP\Domain\Plugin\Models\Plugin; + +/** + * Class PluginGenerator + */ +final class PluginGenerator extends DataGenerator +{ + + public function buildPlugin(): Plugin + { + return new Plugin($this->pluginProperties()); + } + + private function pluginProperties(): array + { + return [ + 'id' => $this->faker->randomNumber(3), + 'name' => $this->faker->colorName(), + 'data' => $this->faker->text(), + 'enabled' => $this->faker->boolean() + ]; + } + +} diff --git a/tests/SPT/Infrastructure/Plugin/Repositories/PluginTest.php b/tests/SPT/Infrastructure/Plugin/Repositories/PluginTest.php new file mode 100644 index 00000000..e7114a0f --- /dev/null +++ b/tests/SPT/Infrastructure/Plugin/Repositories/PluginTest.php @@ -0,0 +1,522 @@ +. + */ + +namespace SPT\Infrastructure\Plugin\Repositories; + +use Aura\SqlQuery\Common\DeleteInterface; +use Aura\SqlQuery\Common\InsertInterface; +use Aura\SqlQuery\Common\SelectInterface; +use Aura\SqlQuery\Common\UpdateInterface; +use Aura\SqlQuery\QueryFactory; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Constraint\Callback; +use SP\DataModel\ItemSearchData; +use SP\Domain\Common\Models\Simple; +use SP\Domain\Core\Exceptions\ConstraintException; +use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Plugin\Models\Plugin as PluginModel; +use SP\Infrastructure\Database\DatabaseInterface; +use SP\Infrastructure\Database\QueryData; +use SP\Infrastructure\Database\QueryResult; +use SP\Infrastructure\Plugin\Repositories\Plugin; +use SPT\Generators\PluginGenerator; +use SPT\UnitaryTestCase; + +/** + * Class PluginTest + */ +#[Group('unitary')] +class PluginTest extends UnitaryTestCase +{ + + private Plugin $plugin; + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testToggleAvailableByName() + { + $callbackCreate = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 3 + && $params['available'] === true + && $params['enabled'] === 0 + && $params['name'] === 'test_name' + && is_a($query, UpdateInterface::class) + && !empty($query->getStatement()); + } + ); + + $queryResult = new QueryResult([]); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn($queryResult->setAffectedNumRows(1)); + + $out = $this->plugin->toggleAvailableByName('test_name', true); + + $this->assertEquals(1, $out); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testToggleEnabledByName() + { + $callbackCreate = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 2 + && $params['enabled'] === true + && $params['name'] === 'test_name' + && is_a($query, UpdateInterface::class) + && !empty($query->getStatement()); + } + ); + + $queryResult = new QueryResult([]); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn($queryResult->setAffectedNumRows(1)); + + $out = $this->plugin->toggleEnabledByName('test_name', true); + + $this->assertEquals(1, $out); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testUpdate() + { + $plugin = PluginGenerator::factory()->buildPlugin(); + + $callbackCreate = new Callback( + static function (QueryData $arg) use ($plugin) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 5 + && $params['id'] === $plugin->getId() + && $params['name'] === $plugin->getName() + && $params['data'] === $plugin->getData() + && $params['enabled'] === $plugin->getEnabled() + && $params['versionLevel'] === $plugin->getVersionLevel() + && is_a($query, UpdateInterface::class) + && !empty($query->getStatement()); + } + ); + + $queryResult = new QueryResult([]); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn($queryResult->setAffectedNumRows(1)); + + $out = $this->plugin->update($plugin); + + $this->assertEquals(1, $out); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testToggleEnabled() + { + $callbackCreate = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 2 + && $params['enabled'] === true + && $params['id'] === 100 + && is_a($query, UpdateInterface::class) + && !empty($query->getStatement()); + } + ); + + $queryResult = new QueryResult([]); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn($queryResult->setAffectedNumRows(1)); + + $out = $this->plugin->toggleEnabled(100, true); + + $this->assertEquals(1, $out); + } + + public function testGetEnabled() + { + $callback = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 0 + && $arg->getMapClassName() === PluginModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback); + + $this->plugin->getEnabled(); + } + + /** + * @throws ConstraintException + * @throws SPException + * @throws QueryException + */ + public function testDeleteByIdBatch() + { + $ids = [self::$faker->randomNumber(), self::$faker->randomNumber(), self::$faker->randomNumber()]; + + $callback = new Callback( + static function (QueryData $arg) use ($ids) { + $query = $arg->getQuery(); + $values = $query->getBindValues(); + + return count($values) === 3 + && array_shift($values) === array_shift($ids) + && array_shift($values) === array_shift($ids) + && array_shift($values) === array_shift($ids) + && $arg->getMapClassName() === Simple::class + && is_a($query, DeleteInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doQuery') + ->with($callback); + + $this->plugin->deleteByIdBatch($ids); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testToggleAvailable() + { + $callbackCreate = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 3 + && $params['available'] === true + && $params['enabled'] === 0 + && $params['id'] === 100 + && is_a($query, UpdateInterface::class) + && !empty($query->getStatement()); + } + ); + + $queryResult = new QueryResult([]); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn($queryResult->setAffectedNumRows(1)); + + $out = $this->plugin->toggleAvailable(100, true); + + $this->assertEquals(1, $out); + } + + public function testSearch() + { + $item = new ItemSearchData(self::$faker->name); + + $callback = new Callback( + static function (QueryData $arg) use ($item) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + $searchStringLike = '%' . $item->getSeachString() . '%'; + + return count($params) === 1 + && $params['name'] === $searchStringLike + && $arg->getMapClassName() === PluginModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback, true); + + $this->plugin->search($item); + } + + public function testSearchWithEmptyString() + { + $item = new ItemSearchData(); + + $callback = new Callback( + static function (QueryData $arg) use ($item) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + $searchStringLike = '%' . $item->getSeachString() . '%'; + + return count($params) === 0 + && $arg->getMapClassName() === PluginModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback, true); + + $this->plugin->search($item); + } + + public function testGetAll() + { + $callback = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + + return $arg->getMapClassName() === PluginModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback); + + $this->plugin->getAll(); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testResetById() + { + $callbackCreate = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 2 + && $params['data'] === null + && $params['id'] === 100 + && is_a($query, UpdateInterface::class) + && !empty($query->getStatement()); + } + ); + + $queryResult = new QueryResult([]); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn($queryResult->setAffectedNumRows(1)); + + $out = $this->plugin->resetById(100); + + $this->assertEquals(1, $out); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testCreate() + { + $plugin = PluginGenerator::factory()->buildPlugin(); + + $callbackCreate = new Callback( + static function (QueryData $arg) use ($plugin) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 4 + && $params['name'] === $plugin->getName() + && $params['data'] === $plugin->getData() + && $params['enabled'] === $plugin->getEnabled() + && $params['versionLevel'] === $plugin->getVersionLevel() + && is_a($query, InsertInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn(new QueryResult([])); + + $this->plugin->create($plugin); + } + + public function testGetByName() + { + $callback = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 1 + && $params['name'] === 'test_name' + && $arg->getMapClassName() === PluginModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback); + + $this->plugin->getByName('test_name'); + } + + public function testGetByIdBatch() + { + $ids = [self::$faker->randomNumber(), self::$faker->randomNumber(), self::$faker->randomNumber()]; + + $callback = new Callback( + static function (QueryData $arg) use ($ids) { + $query = $arg->getQuery(); + $values = $query->getBindValues(); + + return count($values) === 3 + && array_shift($values) === array_shift($ids) + && array_shift($values) === array_shift($ids) + && array_shift($values) === array_shift($ids) + && $arg->getMapClassName() === PluginModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback); + + $this->plugin->getByIdBatch($ids); + } + + public function testGetById() + { + $callback = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 1 + && $params['id'] === 100 + && $arg->getMapClassName() === PluginModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback); + + $this->plugin->getById(100); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testDelete() + { + $id = self::$faker->randomNumber(); + + $callback = new Callback( + static function (QueryData $arg) use ($id) { + $query = $arg->getQuery(); + + return $query->getBindValues()['id'] === $id + && is_a($query, DeleteInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database->expects(self::once())->method('doQuery')->with($callback); + + $this->plugin->delete($id); + } + + protected function setUp(): void + { + parent::setUp(); + + $this->database = $this->createMock(DatabaseInterface::class); + $queryFactory = new QueryFactory('mysql'); + + $this->plugin = new Plugin( + $this->database, + $this->context, + $this->application->getEventDispatcher(), + $queryFactory, + ); + } +}