From 29c1efb3e51254b2b236bf06212296a3b2205c09 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Tue, 15 Nov 2022 14:09:18 +0300 Subject: [PATCH 01/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D0=B0=D1=82=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=84=D0=B8=D0=BB=D1=8C=D1=82=D1=80=D0=BE=D0=B2=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20ApiQL=20=D0=BF=D0=BE=20=D1=81=D0=BE=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D1=8F=D0=BD=D0=B8=D1=8F=D0=BC=20=D0=B2=20StateService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/StateServiceInterface.php | 4 ++-- .../State/Formatter/ComplexStateFormatter.php | 6 +++--- .../Service/State/Formatter/Formatter.php | 18 ++++++++++++++++-- .../State/Formatter/SimpleStateFormatter.php | 12 +++++++++++- .../Service/State/StateService.php | 4 ++-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/Application/Service/StateServiceInterface.php b/src/Application/Service/StateServiceInterface.php index fba3ac3..2e6e3f5 100644 --- a/src/Application/Service/StateServiceInterface.php +++ b/src/Application/Service/StateServiceInterface.php @@ -10,7 +10,7 @@ namespace ServiceCore\Application\Service; interface StateServiceInterface { /** - * @param int[]|int $states + * @param int[] $states * @param array $recordData * @param string $logicalOperator * @param bool $addWhere @@ -18,7 +18,7 @@ interface StateServiceInterface * @return array */ public function convertToApiQl( - $states, + array $states, array $recordData = [], string $logicalOperator = 'and', bool $addWhere = true diff --git a/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php b/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php index ab52cac..a518c3f 100644 --- a/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php +++ b/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php @@ -46,14 +46,14 @@ class ComplexStateFormatter $this->recordData = $recordData; } - public function format(array $state): array + public function format(array $state): ?array { if (!isset($state['properties'])) { - return []; + return null; } if (!isset($state['properties']['filters'])) { - return []; + return null; } return $this->finalFormat([ diff --git a/src/Infrastructure/Service/State/Formatter/Formatter.php b/src/Infrastructure/Service/State/Formatter/Formatter.php index ef2648a..e05b33f 100644 --- a/src/Infrastructure/Service/State/Formatter/Formatter.php +++ b/src/Infrastructure/Service/State/Formatter/Formatter.php @@ -121,7 +121,21 @@ class Formatter ]; foreach ($states as $state) { - $exprGroups['query']['children'][] = $this->formatting($state); + $childGroup = $this->formatting($state); + + if (!is_null($childGroup)) { + if ( + $childGroup['query']['logical_operator'] === $logicalOperator + && count($childGroup['query']['children']) === 1 + ) { + $exprGroups['query']['children'] = array_merge( + $exprGroups['query']['children'], + $childGroup['query']['children'] + ); + } else { + $exprGroups['query']['children'][] = $childGroup; + } + } } return $exprGroups; @@ -132,7 +146,7 @@ class Formatter * * @return array */ - private function formatting(array $state): array { + private function formatting(array $state): ?array { if ($state['is_complex'] === true) { return $this->complexFormatter->format($state); } else { diff --git a/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php b/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php index fffb813..a4b4596 100644 --- a/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php +++ b/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php @@ -46,8 +46,18 @@ class SimpleStateFormatter $this->recordData = $recordData; } - public function format(array $state): array + public function format(array $state): ?array { + if ( + !is_array($state['state_fields']) + || ( + is_array($state['state_fields']) + && count($state['state_fields']) === 0 + ) + ) { + return null; + } + $expressions = []; foreach ($state['state_fields'] as $stateField) { diff --git a/src/Infrastructure/Service/State/StateService.php b/src/Infrastructure/Service/State/StateService.php index 29ec2e1..08238e3 100644 --- a/src/Infrastructure/Service/State/StateService.php +++ b/src/Infrastructure/Service/State/StateService.php @@ -49,7 +49,7 @@ class StateService implements StateServiceInterface /** * Конвертирует состояния РІ ApiQL * - * @param int[]|int $states + * @param int[] $states * @param array $recordData * @param string $logicalOperator * @param bool $addWhere @@ -57,7 +57,7 @@ class StateService implements StateServiceInterface * @return array */ public function convertToApiQl( - $states, + array $states, array $recordData = [], string $logicalOperator = 'and', bool $addWhere = true -- GitLab From cad59a204b63464b07ae13bc696478f53f604750 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Fri, 18 Nov 2022 11:26:58 +0300 Subject: [PATCH 02/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B7=D0=B0=D0=B3=D1=80=D1=83?= =?UTF-8?q?=D0=B7=D0=BA=D0=B0=20=D1=80=D0=B5=D1=81=D1=83=D1=80=D1=81=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B2=20=D0=B1=D1=83=D1=82=D1=81=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D0=BF=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Query/Service/QueryBusHandlerLocator.php | 5 ++ .../Delivery/AbstractBootstrap.php | 80 +++++++++++++++++-- .../Domain/Repository/QueryableTrait.php | 9 ++- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/src/Application/Query/Service/QueryBusHandlerLocator.php b/src/Application/Query/Service/QueryBusHandlerLocator.php index edb96cd..0ceff68 100644 --- a/src/Application/Query/Service/QueryBusHandlerLocator.php +++ b/src/Application/Query/Service/QueryBusHandlerLocator.php @@ -44,6 +44,11 @@ class QueryBusHandlerLocator } } + public function setLazyLoader(QueryHandlerLoaderInterface $loader): void + { + $this->loader = $loader; + } + /** * @param QueryInterface $query * diff --git a/src/Infrastructure/Delivery/AbstractBootstrap.php b/src/Infrastructure/Delivery/AbstractBootstrap.php index cc966ec..4e947f0 100644 --- a/src/Infrastructure/Delivery/AbstractBootstrap.php +++ b/src/Infrastructure/Delivery/AbstractBootstrap.php @@ -3,7 +3,7 @@ namespace ServiceCore\Infrastructure\Delivery; use Doctrine\DBAL\Connection; -use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Types\Type; use Doctrine\ORM\EntityManager; use Doctrine\ORM\ORMException; @@ -153,18 +153,84 @@ abstract class AbstractBootstrap $this->di->set('event_provider', new DomainEventProvider($this->di->get('user_information'))); $this->di->set('event_bus', new DomainEventBus()); - $this->di->set("command_bus", new CommandBus( - new CommandBusHandlerLocator([], $this->getCommandContext()), + $this->loadCommandBus(); + $this->loadQueryBus(); + + $this->afterLoadDi(); + } + + /** + * Загрузка шины команд + */ + protected function loadCommandBus() + { + $commandContext = $this->getCommandContext(); + $commandLocator = new CommandBusHandlerLocator( + $this->getCommandBusRoutes(), + $commandContext + ); + + $this->di->set('command_bus', new CommandBus( + $commandLocator, new DoctrineORMTransactionService($this->entityManager), $this->di->get('event_provider'), $this->di->get('event_bus') )); + $this->di->set('command_context', $commandContext); + $this->di->set('query_loader', $commandLocator); + } - $this->di->set('query_bus', new QueryBus( - new QueryBusHandlerLocator([], $this->getQueryContext()) - )); + /** + * Routes for calling command handlers using CommandBus + * + * ```php + * return [ + * EntityCreateCommand::class => new EntityCreateHandler( + * $this->di->get('entity_command_repository') + * ) + * ] + * ``` + * + * @return array + */ + protected function getCommandBusRoutes(): array + { + return []; + } - $this->afterLoadDi(); + /** + * Загрузка шины запросов + */ + protected function loadQueryBus() + { + $queryContext = $this->getQueryContext(); + + $queryLocator = new QueryBusHandlerLocator( + $this->getQueryBusRoutes(), + $queryContext + ); + + $this->di->set('query_bus', new QueryBus($queryLocator)); + $this->di->set('query_context', $queryContext); + $this->di->set('query_locator', $queryLocator); + } + + /** + * Routes for calling query handlers using QueryBus + * + * ```php + * return [ + * EntityQuery::class => new EntityQueryHandler( + * $this->di->get('entity_query_repository') + * ) + * ] + * ``` + * + * @return array + */ + protected function getQueryBusRoutes(): array + { + return []; } /** diff --git a/src/Infrastructure/Domain/Repository/QueryableTrait.php b/src/Infrastructure/Domain/Repository/QueryableTrait.php index ffa2ff3..c6e9fb4 100644 --- a/src/Infrastructure/Domain/Repository/QueryableTrait.php +++ b/src/Infrastructure/Domain/Repository/QueryableTrait.php @@ -11,7 +11,10 @@ use Doctrine\DBAL\Query\QueryBuilder; * * @property QueryBuilder $queryBuilder * @property Connection $connection - * + * @property string[] $jsonFields + * @property bool $payload + * @property bool $ordered + * @property string $orderedBy * @property string $tableName * * @package ServiceCore\Infrastructure\Domain\Repository @@ -134,7 +137,9 @@ trait QueryableTrait if (isset($result[0])) { foreach ($result as $index => $value) { foreach ($this->jsonFields as $field) { - $result[$index][$field] = json_decode($value[$field], true); + if (isset($result[$index][$field])) { + $result[$index][$field] = json_decode($value[$field], true); + } } } } else { -- GitLab From f45dc49cfe7079bf0b08a0dd3f4f79f951f56108 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Fri, 18 Nov 2022 11:40:39 +0300 Subject: [PATCH 03/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=B8=D0=BC=D1=8F=20=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD=D0=B4=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BB=D0=BE?= =?UTF-8?q?=D0=BA=D0=B0=D1=82=D0=BE=D1=80=D0=B0=20=D0=B2=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B5=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Infrastructure/Delivery/AbstractBootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Infrastructure/Delivery/AbstractBootstrap.php b/src/Infrastructure/Delivery/AbstractBootstrap.php index 4e947f0..c0eb980 100644 --- a/src/Infrastructure/Delivery/AbstractBootstrap.php +++ b/src/Infrastructure/Delivery/AbstractBootstrap.php @@ -177,7 +177,7 @@ abstract class AbstractBootstrap $this->di->get('event_bus') )); $this->di->set('command_context', $commandContext); - $this->di->set('query_loader', $commandLocator); + $this->di->set('command_locator', $commandLocator); } /** -- GitLab From 47c575065cafd72578799cb77ca2fb4ef57b1934 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Thu, 29 Dec 2022 12:07:37 +0300 Subject: [PATCH 04/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D0=B8=D1=81=D1=82=D0=BE=D1=87=D0=BD=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Domain/Repository/QueryableTrait.php | 2 +- .../Exception/ParameterNotSet.php | 15 ++ .../ReportEditor/ReportQueryRepository.php | 205 +++++++++++++++++- 3 files changed, 211 insertions(+), 11 deletions(-) create mode 100644 src/Infrastructure/Domain/Repository/ReportEditor/Exception/ParameterNotSet.php diff --git a/src/Infrastructure/Domain/Repository/QueryableTrait.php b/src/Infrastructure/Domain/Repository/QueryableTrait.php index c6e9fb4..af8ddd2 100644 --- a/src/Infrastructure/Domain/Repository/QueryableTrait.php +++ b/src/Infrastructure/Domain/Repository/QueryableTrait.php @@ -144,7 +144,7 @@ trait QueryableTrait } } else { foreach ($this->jsonFields as $field) { - if (isset($result[$field])) { + if (isset($result[$field]) && is_string($result[$field])) { $result[$field] = json_decode($result[$field], true); } } diff --git a/src/Infrastructure/Domain/Repository/ReportEditor/Exception/ParameterNotSet.php b/src/Infrastructure/Domain/Repository/ReportEditor/Exception/ParameterNotSet.php new file mode 100644 index 0000000..33fc3fe --- /dev/null +++ b/src/Infrastructure/Domain/Repository/ReportEditor/Exception/ParameterNotSet.php @@ -0,0 +1,15 @@ +<?php + +namespace ServiceCore\Infrastructure\Domain\Repository\ReportEditor\Exception; + +use ServiceCore\Domain\Exception\AbstractDomainException; + +/** + * Class UnexpectedFileType + * + * @package ReportEditor\Domain\Exception + */ +class ParameterNotSet extends AbstractDomainException +{ + protected $code = 'parameter_not_set'; +} diff --git a/src/Infrastructure/Domain/Repository/ReportEditor/ReportQueryRepository.php b/src/Infrastructure/Domain/Repository/ReportEditor/ReportQueryRepository.php index 7415079..1c35281 100644 --- a/src/Infrastructure/Domain/Repository/ReportEditor/ReportQueryRepository.php +++ b/src/Infrastructure/Domain/Repository/ReportEditor/ReportQueryRepository.php @@ -6,6 +6,7 @@ use ApiQL\ApiQL; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; use ServiceCore\Domain\Repository\ReportEditor\ReportQueryRepositoryInterface; +use ServiceCore\Infrastructure\Domain\Repository\ReportEditor\Exception\ParameterNotSet; use ServiceCore\Infrastructure\Domain\Repository\ReportEditor\Exception\ReportSourceAliasNotDefined; use ServiceCore\Infrastructure\Domain\Repository\ReportEditor\Exception\ReportSourcePropertiesIsInvalid; use ServiceCore\Infrastructure\Domain\Repository\ReportEditor\Exception\ReportSourceRelationNotDefined; @@ -126,7 +127,7 @@ class ReportQueryRepository implements ReportQueryRepositoryInterface if ($this->validateProperties($reportSource['properties'])) { if ($reportSource['report_source_type_id'] === 'extended_object') { $extendedObject = $this->getExtendedObject($reportSource['properties']['id']); - $sourceQuery = $this->buildExtendedObjectQuery($extendedObject); + $sourceQuery = $this->buildExtendedObjectQuery($extendedObject, $payload ?? []); } else { $sourceQuery = sprintf("SELECT * FROM %s", $this->getSourceTable( $reportSource['report_source_type_id'], @@ -168,10 +169,11 @@ class ReportQueryRepository implements ReportQueryRepositoryInterface /** * @param array $extendedObject + * @param array $payload * * @return string */ - private function buildExtendedObjectQuery(array $extendedObject): string + private function buildExtendedObjectQuery(array $extendedObject, array $payload): string { $sqlStatements = $extendedObject['sql_statements']; @@ -192,8 +194,20 @@ class ReportQueryRepository implements ReportQueryRepositoryInterface )); } - if (!empty($extendedObject['filter'])) { - $apiQL = new ApiQL($extendedObject['filter'], $query); + $filter = $extendedObject['filter']; + + // Форматируем фильтры + if (!empty($filter) && isset($filter['logical_operator']) && isset($filter['children'])) { + if (is_array($filter['children']) && count($filter['children']) > 0) { + $filter = $this->toApiQl($filter, $payload); + } else { + $filter = null; + } + } + + // Крепим после форматирования + if (!empty($filter)) { + $apiQL = new ApiQL($filter, $query); $apiQL->execute(); } @@ -210,6 +224,166 @@ class ReportQueryRepository implements ReportQueryRepositoryInterface return $sourceQuery; } + /** + * @param array $filter + * @param array $parameters + * + * @return array|array[] + * + * @throws \Doctrine\DBAL\Driver\Exception + * @throws \Doctrine\DBAL\Exception + */ + private function toApiQl(array $filter, array $parameters = []) + { + $logicalOperator = $filter['logical_operator']; + + $result = [ + $logicalOperator => [] + ]; + + foreach ($filter['children'] as $child) { + $query = $child['query']; + if ($child['type'] === 'condition_group') { + $result[$logicalOperator][] = $this->toApiQl($query, $parameters); + } else { + if (in_array($query['operator'], ['is_null', 'is_not_null'])) { + $result[$logicalOperator][] = [ + $query['operator'] => $query['field'] + ]; + } else { + $value = $this->getValueByFilterType($query, $parameters); + + if ($value) { + $result[$logicalOperator][] = [ + $query['operator'] => [ + $query['field'] => $value + ] + ]; + } + } + } + } + + return $result; + } + + /** + * @param array $filter + * @param array $parameters + * + * @return mixed|null + * + * @throws \Doctrine\DBAL\Driver\Exception + * @throws \Doctrine\DBAL\Exception + */ + private function getValueByFilterType(array $filter, array $parameters) { + // Докрутить таблицу сотрудников, текущего пользователя Рё параметр + switch ($filter['filter_type']) { + case 'users_table': + if ($filter['value']) { + return $this->getUserFieldValue($filter['value'], $this->userInfo->id); + } + + return null; + case 'current_user': + return $this->userInfo->id; + case 'current_datetime': + return date('Y-m-d H:i:s'); + case 'parameter': + $key = $filter['value']; + + if (isset($parameters[$key])) { + return $parameters[$key]; + } + + return null; + default: + return $filter['value']; + } + } + + /** + * @return false|int + * + * @throws \Doctrine\DBAL\Driver\Exception + * @throws \Doctrine\DBAL\Exception + */ + private function getUsersTableId() + { + return $this->connection + ->createQueryBuilder() + ->select('id') + ->from("object_editor.entities") + ->where("\"getPropertyById\"(properties, 'is_users_table') = 'true'") + ->execute() + ->fetchOne(); + } + + /** + * @param int $fieldId + * + * @return string + * + * @throws \Doctrine\DBAL\Driver\Exception + * @throws \Doctrine\DBAL\Exception + */ + private function getFieldType(int $fieldId): string + { + return $this->connection + ->createQueryBuilder() + ->select("entity_type_id") + ->from("object_editor.entities") + ->where("id = :fieldId") + ->setParameter("fieldId", $fieldId) + ->execute() + ->fetchOne(); + } + + /** + * @param int $fieldId + * @param int $userId + * + * @return mixed|null + * + * @throws \Doctrine\DBAL\Driver\Exception + * @throws \Doctrine\DBAL\Exception + */ + private function getUserFieldValue(int $fieldId, int $userId) + { + $tableId = $this->getUsersTableId(); + if (!$tableId) { + return null; + } + + $value = $this->connection + ->createQueryBuilder() + ->select(sprintf("attr_%s_", $fieldId)) + ->from(sprintf("registry.object_%s_main", $tableId)) + ->where("id = :userId") + ->setParameter("userId", $userId) + ->execute() + ->fetchOne(); + + if (!$value) { + return null; + } + + $fieldType = $this->getFieldType($fieldId); + if ($fieldType) { + if (in_array($fieldType, ['xref_field', 'xref_multi_field'])) { + return array_column( + json_decode( + $value, + true + ), + 'id' + ); + } + } + + return $value; + } + /** * @param array $sources * @param int|null $parentId @@ -384,9 +558,11 @@ class ReportQueryRepository implements ReportQueryRepositoryInterface /** * @param array $filters - * @param array $payload + * @param array|null $payload * * @return array + * + * @throws ParameterNotSet */ private function buildExpression(array $filters, ?array $payload): array { @@ -398,14 +574,23 @@ class ReportQueryRepository implements ReportQueryRepositoryInterface $fieldValue = $filter['properties']['value']; if ($filterType === 'parameter' && !empty($payload)) { - isset($payload[$fieldName]) ? $fieldValue = $payload[$fieldName] : $fieldValue = null; + $parameterName = empty($filter['properties']['value']) + ? 'id' + : $filter['properties']['value'] + ; + + if (!isset($payload[$parameterName])) { + throw new ParameterNotSet('Undefined values for one or more parameters', [ + 'payload' => $payload, + 'filter' => $filter + ]); + } + + $fieldValue = $payload[$parameterName]; } elseif ($filterType === 'constant') { - $fieldValue = $filter['properties']['value']; + $fieldValue = $filter['properties']['value'] ?? null; } elseif ($filterType === 'current_user') { $fieldValue = $this->userInfo->id; - } elseif ($filterType === 'current_date') { - } elseif ($filterType === 'current_datetime') { - } elseif ($filterType === 'users_table') { } elseif ($filterType === 'condition') { $expression['and'][] = [ $fieldValue => sprintf('"s.%s"', $fieldValue) -- GitLab From 200a6e84268a25a7293bc902dd80cd05afbc3916 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Mon, 13 Mar 2023 15:03:08 +0300 Subject: [PATCH 05/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=B1=D0=B0=D0=B3=20=D1=81=20=D0=BB?= =?UTF-8?q?=D0=B8=D1=88=D0=BD=D0=B5=D0=B9=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=BE=D0=B9=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF?= =?UTF-8?q?=D0=BE=D0=B9=20=D0=B2=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=B5=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=82=D0=B0=D1=86=D0=B8=D0=B8=20=D1=81=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=8F=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../State/Formatter/SimpleStateFormatter.php | 40 ++- .../Service/State/StateService.php | 10 +- tests/Unit/Repository/StateRepository.php | 255 ++++++++++-------- tests/Unit/StateUnitTest.php | 16 +- 4 files changed, 183 insertions(+), 138 deletions(-) diff --git a/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php b/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php index a4b4596..c76da48 100644 --- a/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php +++ b/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php @@ -82,7 +82,7 @@ class SimpleStateFormatter if (!empty($stateField['current_table_field_id'])) { $field = sprintf('attr_%d_', $stateField['current_table_field_id']); - $value = isset($this->recordData[$field]) ? $this->recordData[$field] : null; + $value = $this->recordData[$field] ?? null; } } elseif ($stateField['state_field_type_id'] === 'constant') { $value = $stateField['properties']['value']; @@ -105,31 +105,27 @@ class SimpleStateFormatter $operator = 'equals_any'; } - if (!empty($this->recordData)) { - if (!$value) { - $value = isset($this->recordData[$attribute]) ? $this->recordData[$attribute] : null; - } - - if (is_string($value)) { - $value = json_decode($value, true); - } + if (is_string($value)) { + $value = json_decode($value, true); + } - if (is_null($value)) { - $value = []; - } + if (is_null($value)) { + $value = []; } } - $expressions[] = [ - 'type' => 'condition', - 'query' => [ - 'field' => $attribute, - 'value' => $value, - 'filter_type' => 'constant', - 'operator' => $operator, - 'field_type' => $fieldType - ] - ]; + if (!is_null($value)) { + $expressions[] = [ + 'type' => 'condition', + 'query' => [ + 'field' => $attribute, + 'value' => $value, + 'filter_type' => 'constant', + 'operator' => $operator, + 'field_type' => $fieldType + ] + ]; + } } return [ diff --git a/src/Infrastructure/Service/State/StateService.php b/src/Infrastructure/Service/State/StateService.php index 08238e3..ebf55dd 100644 --- a/src/Infrastructure/Service/State/StateService.php +++ b/src/Infrastructure/Service/State/StateService.php @@ -49,7 +49,7 @@ class StateService implements StateServiceInterface /** * Конвертирует состояния РІ ApiQL * - * @param int[] $states + * @param int[]|int $states * @param array $recordData * @param string $logicalOperator * @param bool $addWhere @@ -57,7 +57,7 @@ class StateService implements StateServiceInterface * @return array */ public function convertToApiQl( - array $states, + $states, array $recordData = [], string $logicalOperator = 'and', bool $addWhere = true @@ -86,7 +86,11 @@ class StateService implements StateServiceInterface ); if (is_array($states)) { - return $formatter->format($states)->many($logicalOperator); + if (count($states) > 1) { + return $formatter->format($states)->many($logicalOperator); + } else { + return $formatter->format($states)->one(); + } } elseif (is_numeric($states)) { return $formatter->format($states)->one(); } else { diff --git a/tests/Unit/Repository/StateRepository.php b/tests/Unit/Repository/StateRepository.php index 281ced7..da45815 100644 --- a/tests/Unit/Repository/StateRepository.php +++ b/tests/Unit/Repository/StateRepository.php @@ -6,100 +6,160 @@ use ServiceCore\Domain\Repository\StateQueryRepositoryInterface; class StateRepository implements StateQueryRepositoryInterface { - public function getState(int $id): ?array - { - $states = [ - [ - 'id' => 1, - 'name' => 'Simple State', - 'is_complex' => false, - 'properties' => null, - 'state_fields' => [ - [ - 'id' => 1, - 'state_id' => 1, - 'field_id' => 1000, - 'state_field_type_id' => 'constant', - 'properties' => [ - 'value' => 'str1' - ] - ], - [ - 'id' => 2, - 'state_id' => 1, - 'field_id' => 1001, - 'state_field_type_id' => 'constant', - 'properties' => [ - 'value' => '314zdec' - ] - ], - [ - 'id' => 3, - 'state_id' => 1, - 'field_id' => 1002, - 'state_field_type_id' => 'condition', - 'condition_field_type_id' => 'not_empty' - ], - [ - 'id' => 4, - 'state_id' => 1, - 'field_id' => 1003, - 'state_field_type_id' => 'current_table_field', - 'current_table_field_id' => 2000 + static $states = [ + [ + 'id' => 1, + 'name' => 'Simple State', + 'is_complex' => false, + 'properties' => null, + 'state_fields' => [ + [ + 'id' => 1, + 'state_id' => 1, + 'field_id' => 1000, + 'state_field_type_id' => 'constant', + 'properties' => [ + 'value' => 'str1' ] + ], + [ + 'id' => 2, + 'state_id' => 1, + 'field_id' => 1001, + 'state_field_type_id' => 'constant', + 'properties' => [ + 'value' => '314zdec' + ] + ], + [ + 'id' => 3, + 'state_id' => 1, + 'field_id' => 1002, + 'state_field_type_id' => 'condition', + 'condition_field_type_id' => 'not_empty' + ], + [ + 'id' => 4, + 'state_id' => 1, + 'field_id' => 1003, + 'state_field_type_id' => 'current_table_field', + 'current_table_field_id' => 2000 ] - ], - [ - 'id' => 2, - 'name' => 'Complex State', - 'is_complex' => true, - 'properties' => [ - 'filters' => [ - 'logical_operator' => 'and', - 'children' => [ - [ - 'type' => 'condition', - 'query' => [ - 'field' => 'attr_1010_', - 'filter_type' => 'constant', - 'operator' => 'eq', - 'value' => '2021-07-15' - ] - ], - [ - 'type' => 'condition_group', - 'query' => [ - 'logical_operator' => 'or', - 'children' => [ - [ - 'type' => 'condition', - 'query' => [ - 'field' => 'attr_1011_', - 'filter_type' => 'constant', - 'operator' => 'gte', - 'value' => '2022-01-01' - ] - ], - [ - 'type' => 'condition', - 'query' => [ - 'field' => 'attr_1011_', - 'filter_type' => 'constant', - 'operator' => 'lte', - 'value' => '2021-06-01' - ] + ] + ], + [ + 'id' => 2, + 'name' => 'Complex State', + 'is_complex' => true, + 'properties' => [ + 'filters' => [ + 'logical_operator' => 'and', + 'children' => [ + [ + 'type' => 'condition', + 'query' => [ + 'field' => 'attr_1010_', + 'filter_type' => 'constant', + 'operator' => 'eq', + 'value' => '2021-07-15' + ] + ], + [ + 'type' => 'condition_group', + 'query' => [ + 'logical_operator' => 'or', + 'children' => [ + [ + 'type' => 'condition', + 'query' => [ + 'field' => 'attr_1011_', + 'filter_type' => 'constant', + 'operator' => 'gte', + 'value' => '2022-01-01' + ] + ], + [ + 'type' => 'condition', + 'query' => [ + 'field' => 'attr_1011_', + 'filter_type' => 'constant', + 'operator' => 'lte', + 'value' => '2021-06-01' ] ] ] ] ] ] + ] + ], + 'state_fields' => [] + ], + [ + 'id' => 3, + 'name' => 'Simple State 2', + 'is_complex' => false, + 'properties' => null, + 'state_fields' => [ + [ + 'id' => 1, + 'state_id' => 1, + 'field_id' => 2000, + 'state_field_type_id' => 'constant', + 'properties' => [ + 'value' => 4 + ] ], - 'state_fields' => [] + [ + 'id' => 2, + 'state_id' => 1, + 'field_id' => 2001, + 'state_field_type_id' => 'constant', + 'properties' => [ + 'value' => 0 + ] + ] ] - ]; + ] + ]; + static $fields = [ + [ + 'id' => 1000, + 'type' => 'string_field' + ], + [ + 'id' => 1001, + 'type' => 'string_field' + ], + [ + 'id' => 1002, + 'type' => 'string_field' + ], + [ + 'id' => 1003, + 'type' => 'string_field' + ], + [ + 'id' => 1010, + 'type' => 'date_field' + ], + [ + 'id' => 1011, + 'type' => 'date_field' + ], + [ + 'id' => 2000, + 'type' => 'xref_field' + ], + [ + 'id' => 2001, + 'type' => 'xref_field' + ] + ]; - foreach ($states as $state) { + public function getState(int $id): ?array + { + foreach (self::$states as $state) { if ($state['id'] === $id) { return $state; } @@ -109,34 +169,7 @@ class StateRepository implements StateQueryRepositoryInterface } public function getFieldType(int $fieldId): string { - $fields = [ - [ - 'id' => 1000, - 'type' => 'string_field' - ], - [ - 'id' => 1001, - 'type' => 'string_field' - ], - [ - 'id' => 1002, - 'type' => 'string_field' - ], - [ - 'id' => 1003, - 'type' => 'string_field' - ], - [ - 'id' => 1010, - 'type' => 'date_field' - ], - [ - 'id' => 1011, - 'type' => 'date_field' - ] - ]; - - foreach ($fields as $field) { + foreach (self::$fields as $field) { if ($field['id'] === $fieldId) { return $field['type']; } diff --git a/tests/Unit/StateUnitTest.php b/tests/Unit/StateUnitTest.php index 91f018e..994ee57 100644 --- a/tests/Unit/StateUnitTest.php +++ b/tests/Unit/StateUnitTest.php @@ -39,6 +39,18 @@ class StateUnitTest extends TestCase $this->repository = new StateRepository(); } + /** + * Баг СЃ логической РіСЂСѓРїРїРёСЂРѕРІРєРѕР№ состояний для множественной конвертации + */ + public function testStateBag1() + { + $service = new StateService($this->repository, $this->userInfo); + + $result = $service->convertToApiQl(3, $this->recordData); + $testResult = '{"where":[{"and":[{"equals_any":{"attr_2000_id":4}},{"equals_any":{"attr_2001_id":0}}]}]}'; + self::assertEquals(json_encode($result), $testResult); + } + public function testStateFormatting(): void { $service = new StateService($this->repository, $this->userInfo); @@ -91,14 +103,14 @@ class StateUnitTest extends TestCase { $service = new StateService($this->repository, $this->userInfo); - $result = $service->convertToApiQl(1, $this->recordData); + $result = $service->convertToApiQl([1], $this->recordData); $testResult = '{"where":[{"and":[{"eq":{"attr_1000_":"str1"}},{"eq":{"attr_1001_":"314zdec"}},{"is_null":"attr_1002_"},' . '{"eq":{"attr_1003_":"value of the current table field"}}]}]}' ; self::assertEquals(json_encode($result), $testResult); - $result = $service->convertToApiQl(2, $this->recordData); + $result = $service->convertToApiQl([2], $this->recordData); $testResult = '{"where":[{"and":[{"eq":{"attr_1010_":"2021-07-15"}},{"or":[{"gte":{"attr_1011_":"2022-01-01"}},{"lte":{' . '"attr_1011_":"2021-06-01"}}]}]}]}' -- GitLab From a6008d4ea7e7a44a661d9c0709c1613508d3bcb7 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Wed, 29 Mar 2023 16:13:07 +0300 Subject: [PATCH 06/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=82=D0=B0=D1=86=D0=B8=D1=8F=20=D1=81=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=8F=D0=BD=D0=B8=D0=B9=20=D0=B2=20=D1=84=D0=B8=D0=BB?= =?UTF-8?q?=D1=8C=D1=82=D1=80=D1=8B=20ApiQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Infrastructure/Service/State/StateService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Infrastructure/Service/State/StateService.php b/src/Infrastructure/Service/State/StateService.php index ebf55dd..6e5302f 100644 --- a/src/Infrastructure/Service/State/StateService.php +++ b/src/Infrastructure/Service/State/StateService.php @@ -89,7 +89,7 @@ class StateService implements StateServiceInterface if (count($states) > 1) { return $formatter->format($states)->many($logicalOperator); } else { - return $formatter->format($states)->one(); + return $formatter->format($states[0])->one(); } } elseif (is_numeric($states)) { return $formatter->format($states)->one(); -- GitLab From a4d135c8cdcacfec12b45709e25af1b403c9d297 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Wed, 29 Mar 2023 16:14:13 +0300 Subject: [PATCH 07/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=82=D0=B0=D1=86=D0=B8=D1=8F=20=D1=81=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=8F=D0=BD=D0=B8=D0=B9=20=D0=B2=20=D1=84=D0=B8=D0=BB?= =?UTF-8?q?=D1=8C=D1=82=D1=80=D1=8B=20ApiQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Infrastructure/Service/State/StateService.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Infrastructure/Service/State/StateService.php b/src/Infrastructure/Service/State/StateService.php index 6e5302f..75dfbbc 100644 --- a/src/Infrastructure/Service/State/StateService.php +++ b/src/Infrastructure/Service/State/StateService.php @@ -88,8 +88,10 @@ class StateService implements StateServiceInterface if (is_array($states)) { if (count($states) > 1) { return $formatter->format($states)->many($logicalOperator); - } else { + } else if (count($states) == 1) { return $formatter->format($states[0])->one(); + } else { + return []; } } elseif (is_numeric($states)) { return $formatter->format($states)->one(); -- GitLab From c35c9ff24eb62c35283d001f8f144caeeedbe138 Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Fri, 14 Apr 2023 12:39:01 +0300 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=81?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=BD=D1=8B=D1=85=20=D1=81=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=8F=D0=BD=D0=B8=D0=B9=20=D0=BF=D0=BE=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=D1=83=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82=D1=80=D0=B0.=20?= =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0=20=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B8=D1=85=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=D0=BE=D0=B2=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82=D1=80=D0=BE=D0=B2?= =?UTF-8?q?:=20"=D0=9F=D0=BE=D0=BB=D0=B5=20=D1=82=D0=B5=D0=BA=D1=83=D1=89?= =?UTF-8?q?=D0=B5=D0=B9=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D1=8B",=20"?= =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D0=B5=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86?= =?UTF-8?q?=D1=8B=20=D1=81=D0=BE=D1=81=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8?= =?UTF-8?q?=D0=BA=D0=BE=D0=B2",=20"=D0=A2=D0=B5=D0=BA=D1=83=D1=89=D0=B8?= =?UTF-8?q?=D0=B9=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C"=20=D0=B8=20"=D0=A2=D0=B5=D0=BA=D1=83=D1=89?= =?UTF-8?q?=D0=B0=D1=8F=20=D0=B4=D0=B0=D1=82=D0=B0=20=D0=B8=20=D0=B2=D1=80?= =?UTF-8?q?=D0=B5=D0=BC=D1=8F"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../State/Formatter/ComplexStateFormatter.php | 29 +++++++- tests/Unit/Repository/StateRepository.php | 68 +++++++++++++++++-- tests/Unit/StateUnitTest.php | 15 +++- 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php b/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php index a518c3f..b400cef 100644 --- a/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php +++ b/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php @@ -80,8 +80,9 @@ class ComplexStateFormatter } else { $fieldId = (int)filter_var($item['query']['field'], FILTER_SANITIZE_NUMBER_INT); $fieldType = $this->stateRepository->getFieldType($fieldId); + $filterType = $item['query']['filter_type'] ?? 'constant'; - if ($fieldType === 'xref_field' || $fieldType === 'xref_multi_field') { + if (in_array($fieldType, ['xref_field', 'xref_multi_field'])) { $item['query']['field'] = sprintf('%sid', $item['query']['field']); if ($item['query']['operator'] === 'eq') { @@ -91,6 +92,32 @@ class ComplexStateFormatter } } + if ($filterType === 'users_table') { + $item['query']['value'] = $this->stateRepository->getUserFieldValue( + $item['query']['value'], + $this->userInfo->id + ); + } elseif ($fieldType === 'current_table_field') { + $attribute = sprintf('attr_%s_', $item['query']['value']); + $attributeType = $this->stateRepository->getFieldType($item['query']['value']); + $attributeValue = null; + if (in_array($attributeType, ['xref_field', 'xref_multi_field'])) { + $attribute .= 'id'; + $attributeValue = $this->recordData[$attribute] ?? null; + if (is_string($attributeValue)) { + $attributeValue = json_decode($attributeValue, true); + } + } else { + $attributeValue = $this->recordData[$attribute] ?? null; + } + + $item['query']['value'] = $attributeValue; + } elseif ($filterType === 'current_user') { + $item['query']['value'] = $this->userInfo->id; + } elseif ($filterType === 'current_datetime') { + $item['query']['value'] = date("Y-m-d H:i:s"); + } + $item['query']['field_type'] = $fieldType; $expressions[] = $item; diff --git a/tests/Unit/Repository/StateRepository.php b/tests/Unit/Repository/StateRepository.php index da45815..58e0219 100644 --- a/tests/Unit/Repository/StateRepository.php +++ b/tests/Unit/Repository/StateRepository.php @@ -120,8 +120,31 @@ class StateRepository implements StateQueryRepositoryInterface ] ] ] + ], + [ + 'id' => 4, + 'name' => 'Complex State', + 'is_complex' => true, + 'properties' => [ + 'filters' => [ + 'logical_operator' => 'and', + 'children' => [ + [ + 'type' => 'condition', + 'query' => [ + 'field' => 'attr_2001_', + 'filter_type' => 'users_table', + 'operator' => 'eq', + 'value' => 3001 + ] + ] + ] + ] + ], + 'state_fields' => [] ] ]; + static $fields = [ [ 'id' => 1000, @@ -154,6 +177,10 @@ class StateRepository implements StateQueryRepositoryInterface [ 'id' => 2001, 'type' => 'xref_field' + ], + [ + 'id' => 3001, + 'type' => 'xref_field' ] ]; @@ -168,17 +195,50 @@ class StateRepository implements StateQueryRepositoryInterface return null; } - public function getFieldType(int $fieldId): string { + public function getFieldType(int $fieldId): string + { foreach (self::$fields as $field) { if ($field['id'] === $fieldId) { return $field['type']; } } - return 'huy_field'; + return 'undef_field'; } - public function getUserFieldValue(int $fieldId, int $userId): int { - return 666; + public function getUserFieldValue(int $fieldId, int $userId) + { + $users = [ + [ + 'id' => 1, + 'username' => 'test1', + 'attr_3001_' => '[{"id": 1, "name": "Name1"}]', + 'attr_3001_id' => 1 + ] + ]; + + $targetAttribute = sprintf('attr_%s_', $fieldId); + + $value = null; + + foreach ($users as $user) { + if ($user['id'] === $userId) { + $value = $user[$targetAttribute] ?? null; + break; + } + } + + $fieldType = $this->getFieldType($fieldId); + if (in_array($fieldType, ['xref_field', 'xref_multi_field'])) { + return array_column( + json_decode( + $value, + true + ), + 'id' + ); + } + + return $value; } } diff --git a/tests/Unit/StateUnitTest.php b/tests/Unit/StateUnitTest.php index 994ee57..15ef58d 100644 --- a/tests/Unit/StateUnitTest.php +++ b/tests/Unit/StateUnitTest.php @@ -30,7 +30,8 @@ class StateUnitTest extends TestCase 'attr_2010_' => '2022-12-01', 'attr_2011_' => '2022-12-01', // Для сравнения РѕРґРЅРѕРіРѕ поля СЃ РґСЂСѓРіРёРј полем РІ текущей таблице - 'attr_2000_' => 'value of the current table field' + 'attr_2000_' => 'value of the current table field', + 'attr_2001_' => null ]; $this->userInfo = new \stdClass(); @@ -51,6 +52,18 @@ class StateUnitTest extends TestCase self::assertEquals(json_encode($result), $testResult); } + /** + * Баг СЃ получением значения РёР· поля таблицы сотрудников, если РѕРЅРѕ СЃ типом "Ссылка" + */ + public function testStateBag2() + { + $service = new StateService($this->repository, $this->userInfo); + + $result = $service->convertToApiQl(4, $this->recordData); + $testResult = '{"where":[{"and":[{"equals_any":{"attr_2001_id":[1]}}]}]}'; + self::assertEquals($testResult, json_encode($result)); + } + public function testStateFormatting(): void { $service = new StateService($this->repository, $this->userInfo); -- GitLab From f050e58f03ddaa3f577a8655b89ae32d3b2a740c Mon Sep 17 00:00:00 2001 From: "e.kremnev" <e.kremnev@bingosoft.ru> Date: Wed, 19 Apr 2023 14:25:52 +0300 Subject: [PATCH 09/10] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=D0=BC=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/State/Converter.php | 4 +- .../State/Formatter/ComplexStateFormatter.php | 133 ++++++++++---- .../State/Formatter/SimpleStateFormatter.php | 111 +++++++----- .../Service/State/StateService.php | 169 ++++++++++++++++++ tests/Unit/Repository/StateRepository.php | 2 +- tests/Unit/StateUnitTest.php | 112 +++++++----- 6 files changed, 407 insertions(+), 124 deletions(-) diff --git a/src/Infrastructure/Service/State/Converter.php b/src/Infrastructure/Service/State/Converter.php index 86edceb..41cd791 100644 --- a/src/Infrastructure/Service/State/Converter.php +++ b/src/Infrastructure/Service/State/Converter.php @@ -25,7 +25,7 @@ class Converter ] ); - return $addWhere ? ['where' => $result] : $result; + return $addWhere ? ['where' => $result[0]] : $result[0]; } /** @@ -50,7 +50,7 @@ class Converter } else { $result[] = [ $expr['query']['operator'] => [ - $expr['query']['field'] => $expr['query']['value'] + $expr['query']['field'] => $expr['query']['y_value'] ] ]; } diff --git a/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php b/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php index b400cef..66bf136 100644 --- a/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php +++ b/src/Infrastructure/Service/State/Formatter/ComplexStateFormatter.php @@ -64,6 +64,13 @@ class ComplexStateFormatter ])[0]; } + /** + * @param array $data + * + * @return array + * + * @throws \Exception + */ private function finalFormat(array $data): array { $expressions = []; @@ -78,52 +85,112 @@ class ComplexStateFormatter ] ]; } else { + $xField = $item['query']['field']; $fieldId = (int)filter_var($item['query']['field'], FILTER_SANITIZE_NUMBER_INT); - $fieldType = $this->stateRepository->getFieldType($fieldId); + $xFieldType = !isset($item['query']['field_type']) + ? $this->stateRepository->getFieldType($fieldId) + : $item['query']['field_type']; $filterType = $item['query']['filter_type'] ?? 'constant'; + $operator = $item['query']['operator'] ?? 'eq'; + $xValue = $this->getFieldValue($xField, $xFieldType); + $yValue = null; + + if ($filterType === 'condition') { + $operator = $item['query']['value'] === 'not_empty' + ? 'is_not_null' + : 'is_null'; + } else { + $yValue = $this->getYValue($filterType, $item['query']['value'] ?? null); + } - if (in_array($fieldType, ['xref_field', 'xref_multi_field'])) { - $item['query']['field'] = sprintf('%sid', $item['query']['field']); + if (in_array($xFieldType, ['xref_field', 'xref_multi_field'])) { + $xField = sprintf('%sid', $xField); - if ($item['query']['operator'] === 'eq') { - $item['query']['operator'] = 'equals_any'; - } elseif ($item['query']['operator'] === 'neq') { - $item['query']['operator'] = 'not_equals_any'; + if ($operator === 'eq') { + $operator = 'equals_any'; } } - if ($filterType === 'users_table') { - $item['query']['value'] = $this->stateRepository->getUserFieldValue( - $item['query']['value'], - $this->userInfo->id - ); - } elseif ($fieldType === 'current_table_field') { - $attribute = sprintf('attr_%s_', $item['query']['value']); - $attributeType = $this->stateRepository->getFieldType($item['query']['value']); - $attributeValue = null; - if (in_array($attributeType, ['xref_field', 'xref_multi_field'])) { - $attribute .= 'id'; - $attributeValue = $this->recordData[$attribute] ?? null; - if (is_string($attributeValue)) { - $attributeValue = json_decode($attributeValue, true); - } - } else { - $attributeValue = $this->recordData[$attribute] ?? null; - } + $expressions[] = [ + 'type' => 'condition', + 'query' => [ + 'field' => $xField, + 'field_type' => $xFieldType, + 'x_value' => $xValue, + 'y_value' => $yValue, + 'operator' => $operator + ] + ]; + } + } + + return $expressions; + } - $item['query']['value'] = $attributeValue; - } elseif ($filterType === 'current_user') { - $item['query']['value'] = $this->userInfo->id; - } elseif ($filterType === 'current_datetime') { - $item['query']['value'] = date("Y-m-d H:i:s"); + /** + * @param string $filterType + * @param $value + * + * @return mixed + * + * @throws \Exception + */ + private function getYValue(string $filterType, $value) + { + switch ($filterType) { + case 'current_user': + return $this->userInfo->id; + case 'users_table': + return $this->stateRepository->getUserFieldValue( + $value, + $this->userInfo->id + ); + case 'current_date': + return date("Y-m-d"); + case 'current_datetime': + return date("Y-m-d H:i:s"); + case 'current_table_field': + if (!empty($value)) { + $field = sprintf('attr_%s_', $value); + $fieldType = $this->stateRepository->getFieldType($value); + + return $this->getFieldValue($field, $fieldType); + } else { + throw new \Exception('Состояние СЃ типом "Поле текущей таблицы" РЅРµ настроено'); + } + case 'external_table_field': + throw new \Exception('Состояние СЃ типом "Поле внещней таблицы" РЅРµ обслуживается'); + default: + if (is_null($value) || $value === '') { + throw new \Exception('Состояние СЃ типом "Константа" соддержит пустое значение'); } - $item['query']['field_type'] = $fieldType; + return $value; + } + } + + private function getFieldValue(string $field, string $fieldType) { + if (in_array($fieldType, ['xref_field', 'xref_multi_field'])) { + $value = $this->recordData[$field . 'id'] ?? []; + + if (is_string($value)) { + $value = str_replace('{', '[', $value); + $value = str_replace('}', ']', $value); - $expressions[] = $item; + $value = json_decode($value, true); + } elseif (is_null($value)) { + $value = []; + } elseif (is_numeric($value)) { + $value = [$value]; } + + return $value; + } elseif ($fieldType === 'boolean_field') { + $value = $this->recordData[$field] ?? null; + + return $value === 'true' || $value === true; } - return $expressions; + return $this->recordData[$field] ?? null; } } diff --git a/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php b/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php index c76da48..31a3ba3 100644 --- a/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php +++ b/src/Infrastructure/Service/State/Formatter/SimpleStateFormatter.php @@ -61,71 +61,65 @@ class SimpleStateFormatter $expressions = []; foreach ($state['state_fields'] as $stateField) { - $attribute = sprintf('attr_%d_', $stateField['field_id']); - $fieldType = $this->stateRepository->getFieldType($stateField['field_id']); + $xField = sprintf('attr_%d_', $stateField['field_id']); + $xFieldType = $this->stateRepository->getFieldType($stateField['field_id']); + $filterType = $stateField['state_field_type_id']; $operator = 'eq'; - $value = null; - - if ($stateField['state_field_type_id'] === 'current_user') { - $value = $this->userInfo->id; - } elseif ($stateField['state_field_type_id'] === 'users_table') { - $value = $this->stateRepository->getUserFieldValue($stateField['users_field_id'], $this->userInfo->id); - } elseif ($stateField['state_field_type_id'] === 'current_date') { - $value = date('Y-m-d'); - } elseif ($stateField['state_field_type_id'] === 'condition') { - if ($stateField['state_field_type_id'] === 'not_empty') { + $xValue = $this->getFieldValue($xField, $xFieldType); + $yValue = null; + + // Вычисляем значение Y + if ($filterType === 'current_user') { + $yValue = $this->userInfo->id; + } elseif ($filterType === 'users_table') { + $yValue = $this->stateRepository->getUserFieldValue($stateField['users_field_id'], $this->userInfo->id); + } elseif ($filterType === 'current_date') { + $yValue = date('Y-m-d'); + } elseif ($filterType === 'current_datetime') { + $yValue = date('Y-m-d H:i:s'); + } elseif ($filterType === 'condition') { + if ($stateField['condition_field_type_id'] === 'not_empty') { $operator = 'is_not_null'; } else { $operator = 'is_null'; } - } elseif ($stateField['state_field_type_id'] === 'current_table_field') { + } elseif ($filterType === 'current_table_field') { if (!empty($stateField['current_table_field_id'])) { - $field = sprintf('attr_%d_', $stateField['current_table_field_id']); + $yField = sprintf('attr_%s_', $stateField['current_table_field_id']); + $yFieldType = $this->stateRepository->getFieldType($stateField['current_table_field_id']); - $value = $this->recordData[$field] ?? null; + $yValue = $this->getFieldValue($yField, $yFieldType); + } else { + throw new \Exception('Состояние СЃ типом "Поле текущей таблицы" РЅРµ настроено'); } + } elseif ($filterType === 'external_table_field') { + throw new \Exception('Состояние СЃ типом "Поле внещней таблицы" РЅРµ обслуживается'); } elseif ($stateField['state_field_type_id'] === 'constant') { - $value = $stateField['properties']['value']; - } else { - continue; - } + $yValue = $stateField['properties']['value'] ?? null; - if ($fieldType === 'boolean_field') { - if ($value === 'true' || $value === true) { - $value = true; - } else { - $value = false; + if (is_null($yValue)) { + throw new \Exception('Состояние СЃ типом "Константа" соддержит пустое значение'); } } - if ($fieldType === 'xref_field' || $fieldType === 'xref_multi_field') { - $attribute = sprintf('%sid', $attribute); + if (in_array($xFieldType, ['xref_field', 'xref_multi_field'])) { + $xField = sprintf('%sid', $xField); if ($operator === 'eq') { $operator = 'equals_any'; } - - if (is_string($value)) { - $value = json_decode($value, true); - } - - if (is_null($value)) { - $value = []; - } } - if (!is_null($value)) { - $expressions[] = [ - 'type' => 'condition', - 'query' => [ - 'field' => $attribute, - 'value' => $value, - 'filter_type' => 'constant', - 'operator' => $operator, - 'field_type' => $fieldType - ] - ]; - } + $expressions[] = [ + 'type' => 'condition', + 'query' => [ + 'field' => $xField, + 'field_type' => $xFieldType, + 'x_value' => $xValue, + 'y_value' => $yValue, + 'operator' => $operator + ] + ]; } return [ @@ -136,4 +130,29 @@ class SimpleStateFormatter ] ]; } + + private function getFieldValue(string $field, string $fieldType) { + if ($fieldType === 'xref_field' || $fieldType === 'xref_multi_field') { + $value = $this->recordData[$field . 'id'] ?? []; + + if (is_string($value)) { + $value = str_replace('{', '[', $value); + $value = str_replace('}', ']', $value); + + $value = json_decode($value, true); + } elseif (is_null($value)) { + $value = []; + } elseif (is_numeric($value)) { + $value = [$value]; + } + + return $value; + } elseif ($fieldType === 'boolean_field') { + $value = $this->recordData[$field] ?? null; + + return $value === 'true' || $value === true; + } + + return $this->recordData[$field] ?? null; + } } diff --git a/src/Infrastructure/Service/State/StateService.php b/src/Infrastructure/Service/State/StateService.php index 75dfbbc..e3b6ee1 100644 --- a/src/Infrastructure/Service/State/StateService.php +++ b/src/Infrastructure/Service/State/StateService.php @@ -68,6 +68,175 @@ class StateService implements StateServiceInterface ); } + /** + * @param array $states - РЎРїРёСЃРѕРє идентификаторов состояний + * @param array $recordData - Актуальные данные записи реестра, если необходимо использование типа "Поле текущей таблицы" + * @param string $matchType - Логическуая СЃРІСЏР·РєР° "all", "any", или "and", "or" + * @param bool $isDeny - Отрицание условия `if (!$myVar)` + * + * @return bool + * + * @throw \Exception + */ + public function checkConditions( + array $states, + array $recordData = [], + string $matchType = 'all', + bool $isDeny = false + ) { + $matches = []; + + if (!empty($states)) { + foreach ($states as $stateId) { + $matches[] = $this->isEqualsState( + $stateId, + $recordData + ); + } + + if (in_array($matchType, ['all', 'and'])) { + /* + * Если логическая СЃРІСЏР·РєР° "Р’СЃРµ", то есть "Р" + * Если (Состояние1 РСостояние2 Р ...) + */ + if ($isDeny) { + /* + * Если "РќРµ соответствует условию" Р РІСЃРµ состояния РІ логической СЃРІСЏР·РєРµ "Р" прошли проверку + * РўРѕРіРґР° пропускаем ограничение + */ + if (!in_array(false, $matches)) { + return false; + } + } else { + /* + * Если "Соответствует условию" + * Р РѕРґРЅРѕ состояние РІ логической СЃРІСЏР·РєРµ "Р" РЅРµ РїСЂРѕС…РѕРґРёС‚ проверку + * РўРѕРіРґР° пропускаем ограничение + */ + if (in_array(false, $matches)) { + return false; + } + } + } else { + /* + * Если логическая СЃРІСЏР·РєР° "Любое", то есть "РР›Р" + * Если (Состояние1 РЛРСостояние2 РЛР...) + */ + if ($isDeny) { + /* + * Если "РќРµ соответствует условию" + * Р РѕРґРЅРѕ РёР· состояний РІ логической СЃРІСЏР·РєРµ "РР›Р" прошло проверку + * РўРѕРіРґР° пропускаем ограничение + */ + if (in_array(true, $matches)) { + return false; + } + } else { + /* + * Если "Соответствует условию" + * Р РІСЃРµ состояния РІ логической СЃРІСЏР·РєРµ "РР›Р" РЅРµ прошли проверку + * РўРѕРіРґР° пропускаем ограничение + */ + if (!in_array(true, $matches)) { + return false; + } + } + } + } + + return true; + } + + public function isEqualsState(int $stateId, array $recordData = []): bool + { + $expressions = $this->format($stateId, $recordData); + $expressions = [$expressions]; + + return $this->isEqualsStateRecursive($expressions, $recordData); + } + + private function isEqualsStateRecursive(array $expressions, array $recordData = [], string $logicalOperator = 'and'): bool + { + $matches = []; + + foreach ($expressions as $expr) { + if ($expr['type'] === 'condition_group') { + $matches[] = $this->isEqualsStateRecursive($expr['query']['children'], $recordData, $expr['query']['logical_operator']); + } else { + $xValue = $expr['query']['x_value']; + $yValue = $expr['query']['y_value']; + + switch ($expr['query']['operator']) { + case 'eq': + $matches[] = $xValue == $yValue; + break; + case 'neq': + $matches[] = $xValue != $yValue; + break; + case 'in': + case 'equals_any': + $xValue = !is_array($xValue) + ? (array) $xValue + : $xValue; + + $yValue = !is_array($yValue) + ? (array) $yValue + : $yValue; + + $matches[] = count(array_intersect($xValue, $yValue)) > 0; + break; + case 'not_in': + case 'not_equals_any': + $xValue = !is_array($xValue) + ? (array) $xValue + : $xValue; + + $yValue = !is_array($yValue) + ? (array) $yValue + : $yValue; + + $matches[] = count(array_intersect($xValue, $yValue)) === 0; + break; + case 'gt': + $matches[] = $xValue > $yValue; + break; + case 'lt': + $matches[] = $xValue < $yValue; + break; + case 'gte': + $matches[] = $xValue >= $yValue; + break; + case 'lte': + $matches[] = $xValue <= $yValue; + break; + case 'is_null': + $matches[] = empty($xValue); + break; + case 'is_not_null': + $matches[] = !empty($xValue); + break; + case 'like': + $matches[] = strpos(mb_strtolower($xValue), mb_strtolower($yValue)) !== false; + break; + case 'not_like': + $matches[] = strpos(mb_strtolower($xValue), mb_strtolower($yValue)) === false; + break; + default: + $matches[] = false; + break; + } + } + } + + if ($logicalOperator === 'and') { + // Если РѕРґРЅРѕ РёР· всех выражение вернёт ЛОЖЬ, тогда условие РЅРµ прошло проверку + return !in_array(false, $matches); + } + + // если любое (any, or) РёР· выражений равно РРЎРўРРќРђ, тогда условие прошло проверку + return in_array(true, $matches); + } + /** * Форматирует разные состояния, простые Рё сложные, РѕРґРЅРѕ или несколько, РІ РѕРґРёРЅ формат * diff --git a/tests/Unit/Repository/StateRepository.php b/tests/Unit/Repository/StateRepository.php index 58e0219..8913339 100644 --- a/tests/Unit/Repository/StateRepository.php +++ b/tests/Unit/Repository/StateRepository.php @@ -43,7 +43,7 @@ class StateRepository implements StateQueryRepositoryInterface 'state_id' => 1, 'field_id' => 1003, 'state_field_type_id' => 'current_table_field', - 'current_table_field_id' => 2000 + 'current_table_field_id' => 1002 ] ] ], diff --git a/tests/Unit/StateUnitTest.php b/tests/Unit/StateUnitTest.php index 15ef58d..ac8b95b 100644 --- a/tests/Unit/StateUnitTest.php +++ b/tests/Unit/StateUnitTest.php @@ -24,14 +24,18 @@ class StateUnitTest extends TestCase $this->recordData = [ 'id' => 1, 'attr_1000_' => 'str1', - 'attr_1001_' => 'str2', + 'attr_1001_' => '314zdec', 'attr_1002_' => 'str3', - 'attr_1003_' => 'str4', + 'attr_1003_' => 'str3', 'attr_2010_' => '2022-12-01', 'attr_2011_' => '2022-12-01', // Для сравнения РѕРґРЅРѕРіРѕ поля СЃ РґСЂСѓРіРёРј полем РІ текущей таблице - 'attr_2000_' => 'value of the current table field', - 'attr_2001_' => null + 'attr_2000_' => [], + 'attr_2001_' => [], + 'attr_3001_' => [], + 'attr_2000_id' => null, + 'attr_2001_id' => null, + 'attr_3001_id' => null ]; $this->userInfo = new \stdClass(); @@ -64,78 +68,102 @@ class StateUnitTest extends TestCase self::assertEquals($testResult, json_encode($result)); } + public function testIsEqualsState() + { + $service = new StateService($this->repository, $this->userInfo); + + $result = $service->isEqualsState(1, $this->recordData); + $testResult = true; + self::assertEquals($testResult, $result); + } + + public function testCheckConditions() + { + $service = new StateService($this->repository, $this->userInfo); + + $result = $service->checkConditions([1], $this->recordData); + $testResult = true; + self::assertEquals($testResult, $result); + } + public function testStateFormatting(): void { $service = new StateService($this->repository, $this->userInfo); - $result = $service->format(1); + $result = $service->format(1, $this->recordData); $testResult = '{"type":"condition_group","query":{"logical_operator":"and","children":[{"type":"condition","query":{"fi' . - 'eld":"attr_1000_","value":"str1","filter_type":"constant","operator":"eq","field_type":"string_field"}},' . - '{"type":"condition","query":{"field":"attr_1001_","value":"314zdec","filter_type":"constant","operator":' . - '"eq","field_type":"string_field"}},{"type":"condition","query":{"field":"attr_1002_","value":null,"filte' . - 'r_type":"constant","operator":"is_null","field_type":"string_field"}},{"type":"condition","query":{"fiel' . - 'd":"attr_1003_","value":null,"filter_type":"constant","operator":"eq","field_type":"string_field"}}]}}' + 'eld":"attr_1000_","field_type":"string_field","x_value":"str1","y_value":"str1","operator":"eq"}},{"type' . + '":"condition","query":{"field":"attr_1001_","field_type":"string_field","x_value":"314zdec","y_value":"3' . + '14zdec","operator":"eq"}},{"type":"condition","query":{"field":"attr_1002_","field_type":"string_field",' . + '"x_value":"str3","y_value":null,"operator":"is_not_null"}},{"type":"condition","query":{"field":"attr_10' . + '03_","field_type":"string_field","x_value":"str3","y_value":"str3","operator":"eq"}}]}}' ; - self::assertEquals(json_encode($result), $testResult); + self::assertEquals($testResult, json_encode($result)); - $result = $service->format(2); + $result = $service->format(2, $this->recordData); $testResult = '{"type":"condition_group","query":{"logical_operator":"and","children":[{"type":"condition","query":{"fi' . - 'eld":"attr_1010_","filter_type":"constant","operator":"eq","value":"2021-07-15","field_type":"date_field' . - '"}},{"type":"condition_group","query":{"logical_operator":"or","children":[{"type":"condition","query":{' . - '"field":"attr_1011_","filter_type":"constant","operator":"gte","value":"2022-01-01","field_type":"date_f' . - 'ield"}},{"type":"condition","query":{"field":"attr_1011_","filter_type":"constant","operator":"lte","val' . - 'ue":"2021-06-01","field_type":"date_field"}}]}}]}}' + 'eld":"attr_1010_","field_type":"date_field","x_value":null,"y_value":"2021-07-15","operator":"eq"}},{"ty' . + 'pe":"condition_group","query":{"logical_operator":"or","children":[{"type":"condition","query":{"field":' . + '"attr_1011_","field_type":"date_field","x_value":null,"y_value":"2022-01-01","operator":"gte"}},{"type":' . + '"condition","query":{"field":"attr_1011_","field_type":"date_field","x_value":null,"y_value":"2021-06-01' . + '","operator":"lte"}}]}}]}}' ; - self::assertEquals(json_encode($result), $testResult); + self::assertEquals($testResult, json_encode($result)); - $result = $service->format([1, 2]); + $result = $service->format([1, 2], $this->recordData); $testResult = '{"type":"condition_group","query":{"logical_operator":"and","children":[{"type":"condition_group","query' . - '":{"logical_operator":"and","children":[{"type":"condition","query":{"field":"attr_1000_","value":"str1"' . - ',"filter_type":"constant","operator":"eq","field_type":"string_field"}},{"type":"condition","query":{"fi' . - 'eld":"attr_1001_","value":"314zdec","filter_type":"constant","operator":"eq","field_type":"string_field"' . - '}},{"type":"condition","query":{"field":"attr_1002_","value":null,"filter_type":"constant","operator":"i' . - 's_null","field_type":"string_field"}},{"type":"condition","query":{"field":"attr_1003_","value":null,"fi' . - 'lter_type":"constant","operator":"eq","field_type":"string_field"}}]}},{"type":"condition_group","query"' . - ':{"logical_operator":"and","children":[{"type":"condition","query":{"field":"attr_1010_","filter_type":"' . - 'constant","operator":"eq","value":"2021-07-15","field_type":"date_field"}},{"type":"condition_group","qu' . - 'ery":{"logical_operator":"or","children":[{"type":"condition","query":{"field":"attr_1011_","filter_type' . - '":"constant","operator":"gte","value":"2022-01-01","field_type":"date_field"}},{"type":"condition","quer' . - 'y":{"field":"attr_1011_","filter_type":"constant","operator":"lte","value":"2021-06-01","field_type":"da' . - 'te_field"}}]}}]}}]}}' + '":{"logical_operator":"and","children":[{"type":"condition","query":{"field":"attr_1000_","field_type":"' . + 'string_field","x_value":"str1","y_value":"str1","operator":"eq"}},{"type":"condition","query":{"field":"' . + 'attr_1001_","field_type":"string_field","x_value":"314zdec","y_value":"314zdec","operator":"eq"}},{"type' . + '":"condition","query":{"field":"attr_1002_","field_type":"string_field","x_value":"str3","y_value":null,' . + '"operator":"is_not_null"}},{"type":"condition","query":{"field":"attr_1003_","field_type":"string_field"' . + ',"x_value":"str3","y_value":"str3","operator":"eq"}}]}},{"type":"condition_group","query":{"logical_oper' . + 'ator":"and","children":[{"type":"condition","query":{"field":"attr_1010_","field_type":"date_field","x_v' . + 'alue":null,"y_value":"2021-07-15","operator":"eq"}},{"type":"condition_group","query":{"logical_operator' . + '":"or","children":[{"type":"condition","query":{"field":"attr_1011_","field_type":"date_field","x_value"' . + ':null,"y_value":"2022-01-01","operator":"gte"}},{"type":"condition","query":{"field":"attr_1011_","field' . + '_type":"date_field","x_value":null,"y_value":"2021-06-01","operator":"lte"}}]}}]}}]}}' ; - self::assertEquals(json_encode($result), $testResult); + self::assertEquals($testResult, json_encode($result)); } public function testStateConvertingToApiQl(): void { $service = new StateService($this->repository, $this->userInfo); + $result = $service->convertToApiQl([1], $this->recordData, 'and', false); + $testResult = + '{"and":[{"eq":{"attr_1000_":"str1"}},{"eq":{"attr_1001_":"314zdec"}},{"is_not_null":"attr_1002_"},{"eq":' . + '{"attr_1003_":"str3"}}]}' + ; + self::assertEquals($testResult, json_encode($result)); + $result = $service->convertToApiQl([1], $this->recordData); $testResult = - '{"where":[{"and":[{"eq":{"attr_1000_":"str1"}},{"eq":{"attr_1001_":"314zdec"}},{"is_null":"attr_1002_"},' . - '{"eq":{"attr_1003_":"value of the current table field"}}]}]}' + '{"where":{"and":[{"eq":{"attr_1000_":"str1"}},{"eq":{"attr_1001_":"314zdec"}},{"is_not_null":"attr_1002_' . + '"},{"eq":{"attr_1003_":"str3"}}]}}' ; - self::assertEquals(json_encode($result), $testResult); + self::assertEquals($testResult, json_encode($result)); $result = $service->convertToApiQl([2], $this->recordData); $testResult = - '{"where":[{"and":[{"eq":{"attr_1010_":"2021-07-15"}},{"or":[{"gte":{"attr_1011_":"2022-01-01"}},{"lte":{' . - '"attr_1011_":"2021-06-01"}}]}]}]}' + '{"where":{"and":[{"eq":{"attr_1010_":"2021-07-15"}},{"or":[{"gte":{"attr_1011_":"2022-01-01"}},{"lte":{"' . + 'attr_1011_":"2021-06-01"}}]}]}}' ; - self::assertEquals(json_encode($result), $testResult); + self::assertEquals($testResult, json_encode($result)); $result = $service->convertToApiQl([1, 2], $this->recordData); $testResult = - '{"where":[{"and":[{"and":[{"eq":{"attr_1000_":"str1"}},{"eq":{"attr_1001_":"314zdec"}},{"is_null":"attr_' . - '1002_"},{"eq":{"attr_1003_":"value of the current table field"}}]},{"and":[{"eq":{"attr_1010_":"2021-07-' . - '15"}},{"or":[{"gte":{"attr_1011_":"2022-01-01"}},{"lte":{"attr_1011_":"2021-06-01"}}]}]}]}]}' + '{"where":{"and":[{"and":[{"eq":{"attr_1000_":"str1"}},{"eq":{"attr_1001_":"314zdec"}},{"is_not_null":"at' . + 'tr_1002_"},{"eq":{"attr_1003_":"str3"}}]},{"and":[{"eq":{"attr_1010_":"2021-07-15"}},{"or":[{"gte":{"att' . + 'r_1011_":"2022-01-01"}},{"lte":{"attr_1011_":"2021-06-01"}}]}]}]}}' ; - self::assertEquals(json_encode($result), $testResult); + self::assertEquals($testResult, json_encode($result)); } } -- GitLab From a6be6189810c6fed78aad4b4c3cb11cf61e9d2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=9A=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8E=D0=BD=D0=B8=D1=87=D0=B5=D0=B2?= <slipper7747@gmail.com> Date: Wed, 10 May 2023 11:46:49 +0300 Subject: [PATCH 10/10] =?UTF-8?q?hotfix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D0=B0=D1=80=D1=81=D0=B8=D0=BD?= =?UTF-8?q?=D0=B3=20=D1=82=D0=B5=D0=BB=D0=B0=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D0=B0=20=D0=BF=D1=80=D0=B8=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=D0=B5=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=BD=D1=82=D0=B0=20app?= =?UTF-8?q?lication/json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Infrastructure/Middleware/BodyParserMiddleware.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Infrastructure/Middleware/BodyParserMiddleware.php b/src/Infrastructure/Middleware/BodyParserMiddleware.php index ba2bcf0..c108f7f 100644 --- a/src/Infrastructure/Middleware/BodyParserMiddleware.php +++ b/src/Infrastructure/Middleware/BodyParserMiddleware.php @@ -24,7 +24,7 @@ class BodyParserMiddleware implements MiddlewareInterface public function beforeHandleRoute(Event $event, Micro $application): void { $contentType = strtolower($application->request->getHeader('CONTENT_TYPE')); - if ($contentType === 'application/json' || $contentType === 'application/json;charset=utf-8') { + if (stripos($contentType, 'application/json') === 0) { $requestBody = $application->request->getRawBody(); if (!empty($requestBody)) { $jsonRawBody = json_decode($requestBody, true); -- GitLab