Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@
<testsuite name="integration_tests_landing_repowidget">
<directory>./tests/Integration/Services/Landing/RepoWidget/</directory>
</testsuite>
<testsuite name="integration_tests_catalog_product_property_enum">
<directory>./tests/Integration/Services/Catalog/ProductPropertyEnum/Service/</directory>
</testsuite>
<testsuite name="integration_tests_catalog_product_property_enum_annotations">
<file>./tests/Integration/Services/Catalog/ProductPropertyEnum/Result/ProductPropertyEnumItemResultTest.php</file>
</testsuite>
</testsuites>
<source>
<include>
Expand Down
2 changes: 1 addition & 1 deletion src/Services/Catalog/Catalog/Result/CatalogItemResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@
*/
class CatalogItemResult extends AbstractCatalogItem
{
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Catalog/Result/CatalogResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ public function catalog(): CatalogItemResult
{
return new CatalogItemResult($this->getCoreResponse()->getResponseData()->getResult()['catalog']);
}
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Catalog/Result/CatalogsResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ public function getCatalogs(): array

return $res;
}
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Catalog/Service/Catalog.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ public function fields(): FieldsResult
{
return new FieldsResult($this->core->call('catalog.catalog.getFields'));
}
}
}
20 changes: 18 additions & 2 deletions src/Services/Catalog/CatalogServiceBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Expand All @@ -44,4 +46,18 @@ public function catalog(): Catalog\Catalog\Service\Catalog

return $this->serviceCache[__METHOD__];
}
}

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__];
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Common/ProductType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ enum ProductType: int
case SKU = 3;
case productOffer = 4;
case genericOffer = 5;
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Common/Result/AbstractCatalogItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ protected function getKeyWithUserfieldByFieldName(string $fieldName)

return $this->$fieldName;
}
}
}
108 changes: 108 additions & 0 deletions src/Services/Catalog/Product/Batch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

/**
* This file is part of the bitrix24-php-sdk package.
*
* © Dmitriy Ignatenko <algonexys@gmail.com>
*
* 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<mixed>|null $additionalParameters
*
* @return Generator<int, ResponseData>|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');
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Product/Result/ProductItemResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@
*/
class ProductItemResult extends AbstractCatalogItem
{
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Product/Result/ProductResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ public function product(): ProductItemResult

return new ProductItemResult($this->getCoreResponse()->getResponseData()->getResult()['product']);
}
}
}
2 changes: 1 addition & 1 deletion src/Services/Catalog/Product/Result/ProductsResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ public function getProducts(): array

return $res;
}
}
}
6 changes: 3 additions & 3 deletions src/Services/Catalog/Product/Service/Batch.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
{
public function __construct(
protected BatchOperationsInterface $batch,
protected LoggerInterface $log)
{
protected LoggerInterface $log
) {
}
}
}
10 changes: 5 additions & 5 deletions src/Services/Catalog/Product/Service/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']))]
Expand All @@ -35,8 +34,7 @@ public function __construct(
public Batch $batch,
CoreInterface $core,
LoggerInterface $logger
)
{
) {
parent::__construct($core, $logger);
}

Expand Down Expand Up @@ -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
]
));
Expand Down Expand Up @@ -140,4 +140,4 @@ public function fieldsByFilter(int $iblockId, ProductType $productType, ?array $

return new FieldsResult($this->core->call('catalog.product.getFieldsByFilter', ['filter' => $filter]));
}
}
}
Loading
Loading