diff --git a/composer.json b/composer.json index ac3e86e..5d5843f 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "fastybird/application-library": "dev-main", "fastybird/datetime-factory": "^0.6", "fastybird/exchange-library": "dev-main", - "fastybird/json-api": "^0.17", + "fastybird/json-api": "^0.18", "fastybird/metadata-library": "dev-main", "fastybird/simple-auth": "^0.14", "fastybird/tools-library": "dev-main", diff --git a/resources/schemas/document.widget.dataSource.json b/resources/schemas/document.widget.dataSource.json index ffa74fa..085ac5f 100644 --- a/resources/schemas/document.widget.dataSource.json +++ b/resources/schemas/document.widget.dataSource.json @@ -11,9 +11,6 @@ "type": "string", "description": "Data source source" }, - "params": { - "type": "object" - }, "widget": { "type": "string", "format": "uuid", @@ -60,7 +57,6 @@ }, "required": [ "id", - "params", "widget", "owner" ] diff --git a/src/Controllers/BaseV1.php b/src/Controllers/BaseV1.php index 46bddcd..37a5c17 100644 --- a/src/Controllers/BaseV1.php +++ b/src/Controllers/BaseV1.php @@ -64,6 +64,7 @@ abstract class BaseV1 protected Router\Validator $routesValidator; + /** @var JsonApiHydrators\Container */ protected JsonApiHydrators\Container $hydratorsContainer; protected Ui\Logger $logger; @@ -93,6 +94,9 @@ public function injectRoutesValidator(Router\Validator $validator): void $this->routesValidator = $validator; } + /** + * @param JsonApiHydrators\Container $hydratorsContainer + */ public function injectHydratorsContainer(JsonApiHydrators\Container $hydratorsContainer): void { $this->hydratorsContainer = $hydratorsContainer; @@ -112,18 +116,18 @@ public function readRelationship( if ($relationEntity !== '') { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.relationNotFound.heading'), - $this->translator->translate( + strval($this->translator->translate('//ui-module.base.messages.relationNotFound.heading')), + strval($this->translator->translate( '//ui-module.base.messages.relationNotFound.message', ['relation' => $relationEntity], - ), + )), ); } throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.unknownRelation.heading'), - $this->translator->translate('//ui-module.base.messages.unknownRelation.message'), + strval($this->translator->translate('//ui-module.base.messages.unknownRelation.heading')), + strval($this->translator->translate('//ui-module.base.messages.unknownRelation.message')), ); } @@ -139,8 +143,8 @@ protected function createDocument(Message\ServerRequestInterface $request): Json if (!$content instanceof stdClass) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_BAD_REQUEST, - $this->translator->translate('//ui-module.base.messages.notValidJsonApi.heading'), - $this->translator->translate('//ui-module.base.messages.notValidJsonApi.message'), + strval($this->translator->translate('//ui-module.base.messages.notValidJsonApi.heading')), + strval($this->translator->translate('//ui-module.base.messages.notValidJsonApi.message')), ); } @@ -149,14 +153,14 @@ protected function createDocument(Message\ServerRequestInterface $request): Json } catch (Utils\JsonException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_BAD_REQUEST, - $this->translator->translate('//ui-module.base.messages.notValidJson.heading'), - $this->translator->translate('//ui-module.base.messages.notValidJson.message'), + strval($this->translator->translate('//ui-module.base.messages.notValidJson.heading')), + strval($this->translator->translate('//ui-module.base.messages.notValidJson.message')), ); } catch (JsonAPIDocument\Exceptions\RuntimeException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_BAD_REQUEST, - $this->translator->translate('//ui-module.base.messages.notValidJsonApi.heading'), - $this->translator->translate('//ui-module.base.messages.notValidJsonApi.message'), + strval($this->translator->translate('//ui-module.base.messages.notValidJsonApi.heading')), + strval($this->translator->translate('//ui-module.base.messages.notValidJsonApi.message')), ); } @@ -181,8 +185,8 @@ protected function validateIdentifier( ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_BAD_REQUEST, - $this->translator->translate('//ui-module.base.messages.invalidIdentifier.heading'), - $this->translator->translate('//ui-module.base.messages.invalidIdentifier.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidIdentifier.message')), ); } diff --git a/src/Controllers/DashboardsV1.php b/src/Controllers/DashboardsV1.php index 65b0b5e..9e5326e 100644 --- a/src/Controllers/DashboardsV1.php +++ b/src/Controllers/DashboardsV1.php @@ -123,20 +123,20 @@ public function create( } catch (JsonApiExceptions\JsonApi $ex) { throw $ex; - } catch (DoctrineCrudExceptions\MissingRequiredFieldException $ex) { + } catch (DoctrineCrudExceptions\MissingRequiredField $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], ); - } catch (DoctrineCrudExceptions\EntityCreationException $ex) { + } catch (DoctrineCrudExceptions\EntityCreation $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], @@ -145,8 +145,8 @@ public function create( if (preg_match("%PRIMARY'%", $ex->getMessage(), $match) === 1) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message')), [ 'pointer' => '/data/id', ], @@ -158,8 +158,8 @@ public function create( if (str_starts_with($columnKey, 'dashboard_')) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi( Utils\Strings::substring($columnKey, 7), @@ -171,8 +171,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), ); } catch (Throwable $ex) { // Log caught exception @@ -187,8 +187,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notCreated.heading'), - $this->translator->translate('//ui-module.base.messages.notCreated.message'), + strval($this->translator->translate('//ui-module.base.messages.notCreated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notCreated.message')), ); } finally { // Revert all changes when error occur @@ -204,8 +204,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -253,8 +253,8 @@ public function update( if (str_starts_with($columnKey, 'dashboard_')) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi( Utils\Strings::substring($columnKey, 7), @@ -266,8 +266,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), ); } catch (Throwable $ex) { // Log caught exception @@ -282,8 +282,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notUpdated.heading'), - $this->translator->translate('//ui-module.base.messages.notUpdated.message'), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.message')), ); } finally { // Revert all changes when error occur @@ -297,8 +297,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -348,8 +348,8 @@ public function delete( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notDeleted.heading'), - $this->translator->translate('//ui-module.base.messages.notDeleted.message'), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.heading')), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.message')), ); } finally { // Revert all changes when error occur diff --git a/src/Controllers/DataSourcesV1.php b/src/Controllers/DataSourcesV1.php index 456fbb0..1996a9a 100644 --- a/src/Controllers/DataSourcesV1.php +++ b/src/Controllers/DataSourcesV1.php @@ -136,20 +136,20 @@ public function create( } catch (JsonApiExceptions\JsonApi $ex) { throw $ex; - } catch (DoctrineCrudExceptions\MissingRequiredFieldException $ex) { + } catch (DoctrineCrudExceptions\MissingRequiredField $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], ); - } catch (DoctrineCrudExceptions\EntityCreationException $ex) { + } catch (DoctrineCrudExceptions\EntityCreation $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], @@ -158,8 +158,8 @@ public function create( if (preg_match("%PRIMARY'%", $ex->getMessage(), $match) === 1) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message')), [ 'pointer' => '/data/id', ], @@ -171,8 +171,8 @@ public function create( if (str_starts_with($columnKey, 'dataSource_')) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi( Utils\Strings::substring($columnKey, 7), @@ -184,8 +184,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), ); } catch (Throwable $ex) { // Log caught exception @@ -200,8 +200,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notCreated.heading'), - $this->translator->translate('//ui-module.base.messages.notCreated.message'), + strval($this->translator->translate('//ui-module.base.messages.notCreated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notCreated.message')), ); } finally { // Revert all changes when error occur @@ -217,8 +217,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -277,8 +277,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notUpdated.heading'), - $this->translator->translate('//ui-module.base.messages.notUpdated.message'), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.message')), ); } finally { // Revert all changes when error occur @@ -292,8 +292,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -346,8 +346,8 @@ public function delete( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notDeleted.heading'), - $this->translator->translate('//ui-module.base.messages.notDeleted.message'), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.heading')), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.message')), ); } finally { // Revert all changes when error occur @@ -401,15 +401,15 @@ protected function findDataSource( if ($dataSource === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } } catch (Uuid\Exception\InvalidUuidStringException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } diff --git a/src/Controllers/DisplayV1.php b/src/Controllers/DisplayV1.php index 736c5c5..7715ec3 100644 --- a/src/Controllers/DisplayV1.php +++ b/src/Controllers/DisplayV1.php @@ -116,8 +116,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notUpdated.heading'), - $this->translator->translate('//ui-module.base.messages.notUpdated.message'), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.message')), ); } finally { // Revert all changes when error occur @@ -131,8 +131,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], diff --git a/src/Controllers/Finders/TDashboard.php b/src/Controllers/Finders/TDashboard.php index ad6e7d7..82c3ab2 100644 --- a/src/Controllers/Finders/TDashboard.php +++ b/src/Controllers/Finders/TDashboard.php @@ -23,6 +23,7 @@ use Fig\Http\Message\StatusCodeInterface; use Nette\Localization; use Ramsey\Uuid; +use function strval; /** * @property-read Localization\Translator $translator @@ -46,15 +47,15 @@ protected function findDashboard(string $id): Entities\Dashboards\Dashboard if ($dashboard === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } } catch (Uuid\Exception\InvalidUuidStringException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } diff --git a/src/Controllers/Finders/TGroup.php b/src/Controllers/Finders/TGroup.php index 53e2645..3876387 100644 --- a/src/Controllers/Finders/TGroup.php +++ b/src/Controllers/Finders/TGroup.php @@ -22,6 +22,7 @@ use Fig\Http\Message\StatusCodeInterface; use Nette\Localization; use Ramsey\Uuid; +use function strval; /** * @property-read Localization\Translator $translator @@ -42,15 +43,15 @@ protected function findGroup(string $id): Entities\Groups\Group if ($group === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } } catch (Uuid\Exception\InvalidUuidStringException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } diff --git a/src/Controllers/Finders/TTab.php b/src/Controllers/Finders/TTab.php index 1ef0550..28c65fb 100644 --- a/src/Controllers/Finders/TTab.php +++ b/src/Controllers/Finders/TTab.php @@ -23,6 +23,7 @@ use Fig\Http\Message\StatusCodeInterface; use Nette\Localization; use Ramsey\Uuid; +use function strval; /** * @property-read Localization\Translator $translator @@ -55,15 +56,15 @@ protected function findTab( if ($tab === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } } catch (Uuid\Exception\InvalidUuidStringException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } diff --git a/src/Controllers/Finders/TWidget.php b/src/Controllers/Finders/TWidget.php index 524c572..9dd6155 100644 --- a/src/Controllers/Finders/TWidget.php +++ b/src/Controllers/Finders/TWidget.php @@ -23,6 +23,7 @@ use Fig\Http\Message\StatusCodeInterface; use Nette\Localization; use Ramsey\Uuid; +use function strval; /** * @property-read Localization\ITranslator $translator @@ -46,15 +47,15 @@ protected function findWidget(string $id): Entities\Widgets\Widget if ($widget === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } } catch (Uuid\Exception\InvalidUuidStringException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_NOT_FOUND, - $this->translator->translate('//ui-module.base.messages.notFound.heading'), - $this->translator->translate('//ui-module.base.messages.notFound.message'), + strval($this->translator->translate('//ui-module.base.messages.notFound.heading')), + strval($this->translator->translate('//ui-module.base.messages.notFound.message')), ); } diff --git a/src/Controllers/GroupsV1.php b/src/Controllers/GroupsV1.php index 9f3c835..66527df 100644 --- a/src/Controllers/GroupsV1.php +++ b/src/Controllers/GroupsV1.php @@ -124,20 +124,20 @@ public function create( } catch (JsonApiExceptions\JsonApi $ex) { throw $ex; - } catch (DoctrineCrudExceptions\MissingRequiredFieldException $ex) { + } catch (DoctrineCrudExceptions\MissingRequiredField $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], ); - } catch (DoctrineCrudExceptions\EntityCreationException $ex) { + } catch (DoctrineCrudExceptions\EntityCreation $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], @@ -146,8 +146,8 @@ public function create( if (preg_match("%PRIMARY'%", $ex->getMessage(), $match) === 1) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message')), [ 'pointer' => '/data/id', ], @@ -159,8 +159,8 @@ public function create( if (str_starts_with($columnKey, 'group_')) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi( Utils\Strings::substring($columnKey, 7), @@ -172,8 +172,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), ); } catch (Throwable $ex) { // Log caught exception @@ -188,8 +188,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notCreated.heading'), - $this->translator->translate('//ui-module.base.messages.notCreated.message'), + strval($this->translator->translate('//ui-module.base.messages.notCreated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notCreated.message')), ); } finally { // Revert all changes when error occur @@ -205,8 +205,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -259,8 +259,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notUpdated.heading'), - $this->translator->translate('//ui-module.base.messages.notUpdated.message'), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.message')), ); } finally { // Revert all changes when error occur @@ -274,8 +274,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -325,8 +325,8 @@ public function delete( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notDeleted.heading'), - $this->translator->translate('//ui-module.base.messages.notDeleted.message'), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.heading')), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.message')), ); } finally { // Revert all changes when error occur diff --git a/src/Controllers/TabsV1.php b/src/Controllers/TabsV1.php index 8a0c076..624957b 100644 --- a/src/Controllers/TabsV1.php +++ b/src/Controllers/TabsV1.php @@ -144,20 +144,20 @@ public function create( } catch (JsonApiExceptions\JsonApi $ex) { throw $ex; - } catch (DoctrineCrudExceptions\MissingRequiredFieldException $ex) { + } catch (DoctrineCrudExceptions\MissingRequiredField $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], ); - } catch (DoctrineCrudExceptions\EntityCreationException $ex) { + } catch (DoctrineCrudExceptions\EntityCreation $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], @@ -166,8 +166,8 @@ public function create( if (preg_match("%PRIMARY'%", $ex->getMessage(), $match) === 1) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message')), [ 'pointer' => '/data/id', ], @@ -179,8 +179,8 @@ public function create( if (str_starts_with($columnKey, 'tab_')) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi( Utils\Strings::substring($columnKey, 7), @@ -192,8 +192,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), ); } catch (Throwable $ex) { // Log caught exception @@ -208,8 +208,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notCreated.heading'), - $this->translator->translate('//ui-module.base.messages.notCreated.message'), + strval($this->translator->translate('//ui-module.base.messages.notCreated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notCreated.message')), ); } finally { // Revert all changes when error occur @@ -225,8 +225,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -282,8 +282,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notUpdated.heading'), - $this->translator->translate('//ui-module.base.messages.notUpdated.message'), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.message')), ); } finally { // Revert all changes when error occur @@ -297,8 +297,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -351,8 +351,8 @@ public function delete( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notDeleted.heading'), - $this->translator->translate('//ui-module.base.messages.notDeleted.message'), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.heading')), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.message')), ); } finally { // Revert all changes when error occur diff --git a/src/Controllers/WidgetsV1.php b/src/Controllers/WidgetsV1.php index 98df771..e299f0c 100644 --- a/src/Controllers/WidgetsV1.php +++ b/src/Controllers/WidgetsV1.php @@ -126,20 +126,20 @@ public function create( } catch (JsonApiExceptions\JsonApi $ex) { throw $ex; - } catch (DoctrineCrudExceptions\MissingRequiredFieldException $ex) { + } catch (DoctrineCrudExceptions\MissingRequiredField $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], ); - } catch (DoctrineCrudExceptions\EntityCreationException $ex) { + } catch (DoctrineCrudExceptions\EntityCreation $ex) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi($ex->getField()), ], @@ -148,8 +148,8 @@ public function create( if (preg_match("%PRIMARY'%", $ex->getMessage(), $match) === 1) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueIdentifier.message')), [ 'pointer' => '/data/id', ], @@ -161,8 +161,8 @@ public function create( if (str_starts_with($columnKey, 'widget_')) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi( Utils\Strings::substring($columnKey, 7), @@ -174,8 +174,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), ); } catch (Throwable $ex) { // Log caught exception @@ -190,8 +190,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notCreated.heading'), - $this->translator->translate('//ui-module.base.messages.notCreated.message'), + strval($this->translator->translate('//ui-module.base.messages.notCreated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notCreated.message')), ); } finally { // Revert all changes when error occur @@ -207,8 +207,8 @@ public function create( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -256,8 +256,8 @@ public function update( if (str_starts_with($columnKey, 'widget_')) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), [ 'pointer' => '/data/attributes/' . Utilities\Api::fieldToJsonApi( Utils\Strings::substring($columnKey, 7), @@ -269,8 +269,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.uniqueAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.uniqueAttribute.message')), ); } catch (Throwable $ex) { // Log caught exception @@ -285,8 +285,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notUpdated.heading'), - $this->translator->translate('//ui-module.base.messages.notUpdated.message'), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.heading')), + strval($this->translator->translate('//ui-module.base.messages.notUpdated.message')), ); } finally { // Revert all changes when error occur @@ -300,8 +300,8 @@ public function update( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidType.heading'), - $this->translator->translate('//ui-module.base.messages.invalidType.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidType.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidType.message')), [ 'pointer' => '/data/type', ], @@ -358,8 +358,8 @@ public function delete( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.notDeleted.heading'), - $this->translator->translate('//ui-module.base.messages.notDeleted.message'), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.heading')), + strval($this->translator->translate('//ui-module.base.messages.notDeleted.message')), ); } finally { // Revert all changes when error occur diff --git a/src/DI/UiExtension.php b/src/DI/UiExtension.php index a83b171..0227f98 100644 --- a/src/DI/UiExtension.php +++ b/src/DI/UiExtension.php @@ -233,12 +233,6 @@ public function loadConfiguration(): void $builder->addDefinition($this->prefix('schemas.widgets.digitalSensor'), new DI\Definitions\ServiceDefinition()) ->setType(Schemas\Widgets\DigitalSensor::class); - $builder->addDefinition( - $this->prefix('schemas.dataSources.channelProperty'), - new DI\Definitions\ServiceDefinition(), - ) - ->setType(Schemas\Widgets\DataSources\ChannelProperty::class); - $builder->addDefinition($this->prefix('schemas.display.analogValue'), new DI\Definitions\ServiceDefinition()) ->setType(Schemas\Widgets\Display\AnalogValue::class); @@ -260,6 +254,9 @@ public function loadConfiguration(): void $builder->addDefinition($this->prefix('schemas.display.slider'), new DI\Definitions\ServiceDefinition()) ->setType(Schemas\Widgets\Display\Slider::class); + $builder->addDefinition($this->prefix('schemas.dataSource.generic'), new DI\Definitions\ServiceDefinition()) + ->setType(Schemas\Widgets\DataSources\Generic::class); + /** * JSON-API HYDRATORS */ @@ -294,36 +291,33 @@ public function loadConfiguration(): void ) ->setType(Hydrators\Widgets\DigitalSensor::class); - $builder->addDefinition( - $this->prefix('hydrators.dataSources.channelProperty'), - new DI\Definitions\ServiceDefinition(), - ) - ->setType(Hydrators\Widgets\DataSources\ChannelProperty::class); - - $builder->addDefinition($this->prefix('hydrators.widgets.analogValue'), new DI\Definitions\ServiceDefinition()) + $builder->addDefinition($this->prefix('hydrators.display.analogValue'), new DI\Definitions\ServiceDefinition()) ->setType(Hydrators\Widgets\Displays\AnalogValue::class); - $builder->addDefinition($this->prefix('hydrators.widgets.button'), new DI\Definitions\ServiceDefinition()) + $builder->addDefinition($this->prefix('hydrators.display.button'), new DI\Definitions\ServiceDefinition()) ->setType(Hydrators\Widgets\Displays\Button::class); - $builder->addDefinition($this->prefix('hydrators.widgets.chartGraph'), new DI\Definitions\ServiceDefinition()) + $builder->addDefinition($this->prefix('hydrators.display.chartGraph'), new DI\Definitions\ServiceDefinition()) ->setType(Hydrators\Widgets\Displays\ChartGraph::class); - $builder->addDefinition($this->prefix('hydrators.widgets.digitalValue'), new DI\Definitions\ServiceDefinition()) + $builder->addDefinition($this->prefix('hydrators.display.digitalValue'), new DI\Definitions\ServiceDefinition()) ->setType(Hydrators\Widgets\Displays\DigitalValue::class); - $builder->addDefinition($this->prefix('hydrators.widgets.gauge'), new DI\Definitions\ServiceDefinition()) + $builder->addDefinition($this->prefix('hydrators.display.gauge'), new DI\Definitions\ServiceDefinition()) ->setType(Hydrators\Widgets\Displays\Gauge::class); $builder->addDefinition( - $this->prefix('hydrators.widgets.groupedButton'), + $this->prefix('hydrators.display.groupedButton'), new DI\Definitions\ServiceDefinition(), ) ->setType(Hydrators\Widgets\Displays\GroupedButton::class); - $builder->addDefinition($this->prefix('hydrators.widgets.slider'), new DI\Definitions\ServiceDefinition()) + $builder->addDefinition($this->prefix('hydrators.display.slider'), new DI\Definitions\ServiceDefinition()) ->setType(Hydrators\Widgets\Displays\Slider::class); + $builder->addDefinition($this->prefix('hydrators.dataSources.generic'), new DI\Definitions\ServiceDefinition()) + ->setType(Hydrators\Widgets\DataSources\Generic::class); + /** * COMMANDS */ diff --git a/src/Entities/Widgets/DataSources/ChannelProperty.php b/src/Entities/Widgets/DataSources/ChannelProperty.php deleted file mode 100644 index 2a60fbd..0000000 --- a/src/Entities/Widgets/DataSources/ChannelProperty.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @package FastyBird:UIModule! - * @subpackage Entities - * @since 1.0.0 - * - * @date 25.05.20 - */ - -namespace FastyBird\Module\Ui\Entities\Widgets\DataSources; - -use Doctrine\ORM\Mapping as ORM; -use FastyBird\Library\Application\Entities\Mapping as ApplicationMapping; -use FastyBird\Module\Ui\Entities; -use IPub\DoctrineCrud\Mapping\Attribute as IPubDoctrine; -use Ramsey\Uuid; -use function array_merge; - -#[ORM\Entity] -#[ORM\Table( - name: 'fb_ui_module_widgets_data_sources_channels_properties', - options: [ - 'collate' => 'utf8mb4_general_ci', - 'charset' => 'utf8mb4', - 'comment' => 'Widget data source connection to channel', - ], -)] -#[ApplicationMapping\DiscriminatorEntry(name: self::TYPE)] -class ChannelProperty extends DataSource -{ - - public const TYPE = 'channel-property'; - - #[IPubDoctrine\Crud(required: true, writable: true)] - #[ORM\Column(name: 'data_source_channel', type: Uuid\Doctrine\UuidBinaryType::NAME, nullable: false)] - private Uuid\UuidInterface $channel; - - #[IPubDoctrine\Crud(required: true, writable: true)] - #[ORM\Column(name: 'data_source_property', type: Uuid\Doctrine\UuidBinaryType::NAME, nullable: false)] - private Uuid\UuidInterface $property; - - public function __construct( - Uuid\UuidInterface $channel, - Uuid\UuidInterface $property, - Entities\Widgets\Widget $widget, - Uuid\UuidInterface|null $id = null, - ) - { - parent::__construct($widget, $id); - - $this->channel = $channel; - $this->property = $property; - } - - public static function getType(): string - { - return self::TYPE; - } - - public function getChannel(): Uuid\UuidInterface - { - return $this->channel; - } - - public function setChannel(Uuid\UuidInterface $channel): void - { - $this->channel = $channel; - } - - public function getProperty(): Uuid\UuidInterface - { - return $this->property; - } - - public function setProperty(Uuid\UuidInterface $property): void - { - $this->property = $property; - } - - /** - * {@inheritDoc} - */ - public function toArray(): array - { - return array_merge(parent::toArray(), [ - 'channel' => $this->getChannel()->toString(), - 'property' => $this->getProperty()->toString(), - ]); - } - -} diff --git a/src/Entities/Widgets/DataSources/DataSource.php b/src/Entities/Widgets/DataSources/DataSource.php index 0972451..4271250 100644 --- a/src/Entities/Widgets/DataSources/DataSource.php +++ b/src/Entities/Widgets/DataSources/DataSource.php @@ -19,7 +19,6 @@ use Doctrine\ORM\Mapping as ORM; use FastyBird\Library\Metadata\Types as MetadataTypes; use FastyBird\Module\Ui\Entities; -use IPub\DoctrineCrud\Mapping\Attribute as IPubDoctrine; use IPub\DoctrineTimestampable; use Nette\Utils; use Ramsey\Uuid; @@ -52,7 +51,6 @@ abstract class DataSource implements Entities\Entity, #[ORM\CustomIdGenerator(class: Uuid\Doctrine\UuidGenerator::class)] protected Uuid\UuidInterface $id; - #[IPubDoctrine\Crud(required: true)] #[ORM\ManyToOne( targetEntity: Entities\Widgets\Widget::class, cascade: ['persist'], @@ -93,7 +91,6 @@ public function toArray(): array return [ 'id' => $this->getId()->toString(), 'type' => static::getType(), - 'params' => (array) $this->getParams(), 'widget' => $this->getWidget()->getId()->toString(), diff --git a/src/Entities/Widgets/DataSources/Generic.php b/src/Entities/Widgets/DataSources/Generic.php new file mode 100644 index 0000000..599e808 --- /dev/null +++ b/src/Entities/Widgets/DataSources/Generic.php @@ -0,0 +1,47 @@ + + * @package FastyBird:UIModule! + * @subpackage Entities + * @since 1.0.0 + * + * @date 03.08.24 + */ + +namespace FastyBird\Module\Ui\Entities\Widgets\DataSources; + +use Doctrine\ORM\Mapping as ORM; +use FastyBird\Library\Application\Entities\Mapping as ApplicationMapping; +use FastyBird\Library\Metadata\Types as MetadataTypes; + +#[ORM\Entity] +#[ORM\Table( + name: 'fb_ui_module_widgets_generic_data_sources', + options: [ + 'collate' => 'utf8mb4_general_ci', + 'charset' => 'utf8mb4', + 'comment' => 'Widget generic data source', + ], +)] +#[ApplicationMapping\DiscriminatorEntry(name: self::TYPE)] +class Generic extends DataSource +{ + + public const TYPE = 'generic'; + + public static function getType(): string + { + return self::TYPE; + } + + public function getSource(): MetadataTypes\Sources\Module + { + return MetadataTypes\Sources\Module::UI; + } + +} diff --git a/src/Hydrators/Dashboards/Dashboard.php b/src/Hydrators/Dashboards/Dashboard.php index fc10a02..3bde7cc 100644 --- a/src/Hydrators/Dashboards/Dashboard.php +++ b/src/Hydrators/Dashboards/Dashboard.php @@ -51,6 +51,18 @@ public function getEntityName(): string return Entities\Dashboards\Dashboard::class; } + protected function hydrateNameAttribute(JsonAPIDocument\Objects\IStandardObject $attributes): string|null + { + if ( + !is_scalar($attributes->get('name')) + || (string) $attributes->get('name') === '' + ) { + return null; + } + + return (string) $attributes->get('name'); + } + protected function hydrateCommentAttribute(JsonAPIDocument\Objects\IStandardObject $attributes): string|null { if ( diff --git a/src/Hydrators/Dashboards/Tabs/Tab.php b/src/Hydrators/Dashboards/Tabs/Tab.php index 357ad2e..78b0a72 100644 --- a/src/Hydrators/Dashboards/Tabs/Tab.php +++ b/src/Hydrators/Dashboards/Tabs/Tab.php @@ -51,6 +51,18 @@ public function getEntityName(): string return Entities\Dashboards\Tabs\Tab::class; } + protected function hydrateNameAttribute(JsonAPIDocument\Objects\IStandardObject $attributes): string|null + { + if ( + !is_scalar($attributes->get('name')) + || (string) $attributes->get('name') === '' + ) { + return null; + } + + return (string) $attributes->get('name'); + } + protected function hydrateCommentAttribute(JsonAPIDocument\Objects\IStandardObject $attributes): string|null { if ( diff --git a/src/Hydrators/Groups/Group.php b/src/Hydrators/Groups/Group.php index a2d9a45..7c295d4 100644 --- a/src/Hydrators/Groups/Group.php +++ b/src/Hydrators/Groups/Group.php @@ -50,6 +50,18 @@ public function getEntityName(): string return Entities\Groups\Group::class; } + protected function hydrateNameAttribute(JsonAPIDocument\Objects\IStandardObject $attributes): string|null + { + if ( + !is_scalar($attributes->get('name')) + || (string) $attributes->get('name') === '' + ) { + return null; + } + + return (string) $attributes->get('name'); + } + protected function hydrateCommentAttribute(JsonAPIDocument\Objects\IStandardObject $attributes): string|null { if ( diff --git a/src/Hydrators/Widgets/DataSources/ChannelProperty.php b/src/Hydrators/Widgets/DataSources/ChannelProperty.php deleted file mode 100644 index c0a7049..0000000 --- a/src/Hydrators/Widgets/DataSources/ChannelProperty.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @package FastyBird:UIModule! - * @subpackage Hydrators - * @since 1.0.0 - * - * @date 27.05.20 - */ - -namespace FastyBird\Module\Ui\Hydrators\Widgets\DataSources; - -use FastyBird\Module\Ui\Entities; -use IPub\JsonAPIDocument; -use Ramsey\Uuid; -use function is_scalar; - -/** - * Channel property data source entity hydrator - * - * @extends DataSource - * - * @package FastyBird:UIModule! - * @subpackage Hydrators - * @author Adam Kadlec - */ -final class ChannelProperty extends DataSource -{ - - /** @var array */ - protected array $attributes = [ - 'channel', - 'property', - ]; - - public function getEntityName(): string - { - return Entities\Widgets\DataSources\ChannelProperty::class; - } - - public function hydrateChannelAttribute( - JsonAPIDocument\Objects\IStandardObject $attributes, - Entities\Widgets\DataSources\DataSource|null $entity = null, - ): Uuid\UuidInterface|null - { - if ( - !is_scalar($attributes->get('channel')) - || (string) $attributes->get('channel') === '' - || !Uuid\Uuid::isValid((string) $attributes->get('channel')) - ) { - return null; - } - - return Uuid\Uuid::fromString((string) $attributes->get('channel')); - } - - public function hydratePropertyAttribute( - JsonAPIDocument\Objects\IStandardObject $attributes, - Entities\Widgets\DataSources\DataSource|null $entity = null, - ): Uuid\UuidInterface|null - { - if ( - !is_scalar($attributes->get('property')) - || (string) $attributes->get('property') === '' - || !Uuid\Uuid::isValid((string) $attributes->get('property')) - ) { - return null; - } - - return Uuid\Uuid::fromString((string) $attributes->get('property')); - } - -} diff --git a/src/Hydrators/Widgets/DataSources/Generic.php b/src/Hydrators/Widgets/DataSources/Generic.php new file mode 100644 index 0000000..b6ef119 --- /dev/null +++ b/src/Hydrators/Widgets/DataSources/Generic.php @@ -0,0 +1,37 @@ + + * @package FastyBird:UIModule! + * @subpackage Hydrators + * @since 1.0.0 + * + * @date 03.08.24 + */ + +namespace FastyBird\Module\Ui\Hydrators\Widgets\DataSources; + +use FastyBird\Module\Ui\Entities; + +/** + * Generic data source entity hydrator + * + * @extends DataSource + * + * @package FastyBird:UIModule! + * @subpackage Hydrators + * @author Adam Kadlec + */ +final class Generic extends DataSource +{ + + public function getEntityName(): string + { + return Entities\Widgets\DataSources\Generic::class; + } + +} diff --git a/src/Hydrators/Widgets/Displays/Button.php b/src/Hydrators/Widgets/Displays/Button.php index 1403c35..879addc 100644 --- a/src/Hydrators/Widgets/Displays/Button.php +++ b/src/Hydrators/Widgets/Displays/Button.php @@ -23,6 +23,7 @@ use TypeError; use ValueError; use function is_scalar; +use function strval; /** * Button widget display entity hydrator @@ -59,8 +60,8 @@ protected function hydrateIconAttribute(JsonAPIDocument\Objects\IStandardObject ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/icon', ], @@ -70,8 +71,8 @@ protected function hydrateIconAttribute(JsonAPIDocument\Objects\IStandardObject if (Types\WidgetIcon::tryFrom((string) $attributes->get('icon')) === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.invalidAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidAttribute.message')), [ 'pointer' => '/data/attributes/icon', ], diff --git a/src/Hydrators/Widgets/Displays/ChartGraph.php b/src/Hydrators/Widgets/Displays/ChartGraph.php index 0d9f942..e5b6d9c 100644 --- a/src/Hydrators/Widgets/Displays/ChartGraph.php +++ b/src/Hydrators/Widgets/Displays/ChartGraph.php @@ -20,6 +20,7 @@ use Fig\Http\Message\StatusCodeInterface; use IPub\JsonAPIDocument; use function is_scalar; +use function strval; /** * Chart graph widget display entity hydrator @@ -58,8 +59,8 @@ protected function hydrateEnableMinMaxAttribute(JsonAPIDocument\Objects\IStandar ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/enable_min_max', ], diff --git a/src/Hydrators/Widgets/Displays/Display.php b/src/Hydrators/Widgets/Displays/Display.php index 25a06a3..18e51e6 100644 --- a/src/Hydrators/Widgets/Displays/Display.php +++ b/src/Hydrators/Widgets/Displays/Display.php @@ -22,6 +22,7 @@ use Fig\Http\Message\StatusCodeInterface; use IPub\JsonAPIDocument; use function is_scalar; +use function strval; /** * Widget display entity hydrator @@ -57,8 +58,8 @@ protected function hydratePrecisionAttribute(JsonAPIDocument\Objects\IStandardOb ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/precision', ], @@ -79,8 +80,8 @@ protected function hydrateMinimumValueAttribute(JsonAPIDocument\Objects\IStandar ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/minimum_value', ], @@ -101,8 +102,8 @@ protected function hydrateMaximumValueAttribute(JsonAPIDocument\Objects\IStandar ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/maximum_value', ], @@ -123,8 +124,8 @@ protected function hydrateStepValueAttribute(JsonAPIDocument\Objects\IStandardOb ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/step_value', ], diff --git a/src/Hydrators/Widgets/Displays/GroupedButton.php b/src/Hydrators/Widgets/Displays/GroupedButton.php index 70285fa..fb32ce6 100644 --- a/src/Hydrators/Widgets/Displays/GroupedButton.php +++ b/src/Hydrators/Widgets/Displays/GroupedButton.php @@ -23,6 +23,7 @@ use TypeError; use ValueError; use function is_scalar; +use function strval; /** * Grouped button widget display entity hydrator @@ -59,8 +60,8 @@ protected function hydrateIconAttribute(JsonAPIDocument\Objects\IStandardObject ) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.missingAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingAttribute.message')), [ 'pointer' => '/data/attributes/icon', ], @@ -70,8 +71,8 @@ protected function hydrateIconAttribute(JsonAPIDocument\Objects\IStandardObject if (Types\WidgetIcon::tryFrom((string) $attributes->get('icon')) === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidAttribute.heading'), - $this->translator->translate('//ui-module.base.messages.invalidAttribute.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidAttribute.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidAttribute.message')), [ 'pointer' => '/data/attributes/icon', ], diff --git a/src/Hydrators/Widgets/Widget.php b/src/Hydrators/Widgets/Widget.php index 2066b93..f5b6ff4 100644 --- a/src/Hydrators/Widgets/Widget.php +++ b/src/Hydrators/Widgets/Widget.php @@ -19,14 +19,21 @@ use Doctrine\Persistence; use FastyBird\JsonApi\Exceptions as JsonApiExceptions; use FastyBird\JsonApi\Hydrators as JsonApiHydrators; +use FastyBird\JsonApi\JsonApi as JsonApiJsonApi; use FastyBird\Library\Application\Exceptions as ApplicationExceptions; use FastyBird\Module\Ui\Entities; +use FastyBird\Module\Ui\Hydrators; use FastyBird\Module\Ui\Models; use FastyBird\Module\Ui\Queries; use FastyBird\Module\Ui\Schemas; use Fig\Http\Message\StatusCodeInterface; +use IPub\DoctrineCrud\Entities as DoctrineCrudEntities; use IPub\JsonAPIDocument; +use Nette\DI; use Ramsey\Uuid; +use function assert; +use function is_scalar; +use function strval; /** * Widget entity hydrator @@ -62,8 +69,16 @@ abstract class Widget extends JsonApiHydrators\Hydrator Schemas\Widgets\Widget::RELATIONSHIPS_DATA_SOURCES => 'dataSources', ]; + /** @var JsonApiJsonApi\SchemaContainer|null */ + private JsonApiJsonApi\SchemaContainer|null $jsonApiSchemaContainer = null; + + /** @var array>|null */ + private array|null $dataSourcesHydrators = null; + public function __construct( + private readonly Models\Entities\Dashboards\Tabs\Repository $tabsRepository, private readonly Models\Entities\Groups\Repository $groupsRepository, + private readonly DI\Container $container, Persistence\ManagerRegistry $managerRegistry, Translation\Translator $translator, ) @@ -71,6 +86,18 @@ public function __construct( parent::__construct($managerRegistry, $translator); } + protected function hydrateNameAttribute(JsonAPIDocument\Objects\IStandardObject $attributes): string|null + { + if ( + !is_scalar($attributes->get('name')) + || (string) $attributes->get('name') === '' + ) { + return null; + } + + return (string) $attributes->get('name'); + } + /** * @return array|null * @@ -233,8 +260,8 @@ private function buildDisplay( throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingRelation.heading'), - $this->translator->translate('//ui-module.base.messages.missingRelation.message'), + strval($this->translator->translate('//ui-module.base.messages.missingRelation.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingRelation.message')), [ 'pointer' => '/data/relationships/display/data', ], @@ -244,6 +271,8 @@ private function buildDisplay( /** * @return array * + * @throws DI\MissingServiceException + * @throws JsonApiExceptions\InvalidState * @throws JsonApiExceptions\JsonApiError */ protected function hydrateDataSourcesRelationship( @@ -254,8 +283,8 @@ protected function hydrateDataSourcesRelationship( if ($included === null) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingRelation.heading'), - $this->translator->translate('//ui-module.base.messages.missingRelation.message'), + strval($this->translator->translate('//ui-module.base.messages.missingRelation.heading')), + strval($this->translator->translate('//ui-module.base.messages.missingRelation.message')), [ 'pointer' => '/data/relationships/data-sources/data/id', ], @@ -264,32 +293,83 @@ protected function hydrateDataSourcesRelationship( $dataSources = []; + $dataSourcesHydrators = $this->getDataSourceHydrators(); + foreach ($relationship->getIdentifiers() as $dataSourceRelationIdentifier) { - if ($dataSourceRelationIdentifier->getType() === Schemas\Widgets\DataSources\ChannelProperty::SCHEMA_TYPE) { - foreach ($included->getAll() as $item) { - if ($item->getId() === $dataSourceRelationIdentifier->getId()) { - $dataSources[] = [ - 'entity' => Entities\Widgets\DataSources\ChannelProperty::class, - 'channel' => $item->getAttributes()->get('channel'), - 'property' => $item->getAttributes()->get('property'), - ]; + foreach ($included->getAll() as $item) { + if ($item->getId() === $dataSourceRelationIdentifier->getId()) { + foreach ($dataSourcesHydrators as $dataSourceHydrator) { + $dataSourcesSchema = $this->getSchemaContainer()->getSchemaByClassName( + $dataSourceHydrator->getEntityName(), + ); + + if ($dataSourcesSchema->getType() === $item->getType()) { + $entityMapping = $this->mapEntity($dataSourceHydrator->getEntityName()); + + $dataSource = $this->hydrateAttributes( + $dataSourceHydrator->getEntityName(), + $item->getAttributes(), + $entityMapping, + null, + null, + ); + + if ($item->getId() !== null) { + $dataSource[self::IDENTIFIER_KEY] = Uuid\Uuid::fromString($item->getId()); + } + + $dataSources[] = $dataSource; + } } } } } - if ($dataSources === []) { - throw new JsonApiExceptions\JsonApiError( - StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingRelation.heading'), - $this->translator->translate('//ui-module.base.messages.missingRelation.message'), - [ - 'pointer' => '/data/relationships/data-sources/data/id', - ], - ); + return $dataSources; + } + + /** + * @return array|null + * + * @throws ApplicationExceptions\InvalidState + * @throws JsonApiExceptions\JsonApiError + */ + protected function hydrateTabsRelationship( + JsonAPIDocument\Objects\IRelationshipObject $relationship, + JsonAPIDocument\Objects\IResourceObjectCollection|null $included, + ): array|null + { + if (!$relationship->isHasMany()) { + return null; } - return $dataSources; + $tabs = []; + + foreach ($relationship->getIdentifiers() as $tabRelationIdentifier) { + try { + if ($tabRelationIdentifier->getId() !== null && $tabRelationIdentifier->getId() !== '') { + $findQuery = new Queries\Entities\FindTabs(); + $findQuery->byId(Uuid\Uuid::fromString($tabRelationIdentifier->getId())); + + $tab = $this->tabsRepository->findOneBy($findQuery); + + if ($tab !== null) { + $tabs[] = $tab; + } + } + } catch (Uuid\Exception\InvalidUuidStringException) { + throw new JsonApiExceptions\JsonApiError( + StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, + strval($this->translator->translate('//ui-module.base.messages.invalidIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidIdentifier.message')), + [ + 'pointer' => '/data/relationships/tabs/data/id', + ], + ); + } + } + + return $tabs; } /** @@ -324,8 +404,8 @@ protected function hydrateGroupsRelationship( } catch (Uuid\Exception\InvalidUuidStringException) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.invalidIdentifier.heading'), - $this->translator->translate('//ui-module.base.messages.invalidIdentifier.message'), + strval($this->translator->translate('//ui-module.base.messages.invalidIdentifier.heading')), + strval($this->translator->translate('//ui-module.base.messages.invalidIdentifier.message')), [ 'pointer' => '/data/relationships/groups/data/id', ], @@ -333,18 +413,48 @@ protected function hydrateGroupsRelationship( } } - if ($groups === []) { - throw new JsonApiExceptions\JsonApiError( - StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - $this->translator->translate('//ui-module.base.messages.missingRelation.heading'), - $this->translator->translate('//ui-module.base.messages.missingRelation.message'), - [ - 'pointer' => '/data/relationships/groups/data/id', - ], - ); + return $groups; + } + + /** + * @return JsonApiJsonApi\SchemaContainer + * + * @throws DI\MissingServiceException + */ + private function getSchemaContainer(): JsonApiJsonApi\SchemaContainer + { + if ($this->jsonApiSchemaContainer !== null) { + return $this->jsonApiSchemaContainer; } - return $groups; + $this->jsonApiSchemaContainer = $this->container->getByType(JsonApiJsonApi\SchemaContainer::class); + + return $this->jsonApiSchemaContainer; + } + + /** + * @return array> + * + * @throws DI\MissingServiceException + */ + private function getDataSourceHydrators(): array + { + if ($this->dataSourcesHydrators !== null) { + return $this->dataSourcesHydrators; + } + + $this->dataSourcesHydrators = []; + + $serviceNames = $this->container->findByType(Hydrators\Widgets\DataSources\DataSource::class); + + foreach ($serviceNames as $serviceName) { + $service = $this->container->getByName($serviceName); + assert($service instanceof Hydrators\Widgets\DataSources\DataSource); + + $this->dataSourcesHydrators[] = $service; + } + + return $this->dataSourcesHydrators; } } diff --git a/src/Middleware/Access.php b/src/Middleware/Access.php index 6745427..d486981 100644 --- a/src/Middleware/Access.php +++ b/src/Middleware/Access.php @@ -23,6 +23,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use function strval; /** * Access check middleware @@ -49,14 +50,14 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface } catch (SimpleAuthExceptions\UnauthorizedAccess) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_UNAUTHORIZED, - $this->translator->translate('//ui-module.base.messages.unauthorized.heading'), - $this->translator->translate('//ui-module.base.messages.unauthorized.message'), + strval($this->translator->translate('//ui-module.base.messages.unauthorized.heading')), + strval($this->translator->translate('//ui-module.base.messages.unauthorized.message')), ); } catch (SimpleAuthExceptions\ForbiddenAccess) { throw new JsonApiExceptions\JsonApiError( StatusCodeInterface::STATUS_FORBIDDEN, - $this->translator->translate('//ui-module.base.messages.forbidden.heading'), - $this->translator->translate('//ui-module.base.messages.forbidden.message'), + strval($this->translator->translate('//ui-module.base.messages.forbidden.heading')), + strval($this->translator->translate('//ui-module.base.messages.forbidden.message')), ); } } diff --git a/src/Models/Entities/Dashboards/Manager.php b/src/Models/Entities/Dashboards/Manager.php index bf8eeb6..0d9b64b 100644 --- a/src/Models/Entities/Dashboards/Manager.php +++ b/src/Models/Entities/Dashboards/Manager.php @@ -15,6 +15,7 @@ namespace FastyBird\Module\Ui\Models\Entities\Dashboards; +use Doctrine\DBAL; use FastyBird\Module\Ui\Entities; use FastyBird\Module\Ui\Events; use FastyBird\Module\Ui\Models; @@ -51,6 +52,12 @@ public function __construct( { } + /** + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\EntityCreation + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState + */ public function create( Utils\ArrayHash $values, ): Entities\Dashboards\Dashboard @@ -64,7 +71,9 @@ public function create( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function update( Entities\Dashboards\Dashboard $entity, @@ -80,7 +89,8 @@ public function update( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function delete(Entities\Dashboards\Dashboard $entity): bool { diff --git a/src/Models/Entities/Dashboards/Tabs/Manager.php b/src/Models/Entities/Dashboards/Tabs/Manager.php index f29f7c1..0bf5c85 100644 --- a/src/Models/Entities/Dashboards/Tabs/Manager.php +++ b/src/Models/Entities/Dashboards/Tabs/Manager.php @@ -15,6 +15,7 @@ namespace FastyBird\Module\Ui\Models\Entities\Dashboards\Tabs; +use Doctrine\DBAL; use FastyBird\Module\Ui\Entities; use FastyBird\Module\Ui\Events; use FastyBird\Module\Ui\Models; @@ -51,6 +52,12 @@ public function __construct( { } + /** + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\EntityCreation + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState + */ public function create(Utils\ArrayHash $values): Entities\Dashboards\Tabs\Tab { $entity = $this->getEntityCrud()->getEntityCreator()->create($values); @@ -62,7 +69,9 @@ public function create(Utils\ArrayHash $values): Entities\Dashboards\Tabs\Tab } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function update( Entities\Dashboards\Tabs\Tab $entity, @@ -78,7 +87,8 @@ public function update( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function delete(Entities\Dashboards\Tabs\Tab $entity): bool { diff --git a/src/Models/Entities/Groups/Manager.php b/src/Models/Entities/Groups/Manager.php index 30a4e99..0f19afa 100644 --- a/src/Models/Entities/Groups/Manager.php +++ b/src/Models/Entities/Groups/Manager.php @@ -15,6 +15,7 @@ namespace FastyBird\Module\Ui\Models\Entities\Groups; +use Doctrine\DBAL; use FastyBird\Module\Ui\Entities; use FastyBird\Module\Ui\Events; use FastyBird\Module\Ui\Models; @@ -51,6 +52,12 @@ public function __construct( { } + /** + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\EntityCreation + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState + */ public function create(Utils\ArrayHash $values): Entities\Groups\Group { $entity = $this->getEntityCrud()->getEntityCreator()->create($values); @@ -62,7 +69,9 @@ public function create(Utils\ArrayHash $values): Entities\Groups\Group } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function update( Entities\Groups\Group $entity, @@ -78,7 +87,8 @@ public function update( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function delete(Entities\Groups\Group $entity): bool { diff --git a/src/Models/Entities/Widgets/DataSources/Manager.php b/src/Models/Entities/Widgets/DataSources/Manager.php index 034858b..638c439 100644 --- a/src/Models/Entities/Widgets/DataSources/Manager.php +++ b/src/Models/Entities/Widgets/DataSources/Manager.php @@ -15,6 +15,7 @@ namespace FastyBird\Module\Ui\Models\Entities\Widgets\DataSources; +use Doctrine\DBAL; use FastyBird\Module\Ui\Entities; use FastyBird\Module\Ui\Events; use FastyBird\Module\Ui\Models; @@ -51,6 +52,12 @@ public function __construct( { } + /** + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\EntityCreation + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState + */ public function create( Utils\ArrayHash $values, ): Entities\Widgets\DataSources\DataSource @@ -64,7 +71,9 @@ public function create( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function update( Entities\Widgets\DataSources\DataSource $entity, @@ -80,7 +89,8 @@ public function update( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function delete(Entities\Widgets\DataSources\DataSource $entity): bool { diff --git a/src/Models/Entities/Widgets/Displays/Manager.php b/src/Models/Entities/Widgets/Displays/Manager.php index 374cb0a..57d5456 100644 --- a/src/Models/Entities/Widgets/Displays/Manager.php +++ b/src/Models/Entities/Widgets/Displays/Manager.php @@ -15,6 +15,7 @@ namespace FastyBird\Module\Ui\Models\Entities\Widgets\Displays; +use Doctrine\DBAL; use FastyBird\Module\Ui\Entities; use FastyBird\Module\Ui\Events; use FastyBird\Module\Ui\Models; @@ -52,7 +53,9 @@ public function __construct( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function update( Entities\Widgets\Display\Display $entity, diff --git a/src/Models/Entities/Widgets/Manager.php b/src/Models/Entities/Widgets/Manager.php index bde4898..87723aa 100644 --- a/src/Models/Entities/Widgets/Manager.php +++ b/src/Models/Entities/Widgets/Manager.php @@ -15,6 +15,7 @@ namespace FastyBird\Module\Ui\Models\Entities\Widgets; +use Doctrine\DBAL; use FastyBird\Module\Ui\Entities; use FastyBird\Module\Ui\Events; use FastyBird\Module\Ui\Models; @@ -51,6 +52,12 @@ public function __construct( { } + /** + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\EntityCreation + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState + */ public function create(Utils\ArrayHash $values): Entities\Widgets\Widget { $entity = $this->getEntityCrud()->getEntityCreator()->create($values); @@ -62,7 +69,9 @@ public function create(Utils\ArrayHash $values): Entities\Widgets\Widget } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DBAL\Exception\UniqueConstraintViolationException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function update( Entities\Widgets\Widget $entity, @@ -78,7 +87,8 @@ public function update( } /** - * @throws DoctrineCrudExceptions\InvalidArgumentException + * @throws DoctrineCrudExceptions\InvalidArgument + * @throws DoctrineCrudExceptions\InvalidState */ public function delete(Entities\Widgets\Widget $entity): bool { diff --git a/src/Schemas/Dashboards/Dashboard.php b/src/Schemas/Dashboards/Dashboard.php index 141cf72..945920a 100644 --- a/src/Schemas/Dashboards/Dashboard.php +++ b/src/Schemas/Dashboards/Dashboard.php @@ -46,7 +46,7 @@ final class Dashboard extends JsonApiSchemas\JsonApi */ public const RELATIONSHIPS_TABS = 'tabs'; - public function __construct(protected Routing\IRouter $router) + public function __construct(protected readonly Routing\IRouter $router) { } diff --git a/src/Schemas/Dashboards/Tabs/Tab.php b/src/Schemas/Dashboards/Tabs/Tab.php index 404fec6..b41611b 100644 --- a/src/Schemas/Dashboards/Tabs/Tab.php +++ b/src/Schemas/Dashboards/Tabs/Tab.php @@ -49,7 +49,7 @@ final class Tab extends JsonApiSchemas\JsonApi public const RELATIONSHIPS_WIDGETS = 'widgets'; - public function __construct(protected Routing\IRouter $router) + public function __construct(protected readonly Routing\IRouter $router) { } diff --git a/src/Schemas/Groups/Group.php b/src/Schemas/Groups/Group.php index 90b9f50..ec660e3 100644 --- a/src/Schemas/Groups/Group.php +++ b/src/Schemas/Groups/Group.php @@ -46,7 +46,7 @@ final class Group extends JsonApiSchemas\JsonApi */ public const RELATIONSHIPS_WIDGETS = 'widgets'; - public function __construct(protected Routing\IRouter $router) + public function __construct(protected readonly Routing\IRouter $router) { } diff --git a/src/Schemas/Widgets/DataSources/ChannelProperty.php b/src/Schemas/Widgets/DataSources/ChannelProperty.php deleted file mode 100644 index 617fe7f..0000000 --- a/src/Schemas/Widgets/DataSources/ChannelProperty.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @package FastyBird:UIModule! - * @subpackage Schemas - * @since 1.0.0 - * - * @date 26.05.20 - */ - -namespace FastyBird\Module\Ui\Schemas\Widgets\DataSources; - -use FastyBird\Library\Metadata\Types as MetadataTypes; -use FastyBird\Module\Ui\Entities; -use Neomerx\JsonApi; -use function array_merge; - -/** - * Channel data source entity schema - * - * @template T of Entities\Widgets\DataSources\ChannelProperty - * @extends DataSource - * - * @package FastyBird:UIModule! - * @subpackage Schemas - * @author Adam Kadlec - */ -final class ChannelProperty extends DataSource -{ - - /** - * Define entity schema type string - */ - public const SCHEMA_TYPE = MetadataTypes\Sources\Module::UI->value . '/data-source/' . Entities\Widgets\DataSources\ChannelProperty::TYPE; - - public function getType(): string - { - return self::SCHEMA_TYPE; - } - - public function getEntityClass(): string - { - return Entities\Widgets\DataSources\ChannelProperty::class; - } - - /** - * @param T $resource - * - * @return iterable - * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint - */ - public function getAttributes( - $resource, - JsonApi\Contracts\Schema\ContextInterface $context, - ): iterable - { - return array_merge( - (array) parent::getAttributes($resource, $context), - [ - 'channel' => $resource->getChannel()->toString(), - 'property' => $resource->getProperty()->toString(), - ], - ); - } - -} diff --git a/src/Schemas/Widgets/DataSources/DataSource.php b/src/Schemas/Widgets/DataSources/DataSource.php index dbc8921..baf780d 100644 --- a/src/Schemas/Widgets/DataSources/DataSource.php +++ b/src/Schemas/Widgets/DataSources/DataSource.php @@ -40,7 +40,7 @@ abstract class DataSource extends JsonApiSchemas\JsonApi */ public const RELATIONSHIPS_WIDGET = 'widget'; - public function __construct(protected Routing\IRouter $router) + public function __construct(protected readonly Routing\IRouter $router) { } @@ -56,9 +56,7 @@ public function getAttributes( JsonApi\Contracts\Schema\ContextInterface $context, ): iterable { - return [ - 'params' => (array) $resource->getParams(), - ]; + return []; } /** diff --git a/src/Schemas/Widgets/DataSources/Generic.php b/src/Schemas/Widgets/DataSources/Generic.php new file mode 100644 index 0000000..b7c1c8d --- /dev/null +++ b/src/Schemas/Widgets/DataSources/Generic.php @@ -0,0 +1,49 @@ + + * @package FastyBird:UIModule! + * @subpackage Schemas + * @since 1.0.0 + * + * @date 04.08.24 + */ + +namespace FastyBird\Module\Ui\Schemas\Widgets\DataSources; + +use FastyBird\Library\Metadata\Types as MetadataTypes; +use FastyBird\Module\Ui\Entities; +use FastyBird\Module\Ui\Schemas; + +/** + * Generic data source entity schema + * + * @extends DataSource + * + * @package FastyBird:UIModule! + * @subpackage Schemas + * @author Adam Kadlec + */ +final class Generic extends DataSource +{ + + /** + * Define entity schema type string + */ + public const SCHEMA_TYPE = MetadataTypes\Sources\Module::UI->value . '/data-source/' . Entities\Widgets\DataSources\Generic::TYPE; + + public function getEntityClass(): string + { + return Entities\Widgets\DataSources\Generic::class; + } + + public function getType(): string + { + return self::SCHEMA_TYPE; + } + +} diff --git a/src/Schemas/Widgets/Display/Display.php b/src/Schemas/Widgets/Display/Display.php index 13ac2fb..03d2f6f 100644 --- a/src/Schemas/Widgets/Display/Display.php +++ b/src/Schemas/Widgets/Display/Display.php @@ -40,7 +40,7 @@ abstract class Display extends JsonApiSchemas\JsonApi */ public const RELATIONSHIPS_WIDGET = 'widget'; - public function __construct(protected Routing\IRouter $router) + public function __construct(protected readonly Routing\IRouter $router) { } diff --git a/src/Schemas/Widgets/Widget.php b/src/Schemas/Widgets/Widget.php index 31f10d4..1ef870d 100644 --- a/src/Schemas/Widgets/Widget.php +++ b/src/Schemas/Widgets/Widget.php @@ -47,7 +47,7 @@ abstract class Widget extends JsonApiSchemas\JsonApi public const RELATIONSHIPS_DATA_SOURCES = 'data-sources'; - public function __construct(protected Routing\IRouter $router) + public function __construct(protected readonly Routing\IRouter $router) { } diff --git a/tests/cases/unit/Controllers/DataSourcesV1Test.php b/tests/cases/unit/Controllers/DataSourcesV1Test.php index 30c23ab..1e438a9 100644 --- a/tests/cases/unit/Controllers/DataSourcesV1Test.php +++ b/tests/cases/unit/Controllers/DataSourcesV1Test.php @@ -163,15 +163,6 @@ public static function dataSourcesCreate(): array StatusCodeInterface::STATUS_CREATED, __DIR__ . '/../../../fixtures/Controllers/responses/dataSources.create.json', ], - 'missingRequired' => [ - '/api/' . Metadata\Constants::MODULE_UI_PREFIX . '/v1/widgets/15553443-4564-454d-af04-0dfeef08aa96/data-sources', - 'Bearer ' . self::VALID_TOKEN, - file_get_contents( - __DIR__ . '/../../../fixtures/Controllers/requests/dataSources.create.missing.required.json', - ), - StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, - __DIR__ . '/../../../fixtures/Controllers/responses/dataSources.missing.required.json', - ], 'widgetNotFound' => [ '/api/' . Metadata\Constants::MODULE_UI_PREFIX . '/v1/widgets/11553443-4564-454d-af04-0dfeef08aa96/data-sources', 'Bearer ' . self::VALID_TOKEN, diff --git a/tests/cases/unit/DI/UiExtensionTest.php b/tests/cases/unit/DI/UiExtensionTest.php index 420e74a..42b753c 100644 --- a/tests/cases/unit/DI/UiExtensionTest.php +++ b/tests/cases/unit/DI/UiExtensionTest.php @@ -68,9 +68,7 @@ public function testServicesRegistration(): void self::assertNotNull($this->getContainer()->getByType(Schemas\Widgets\Display\Gauge::class, false)); self::assertNotNull($this->getContainer()->getByType(Schemas\Widgets\Display\GroupedButton::class, false)); self::assertNotNull($this->getContainer()->getByType(Schemas\Widgets\Display\Slider::class, false)); - self::assertNotNull( - $this->getContainer()->getByType(Schemas\Widgets\DataSources\ChannelProperty::class, false), - ); + self::assertNotNull($this->getContainer()->getByType(Schemas\Widgets\DataSources\Generic::class, false)); self::assertNotNull($this->getContainer()->getByType(Hydrators\Dashboards\Dashboard::class, false)); self::assertNotNull($this->getContainer()->getByType(Hydrators\Dashboards\Tabs\Tab::class, false)); @@ -86,9 +84,7 @@ public function testServicesRegistration(): void self::assertNotNull($this->getContainer()->getByType(Hydrators\Widgets\Displays\Gauge::class, false)); self::assertNotNull($this->getContainer()->getByType(Hydrators\Widgets\Displays\GroupedButton::class, false)); self::assertNotNull($this->getContainer()->getByType(Hydrators\Widgets\Displays\Slider::class, false)); - self::assertNotNull( - $this->getContainer()->getByType(Hydrators\Widgets\DataSources\ChannelProperty::class, false), - ); + self::assertNotNull($this->getContainer()->getByType(Hydrators\Widgets\DataSources\Generic::class, false)); self::assertNotNull($this->getContainer()->getByType(Subscribers\DashboardEntity::class, false)); } diff --git a/tests/fixtures/Controllers/requests/dataSources.create.invalidType.json b/tests/fixtures/Controllers/requests/dataSources.create.invalidType.json index 3c0537d..ae4ceb1 100644 --- a/tests/fixtures/Controllers/requests/dataSources.create.invalidType.json +++ b/tests/fixtures/Controllers/requests/dataSources.create.invalidType.json @@ -2,10 +2,7 @@ "data" : { "id" : "0c96af0b-d5be-4e1b-81e6-0d02415b4d1b", "type" : "com.fastybird.ui-module/data-source/invalid", - "attributes" : { - "channel" : "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property" : "099609af-b9f1-4611-9132-616375399fdf" - }, + "attributes" : {}, "relationships" : { "widget" : { "data" : { diff --git a/tests/fixtures/Controllers/requests/dataSources.create.json b/tests/fixtures/Controllers/requests/dataSources.create.json index e807e91..fbf86c7 100644 --- a/tests/fixtures/Controllers/requests/dataSources.create.json +++ b/tests/fixtures/Controllers/requests/dataSources.create.json @@ -1,11 +1,8 @@ { "data" : { "id" : "0c96af0b-d5be-4e1b-81e6-0d02415b4d1b", - "type" : "com.fastybird.ui-module/data-source/channel-property", - "attributes" : { - "channel" : "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property" : "099609af-b9f1-4611-9132-616375399fdf" - }, + "type" : "com.fastybird.ui-module/data-source/generic", + "attributes" : {}, "relationships" : { "widget" : { "data" : { diff --git a/tests/fixtures/Controllers/requests/dataSources.create.missing.required.json b/tests/fixtures/Controllers/requests/dataSources.create.missing.required.json deleted file mode 100644 index cd4aa13..0000000 --- a/tests/fixtures/Controllers/requests/dataSources.create.missing.required.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "data" : { - "id" : "0c96af0b-d5be-4e1b-81e6-0d02415b4d1b", - "type" : "com.fastybird.ui-module/data-source/channel-property", - "attributes" : { - "property" : "099609af-b9f1-4611-9132-616375399fdf" - }, - "relationships" : { - "widget" : { - "data" : { - "id" : "15553443-4564-454d-af04-0dfeef08aa96", - "type" : "com.fastybird.ui-module/widget/analog-sensor" - } - } - } - } -} diff --git a/tests/fixtures/Controllers/requests/dataSources.update.idMismatch.json b/tests/fixtures/Controllers/requests/dataSources.update.idMismatch.json index 2f54f05..fe8d741 100644 --- a/tests/fixtures/Controllers/requests/dataSources.update.idMismatch.json +++ b/tests/fixtures/Controllers/requests/dataSources.update.idMismatch.json @@ -1,10 +1,7 @@ { "data" : { "id" : "774937a7-8565-472e-8e12-fe97cd55a377", - "type" : "com.fastybird.ui-module/data-source/channel-property", - "attributes" : { - "channel" : "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property" : "099609af-b9f1-4611-9132-616375399fdf" - } + "type" : "com.fastybird.ui-module/data-source/generic", + "attributes" : {} } } diff --git a/tests/fixtures/Controllers/requests/dataSources.update.invalidType.json b/tests/fixtures/Controllers/requests/dataSources.update.invalidType.json index 865fccd..ac668c4 100644 --- a/tests/fixtures/Controllers/requests/dataSources.update.invalidType.json +++ b/tests/fixtures/Controllers/requests/dataSources.update.invalidType.json @@ -2,9 +2,6 @@ "data" : { "id" : "764937a7-8565-472e-8e12-fe97cd55a377", "type" : "com.fastybird.ui-module/data-source/invalid", - "attributes" : { - "channel" : "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property" : "099609af-b9f1-4611-9132-616375399fdf" - } + "attributes" : {} } } diff --git a/tests/fixtures/Controllers/requests/dataSources.update.json b/tests/fixtures/Controllers/requests/dataSources.update.json index f620fc7..99ccb8a 100644 --- a/tests/fixtures/Controllers/requests/dataSources.update.json +++ b/tests/fixtures/Controllers/requests/dataSources.update.json @@ -1,10 +1,7 @@ { "data" : { "id" : "764937a7-8565-472e-8e12-fe97cd55a377", - "type" : "com.fastybird.ui-module/data-source/channel-property", - "attributes" : { - "channel" : "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property" : "099609af-b9f1-4611-9132-616375399fdf" - } + "type" : "com.fastybird.ui-module/data-source/generic", + "attributes" : {} } } diff --git a/tests/fixtures/Controllers/requests/dataSources.update.notFound.json b/tests/fixtures/Controllers/requests/dataSources.update.notFound.json index 2f54f05..fe8d741 100644 --- a/tests/fixtures/Controllers/requests/dataSources.update.notFound.json +++ b/tests/fixtures/Controllers/requests/dataSources.update.notFound.json @@ -1,10 +1,7 @@ { "data" : { "id" : "774937a7-8565-472e-8e12-fe97cd55a377", - "type" : "com.fastybird.ui-module/data-source/channel-property", - "attributes" : { - "channel" : "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property" : "099609af-b9f1-4611-9132-616375399fdf" - } + "type" : "com.fastybird.ui-module/data-source/generic", + "attributes" : {} } } diff --git a/tests/fixtures/Controllers/requests/widgets.create.invalidDisplay.json b/tests/fixtures/Controllers/requests/widgets.create.invalidDisplay.json index 763eb6f..e027b80 100644 --- a/tests/fixtures/Controllers/requests/widgets.create.invalidDisplay.json +++ b/tests/fixtures/Controllers/requests/widgets.create.invalidDisplay.json @@ -18,11 +18,11 @@ } ] }, - "data_sources" : { + "data-sources" : { "data" : [ { "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" } ] }, @@ -36,12 +36,9 @@ }, "included" : [ { - "attributes" : { - "channel" : "7b023b2d-dcdc-444d-8d4c-8a8d2ae61e06", - "property" : "55e3ce0e-8967-4173-b454-30aa5ab1ad6b" - }, + "attributes" : {}, "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" }, { "attributes" : { diff --git a/tests/fixtures/Controllers/requests/widgets.create.invalidType.json b/tests/fixtures/Controllers/requests/widgets.create.invalidType.json index 5d3f724..5d41fb7 100644 --- a/tests/fixtures/Controllers/requests/widgets.create.invalidType.json +++ b/tests/fixtures/Controllers/requests/widgets.create.invalidType.json @@ -18,11 +18,11 @@ } ] }, - "data_sources" : { + "data-sources" : { "data" : [ { "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" } ] }, @@ -36,12 +36,9 @@ }, "included" : [ { - "attributes" : { - "channel" : "7b023b2d-dcdc-444d-8d4c-8a8d2ae61e06", - "property" : "55e3ce0e-8967-4173-b454-30aa5ab1ad6b" - }, + "attributes" : {}, "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" }, { "attributes" : { diff --git a/tests/fixtures/Controllers/requests/widgets.create.json b/tests/fixtures/Controllers/requests/widgets.create.json index 7cfed3f..fc810f1 100644 --- a/tests/fixtures/Controllers/requests/widgets.create.json +++ b/tests/fixtures/Controllers/requests/widgets.create.json @@ -19,11 +19,11 @@ } ] }, - "data_sources" : { + "data-sources" : { "data" : [ { "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" } ] }, @@ -37,12 +37,9 @@ }, "included" : [ { - "attributes" : { - "channel" : "7b023b2d-dcdc-444d-8d4c-8a8d2ae61e06", - "property" : "55e3ce0e-8967-4173-b454-30aa5ab1ad6b" - }, + "attributes" : {}, "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" }, { "attributes" : { diff --git a/tests/fixtures/Controllers/requests/widgets.create.missing.required.json b/tests/fixtures/Controllers/requests/widgets.create.missing.required.json index 6cb99c4..2dd7eb4 100644 --- a/tests/fixtures/Controllers/requests/widgets.create.missing.required.json +++ b/tests/fixtures/Controllers/requests/widgets.create.missing.required.json @@ -18,11 +18,11 @@ } ] }, - "data_sources" : { + "data-sources" : { "data" : [ { "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" } ] }, @@ -36,12 +36,9 @@ }, "included" : [ { - "attributes" : { - "channel" : "7b023b2d-dcdc-444d-8d4c-8a8d2ae61e06", - "property" : "55e3ce0e-8967-4173-b454-30aa5ab1ad6b" - }, + "attributes" : {}, "id" : "874c5f81-b60b-4fcc-adb2-3f83b43cf182", - "type" : "com.fastybird.ui-module/data-source/channel-property" + "type" : "com.fastybird.ui-module/data-source/generic" }, { "attributes" : { diff --git a/tests/fixtures/Controllers/responses/dataSources.create.json b/tests/fixtures/Controllers/responses/dataSources.create.json index 4462d55..8d29bb7 100644 --- a/tests/fixtures/Controllers/responses/dataSources.create.json +++ b/tests/fixtures/Controllers/responses/dataSources.create.json @@ -10,13 +10,8 @@ "self": "/api/ui-module/v1/widgets/15553443-4564-454d-af04-0dfeef08aa96/data-sources" }, "data": { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "0c96af0b-d5be-4e1b-81e6-0d02415b4d1b", - "attributes": { - "params": [], - "channel": "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property": "099609af-b9f1-4611-9132-616375399fdf" - }, "relationships": { "widget": { "links": { diff --git a/tests/fixtures/Controllers/responses/dataSources.index.json b/tests/fixtures/Controllers/responses/dataSources.index.json index 1475d16..cc3e3cc 100644 --- a/tests/fixtures/Controllers/responses/dataSources.index.json +++ b/tests/fixtures/Controllers/responses/dataSources.index.json @@ -11,13 +11,8 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377", - "attributes": { - "params": [], - "channel": "81e0d8e1-f640-47d3-b471-6f139ed31bb9", - "property": "459fd862-886a-44c8-8e38-d0ac7338e09e" - }, "relationships": { "widget": { "links": { diff --git a/tests/fixtures/Controllers/responses/dataSources.index.paging.json b/tests/fixtures/Controllers/responses/dataSources.index.paging.json index c231963..1948254 100644 --- a/tests/fixtures/Controllers/responses/dataSources.index.paging.json +++ b/tests/fixtures/Controllers/responses/dataSources.index.paging.json @@ -15,13 +15,8 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377", - "attributes": { - "params": [], - "channel": "81e0d8e1-f640-47d3-b471-6f139ed31bb9", - "property": "459fd862-886a-44c8-8e38-d0ac7338e09e" - }, "relationships": { "widget": { "links": { diff --git a/tests/fixtures/Controllers/responses/dataSources.missing.required.json b/tests/fixtures/Controllers/responses/dataSources.missing.required.json deleted file mode 100644 index 186c0fe..0000000 --- a/tests/fixtures/Controllers/responses/dataSources.missing.required.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "errors": [ - { - "status": "422", - "code": "422", - "title": "Missing attribute", - "detail": "Provided request is missing required attribute", - "source": { - "pointer": "/data/attributes/channel" - } - } - ], - "jsonapi": { - "version": "1.1" - } -} diff --git a/tests/fixtures/Controllers/responses/dataSources.read.json b/tests/fixtures/Controllers/responses/dataSources.read.json index e6e508b..c8dd022 100644 --- a/tests/fixtures/Controllers/responses/dataSources.read.json +++ b/tests/fixtures/Controllers/responses/dataSources.read.json @@ -10,13 +10,8 @@ "self": "/api/ui-module/v1/widgets/15553443-4564-454d-af04-0dfeef08aa96/data-sources/764937a7-8565-472e-8e12-fe97cd55a377" }, "data": { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377", - "attributes": { - "params": [], - "channel": "81e0d8e1-f640-47d3-b471-6f139ed31bb9", - "property": "459fd862-886a-44c8-8e38-d0ac7338e09e" - }, "relationships": { "widget": { "links": { diff --git a/tests/fixtures/Controllers/responses/dataSources.update.json b/tests/fixtures/Controllers/responses/dataSources.update.json index 3630504..c8dd022 100644 --- a/tests/fixtures/Controllers/responses/dataSources.update.json +++ b/tests/fixtures/Controllers/responses/dataSources.update.json @@ -10,13 +10,8 @@ "self": "/api/ui-module/v1/widgets/15553443-4564-454d-af04-0dfeef08aa96/data-sources/764937a7-8565-472e-8e12-fe97cd55a377" }, "data": { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377", - "attributes": { - "params": [], - "channel": "077ed354-a2e0-4266-b5e5-0f3b3ae9c11b", - "property": "099609af-b9f1-4611-9132-616375399fdf" - }, "relationships": { "widget": { "links": { diff --git a/tests/fixtures/Controllers/responses/widgets.create.json b/tests/fixtures/Controllers/responses/widgets.create.json index 90a34ee..e0eaad9 100644 --- a/tests/fixtures/Controllers/responses/widgets.create.json +++ b/tests/fixtures/Controllers/responses/widgets.create.json @@ -33,11 +33,16 @@ "related": { "href": "/api/ui-module/v1/widgets/329a7ac2-a309-4c39-9d97-c7ba69efe74f/data-sources", "meta": { - "count": 0 + "count": 1 } } }, - "data": [] + "data": [ + { + "type": "com.fastybird.ui-module/data-source/generic", + "id": "874c5f81-b60b-4fcc-adb2-3f83b43cf182" + } + ] }, "tabs": { "links": { diff --git a/tests/fixtures/Controllers/responses/widgets.index.json b/tests/fixtures/Controllers/responses/widgets.index.json index b663e53..55f90e2 100644 --- a/tests/fixtures/Controllers/responses/widgets.index.json +++ b/tests/fixtures/Controllers/responses/widgets.index.json @@ -40,7 +40,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377" } ] @@ -102,7 +102,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "32dd50e4-4b66-4dea-9bc5-e835f8543dc4" } ] @@ -164,7 +164,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "ffe067c8-8c02-4c2c-b8dd-05256a121215" } ] @@ -226,7 +226,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "cd96aa91-a0a4-4a6c-9d68-2e0754a0a56d" } ] diff --git a/tests/fixtures/Controllers/responses/widgets.index.paging.json b/tests/fixtures/Controllers/responses/widgets.index.paging.json index 3afdccc..dc16dc1 100644 --- a/tests/fixtures/Controllers/responses/widgets.index.paging.json +++ b/tests/fixtures/Controllers/responses/widgets.index.paging.json @@ -45,7 +45,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377" } ] diff --git a/tests/fixtures/Controllers/responses/widgets.read.include.json b/tests/fixtures/Controllers/responses/widgets.read.include.json index c87e06c..3fdd618 100644 --- a/tests/fixtures/Controllers/responses/widgets.read.include.json +++ b/tests/fixtures/Controllers/responses/widgets.read.include.json @@ -39,7 +39,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377" } ] @@ -105,13 +105,8 @@ } }, { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377", - "attributes": { - "params": [], - "channel": "81e0d8e1-f640-47d3-b471-6f139ed31bb9", - "property": "459fd862-886a-44c8-8e38-d0ac7338e09e" - }, "relationships": { "widget": { "links": { diff --git a/tests/fixtures/Controllers/responses/widgets.read.json b/tests/fixtures/Controllers/responses/widgets.read.json index 94c24ef..a51d8f1 100644 --- a/tests/fixtures/Controllers/responses/widgets.read.json +++ b/tests/fixtures/Controllers/responses/widgets.read.json @@ -39,7 +39,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377" } ] diff --git a/tests/fixtures/Controllers/responses/widgets.readRelationships.dataSources.json b/tests/fixtures/Controllers/responses/widgets.readRelationships.dataSources.json index 1d636f0..c2270c9 100644 --- a/tests/fixtures/Controllers/responses/widgets.readRelationships.dataSources.json +++ b/tests/fixtures/Controllers/responses/widgets.readRelationships.dataSources.json @@ -12,7 +12,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377" } ] diff --git a/tests/fixtures/Controllers/responses/widgets.update.json b/tests/fixtures/Controllers/responses/widgets.update.json index 65af31b..8b28a3c 100644 --- a/tests/fixtures/Controllers/responses/widgets.update.json +++ b/tests/fixtures/Controllers/responses/widgets.update.json @@ -39,7 +39,7 @@ }, "data": [ { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377" } ] @@ -105,13 +105,8 @@ } }, { - "type": "com.fastybird.ui-module/data-source/channel-property", + "type": "com.fastybird.ui-module/data-source/generic", "id": "764937a7-8565-472e-8e12-fe97cd55a377", - "attributes": { - "params": [], - "channel": "81e0d8e1-f640-47d3-b471-6f139ed31bb9", - "property": "459fd862-886a-44c8-8e38-d0ac7338e09e" - }, "relationships": { "widget": { "links": { diff --git a/tests/sql/dummy.data.sql b/tests/sql/dummy.data.sql index 28fcebf..8dadf85 100644 --- a/tests/sql/dummy.data.sql +++ b/tests/sql/dummy.data.sql @@ -23,17 +23,17 @@ IGNORE INTO `fb_ui_module_widgets` (`widget_id`, `widget_identifier`, `widget_na INSERT IGNORE INTO `fb_ui_module_widgets_data_sources` (`data_source_id`, `widget_id`, `params`, `created_at`, `updated_at`, `data_source_type`) VALUES -(_binary 0x32DD50E44B664DEA9BC5E835F8543DC4, _binary 0x1D60090154E743EE8F5DA9E22663DDD7, '[]', '2020-05-28 12:27:47', '2020-05-28 12:27:47', 'channel-property'), -(_binary 0x764937A78565472E8E12FE97CD55A377, _binary 0x155534434564454DAF040DFEEF08AA96, '[]', '2020-05-28 12:29:32', '2020-05-28 12:29:32', 'channel-property'), -(_binary 0xCD96AA91A0A44A6C9D682E0754A0A56D, _binary 0x9A91473298DC47F6BFD19D81CA9F8CB6, '[]', '2020-05-28 11:35:44', '2020-05-28 11:35:44', 'channel-property'), -(_binary 0xFFE067C88C024C2CB8DD05256A121215, _binary 0x5626E7A1C42C4A319B5D848E3CF0E82A, '[]', '2020-05-28 12:07:27', '2020-05-28 12:07:27', 'channel-property'); +(_binary 0x32DD50E44B664DEA9BC5E835F8543DC4, _binary 0x1D60090154E743EE8F5DA9E22663DDD7, '[]', '2020-05-28 12:27:47', '2020-05-28 12:27:47', 'generic'), +(_binary 0x764937A78565472E8E12FE97CD55A377, _binary 0x155534434564454DAF040DFEEF08AA96, '[]', '2020-05-28 12:29:32', '2020-05-28 12:29:32', 'generic'), +(_binary 0xCD96AA91A0A44A6C9D682E0754A0A56D, _binary 0x9A91473298DC47F6BFD19D81CA9F8CB6, '[]', '2020-05-28 11:35:44', '2020-05-28 11:35:44', 'generic'), +(_binary 0xFFE067C88C024C2CB8DD05256A121215, _binary 0x5626E7A1C42C4A319B5D848E3CF0E82A, '[]', '2020-05-28 12:07:27', '2020-05-28 12:07:27', 'generic'); INSERT -IGNORE INTO `fb_ui_module_widgets_data_sources_channels_properties` (`data_source_id`, `data_source_channel`, `data_source_property`) VALUES -(_binary 0x32DD50E44B664DEA9BC5E835F8543DC4, _binary 0xf37e236f975544a5a4ad669a6be3c797, _binary 0x784b319cd06542dea2a27d0800246a48), -(_binary 0x764937A78565472E8E12FE97CD55A377, _binary 0x81e0d8e1f64047d3b4716f139ed31bb9, _binary 0x459fd862886a44c88e38d0ac7338e09e), -(_binary 0xCD96AA91A0A44A6C9D682E0754A0A56D, _binary 0x7a12882ca37c4bbaa1910498f49abd9b, _binary 0xc03e9a0ac20e47248828a844168efd0d), -(_binary 0xFFE067C88C024C2CB8DD05256A121215, _binary 0x8137cbefb076431d88d4567d1083669c, _binary 0x4353865c9f7f4d78b7f1648f63584cb2); +IGNORE INTO `fb_ui_module_widgets_generic_data_sources` (`data_source_id`) VALUES +(_binary 0x32DD50E44B664DEA9BC5E835F8543DC4), +(_binary 0x764937A78565472E8E12FE97CD55A377), +(_binary 0xCD96AA91A0A44A6C9D682E0754A0A56D), +(_binary 0xFFE067C88C024C2CB8DD05256A121215); INSERT IGNORE INTO `fb_ui_module_widgets_display` (`display_id`, `widget_id`, `params`, `created_at`, `updated_at`, `display_type`) VALUES