From e1e717ba87529e460809f00a2fff9eb8d7605b2d Mon Sep 17 00:00:00 2001 From: Dmitriy Ignatenko Date: Fri, 24 Jul 2026 15:11:36 +0400 Subject: [PATCH 1/2] Add catalog.productPropertyEnum methods --- .php-cs-fixer.php | 1 + CHANGELOG.md | 15 ++ Makefile | 8 + phpunit.xml.dist | 6 + .../Catalog/Result/CatalogItemResult.php | 2 +- .../Catalog/Catalog/Result/CatalogResult.php | 2 +- .../Catalog/Catalog/Result/CatalogsResult.php | 2 +- .../Catalog/Catalog/Service/Catalog.php | 2 +- .../Catalog/CatalogServiceBuilder.php | 20 +- src/Services/Catalog/Common/ProductType.php | 2 +- .../Common/Result/AbstractCatalogItem.php | 2 +- src/Services/Catalog/Product/Batch.php | 108 +++++++++ .../Product/Result/ProductItemResult.php | 2 +- .../Catalog/Product/Result/ProductResult.php | 2 +- .../Catalog/Product/Result/ProductsResult.php | 2 +- .../Catalog/Product/Service/Batch.php | 6 +- .../Catalog/Product/Service/Product.php | 10 +- .../Catalog/ProductPropertyEnum/Batch.php | 108 +++++++++ .../ProductPropertyEnumFieldsResult.php | 34 +++ .../Result/ProductPropertyEnumItemResult.php | 28 +++ .../Result/ProductPropertyEnumResult.php | 30 +++ .../Result/ProductPropertyEnumsResult.php | 34 +++ .../ProductPropertyEnum/Service/Batch.php | 26 +++ .../Service/ProductPropertyEnum.php | 195 +++++++++++++++++ .../ProductPropertyEnumItemResultTest.php | 104 +++++++++ .../Service/ProductPropertyEnumTest.php | 205 ++++++++++++++++++ .../Service/ProductPropertyEnumTest.php | 180 +++++++++++++++ 27 files changed, 1117 insertions(+), 19 deletions(-) create mode 100644 src/Services/Catalog/Product/Batch.php create mode 100644 src/Services/Catalog/ProductPropertyEnum/Batch.php create mode 100644 src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumFieldsResult.php create mode 100644 src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php create mode 100644 src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumResult.php create mode 100644 src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumsResult.php create mode 100644 src/Services/Catalog/ProductPropertyEnum/Service/Batch.php create mode 100644 src/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnum.php create mode 100644 tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php create mode 100644 tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php create mode 100644 tests/Unit/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 6e5393c3..15e131ad 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -29,6 +29,7 @@ ->in(__DIR__ . '/src/Services/SonetGroup/') ->in(__DIR__ . '/src/Services/IMOpenLines/') ->in(__DIR__ . '/src/Services/Landing/') + ->in(__DIR__ . '/src/Services/Catalog/') ->name('*.php') ->exclude(['vendor', 'storage', 'docker', 'docs']) // Exclude directories ->ignoreDotFiles(true) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4bc3b52..68642f14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ ### Added +- Added service `Services\Catalog\ProductPropertyEnum` with support methods, + see [catalog.productPropertyEnum.* methods](https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/index.html) ([#549](https://github.com/bitrix24/b24phpsdk/issues/549)): + - `add` creates a new list-type property value + - `update` updates an existing list-type property value + - `get` gets a list-type property value by identifier + - `list` gets the list of list-type property values by filter + - `delete` deletes a list-type property value by identifier + - `getFields` returns the description of list-type property value fields - Added service `Services\Landing\Site\Service\Site` with support methods, see [landing.site.* methods](https://github.com/bitrix24/b24phpsdk/issues/267): - `add` adds a site @@ -156,6 +164,13 @@ All classes under `Bitrix24\SDK\Legacy\` are marked `@deprecated` and will be removed once v3 reaches feature parity with v1. +### Fixed + +- Fixed batch operations for `Services\Catalog\Product` using the wrong-case `ID` key instead of + the lowercase `id` key expected by `catalog.product.list` and `catalog.product.delete`: added + `Services\Catalog\Product\Batch` overriding `determineKeyId()` and `deleteEntityItems()`, + registered in `CatalogServiceBuilder::product()` ([#549](https://github.com/bitrix24/b24phpsdk/issues/549)) + ## 3.0.0 - 2026.01.01 ### Added diff --git a/Makefile b/Makefile index c2fc4a9a..d2b1cd4f 100644 --- a/Makefile +++ b/Makefile @@ -492,6 +492,14 @@ test-integration-landing-role: test-integration-landing-repowidget: docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_landing_repowidget +.PHONY: test-integration-catalog-product-property-enum +test-integration-catalog-product-property-enum: + docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_catalog_product_property_enum + +.PHONY: test-integration-catalog-product-property-enum-annotations +test-integration-catalog-product-property-enum-annotations: + docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_catalog_product_property_enum_annotations + # work dev environment .PHONY: php-dev-server-up php-dev-server-up: diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d0187ae5..c45ec4f3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -262,6 +262,12 @@ ./tests/Integration/Services/Landing/RepoWidget/ + + ./tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ + + + ./tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php + diff --git a/src/Services/Catalog/Catalog/Result/CatalogItemResult.php b/src/Services/Catalog/Catalog/Result/CatalogItemResult.php index e62fc7cb..189852bb 100644 --- a/src/Services/Catalog/Catalog/Result/CatalogItemResult.php +++ b/src/Services/Catalog/Catalog/Result/CatalogItemResult.php @@ -29,4 +29,4 @@ */ class CatalogItemResult extends AbstractCatalogItem { -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Catalog/Result/CatalogResult.php b/src/Services/Catalog/Catalog/Result/CatalogResult.php index aa468aa8..c5222f11 100644 --- a/src/Services/Catalog/Catalog/Result/CatalogResult.php +++ b/src/Services/Catalog/Catalog/Result/CatalogResult.php @@ -21,4 +21,4 @@ public function catalog(): CatalogItemResult { return new CatalogItemResult($this->getCoreResponse()->getResponseData()->getResult()['catalog']); } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Catalog/Result/CatalogsResult.php b/src/Services/Catalog/Catalog/Result/CatalogsResult.php index add5f259..f721c3bb 100644 --- a/src/Services/Catalog/Catalog/Result/CatalogsResult.php +++ b/src/Services/Catalog/Catalog/Result/CatalogsResult.php @@ -32,4 +32,4 @@ public function getCatalogs(): array return $res; } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Catalog/Service/Catalog.php b/src/Services/Catalog/Catalog/Service/Catalog.php index d9cb55fe..0da76ea3 100644 --- a/src/Services/Catalog/Catalog/Service/Catalog.php +++ b/src/Services/Catalog/Catalog/Service/Catalog.php @@ -82,4 +82,4 @@ public function fields(): FieldsResult { return new FieldsResult($this->core->call('catalog.catalog.getFields')); } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/CatalogServiceBuilder.php b/src/Services/Catalog/CatalogServiceBuilder.php index 57c91b88..202a0561 100644 --- a/src/Services/Catalog/CatalogServiceBuilder.php +++ b/src/Services/Catalog/CatalogServiceBuilder.php @@ -17,14 +17,16 @@ use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Services\AbstractServiceBuilder; use Bitrix24\SDK\Services\Catalog; + #[ApiServiceBuilderMetadata(new Scope(['catalog']))] class CatalogServiceBuilder extends AbstractServiceBuilder { public function product(): Catalog\Product\Service\Product { if (!isset($this->serviceCache[__METHOD__])) { + $productBatch = new Catalog\Product\Batch($this->core, $this->log); $this->serviceCache[__METHOD__] = new Catalog\Product\Service\Product( - new Catalog\Product\Service\Batch($this->batch, $this->log), + new Catalog\Product\Service\Batch($productBatch, $this->log), $this->core, $this->log ); @@ -44,4 +46,18 @@ public function catalog(): Catalog\Catalog\Service\Catalog return $this->serviceCache[__METHOD__]; } -} \ No newline at end of file + + public function productPropertyEnum(): Catalog\ProductPropertyEnum\Service\ProductPropertyEnum + { + if (!isset($this->serviceCache[__METHOD__])) { + $productPropertyEnumBatch = new Catalog\ProductPropertyEnum\Batch($this->core, $this->log); + $this->serviceCache[__METHOD__] = new Catalog\ProductPropertyEnum\Service\ProductPropertyEnum( + new Catalog\ProductPropertyEnum\Service\Batch($productPropertyEnumBatch, $this->log), + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } +} diff --git a/src/Services/Catalog/Common/ProductType.php b/src/Services/Catalog/Common/ProductType.php index 0bf8ef09..ad568a47 100644 --- a/src/Services/Catalog/Common/ProductType.php +++ b/src/Services/Catalog/Common/ProductType.php @@ -20,4 +20,4 @@ enum ProductType: int case SKU = 3; case productOffer = 4; case genericOffer = 5; -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Common/Result/AbstractCatalogItem.php b/src/Services/Catalog/Common/Result/AbstractCatalogItem.php index e2929d73..9761daed 100644 --- a/src/Services/Catalog/Common/Result/AbstractCatalogItem.php +++ b/src/Services/Catalog/Common/Result/AbstractCatalogItem.php @@ -109,4 +109,4 @@ protected function getKeyWithUserfieldByFieldName(string $fieldName) return $this->$fieldName; } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Product/Batch.php b/src/Services/Catalog/Product/Batch.php new file mode 100644 index 00000000..148fcf60 --- /dev/null +++ b/src/Services/Catalog/Product/Batch.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\Product; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; +use Bitrix24\SDK\Core\Response\DTO\ResponseData; +use Generator; + +/** + * Class Batch + * + * Overrides base Batch to handle the lowercase 'id' key used by catalog.product.* REST methods + * instead of the uppercase 'ID' key used by default in the base Batch class. + * + * @see https://apidocs.bitrix24.com/api-reference/catalog/product/catalog-product-list.html + * @see https://apidocs.bitrix24.com/api-reference/catalog/product/catalog-product-delete.html + */ +class Batch extends \Bitrix24\SDK\Core\Batch +{ + /** + * Determines the ID key — lowercase 'id' for catalog.product.* methods + */ + #[\Override] + protected function determineKeyId(string $apiMethod, ?array $additionalParameters): string + { + return 'id'; + } + + /** + * Delete entity items with batch call using lowercase 'id' parameter + * + * @param int[] $entityItemId + * @param array|null $additionalParameters + * + * @return Generator|ResponseData[] + * @throws BaseException + */ + #[\Override] + public function deleteEntityItems( + string $apiMethod, + array $entityItemId, + ?array $additionalParameters = null + ): Generator { + $this->logger->debug( + 'deleteEntityItems.start', + [ + 'apiMethod' => $apiMethod, + 'entityItems' => $entityItemId, + 'additionalParameters' => $additionalParameters, + ] + ); + + try { + $this->clearCommands(); + foreach ($entityItemId as $cnt => $itemId) { + if (!is_int($itemId)) { + throw new InvalidArgumentException( + sprintf( + 'invalid type «%s» of product id «%s» at position %s, product id must be integer type', + gettype($itemId), + $itemId, + $cnt + ) + ); + } + + $this->registerCommand($apiMethod, ['id' => $itemId]); + } + + foreach ($this->getTraversable(true) as $cnt => $deletedItemResult) { + yield $cnt => $deletedItemResult; + } + } catch (InvalidArgumentException $exception) { + $errorMessage = sprintf('batch delete product items: %s', $exception->getMessage()); + $this->logger->error( + $errorMessage, + [ + 'trace' => $exception->getTrace(), + ] + ); + throw $exception; + } catch (\Throwable $exception) { + $errorMessage = sprintf('batch delete product items: %s', $exception->getMessage()); + $this->logger->error( + $errorMessage, + [ + 'trace' => $exception->getTrace(), + ] + ); + + throw new BaseException($errorMessage, $exception->getCode(), $exception); + } + + $this->logger->debug('deleteEntityItems.finish'); + } +} diff --git a/src/Services/Catalog/Product/Result/ProductItemResult.php b/src/Services/Catalog/Product/Result/ProductItemResult.php index c576d9b7..58c80851 100644 --- a/src/Services/Catalog/Product/Result/ProductItemResult.php +++ b/src/Services/Catalog/Product/Result/ProductItemResult.php @@ -52,4 +52,4 @@ */ class ProductItemResult extends AbstractCatalogItem { -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Product/Result/ProductResult.php b/src/Services/Catalog/Product/Result/ProductResult.php index 2751fda8..fc83fa8c 100644 --- a/src/Services/Catalog/Product/Result/ProductResult.php +++ b/src/Services/Catalog/Product/Result/ProductResult.php @@ -26,4 +26,4 @@ public function product(): ProductItemResult return new ProductItemResult($this->getCoreResponse()->getResponseData()->getResult()['product']); } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Product/Result/ProductsResult.php b/src/Services/Catalog/Product/Result/ProductsResult.php index aa644fa3..268d6d8f 100644 --- a/src/Services/Catalog/Product/Result/ProductsResult.php +++ b/src/Services/Catalog/Product/Result/ProductsResult.php @@ -31,4 +31,4 @@ public function getProducts(): array return $res; } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Product/Service/Batch.php b/src/Services/Catalog/Product/Service/Batch.php index 45dddcb7..42970546 100644 --- a/src/Services/Catalog/Product/Service/Batch.php +++ b/src/Services/Catalog/Product/Service/Batch.php @@ -25,7 +25,7 @@ { public function __construct( protected BatchOperationsInterface $batch, - protected LoggerInterface $log) - { + protected LoggerInterface $log + ) { } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/Product/Service/Product.php b/src/Services/Catalog/Product/Service/Product.php index 730fd7c9..d37d34f6 100644 --- a/src/Services/Catalog/Product/Service/Product.php +++ b/src/Services/Catalog/Product/Service/Product.php @@ -25,7 +25,6 @@ use Bitrix24\SDK\Services\Catalog\Common\ProductType; use Bitrix24\SDK\Services\Catalog\Product\Result\ProductResult; use Bitrix24\SDK\Services\Catalog\Product\Result\ProductsResult; - use Psr\Log\LoggerInterface; #[ApiServiceMetadata(new Scope(['catalog']))] @@ -35,8 +34,7 @@ public function __construct( public Batch $batch, CoreInterface $core, LoggerInterface $logger - ) - { + ) { parent::__construct($core, $logger); } @@ -71,7 +69,9 @@ public function get(int $productId): ProductResult )] public function add(array $productFields): ProductResult { - return new ProductResult($this->core->call('catalog.product.add', [ + return new ProductResult($this->core->call( + 'catalog.product.add', + [ 'fields' => $productFields ] )); @@ -140,4 +140,4 @@ public function fieldsByFilter(int $iblockId, ProductType $productType, ?array $ return new FieldsResult($this->core->call('catalog.product.getFieldsByFilter', ['filter' => $filter])); } -} \ No newline at end of file +} diff --git a/src/Services/Catalog/ProductPropertyEnum/Batch.php b/src/Services/Catalog/ProductPropertyEnum/Batch.php new file mode 100644 index 00000000..e235a2e3 --- /dev/null +++ b/src/Services/Catalog/ProductPropertyEnum/Batch.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; +use Bitrix24\SDK\Core\Response\DTO\ResponseData; +use Generator; + +/** + * Class Batch + * + * Overrides base Batch to handle the lowercase 'id' key used by catalog.productPropertyEnum.* REST methods + * instead of the uppercase 'ID' key used by default in the base Batch class. + * + * @see https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-list.html + * @see https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-delete.html + */ +class Batch extends \Bitrix24\SDK\Core\Batch +{ + /** + * Determines the ID key — lowercase 'id' for catalog.productPropertyEnum.* methods + */ + #[\Override] + protected function determineKeyId(string $apiMethod, ?array $additionalParameters): string + { + return 'id'; + } + + /** + * Delete entity items with batch call using lowercase 'id' parameter + * + * @param int[] $entityItemId + * @param array|null $additionalParameters + * + * @return Generator|ResponseData[] + * @throws BaseException + */ + #[\Override] + public function deleteEntityItems( + string $apiMethod, + array $entityItemId, + ?array $additionalParameters = null + ): Generator { + $this->logger->debug( + 'deleteEntityItems.start', + [ + 'apiMethod' => $apiMethod, + 'entityItems' => $entityItemId, + 'additionalParameters' => $additionalParameters, + ] + ); + + try { + $this->clearCommands(); + foreach ($entityItemId as $cnt => $itemId) { + if (!is_int($itemId)) { + throw new InvalidArgumentException( + sprintf( + 'invalid type «%s» of product property enum id «%s» at position %s, product property enum id must be integer type', + gettype($itemId), + $itemId, + $cnt + ) + ); + } + + $this->registerCommand($apiMethod, ['id' => $itemId]); + } + + foreach ($this->getTraversable(true) as $cnt => $deletedItemResult) { + yield $cnt => $deletedItemResult; + } + } catch (InvalidArgumentException $exception) { + $errorMessage = sprintf('batch delete product property enum items: %s', $exception->getMessage()); + $this->logger->error( + $errorMessage, + [ + 'trace' => $exception->getTrace(), + ] + ); + throw $exception; + } catch (\Throwable $exception) { + $errorMessage = sprintf('batch delete product property enum items: %s', $exception->getMessage()); + $this->logger->error( + $errorMessage, + [ + 'trace' => $exception->getTrace(), + ] + ); + + throw new BaseException($errorMessage, $exception->getCode(), $exception); + } + + $this->logger->debug('deleteEntityItems.finish'); + } +} diff --git a/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumFieldsResult.php b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumFieldsResult.php new file mode 100644 index 00000000..3956a9eb --- /dev/null +++ b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumFieldsResult.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class ProductPropertyEnumFieldsResult extends AbstractResult +{ + /** + * @throws BaseException + */ + public function getFieldsDescription(): array + { + $result = $this->getCoreResponse()->getResponseData()->getResult(); + + if (!empty($result['productPropertyEnum']) && is_array($result['productPropertyEnum'])) { + return $result['productPropertyEnum']; + } + + return $result; + } +} diff --git a/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php new file mode 100644 index 00000000..2fe5f6b6 --- /dev/null +++ b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result; + +use Bitrix24\SDK\Core\Result\AbstractAnnotatedItem; + +/** + * @property-read int $id + * @property-read int $propertyId + * @property-read string $value + * @property-read string $xmlId + * @property-read bool|null $def + * @property-read int|null $sort + */ +class ProductPropertyEnumItemResult extends AbstractAnnotatedItem +{ +} diff --git a/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumResult.php b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumResult.php new file mode 100644 index 00000000..272106f0 --- /dev/null +++ b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumResult.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class ProductPropertyEnumResult extends AbstractResult +{ + /** + * @throws BaseException + */ + public function productPropertyEnum(): ProductPropertyEnumItemResult + { + return new ProductPropertyEnumItemResult( + $this->getCoreResponse()->getResponseData()->getResult()['productPropertyEnum'] + ); + } +} diff --git a/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumsResult.php b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumsResult.php new file mode 100644 index 00000000..2d469fa4 --- /dev/null +++ b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumsResult.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class ProductPropertyEnumsResult extends AbstractResult +{ + /** + * @return ProductPropertyEnumItemResult[] + * @throws BaseException + */ + public function getProductPropertyEnums(): array + { + $items = []; + foreach ($this->getCoreResponse()->getResponseData()->getResult()['productPropertyEnums'] as $item) { + $items[] = new ProductPropertyEnumItemResult($item); + } + + return $items; + } +} diff --git a/src/Services/Catalog/ProductPropertyEnum/Service/Batch.php b/src/Services/Catalog/ProductPropertyEnum/Service/Batch.php new file mode 100644 index 00000000..aef96b76 --- /dev/null +++ b/src/Services/Catalog/ProductPropertyEnum/Service/Batch.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Service; + +use Bitrix24\SDK\Core\Contracts\BatchOperationsInterface; +use Psr\Log\LoggerInterface; + +readonly class Batch +{ + public function __construct( + protected BatchOperationsInterface $batch, + protected LoggerInterface $log + ) { + } +} diff --git a/src/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnum.php b/src/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnum.php new file mode 100644 index 00000000..4245d6b9 --- /dev/null +++ b/src/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnum.php @@ -0,0 +1,195 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Core\Result\DeletedItemResult; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result\ProductPropertyEnumFieldsResult; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result\ProductPropertyEnumResult; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result\ProductPropertyEnumsResult; +use Psr\Log\LoggerInterface; + +#[ApiServiceMetadata(new Scope(['catalog']))] +class ProductPropertyEnum extends AbstractService +{ + public function __construct( + public Batch $batch, + CoreInterface $core, + LoggerInterface $logger + ) { + parent::__construct($core, $logger); + } + + /** + * Adds a new value for a list-type product or variation property. + * + * @link https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-add.html + * + * @param array{ + * propertyId: int, + * value: string, + * xmlId: string, + * def?: string, + * sort?: int + * } $fields + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'catalog.productPropertyEnum.add', + 'https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-add.html', + 'Adds a new value for a list-type product or variation property' + )] + public function add(array $fields): ProductPropertyEnumResult + { + return new ProductPropertyEnumResult( + $this->core->call('catalog.productPropertyEnum.add', ['fields' => $fields]) + ); + } + + /** + * Updates a list-type property value of a commercial catalog product or variation. + * + * @link https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-update.html + * + * @param array{ + * propertyId: int, + * value: string, + * xmlId: string, + * def?: string, + * sort?: int + * } $fields + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'catalog.productPropertyEnum.update', + 'https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-update.html', + 'Updates a list-type property value of a commercial catalog product or variation' + )] + public function update(int $id, array $fields): ProductPropertyEnumResult + { + return new ProductPropertyEnumResult( + $this->core->call('catalog.productPropertyEnum.update', [ + 'id' => $id, + 'fields' => $fields, + ]) + ); + } + + /** + * Returns a list-type property value by its identifier. + * + * @link https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-get.html + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'catalog.productPropertyEnum.get', + 'https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-get.html', + 'Returns a list-type property value by its identifier' + )] + public function get(int $id): ProductPropertyEnumResult + { + return new ProductPropertyEnumResult( + $this->core->call('catalog.productPropertyEnum.get', ['id' => $id]) + ); + } + + /** + * Returns a list of list-type property values by filter. + * + * @link https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-list.html + * + * @param string[] $select + * @param array $filter + * @param array $order + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'catalog.productPropertyEnum.list', + 'https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-list.html', + 'Returns a list of list-type property values by filter' + )] + public function list(array $select = [], array $filter = [], array $order = []): ProductPropertyEnumsResult + { + $params = []; + if ($select !== []) { + $params['select'] = $select; + } + + if ($filter !== []) { + $params['filter'] = $filter; + } + + if ($order !== []) { + $params['order'] = $order; + } + + return new ProductPropertyEnumsResult( + $this->core->call('catalog.productPropertyEnum.list', $params) + ); + } + + /** + * Deletes a list-type property value by its identifier. + * + * @link https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-delete.html + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'catalog.productPropertyEnum.delete', + 'https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-delete.html', + 'Deletes a list-type property value by its identifier' + )] + public function delete(int $id): DeletedItemResult + { + return new DeletedItemResult( + $this->core->call('catalog.productPropertyEnum.delete', ['id' => $id]) + ); + } + + /** + * Returns the field description of list-type property values. + * + * @link https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-get-fields.html + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'catalog.productPropertyEnum.getFields', + 'https://apidocs.bitrix24.com/api-reference/catalog/product-property-enum/catalog-product-property-enum-get-fields.html', + 'Returns the field description of list-type property values' + )] + public function getFields(): ProductPropertyEnumFieldsResult + { + return new ProductPropertyEnumFieldsResult( + $this->core->call('catalog.productPropertyEnum.getFields', []) + ); + } +} diff --git a/tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php b/tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php new file mode 100644 index 00000000..c1825af0 --- /dev/null +++ b/tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Integration\Services\Catalog\ProductPropertyEnum\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result\ProductPropertyEnumItemResult; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Service\ProductPropertyEnum; +use Bitrix24\SDK\Tests\CustomAssertions\CustomBitrix24Assertions; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; + +#[CoversClass(ProductPropertyEnumItemResult::class)] +class ProductPropertyEnumItemResultTest extends TestCase +{ + use CustomBitrix24Assertions; + + private ProductPropertyEnum $productPropertyEnumService; + + private int $propertyId; + + private int $productPropertyEnumId; + + #[Test] + #[TestDox('all fields in ProductPropertyEnumItemResult are annotated in phpdoc and match with raw api response')] + public function testAllFieldsAreAnnotated(): void + { + $rawItem = $this->productPropertyEnumService->get($this->productPropertyEnumId) + ->getCoreResponse()->getResponseData()->getResult()['productPropertyEnum']; + + $this->assertBitrix24AllResultItemFieldsAnnotated( + array_keys($rawItem), + ProductPropertyEnumItemResult::class + ); + } + + #[Test] + #[TestDox('all fields in ProductPropertyEnumItemResult have valid type casting in magic getters')] + public function testAllFieldsHasValidTypeCastingInMagicGetters(): void + { + $productPropertyEnumItemResult = $this->productPropertyEnumService->get($this->productPropertyEnumId)->productPropertyEnum(); + $this->assertBitrix24ResultItemFieldsTypeCastMatchAnnotations( + $productPropertyEnumItemResult, + ProductPropertyEnumItemResult::class + ); + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[\Override] + protected function setUp(): void + { + $this->productPropertyEnumService = Fabric::getServiceBuilder()->getCatalogScope()->productPropertyEnum(); + + $catalogService = Fabric::getServiceBuilder()->getCatalogScope()->catalog(); + $iblockId = $catalogService->list([], [], [], 1)->getCatalogs()[0]->iblockId; + + $propertyResponse = Fabric::getCore()->call('catalog.productProperty.add', [ + 'fields' => [ + 'iblockId' => $iblockId, + 'name' => sprintf('test list property %s', time()), + 'propertyType' => 'L', + 'listType' => 'L', + ], + ]); + $this->propertyId = (int)$propertyResponse->getResponseData()->getResult()['productProperty']['id']; + + $addResult = $this->productPropertyEnumService->add([ + 'propertyId' => $this->propertyId, + 'value' => sprintf('test value %s', time()), + 'xmlId' => sprintf('test-xml-id-%s', time()), + 'def' => 'Y', + 'sort' => 100, + ]); + $this->productPropertyEnumId = $addResult->productPropertyEnum()->id; + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[\Override] + protected function tearDown(): void + { + $this->productPropertyEnumService->delete($this->productPropertyEnumId); + Fabric::getCore()->call('catalog.productProperty.delete', ['id' => $this->propertyId]); + } +} diff --git a/tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php b/tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php new file mode 100644 index 00000000..68ea1625 --- /dev/null +++ b/tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php @@ -0,0 +1,205 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Integration\Services\Catalog\ProductPropertyEnum\Service; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Service\ProductPropertyEnum; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; + +#[CoversClass(ProductPropertyEnum::class)] +class ProductPropertyEnumTest extends TestCase +{ + private ProductPropertyEnum $productPropertyEnumService; + + private int $propertyId; + + /** + * @throws BaseException + * @throws TransportException + */ + #[TestDox('test ProductPropertyEnum::add')] + public function testAdd(): void + { + $fields = [ + 'propertyId' => $this->propertyId, + 'value' => sprintf('test value %s', time()), + 'xmlId' => sprintf('test-xml-id-%s', time()), + 'def' => 'Y', + 'sort' => 100, + ]; + $result = $this->productPropertyEnumService->add($fields); + $this->assertEquals($fields['value'], $result->productPropertyEnum()->value); + $this->assertEquals($fields['xmlId'], $result->productPropertyEnum()->xmlId); + $this->assertEquals($this->propertyId, $result->productPropertyEnum()->propertyId); + + $this->productPropertyEnumService->delete($result->productPropertyEnum()->id); + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[TestDox('test ProductPropertyEnum::update')] + public function testUpdate(): void + { + $addResult = $this->productPropertyEnumService->add([ + 'propertyId' => $this->propertyId, + 'value' => sprintf('test value %s', time()), + 'xmlId' => sprintf('test-xml-id-%s', time()), + 'def' => 'N', + 'sort' => 100, + ]); + $id = $addResult->productPropertyEnum()->id; + + $updatedValue = sprintf('updated value %s', time()); + $this->productPropertyEnumService->update($id, [ + 'propertyId' => $this->propertyId, + 'value' => $updatedValue, + 'xmlId' => $addResult->productPropertyEnum()->xmlId, + 'def' => 'N', + 'sort' => 200, + ]); + + $getResult = $this->productPropertyEnumService->get($id); + $this->assertEquals($updatedValue, $getResult->productPropertyEnum()->value); + $this->assertEquals(200, $getResult->productPropertyEnum()->sort); + + $this->productPropertyEnumService->delete($id); + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[TestDox('test ProductPropertyEnum::get')] + public function testGet(): void + { + $addResult = $this->productPropertyEnumService->add([ + 'propertyId' => $this->propertyId, + 'value' => sprintf('test value %s', time()), + 'xmlId' => sprintf('test-xml-id-%s', time()), + 'def' => 'N', + 'sort' => 100, + ]); + $id = $addResult->productPropertyEnum()->id; + + $getResult = $this->productPropertyEnumService->get($id); + $this->assertEquals($id, $getResult->productPropertyEnum()->id); + $this->assertEquals($addResult->productPropertyEnum()->value, $getResult->productPropertyEnum()->value); + + $this->productPropertyEnumService->delete($id); + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[TestDox('test ProductPropertyEnum::list')] + public function testList(): void + { + $addResult = $this->productPropertyEnumService->add([ + 'propertyId' => $this->propertyId, + 'value' => sprintf('test value %s', time()), + 'xmlId' => sprintf('test-xml-id-%s', time()), + 'def' => 'N', + 'sort' => 100, + ]); + $id = $addResult->productPropertyEnum()->id; + + $listResult = $this->productPropertyEnumService->list( + ['id', 'propertyId', 'value', 'xmlId', 'def', 'sort'], + ['id' => $id], + ['id' => 'ASC'] + ); + $this->assertCount(1, $listResult->getProductPropertyEnums()); + $this->assertEquals($id, $listResult->getProductPropertyEnums()[0]->id); + + $this->productPropertyEnumService->delete($id); + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[TestDox('test ProductPropertyEnum::delete')] + public function testDelete(): void + { + $addResult = $this->productPropertyEnumService->add([ + 'propertyId' => $this->propertyId, + 'value' => sprintf('test value %s', time()), + 'xmlId' => sprintf('test-xml-id-%s', time()), + 'def' => 'N', + 'sort' => 100, + ]); + $id = $addResult->productPropertyEnum()->id; + + $this->assertTrue($this->productPropertyEnumService->delete($id)->isSuccess()); + + $listResult = $this->productPropertyEnumService->list([], ['id' => $id]); + $this->assertCount(0, $listResult->getProductPropertyEnums()); + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[TestDox('test ProductPropertyEnum::getFields')] + public function testGetFields(): void + { + $fields = $this->productPropertyEnumService->getFields()->getFieldsDescription(); + $this->assertArrayHasKey('id', $fields); + $this->assertArrayHasKey('propertyId', $fields); + $this->assertArrayHasKey('value', $fields); + $this->assertArrayHasKey('xmlId', $fields); + $this->assertArrayHasKey('def', $fields); + $this->assertArrayHasKey('sort', $fields); + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[\Override] + protected function setUp(): void + { + $this->productPropertyEnumService = Fabric::getServiceBuilder()->getCatalogScope()->productPropertyEnum(); + + $catalogService = Fabric::getServiceBuilder()->getCatalogScope()->catalog(); + $iblockId = $catalogService->list([], [], [], 1)->getCatalogs()[0]->iblockId; + + $propertyResponse = Fabric::getCore()->call('catalog.productProperty.add', [ + 'fields' => [ + 'iblockId' => $iblockId, + 'name' => sprintf('test list property %s', time()), + 'propertyType' => 'L', + 'listType' => 'L', + ], + ]); + $this->propertyId = (int)$propertyResponse->getResponseData()->getResult()['productProperty']['id']; + } + + /** + * @throws BaseException + * @throws TransportException + */ + #[\Override] + protected function tearDown(): void + { + Fabric::getCore()->call('catalog.productProperty.delete', ['id' => $this->propertyId]); + } +} diff --git a/tests/Unit/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php b/tests/Unit/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php new file mode 100644 index 00000000..4435c2ab --- /dev/null +++ b/tests/Unit/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php @@ -0,0 +1,180 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Unit\Services\Catalog\ProductPropertyEnum\Service; + +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Response\Response; +use Bitrix24\SDK\Core\Result\DeletedItemResult; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result\ProductPropertyEnumFieldsResult; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result\ProductPropertyEnumResult; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result\ProductPropertyEnumsResult; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Service\Batch; +use Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Service\ProductPropertyEnum; +use Bitrix24\SDK\Tests\Unit\Stubs\NullBatch; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +#[CoversClass(ProductPropertyEnum::class)] +class ProductPropertyEnumTest extends TestCase +{ + private function createService(CoreInterface $core): ProductPropertyEnum + { + return new ProductPropertyEnum(new Batch(new NullBatch(), new NullLogger()), $core, new NullLogger()); + } + + #[Test] + public function testAddCallsProductPropertyEnumAdd(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $fields = [ + 'propertyId' => 431, + 'value' => 'Medium', + 'xmlId' => 'M', + 'def' => 'Y', + 'sort' => 100, + ]; + + $core->expects($this->once()) + ->method('call') + ->with('catalog.productPropertyEnum.add', ['fields' => $fields]) + ->willReturn($response); + + $this->assertInstanceOf( + ProductPropertyEnumResult::class, + $this->createService($core)->add($fields) + ); + } + + #[Test] + public function testUpdateCallsProductPropertyEnumUpdate(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $fields = [ + 'propertyId' => 431, + 'value' => 'Medium', + 'xmlId' => 'M', + 'def' => 'N', + 'sort' => 110, + ]; + + $core->expects($this->once()) + ->method('call') + ->with('catalog.productPropertyEnum.update', ['id' => 1739, 'fields' => $fields]) + ->willReturn($response); + + $this->assertInstanceOf( + ProductPropertyEnumResult::class, + $this->createService($core)->update(1739, $fields) + ); + } + + #[Test] + public function testGetCallsProductPropertyEnumGet(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with('catalog.productPropertyEnum.get', ['id' => 1739]) + ->willReturn($response); + + $this->assertInstanceOf( + ProductPropertyEnumResult::class, + $this->createService($core)->get(1739) + ); + } + + #[Test] + public function testListCallsProductPropertyEnumListWithoutOptionalParams(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with('catalog.productPropertyEnum.list', []) + ->willReturn($response); + + $this->assertInstanceOf( + ProductPropertyEnumsResult::class, + $this->createService($core)->list() + ); + } + + #[Test] + public function testListCallsProductPropertyEnumListWithAllParams(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $select = ['id', 'propertyId', 'value', 'def', 'sort', 'xmlId']; + $filter = ['propertyId' => 431]; + $order = ['id' => 'ASC']; + + $core->expects($this->once()) + ->method('call') + ->with('catalog.productPropertyEnum.list', [ + 'select' => $select, + 'filter' => $filter, + 'order' => $order, + ]) + ->willReturn($response); + + $this->assertInstanceOf( + ProductPropertyEnumsResult::class, + $this->createService($core)->list($select, $filter, $order) + ); + } + + #[Test] + public function testDeleteCallsProductPropertyEnumDelete(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with('catalog.productPropertyEnum.delete', ['id' => 122]) + ->willReturn($response); + + $this->assertInstanceOf( + DeletedItemResult::class, + $this->createService($core)->delete(122) + ); + } + + #[Test] + public function testGetFieldsCallsProductPropertyEnumGetFields(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with('catalog.productPropertyEnum.getFields', []) + ->willReturn($response); + + $this->assertInstanceOf( + ProductPropertyEnumFieldsResult::class, + $this->createService($core)->getFields() + ); + } +} From ea8a98ed73256ba4d1460a3783a0afa7f4329f92 Mon Sep 17 00:00:00 2001 From: Dmitriy Ignatenko Date: Fri, 24 Jul 2026 16:22:24 +0400 Subject: [PATCH 2/2] Fix on liter results --- .../Result/ProductPropertyEnumItemResult.php | 31 +++++++++++++- .../ProductPropertyEnumItemResultTest.php | 10 ++--- .../Service/ProductPropertyEnumTest.php | 40 +++++++++---------- 3 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php index 2fe5f6b6..da8b33c7 100644 --- a/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php +++ b/src/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResult.php @@ -13,7 +13,7 @@ namespace Bitrix24\SDK\Services\Catalog\ProductPropertyEnum\Result; -use Bitrix24\SDK\Core\Result\AbstractAnnotatedItem; +use Bitrix24\SDK\Core\Result\AbstractItem; /** * @property-read int $id @@ -23,6 +23,33 @@ * @property-read bool|null $def * @property-read int|null $sort */ -class ProductPropertyEnumItemResult extends AbstractAnnotatedItem +class ProductPropertyEnumItemResult extends AbstractItem { + /** + * @param int|string $offset + * + * @return bool|int|mixed|null + */ + public function __get($offset) + { + switch ($offset) { + case 'id': + case 'propertyId': + return (int)$this->data[$offset]; + case 'def': + if ($this->data[$offset] !== null) { + return $this->data[$offset] === 'Y'; + } + + return null; + case 'sort': + if ($this->data[$offset] !== null) { + return (int)$this->data[$offset]; + } + + return null; + } + + return $this->data[$offset] ?? null; + } } diff --git a/tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php b/tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php index c1825af0..0fcd9375 100644 --- a/tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php +++ b/tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php @@ -52,9 +52,9 @@ public function testAllFieldsAreAnnotated(): void #[TestDox('all fields in ProductPropertyEnumItemResult have valid type casting in magic getters')] public function testAllFieldsHasValidTypeCastingInMagicGetters(): void { - $productPropertyEnumItemResult = $this->productPropertyEnumService->get($this->productPropertyEnumId)->productPropertyEnum(); - $this->assertBitrix24ResultItemFieldsTypeCastMatchAnnotations( - $productPropertyEnumItemResult, + $fields = $this->productPropertyEnumService->getFields()->getFieldsDescription(); + $this->assertBitrix24AllResultItemFieldsHasValidTypeAnnotation( + $fields, ProductPropertyEnumItemResult::class ); } @@ -81,14 +81,14 @@ protected function setUp(): void ]); $this->propertyId = (int)$propertyResponse->getResponseData()->getResult()['productProperty']['id']; - $addResult = $this->productPropertyEnumService->add([ + $productPropertyEnumResult = $this->productPropertyEnumService->add([ 'propertyId' => $this->propertyId, 'value' => sprintf('test value %s', time()), 'xmlId' => sprintf('test-xml-id-%s', time()), 'def' => 'Y', 'sort' => 100, ]); - $this->productPropertyEnumId = $addResult->productPropertyEnum()->id; + $this->productPropertyEnumId = $productPropertyEnumResult->productPropertyEnum()->id; } /** diff --git a/tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php b/tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php index 68ea1625..30750379 100644 --- a/tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php +++ b/tests/Integration/Services/Catalog/ProductPropertyEnum/Service/ProductPropertyEnumTest.php @@ -42,12 +42,12 @@ public function testAdd(): void 'def' => 'Y', 'sort' => 100, ]; - $result = $this->productPropertyEnumService->add($fields); - $this->assertEquals($fields['value'], $result->productPropertyEnum()->value); - $this->assertEquals($fields['xmlId'], $result->productPropertyEnum()->xmlId); - $this->assertEquals($this->propertyId, $result->productPropertyEnum()->propertyId); + $productPropertyEnumResult = $this->productPropertyEnumService->add($fields); + $this->assertEquals($fields['value'], $productPropertyEnumResult->productPropertyEnum()->value); + $this->assertEquals($fields['xmlId'], $productPropertyEnumResult->productPropertyEnum()->xmlId); + $this->assertEquals($this->propertyId, $productPropertyEnumResult->productPropertyEnum()->propertyId); - $this->productPropertyEnumService->delete($result->productPropertyEnum()->id); + $this->productPropertyEnumService->delete($productPropertyEnumResult->productPropertyEnum()->id); } /** @@ -57,20 +57,20 @@ public function testAdd(): void #[TestDox('test ProductPropertyEnum::update')] public function testUpdate(): void { - $addResult = $this->productPropertyEnumService->add([ + $productPropertyEnumResult = $this->productPropertyEnumService->add([ 'propertyId' => $this->propertyId, 'value' => sprintf('test value %s', time()), 'xmlId' => sprintf('test-xml-id-%s', time()), 'def' => 'N', 'sort' => 100, ]); - $id = $addResult->productPropertyEnum()->id; + $id = $productPropertyEnumResult->productPropertyEnum()->id; $updatedValue = sprintf('updated value %s', time()); $this->productPropertyEnumService->update($id, [ 'propertyId' => $this->propertyId, 'value' => $updatedValue, - 'xmlId' => $addResult->productPropertyEnum()->xmlId, + 'xmlId' => $productPropertyEnumResult->productPropertyEnum()->xmlId, 'def' => 'N', 'sort' => 200, ]); @@ -89,18 +89,18 @@ public function testUpdate(): void #[TestDox('test ProductPropertyEnum::get')] public function testGet(): void { - $addResult = $this->productPropertyEnumService->add([ + $productPropertyEnumResult = $this->productPropertyEnumService->add([ 'propertyId' => $this->propertyId, 'value' => sprintf('test value %s', time()), 'xmlId' => sprintf('test-xml-id-%s', time()), 'def' => 'N', 'sort' => 100, ]); - $id = $addResult->productPropertyEnum()->id; + $id = $productPropertyEnumResult->productPropertyEnum()->id; $getResult = $this->productPropertyEnumService->get($id); $this->assertEquals($id, $getResult->productPropertyEnum()->id); - $this->assertEquals($addResult->productPropertyEnum()->value, $getResult->productPropertyEnum()->value); + $this->assertEquals($productPropertyEnumResult->productPropertyEnum()->value, $getResult->productPropertyEnum()->value); $this->productPropertyEnumService->delete($id); } @@ -112,22 +112,22 @@ public function testGet(): void #[TestDox('test ProductPropertyEnum::list')] public function testList(): void { - $addResult = $this->productPropertyEnumService->add([ + $productPropertyEnumResult = $this->productPropertyEnumService->add([ 'propertyId' => $this->propertyId, 'value' => sprintf('test value %s', time()), 'xmlId' => sprintf('test-xml-id-%s', time()), 'def' => 'N', 'sort' => 100, ]); - $id = $addResult->productPropertyEnum()->id; + $id = $productPropertyEnumResult->productPropertyEnum()->id; - $listResult = $this->productPropertyEnumService->list( + $productPropertyEnumsResult = $this->productPropertyEnumService->list( ['id', 'propertyId', 'value', 'xmlId', 'def', 'sort'], ['id' => $id], ['id' => 'ASC'] ); - $this->assertCount(1, $listResult->getProductPropertyEnums()); - $this->assertEquals($id, $listResult->getProductPropertyEnums()[0]->id); + $this->assertCount(1, $productPropertyEnumsResult->getProductPropertyEnums()); + $this->assertEquals($id, $productPropertyEnumsResult->getProductPropertyEnums()[0]->id); $this->productPropertyEnumService->delete($id); } @@ -139,19 +139,19 @@ public function testList(): void #[TestDox('test ProductPropertyEnum::delete')] public function testDelete(): void { - $addResult = $this->productPropertyEnumService->add([ + $productPropertyEnumResult = $this->productPropertyEnumService->add([ 'propertyId' => $this->propertyId, 'value' => sprintf('test value %s', time()), 'xmlId' => sprintf('test-xml-id-%s', time()), 'def' => 'N', 'sort' => 100, ]); - $id = $addResult->productPropertyEnum()->id; + $id = $productPropertyEnumResult->productPropertyEnum()->id; $this->assertTrue($this->productPropertyEnumService->delete($id)->isSuccess()); - $listResult = $this->productPropertyEnumService->list([], ['id' => $id]); - $this->assertCount(0, $listResult->getProductPropertyEnums()); + $productPropertyEnumsResult = $this->productPropertyEnumService->list([], ['id' => $id]); + $this->assertCount(0, $productPropertyEnumsResult->getProductPropertyEnums()); } /**