diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94b67449..76e2800b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,23 @@
# b24-php-sdk change log
-## Unreleased 1.3.0 – 2025.01.19
+## Unreleased 1.3.0 – 2025.02.03
### Added
+- Added support new scope `entity`
+- Added service `Services\Entity\Service\Item` with support methods,
+ see [fix entity.item.* methods](https://github.com/bitrix24/b24phpsdk/issues/53):
+ - `get` get item, with batch calls support
+ - `add` add new item, with batch calls support
+ - `delete` delete item, with batch calls support
+ - `update` update item, with batch calls support
+- Added service `Services\Entity\Service\Entity` with support methods,
+ see [fix entity.* methods](https://github.com/bitrix24/b24phpsdk/issues/53):
+ - `get` get entity
+ - `add` add new entity
+ - `delete` delete entity
+ - `update` update entity
+ - `rights` get or change access permissions
- Added new application scope nodes `humanresources.hcmlink` and `sign.b2e`
- Added method `Bitrix24\SDK\Core\Credentials\Scope::contains` for check is current scope code contains in scope, for
task «[split cli commands](https://github.com/bitrix24/b24phpsdk/issues/92)»
@@ -59,6 +73,8 @@
- Fixed errors in `Bitrix24\SDK\Core\Batch` for method
`user.get`, [see details](https://github.com/bitrix24/b24phpsdk/issues/103)
+- Fixed errors in `Bitrix24\SDK\Core\Batch` for methods `entity.item.get` and
+ `entity.item.update`, [see details](https://github.com/bitrix24/b24phpsdk/issues/53)
### Statistics
diff --git a/Makefile b/Makefile
index db997b97..1c447c00 100644
--- a/Makefile
+++ b/Makefile
@@ -127,4 +127,6 @@ test-integration-scope-user:
test-integration-scope-user-consent:
vendor/bin/phpunit --testsuite integration_tests_scope_user_consent
test-integration-core:
- vendor/bin/phpunit --testsuite integration_tests_core
\ No newline at end of file
+ vendor/bin/phpunit --testsuite integration_tests_core
+test-integration-scope-entity:
+ vendor/bin/phpunit --testsuite integration_tests_scope_entity
\ No newline at end of file
diff --git a/docs/EN/Services/bitrix24-php-sdk-methods.md b/docs/EN/Services/bitrix24-php-sdk-methods.md
index 89ca1f2f..c18042ce 100644
--- a/docs/EN/Services/bitrix24-php-sdk-methods.md
+++ b/docs/EN/Services/bitrix24-php-sdk-methods.md
@@ -11,6 +11,15 @@
|`–`|[methods](https://training.bitrix24.com/rest_help/general/methods.php)|Returns the methods available to the current application|[`Bitrix24\SDK\Services\Main\Service\Main::getMethodsByScope`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Main/Service/Main.php#L212-L215) Return type [`Bitrix24\SDK\Core\Response\Response`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Response/Response.php)|
|`–`|[app.info](https://training.bitrix24.com/rest_help/general/app_info.php)|Displays application information. The method supports secure calling convention.|[`Bitrix24\SDK\Services\Main\Service\Main::getApplicationInfo`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Main/Service/Main.php#L229-L232) Return type [`Bitrix24\SDK\Services\Main\Result\ApplicationInfoResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Main/Result/ApplicationInfoResult.php)|
|`–`|[user.admin](https://training.bitrix24.com/rest_help/general/user_admin.php)|Checks if a current user has permissions to manage application parameters.|[`Bitrix24\SDK\Services\Main\Service\Main::isCurrentUserHasAdminRights`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Main/Service/Main.php#L246-L249) Return type [`Bitrix24\SDK\Services\Main\Result\IsUserAdminResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Main/Result/IsUserAdminResult.php)|
+|`entity`|[entity.add](https://apidocs.bitrix24.com/api-reference/entity/entities/entity-add.html)|Create Data Storage|[`Bitrix24\SDK\Services\Entity\Entity\Service\Entity::add`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Service/Entity.php#L54-L69) Return type [`Bitrix24\SDK\Services\Entity\Entity\Result\AddedEntityResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Result/AddedEntityResult.php)|
+|`entity`|[entity.update](https://apidocs.bitrix24.com/api-reference/entity/entities/entity-update.html)|Change Parameters|[`Bitrix24\SDK\Services\Entity\Entity\Service\Entity::update`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Service/Entity.php#L83-L102) Return type [`Bitrix24\SDK\Core\Result\UpdatedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/UpdatedItemResult.php)|
+|`entity`|[entity.delete](https://apidocs.bitrix24.com/api-reference/entity/entities/entity-delete.html)|Delete Storage|[`Bitrix24\SDK\Services\Entity\Entity\Service\Entity::delete`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Service/Entity.php#L117-L129) Return type [`Bitrix24\SDK\Core\Result\DeletedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/DeletedItemResult.php)|
+|`entity`|[entity.get](https://apidocs.bitrix24.com/api-reference/entity/entities/entity-get.html)|Get Storage Parameters or List of All Storages|[`Bitrix24\SDK\Services\Entity\Entity\Service\Entity::get`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Service/Entity.php#L143-L146) Return type [`Bitrix24\SDK\Services\Entity\Entity\Result\EntitiesResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Result/EntitiesResult.php)|
+|`entity`|[entity.rights](https://apidocs.bitrix24.com/api-reference/entity/entities/entity-rights.html)|Get or Change Access Permissions|[`Bitrix24\SDK\Services\Entity\Entity\Service\Entity::rights`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Service/Entity.php#L160-L171) Return type [`Bitrix24\SDK\Services\Entity\Entity\Result\EntityRightsResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Entity/Result/EntityRightsResult.php)|
+|`entity`|[entity.item.add](https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-add.html)|Add Storage Element|[`Bitrix24\SDK\Services\Entity\Item\Service\Item::add`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Item/Service/Item.php#L52-L69) Return type [`Bitrix24\SDK\Core\Result\AddedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/AddedItemResult.php) ⚡️Batch methods:
`Bitrix24\SDK\Services\Entity\Item\Service\Batch::add` Return type: `Generator` |
+|`entity`|[entity.item.get](https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-get.html)|Get the list of storage items|[`Bitrix24\SDK\Services\Entity\Item\Service\Item::get`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Item/Service/Item.php#L83-L98) Return type [`Bitrix24\SDK\Services\Entity\Item\Result\ItemsResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Item/Result/ItemsResult.php) ⚡️Batch methods: `Bitrix24\SDK\Services\Entity\Item\Service\Batch::get` Return type: `Generator` |
+|`entity`|[entity.item.delete](https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-delete.html)|Delete Storage Element|[`Bitrix24\SDK\Services\Entity\Item\Service\Item::delete`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Item/Service/Item.php#L112-L125) Return type [`Bitrix24\SDK\Core\Result\DeletedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/DeletedItemResult.php) ⚡️Batch methods: `Bitrix24\SDK\Services\Entity\Item\Service\Batch::delete` Return type: `Generator` |
+|`entity`|[entity.item.update](https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-update.html)|Update Storage Item|[`Bitrix24\SDK\Services\Entity\Item\Service\Item::update`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Entity/Item/Service/Item.php#L139-L154) Return type [`Bitrix24\SDK\Core\Result\UpdatedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/UpdatedItemResult.php) ⚡️Batch methods: `Bitrix24\SDK\Services\Entity\Item\Service\Batch::update` Return type: `Generator` |
|`catalog`|[catalog.catalog.get](https://training.bitrix24.com/rest_help/catalog/catalog/catalog_catalog_get.php)|The method gets field values of commercial catalog by ID.|[`Bitrix24\SDK\Services\Catalog\Catalog\Service\Catalog::get`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Catalog/Catalog/Service/Catalog.php#L41-L44) Return type [`Bitrix24\SDK\Services\Catalog\Catalog\Result\CatalogResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Catalog/Catalog/Result/CatalogResult.php)|
|`catalog`|[catalog.catalog.list](https://training.bitrix24.com/rest_help/catalog/catalog/catalog_catalog_list.php)|The method gets field value of commercial catalog product list|[`Bitrix24\SDK\Services\Catalog\Catalog\Service\Catalog::list`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Catalog/Catalog/Service/Catalog.php#L58-L66) Return type [`Bitrix24\SDK\Services\Catalog\Catalog\Result\CatalogsResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Catalog/Catalog/Result/CatalogsResult.php)|
|`catalog`|[catalog.catalog.getFields](https://training.bitrix24.com/rest_help/catalog/catalog/catalog_catalog_getfields.php)|Retrieves the fields for the catalog.|[`Bitrix24\SDK\Services\Catalog\Catalog\Service\Catalog::fields`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Catalog/Catalog/Service/Catalog.php#L81-L84) Return type [`Bitrix24\SDK\Core\Result\FieldsResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/FieldsResult.php)|
@@ -160,12 +169,12 @@
|`bizproc`|[bizproc.task.complete](https://training.bitrix24.com/rest_help/workflows/workflows_tasks/bizproc_task_complete.php)|Complete workflow task|[`Bitrix24\SDK\Services\Workflows\Task\Service\Task::complete`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Workflows/Task/Service/Task.php#L63-L71) Return type [`Bitrix24\SDK\Services\Workflows\Task\Result\WorkflowTaskCompleteResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Workflows/Task/Result/WorkflowTaskCompleteResult.php)|
|`bizproc`|[bizproc.task.list](https://training.bitrix24.com/rest_help/workflows/workflows_tasks/bizproc_task_list.php)|List of workflow tasks|[`Bitrix24\SDK\Services\Workflows\Task\Service\Task::list`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Workflows/Task/Service/Task.php#L133-L143) Return type [`Bitrix24\SDK\Services\Workflows\Task\Result\WorkflowTasksResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Workflows/Task/Result/WorkflowTasksResult.php)|
|`bizproc`|[bizproc.event.send](https://training.bitrix24.com/rest_help/workflows/workflows_events/bizproc_event_send.php)|returns output parameters to an activity. Parameters are specified in the activity description.|[`Bitrix24\SDK\Services\Workflows\Event\Service\Event::send`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Workflows/Event/Service/Event.php#L50-L64) Return type [`Bitrix24\SDK\Services\Workflows\Event\Result\EventSendResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Workflows/Event/Result/EventSendResult.php)|
-|`user`|[user.fields](https://training.bitrix24.com/rest_help/users/user_fields.php)|Get user entity fields|[`Bitrix24\SDK\Services\User\Service\User::fields`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L43-L46) Return type [`Bitrix24\SDK\Core\Result\FieldsResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/FieldsResult.php)|
-|`user`|[user.current](https://training.bitrix24.com/rest_help/users/user_current.php)|Get current user|[`Bitrix24\SDK\Services\User\Service\User::current`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L59-L62) Return type [`Bitrix24\SDK\Services\User\Result\UserResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Result/UserResult.php)|
-|`user`|[user.add](https://training.bitrix24.com/rest_help/users/user_add.php)|Invites a user. Available only for users with invitation permissions, usually an administrator. Sends a standard account invitation to the user on success.|[`Bitrix24\SDK\Services\User\Service\User::add`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L77-L92) Return type [`Bitrix24\SDK\Core\Result\AddedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/AddedItemResult.php)|
-|`user`|[user.get](https://training.bitrix24.com/rest_help/users/user_get.php)|Get user by id|[`Bitrix24\SDK\Services\User\Service\User::get`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L104-L116) Return type [`Bitrix24\SDK\Services\User\Result\UsersResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Result/UsersResult.php)|
-|`user`|[user.update](https://training.bitrix24.com/rest_help/users/user_get.php)|Updates user information. Available only for users with invitation permissions.|[`Bitrix24\SDK\Services\User\Service\User::update`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L129-L137) Return type [`Bitrix24\SDK\Core\Result\UpdatedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/UpdatedItemResult.php)|
-|`user`|[user.search](https://training.bitrix24.com/rest_help/users/user_search.php)|This method is used to retrieve list of users with expedited personal data search.|[`Bitrix24\SDK\Services\User\Service\User::search`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L151-L154) Return type [`Bitrix24\SDK\Services\User\Result\UsersResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Result/UsersResult.php)|
+|`user`|[user.fields](https://training.bitrix24.com/rest_help/users/user_fields.php)|Get user entity fields|[`Bitrix24\SDK\Services\User\Service\User::fields`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L50-L53) Return type [`Bitrix24\SDK\Core\Result\FieldsResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/FieldsResult.php)|
+|`user`|[user.current](https://training.bitrix24.com/rest_help/users/user_current.php)|Get current user|[`Bitrix24\SDK\Services\User\Service\User::current`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L66-L69) Return type [`Bitrix24\SDK\Services\User\Result\UserResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Result/UserResult.php)|
+|`user`|[user.add](https://training.bitrix24.com/rest_help/users/user_add.php)|Invites a user. Available only for users with invitation permissions, usually an administrator. Sends a standard account invitation to the user on success.|[`Bitrix24\SDK\Services\User\Service\User::add`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L84-L99) Return type [`Bitrix24\SDK\Core\Result\AddedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/AddedItemResult.php) ⚡️Batch methods: `Bitrix24\SDK\Services\User\Service\Batch::add` Return type: `Generator` |
+|`user`|[user.get](https://training.bitrix24.com/rest_help/users/user_get.php)|Get user by id|[`Bitrix24\SDK\Services\User\Service\User::get`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L111-L123) Return type [`Bitrix24\SDK\Services\User\Result\UsersResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Result/UsersResult.php) ⚡️Batch methods: `Bitrix24\SDK\Services\User\Service\Batch::get` Return type: `Generator` |
+|`user`|[user.update](https://training.bitrix24.com/rest_help/users/user_get.php)|Updates user information. Available only for users with invitation permissions.|[`Bitrix24\SDK\Services\User\Service\User::update`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L136-L144) Return type [`Bitrix24\SDK\Core\Result\UpdatedItemResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/UpdatedItemResult.php)|
+|`user`|[user.search](https://training.bitrix24.com/rest_help/users/user_search.php)|This method is used to retrieve list of users with expedited personal data search.|[`Bitrix24\SDK\Services\User\Service\User::search`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Service/User.php#L158-L161) Return type [`Bitrix24\SDK\Services\User\Result\UsersResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/User/Result/UsersResult.php)|
|`telephony`|[voximplant.user.deactivatePhone](https://training.bitrix24.com/rest_help/scope_telephony/voximplant/voximplant_user_deactivatePhone.php)|This method disables an indicator of SIP-phone availability. Method checks the availability of the access permissions to modify users.|[`Bitrix24\SDK\Services\Telephony\Voximplant\User\Service\User::deactivatePhone`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Telephony/Voximplant/User/Service/User.php#L52-L57) Return type [`Bitrix24\SDK\Core\Result\UserInterfaceDialogCallResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/UserInterfaceDialogCallResult.php)|
|`telephony`|[voximplant.user.activatePhone](https://training.bitrix24.com/rest_help/scope_telephony/voximplant/voximplant_user_activatePhone.php)|This method raises the event of SIP-phone availability for an employee. Method checks the availability of the access permissions to modify users.|[`Bitrix24\SDK\Services\Telephony\Voximplant\User\Service\User::activatePhone`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Telephony/Voximplant/User/Service/User.php#L73-L78) Return type [`Bitrix24\SDK\Core\Result\UserInterfaceDialogCallResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Core/Result/UserInterfaceDialogCallResult.php)|
|`telephony`|[voximplant.user.get](https://training.bitrix24.com/rest_help/scope_telephony/voximplant/voximplant_user_get.php)|This method returns user settings.|[`Bitrix24\SDK\Services\Telephony\Voximplant\User\Service\User::get`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Telephony/Voximplant/User/Service/User.php#L95-L102) Return type [`Bitrix24\SDK\Services\Telephony\Voximplant\User\Result\VoximplantUserSettingsResult`](https://github.com/bitrix24/b24phpsdk/blob/master/src/Services/Telephony/Voximplant/User/Result/VoximplantUserSettingsResult.php)|
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 9976fd86..6c2bcbcc 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -37,6 +37,9 @@
./tests/Integration/Services/Workflows/
+
+ ./tests/Integration/Services/Entity/
+
diff --git a/src/Core/Batch.php b/src/Core/Batch.php
index 39c23814..1dc7d46f 100644
--- a/src/Core/Batch.php
+++ b/src/Core/Batch.php
@@ -108,18 +108,21 @@ public function addEntityItems(string $apiMethod, array $entityItems): Generator
/**
* Delete entity items with batch call
*
- * @param array $entityItemId
*
* @return Generator|ResponseData[]
* @throws \Bitrix24\SDK\Core\Exceptions\BaseException
*/
- public function deleteEntityItems(string $apiMethod, array $entityItemId): Generator
- {
+ public function deleteEntityItems(
+ string $apiMethod,
+ array $entityItemId,
+ ?array $additionalParameters = null
+ ): Generator {
$this->logger->debug(
'deleteEntityItems.start',
[
'apiMethod' => $apiMethod,
'entityItems' => $entityItemId,
+ 'additionalParameters' => $additionalParameters,
]
);
@@ -137,7 +140,12 @@ public function deleteEntityItems(string $apiMethod, array $entityItemId): Gener
);
}
- $this->registerCommand($apiMethod, ['ID' => $itemId]);
+ $parameters = ['ID' => $itemId];
+ if ($apiMethod === 'entity.item.delete') {
+ $parameters = array_merge($parameters, $additionalParameters);
+ }
+
+ $this->registerCommand($apiMethod, $parameters);
}
foreach ($this->getTraversable(true) as $cnt => $deletedItemResult) {
@@ -204,18 +212,22 @@ public function updateEntityItems(string $apiMethod, array $entityItems): Genera
);
}
- if (!array_key_exists('fields', $entityItem)) {
- throw new InvalidArgumentException(
- sprintf('array key «fields» not found in entity item with id %s', $entityItemId)
- );
- }
+ if ($apiMethod !== 'entity.item.update') {
+ if (!array_key_exists('fields', $entityItem)) {
+ throw new InvalidArgumentException(
+ sprintf('array key «fields» not found in entity item with id %s', $entityItemId)
+ );
+ }
- $cmdArguments = [
- 'id' => $entityItemId,
- 'fields' => $entityItem['fields']
- ];
- if (array_key_exists('params', $entityItem)) {
- $cmdArguments['params'] = $entityItem['params'];
+ $cmdArguments = [
+ 'id' => $entityItemId,
+ 'fields' => $entityItem['fields']
+ ];
+ if (array_key_exists('params', $entityItem)) {
+ $cmdArguments['params'] = $entityItem['params'];
+ }
+ } else {
+ $cmdArguments = $entityItem;
}
$this->registerCommand($apiMethod, $cmdArguments);
@@ -397,7 +409,10 @@ public function getTraversableList(
}
$keyId = $isCrmItemsInBatch ? 'id' : 'ID';
-
+ $this->logger->debug('getTraversableList.getFirstPage', [
+ 'apiMethod' => $apiMethod,
+ 'params' => $params,
+ ]);
$response = $this->core->call($apiMethod, $params);
$totalElementsCount = $response->getResponseData()->getPagination()->getTotal();
$this->logger->debug('getTraversableList.totalElementsCount', [
@@ -453,8 +468,11 @@ public function getTraversableList(
// getLastElementId in filtered result
// todo wait new api version
if ($apiMethod !== 'user.get') {
+ $defaultOrderKey = 'order';
+ $orderKey = $apiMethod === 'entity.item.get' ? 'SORT' : $defaultOrderKey;
+
$params = [
- 'order' => $this->getReverseOrder($order),
+ $orderKey => $this->getReverseOrder($order),
'filter' => $filter,
'select' => $select,
'start' => 0,
@@ -474,6 +492,10 @@ public function getTraversableList(
$params = array_merge($params, $additionalParameters);
}
+ $this->logger->debug('getTraversableList.getLastPage', [
+ 'apiMethod' => $apiMethod,
+ 'params' => $params,
+ ]);
$lastResultPage = $this->core->call($apiMethod, $params);
if ($isCrmItemsInBatch) {
$lastElementId = (int)$lastResultPage->getResponseData()->getResult()['items'][0][$keyId];
@@ -481,18 +503,19 @@ public function getTraversableList(
$lastElementId = (int)$lastResultPage->getResponseData()->getResult()[0][$keyId];
}
- // reverse order if you need
+ $this->logger->debug('getTraversableList.lastElementsId', [
+ 'lastElementIdInFirstPage' => $lastElementIdInFirstPage,
+ 'lastElementIdInLastPage' => $lastElementId,
+ ]);
+
+
+ // reverse order if elements in batch ordered in DESC direction
if ($lastElementIdInFirstPage > $lastElementId) {
$tmp = $lastElementIdInFirstPage;
$lastElementIdInFirstPage = $lastElementId;
$lastElementId = $tmp;
}
- $this->logger->debug('getTraversableList.lastElementsId', [
- 'lastElementIdInFirstPage' => $lastElementIdInFirstPage,
- 'lastElementId' => $lastElementId,
- ]);
-
// register commands with updated filter
//more than one page in results - register list commands
++$lastElementIdInFirstPage;
diff --git a/src/Core/Contracts/BatchOperationsInterface.php b/src/Core/Contracts/BatchOperationsInterface.php
index e79b415c..76bd8938 100644
--- a/src/Core/Contracts/BatchOperationsInterface.php
+++ b/src/Core/Contracts/BatchOperationsInterface.php
@@ -76,7 +76,11 @@ public function addEntityItems(string $apiMethod, array $entityItems): Generator
* @return Generator|ResponseData[]
* @throws BaseException
*/
- public function deleteEntityItems(string $apiMethod, array $entityItemId): Generator;
+ public function deleteEntityItems(
+ string $apiMethod,
+ array $entityItemId,
+ ?array $additionalParameters = null
+ ): Generator;
/**
* Update entity items with batch call
diff --git a/src/Services/AbstractService.php b/src/Services/AbstractService.php
index ce1f9fad..756b8a61 100644
--- a/src/Services/AbstractService.php
+++ b/src/Services/AbstractService.php
@@ -55,4 +55,14 @@ protected function guardPositiveId(int $id): void
throw new InvalidArgumentException(sprintf('id must be positive, current value: %s', $id));
}
}
+
+ /**
+ * @throws InvalidArgumentException
+ */
+ protected function guardNonEmptyString(string $value, ?string $message = null): void
+ {
+ if (trim($value) === '') {
+ throw new InvalidArgumentException($message ?? 'value must be non empty');
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Services/CRM/Common/Result/AbstractCrmItem.php b/src/Services/CRM/Common/Result/AbstractCrmItem.php
index d756db80..cf130122 100644
--- a/src/Services/CRM/Common/Result/AbstractCrmItem.php
+++ b/src/Services/CRM/Common/Result/AbstractCrmItem.php
@@ -141,6 +141,8 @@ public function __get($offset)
case 'LAST_ACTIVITY_TIME':
case 'START_TIME':
case 'END_TIME':
+ case 'DATE_ACTIVE_FROM':
+ case 'DATE_ACTIVE_TO':
case 'TIMESTAMP_X':
if ($this->data[$offset] !== '') {
return CarbonImmutable::createFromFormat(DATE_ATOM, $this->data[$offset]);
diff --git a/src/Services/Entity/Entity/Result/AddedEntityResult.php b/src/Services/Entity/Entity/Result/AddedEntityResult.php
new file mode 100644
index 00000000..352a989a
--- /dev/null
+++ b/src/Services/Entity/Entity/Result/AddedEntityResult.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\Entity\Entity\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class AddedEntityResult extends AbstractResult
+{
+ /**
+ * @throws BaseException
+ */
+ public function isSuccess(): bool
+ {
+ return (bool)$this->getCoreResponse()->getResponseData()->getResult()[0];
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Entity/Result/EntitiesResult.php b/src/Services/Entity/Entity/Result/EntitiesResult.php
new file mode 100644
index 00000000..9b539a1e
--- /dev/null
+++ b/src/Services/Entity/Entity/Result/EntitiesResult.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\Entity\Entity\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class EntitiesResult extends AbstractResult
+{
+ /**
+ * @return EntityItemResult[]
+ * @throws BaseException
+ */
+ public function getEntities(): array
+ {
+ $res = [];
+ foreach ($this->getCoreResponse()->getResponseData()->getResult() as $item) {
+ $res[] = new EntityItemResult($item);
+ }
+
+ return $res;
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Entity/Result/EntityItemResult.php b/src/Services/Entity/Entity/Result/EntityItemResult.php
new file mode 100644
index 00000000..5a37c284
--- /dev/null
+++ b/src/Services/Entity/Entity/Result/EntityItemResult.php
@@ -0,0 +1,31 @@
+
+ *
+ * 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\Entity\Entity\Result;
+
+use Bitrix24\SDK\Services\Catalog\Common\ProductType;
+use Bitrix24\SDK\Services\Catalog\Common\Result\AbstractCatalogItem;
+use Bitrix24\SDK\Services\CRM\Common\Result\AbstractCrmItem;
+use Carbon\CarbonImmutable;
+use Money\Currency;
+use Money\Money;
+
+/**
+ * @property-read int $ID
+ * @property-read string $IBLOCK_TYPE_ID
+ * @property-read string $ENTITY
+ * @property-read string $NAME
+ */
+class EntityItemResult extends AbstractCrmItem
+{
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Entity/Result/EntityRightsResult.php b/src/Services/Entity/Entity/Result/EntityRightsResult.php
new file mode 100644
index 00000000..0aa69f55
--- /dev/null
+++ b/src/Services/Entity/Entity/Result/EntityRightsResult.php
@@ -0,0 +1,25 @@
+
+ *
+ * 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\Entity\Entity\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class EntityRightsResult extends AbstractResult
+{
+ public function getRights(): array
+ {
+ return $this->getCoreResponse()->getResponseData()->getResult();
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Entity/Service/Batch.php b/src/Services/Entity/Entity/Service/Batch.php
new file mode 100644
index 00000000..c30c83c6
--- /dev/null
+++ b/src/Services/Entity/Entity/Service/Batch.php
@@ -0,0 +1,31 @@
+
+ *
+ * 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\Entity\Entity\Service;
+
+use Bitrix24\SDK\Core\Contracts\BatchOperationsInterface;
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AddedItemBatchResult;
+use Bitrix24\SDK\Core\Result\DeletedItemBatchResult;
+use Bitrix24\SDK\Core\Result\UpdatedItemBatchResult;
+use Generator;
+use Psr\Log\LoggerInterface;
+
+readonly class Batch
+{
+ public function __construct(
+ protected BatchOperationsInterface $batch,
+ protected LoggerInterface $log)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Entity/Service/Entity.php b/src/Services/Entity/Entity/Service/Entity.php
new file mode 100644
index 00000000..d2501753
--- /dev/null
+++ b/src/Services/Entity/Entity/Service/Entity.php
@@ -0,0 +1,172 @@
+
+ *
+ * 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\Entity\Entity\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\InvalidArgumentException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Core\Result\DeletedItemResult;
+use Bitrix24\SDK\Core\Result\UpdatedItemResult;
+use Bitrix24\SDK\Services\AbstractService;
+use Bitrix24\SDK\Services\Entity\Entity\Result\AddedEntityResult;
+use Bitrix24\SDK\Services\Entity\Entity\Result\EntitiesResult;
+use Bitrix24\SDK\Services\Entity\Entity\Result\EntityRightsResult;
+use Psr\Log\LoggerInterface;
+
+#[ApiServiceMetadata(new Scope(['entity']))]
+class Entity extends AbstractService
+{
+ public function __construct(
+ public Batch $batch,
+ CoreInterface $core,
+ LoggerInterface $logger
+ ) {
+ parent::__construct($core, $logger);
+ }
+
+ /**
+ * Create Data Storage
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/entities/entity-add.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.add',
+ 'https://apidocs.bitrix24.com/api-reference/entity/entities/entity-add.html',
+ 'Create Data Storage'
+ )]
+ public function add(string $entity, string $name, array $access): AddedEntityResult
+ {
+ $this->guardNonEmptyString($entity, 'entity must be an non empty string');
+ $this->guardNonEmptyString($name, 'entity name must be an non empty string');
+
+ return new AddedEntityResult(
+ $this->core->call(
+ 'entity.add',
+ [
+ 'ENTITY' => $entity,
+ 'NAME' => $name,
+ 'ACCESS' => $access,
+ ]
+ )
+ );
+ }
+
+ /**
+ * Change Parameters
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/entities/entity-update.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.update',
+ 'https://apidocs.bitrix24.com/api-reference/entity/entities/entity-update.html',
+ 'Change Parameters'
+ )]
+ public function update(
+ string $entity,
+ ?string $name = null,
+ ?array $access = null,
+ ?string $updatedEntity = null
+ ): UpdatedItemResult {
+ $this->guardNonEmptyString($entity, 'entity must be an non empty string');
+
+ return new UpdatedItemResult(
+ $this->core->call(
+ 'entity.update',
+ [
+ 'ENTITY' => $entity,
+ 'NAME' => $name,
+ 'ACCESS' => $access,
+ 'ENTITY_NEW' => $updatedEntity,
+ ]
+ )
+ );
+ }
+
+ /**
+ * Delete Storage entity.delete
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/entities/entity-delete.html
+ * @throws TransportException
+ * @throws InvalidArgumentException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.delete',
+ 'https://apidocs.bitrix24.com/api-reference/entity/entities/entity-delete.html',
+ 'Delete Storage'
+ )]
+ public function delete(string $entity): DeletedItemResult
+ {
+ $this->guardNonEmptyString($entity, 'entity must be an non empty string');
+
+ return new DeletedItemResult(
+ $this->core->call(
+ 'entity.delete',
+ [
+ 'ENTITY' => $entity,
+ ]
+ )
+ );
+ }
+
+ /**
+ * Get Storage Parameters or List of All Storages
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/entities/entity-get.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.get',
+ 'https://apidocs.bitrix24.com/api-reference/entity/entities/entity-get.html',
+ 'Get Storage Parameters or List of All Storages'
+ )]
+ public function get(?string $entity = null): EntitiesResult
+ {
+ return new EntitiesResult($this->core->call('entity.get', ['ENTITY' => $entity]));
+ }
+
+ /**
+ * Get or Change Access Permissions
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/entities/entity-rights.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.rights',
+ 'https://apidocs.bitrix24.com/api-reference/entity/entities/entity-rights.html',
+ 'Get or Change Access Permissions'
+ )]
+ public function rights(?string $entity = null, ?array $access = null): EntityRightsResult
+ {
+ return new EntityRightsResult(
+ $this->core->call(
+ 'entity.rights',
+ [
+ 'ENTITY' => $entity,
+ 'ACCESS' => $access
+ ]
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/EntityServiceBuilder.php b/src/Services/Entity/EntityServiceBuilder.php
new file mode 100644
index 00000000..2bb6d5d3
--- /dev/null
+++ b/src/Services/Entity/EntityServiceBuilder.php
@@ -0,0 +1,49 @@
+
+ *
+ * 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\Entity;
+
+use Bitrix24\SDK\Attributes\ApiServiceBuilderMetadata;
+use Bitrix24\SDK\Core\Credentials\Scope;
+use Bitrix24\SDK\Services\AbstractServiceBuilder;
+use Bitrix24\SDK\Services\Entity;
+
+#[ApiServiceBuilderMetadata(new Scope(['entity']))]
+class EntityServiceBuilder extends AbstractServiceBuilder
+{
+ public function entity(): Entity\Entity\Service\Entity
+ {
+ if (!isset($this->serviceCache[__METHOD__])) {
+ $this->serviceCache[__METHOD__] = new Entity\Entity\Service\Entity(
+ new Entity\Entity\Service\Batch($this->batch, $this->log),
+ $this->core,
+ $this->log
+ );
+ }
+
+ return $this->serviceCache[__METHOD__];
+ }
+
+ public function item(): Entity\Item\Service\Item
+ {
+ if (!isset($this->serviceCache[__METHOD__])) {
+ $this->serviceCache[__METHOD__] = new Entity\Item\Service\Item(
+ new Entity\Item\Service\Batch($this->batch, $this->log),
+ $this->core,
+ $this->log
+ );
+ }
+
+ return $this->serviceCache[__METHOD__];
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Item/Result/ItemItemResult.php b/src/Services/Entity/Item/Result/ItemItemResult.php
new file mode 100644
index 00000000..2bbc949e
--- /dev/null
+++ b/src/Services/Entity/Item/Result/ItemItemResult.php
@@ -0,0 +1,40 @@
+
+ *
+ * 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\Entity\Item\Result;
+
+use Bitrix24\SDK\Services\CRM\Common\Result\AbstractCrmItem;
+use Carbon\CarbonImmutable;
+
+/**
+ * @property-read int $ID
+ * @property-read CarbonImmutable $TIMESTAMP_X
+ * @property-read int $MODIFIED_BY
+ * @property-read int $CREATED_BY
+ * @property-read int $SORT
+ * @property-read int|null $SECTION
+ * @property-read bool $ACTIVE
+ * @property-read CarbonImmutable $DATE_CREATE
+ * @property-read CarbonImmutable|null $DATE_ACTIVE_FROM
+ * @property-read CarbonImmutable|null $DATE_ACTIVE_TO
+ * @property-read string $NAME
+ * @property-read array|null $PREVIEW_PICTURE
+ * @property-read string|null $PREVIEW_TEXT
+ * @property-read string|null $DETAIL_TEXT
+ * @property-read string|null $CODE
+ * @property-read string $ENTITY
+ * @property-read array|null $DETAIL_PICTURE
+ */
+class ItemItemResult extends AbstractCrmItem
+{
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Item/Result/ItemsResult.php b/src/Services/Entity/Item/Result/ItemsResult.php
new file mode 100644
index 00000000..aeb09e79
--- /dev/null
+++ b/src/Services/Entity/Item/Result/ItemsResult.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\Entity\Item\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class ItemsResult extends AbstractResult
+{
+ /**
+ * @return ItemItemResult[]
+ * @throws BaseException
+ */
+ public function getItems(): array
+ {
+ $res = [];
+ foreach ($this->getCoreResponse()->getResponseData()->getResult() as $item) {
+ $res[] = new ItemItemResult($item);
+ }
+
+ return $res;
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Item/Service/Batch.php b/src/Services/Entity/Item/Service/Batch.php
new file mode 100644
index 00000000..132f0948
--- /dev/null
+++ b/src/Services/Entity/Item/Service/Batch.php
@@ -0,0 +1,116 @@
+
+ *
+ * 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\Entity\Item\Service;
+
+use Bitrix24\SDK\Attributes\ApiBatchMethodMetadata;
+use Bitrix24\SDK\Attributes\ApiBatchServiceMetadata;
+use Bitrix24\SDK\Core\Contracts\BatchOperationsInterface;
+use Bitrix24\SDK\Core\Credentials\Scope;
+use Bitrix24\SDK\Core\Result\AddedItemBatchResult;
+use Bitrix24\SDK\Core\Result\DeletedItemBatchResult;
+use Bitrix24\SDK\Services\Entity\Item\Result\ItemItemResult;
+use Generator;
+use Psr\Log\LoggerInterface;
+
+#[ApiBatchServiceMetadata(new Scope(['entity']))]
+readonly class Batch
+{
+ public function __construct(
+ protected BatchOperationsInterface $batch,
+ protected LoggerInterface $log
+ ) {
+ }
+
+ #[ApiBatchMethodMetadata(
+ 'entity.item.get',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-get.html',
+ 'Get the list of storage items in batch mode'
+ )]
+ public function get(string $entity, array $sort = [], array $filter = [], int $limit = null): Generator
+ {
+ foreach (
+ $this->batch->getTraversableList(
+ 'entity.item.get',
+ $sort,
+ $filter,
+ [],
+ $limit,
+ ['ENTITY' => $entity]
+ ) as $key => $value
+ ) {
+ yield $key => new ItemItemResult($value);
+ }
+ }
+
+ #[ApiBatchMethodMetadata(
+ 'entity.item.add',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-add.html',
+ 'Add in batch mode a list of storage elements'
+ )]
+ public function add(string $entity, array $items): Generator
+ {
+ $elements = [];
+ foreach ($items as $item) {
+ $elements[] = array_merge(
+ [
+ 'ENTITY' => $entity
+ ],
+ $item
+ );
+ }
+ foreach ($this->batch->addEntityItems('entity.item.add', $elements) as $key => $item) {
+ yield $key => new AddedItemBatchResult($item);
+ }
+ }
+
+ #[ApiBatchMethodMetadata(
+ 'entity.item.delete',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-delete.html',
+ 'Delete in batch mode a list of storage elements'
+ )]
+ public function delete(string $entity, array $itemIds): Generator
+ {
+ foreach (
+ $this->batch->deleteEntityItems(
+ 'entity.item.delete',
+ $itemIds,
+ ['ENTITY' => $entity]
+ ) as $key => $item
+ ) {
+ yield $key => new DeletedItemBatchResult($item);
+ }
+ }
+
+ #[ApiBatchMethodMetadata(
+ 'entity.item.update',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-update.html',
+ 'Update in batch mode a list of storage elements'
+ )]
+ public function update(string $entity, array $items): Generator
+ {
+ $dataForUpdate = [];
+ foreach ($items as $item) {
+ unset($item['ENTITY']);
+ $dataForUpdate[] = array_merge(
+ [
+ 'ENTITY' => $entity
+ ],
+ $item
+ );
+ }
+ foreach ($this->batch->updateEntityItems('entity.item.update', $dataForUpdate) as $key => $item) {
+ yield $key => new DeletedItemBatchResult($item);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Entity/Item/Service/Item.php b/src/Services/Entity/Item/Service/Item.php
new file mode 100644
index 00000000..8e77f3b0
--- /dev/null
+++ b/src/Services/Entity/Item/Service/Item.php
@@ -0,0 +1,155 @@
+
+ *
+ * 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\Entity\Item\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\AddedItemResult;
+use Bitrix24\SDK\Core\Result\DeletedItemResult;
+use Bitrix24\SDK\Core\Result\UpdatedItemResult;
+use Bitrix24\SDK\Services\AbstractService;
+use Bitrix24\SDK\Services\Entity\Item\Result\ItemsResult;
+use Psr\Log\LoggerInterface;
+
+#[ApiServiceMetadata(new Scope(['entity']))]
+class Item extends AbstractService
+{
+ public function __construct(
+ public Batch $batch,
+ CoreInterface $core,
+ LoggerInterface $logger
+ ) {
+ parent::__construct($core, $logger);
+ }
+
+ /**
+ * Add Storage Element
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-add.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.item.add',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-add.html',
+ 'Add Storage Element'
+ )]
+ public function add(string $entity, string $name, array $fields): AddedItemResult
+ {
+ $this->guardNonEmptyString($entity, 'entity must be an non empty string');
+ $this->guardNonEmptyString($name, 'entity name must be an non empty string');
+
+ return new AddedItemResult(
+ $this->core->call(
+ 'entity.item.add',
+ array_merge(
+ [
+ 'ENTITY' => $entity,
+ 'NAME' => $name,
+ ],
+ $fields
+ ),
+ )
+ );
+ }
+
+ /**
+ * Get the list of storage items
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-get.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.item.get',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-get.html',
+ 'Get the list of storage items'
+ )]
+ public function get(string $entity, array $sort = [], array $filter = [], int $startItem = 0): ItemsResult
+ {
+ $this->guardNonEmptyString($entity, 'entity must be an non empty string');
+
+ return new ItemsResult(
+ $this->core->call(
+ 'entity.item.get',
+ [
+ 'ENTITY' => $entity,
+ 'SORT' => $sort,
+ 'FILTER' => $filter,
+ 'START' => $startItem,
+ ],
+ )
+ );
+ }
+
+ /**
+ * Delete Storage Element
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-delete.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.item.delete',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-delete.html',
+ 'Delete Storage Element'
+ )]
+ public function delete(string $entity, int $itemId): DeletedItemResult
+ {
+ $this->guardNonEmptyString($entity, 'entity must be an non empty string');
+
+ return new DeletedItemResult(
+ $this->core->call(
+ 'entity.item.delete',
+ [
+ 'ENTITY' => $entity,
+ 'ID' => $itemId,
+ ],
+ )
+ );
+ }
+
+ /**
+ * Update Storage Item
+ *
+ * @see https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-update.html
+ * @throws TransportException
+ * @throws BaseException
+ */
+ #[ApiEndpointMetadata(
+ 'entity.item.update',
+ 'https://apidocs.bitrix24.com/api-reference/entity/items/entity-item-update.html',
+ 'Update Storage Item'
+ )]
+ public function update(string $entity, int $id, array $fields): UpdatedItemResult
+ {
+ $this->guardNonEmptyString($entity, 'entity must be an non empty string');
+ return new UpdatedItemResult(
+ $this->core->call(
+ 'entity.item.update',
+ array_merge(
+ [
+ 'ENTITY' => $entity,
+ 'ID' => $id,
+ ],
+ $fields
+ ),
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/Services/ServiceBuilder.php b/src/Services/ServiceBuilder.php
index 85415f1c..e80b9cfe 100644
--- a/src/Services/ServiceBuilder.php
+++ b/src/Services/ServiceBuilder.php
@@ -18,6 +18,7 @@
use Bitrix24\SDK\Core\Contracts\CoreInterface;
use Bitrix24\SDK\Services\Catalog\CatalogServiceBuilder;
use Bitrix24\SDK\Services\CRM\CRMServiceBuilder;
+use Bitrix24\SDK\Services\Entity\EntityServiceBuilder;
use Bitrix24\SDK\Services\IM\IMServiceBuilder;
use Bitrix24\SDK\Services\IMOpenLines\IMOpenLinesServiceBuilder;
use Bitrix24\SDK\Services\Main\MainServiceBuilder;
@@ -31,18 +32,37 @@
class ServiceBuilder extends AbstractServiceBuilder
{
public function __construct(
- public CoreInterface $core,
+ public CoreInterface $core,
protected BatchOperationsInterface $batch,
protected BulkItemsReaderInterface $bulkItemsReader,
- protected LoggerInterface $log)
- {
+ protected LoggerInterface $log
+ ) {
parent::__construct($core, $batch, $bulkItemsReader, $log);
}
+ public function getEntityScope(): EntityServiceBuilder
+ {
+ if (!isset($this->serviceCache[__METHOD__])) {
+ $this->serviceCache[__METHOD__] = new EntityServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
+ }
+
+ return $this->serviceCache[__METHOD__];
+ }
+
public function getCRMScope(): CRMServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new CRMServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new CRMServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -51,7 +71,12 @@ public function getCRMScope(): CRMServiceBuilder
public function getIMScope(): IMServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new IMServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new IMServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -60,7 +85,12 @@ public function getIMScope(): IMServiceBuilder
public function getIMOpenLinesScope(): IMOpenLinesServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new IMOpenLinesServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new IMOpenLinesServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -72,7 +102,12 @@ public function getIMOpenLinesScope(): IMOpenLinesServiceBuilder
public function getMainScope(): MainServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new MainServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new MainServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -81,7 +116,12 @@ public function getMainScope(): MainServiceBuilder
public function getUserConsentScope(): UserConsentServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new UserConsentServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new UserConsentServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -90,7 +130,12 @@ public function getUserConsentScope(): UserConsentServiceBuilder
public function getUserScope(): UserServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new UserServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new UserServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -102,7 +147,12 @@ public function getUserScope(): UserServiceBuilder
public function getPlacementScope(): PlacementServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new PlacementServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new PlacementServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -111,7 +161,12 @@ public function getPlacementScope(): PlacementServiceBuilder
public function getCatalogScope(): CatalogServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new CatalogServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new CatalogServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -120,7 +175,12 @@ public function getCatalogScope(): CatalogServiceBuilder
public function getBizProcScope(): WorkflowsServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new WorkflowsServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new WorkflowsServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
@@ -129,7 +189,12 @@ public function getBizProcScope(): WorkflowsServiceBuilder
public function getTelephonyScope(): TelephonyServiceBuilder
{
if (!isset($this->serviceCache[__METHOD__])) {
- $this->serviceCache[__METHOD__] = new TelephonyServiceBuilder($this->core, $this->batch, $this->bulkItemsReader, $this->log);
+ $this->serviceCache[__METHOD__] = new TelephonyServiceBuilder(
+ $this->core,
+ $this->batch,
+ $this->bulkItemsReader,
+ $this->log
+ );
}
return $this->serviceCache[__METHOD__];
diff --git a/tests/Integration/Core/BatchTest.php b/tests/Integration/Core/BatchTest.php
index 42c66ba0..99e5639d 100644
--- a/tests/Integration/Core/BatchTest.php
+++ b/tests/Integration/Core/BatchTest.php
@@ -14,13 +14,23 @@
namespace Bitrix24\SDK\Tests\Integration\Core;
use Bitrix24\SDK\Core\Batch;
+use Bitrix24\SDK\Core\Exceptions\BaseException;
use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
use Bitrix24\SDK\Services\ServiceBuilder;
use Bitrix24\SDK\Tests\Builders\DemoDataGenerator;
use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Stopwatch\Stopwatch;
+use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
+#[CoversClass(Batch::class)]
+#[CoversMethod(Batch::class, 'getTraversableList')]
+#[CoversMethod(Batch::class, 'addEntityItems')]
+#[CoversMethod(Batch::class, 'deleteEntityItems')]
class BatchTest extends TestCase
{
private Batch $batch;
@@ -32,13 +42,12 @@ class BatchTest extends TestCase
/**
* @return void
- * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
- * @throws \Bitrix24\SDK\Core\Exceptions\TransportException
+ * @throws BaseException
+ * @throws TransportException
* @throws \Exception
- * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
- * @covers \Bitrix24\SDK\Core\Batch::getTraversableList
- * @testdox Get traversable list items in batch mode with more than max batch page count elements
+ * @throws TransportExceptionInterface
*/
+ #[TestDox("Get traversable list items in batch mode with more than max batch page count elements")]
public function testGetTraversableListWithMoreThanMaxBatchPageCountWithoutLimit(): void
{
// prepare demo data
@@ -122,13 +131,12 @@ public function testGetTraversableListWithMoreThanMaxBatchPageCountWithoutLimit(
/**
* @return void
- * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
- * @throws \Bitrix24\SDK\Core\Exceptions\TransportException
+ * @throws BaseException
+ * @throws TransportException
* @throws \Exception
- * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
- * @covers \Bitrix24\SDK\Core\Batch::getTraversableList
- * @testdox Get traversable list items in batch mode with less than one page with limit elements
+ * @throws TransportExceptionInterface
*/
+ #[TestDox("Get traversable list items in batch mode with less than one page with limit elements")]
public function testGetTraversableListWithLessThanPageSizeWithLimit(): void
{
// prepare demo data
@@ -199,13 +207,12 @@ public function testGetTraversableListWithLessThanPageSizeWithLimit(): void
/**
* @return void
- * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
- * @throws \Bitrix24\SDK\Core\Exceptions\TransportException
+ * @throws BaseException
+ * @throws TransportException
* @throws \Exception
- * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
- * @covers \Bitrix24\SDK\Core\Batch::getTraversableList
- * @testdox Get traversable list items in batch mode with count more than one page without limit
+ * @throws TransportExceptionInterface
*/
+ #[TestDox("Get traversable list items in batch mode with count more than one page without limit")]
public function testGetTraversableListWithLessThanPageSizeWithoutLimit(): void
{
// prepare demo data
@@ -275,8 +282,8 @@ public function testGetTraversableListWithLessThanPageSizeWithoutLimit(): void
/**
* @return void
- * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
- * @throws \Bitrix24\SDK\Core\Exceptions\TransportException
+ * @throws BaseException
+ * @throws TransportException
* @throws \Exception
* @covers \Bitrix24\SDK\Core\Batch::addEntityItems
* @testdox Add items in batch mode
@@ -313,13 +320,11 @@ public function testBatchAddEntityItems(): void
/**
* @return void
- * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
- * @throws \Bitrix24\SDK\Core\Exceptions\TransportException
+ * @throws BaseException
+ * @throws TransportException
* @throws \Exception
- * @covers \Bitrix24\SDK\Core\Batch::addEntityItems
- * @covers \Bitrix24\SDK\Core\Batch::deleteEntityItems
- * @testdox Delete items in batch mode
*/
+ #[TestDox("Delete items in batch mode")]
public function testBatchDeleteEntityItems(): void
{
// prepare demo data
@@ -359,9 +364,9 @@ public function testBatchDeleteEntityItems(): void
/**
* @return void
- * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
- * @testdox Delete items in batch mode with wrong type of entity id
+ * @throws BaseException
*/
+ #[TestDox("Delete items in batch mode with wrong type of entity id")]
public function testBatchDeleteEntityItemsWithWrongTypeOfEntityId(): void
{
$this->expectException(InvalidArgumentException::class);
diff --git a/tests/Integration/Fabric.php b/tests/Integration/Fabric.php
index 238e4b9b..322888b0 100644
--- a/tests/Integration/Fabric.php
+++ b/tests/Integration/Fabric.php
@@ -49,7 +49,7 @@ public static function getServiceBuilder(bool $isNeedApplicationCredentials = fa
{
return new ServiceBuilder(
self::getCore($isNeedApplicationCredentials),
- self::getBatchService(),
+ self::getBatchService($isNeedApplicationCredentials),
self::getBulkItemsReader(),
self::getLogger()
);
@@ -65,7 +65,7 @@ public static function getOpenLineCode(): string
/**
* @return \Bitrix24\SDK\Core\Contracts\BulkItemsReaderInterface
- * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException
+ * @throws InvalidArgumentException
*/
public static function getBulkItemsReader(): BulkItemsReaderInterface
{
@@ -94,24 +94,28 @@ public static function getCore(bool $isNeedApplicationCredentials = false): Core
$credentialsProvider = ApplicationCredentialsProvider::buildProviderForLocalApplication();
- if ($credentialsProvider->isCredentialsAvailable()) {
- // register event handler for store new tokens
- $eventDispatcher = new EventDispatcher();
- $eventDispatcher->addListener(AuthTokenRenewedEvent::class, [
- $credentialsProvider,
- 'onAuthTokenRenewedEventListener'
- ]);
-
- $credentials = $credentialsProvider->getCredentials(
- ApplicationProfile::initFromArray($_ENV),
- $_ENV['BITRIX24_PHP_SDK_APPLICATION_DOMAIN_URL']);
-
- return (new CoreBuilder())
- ->withLogger(self::getLogger())
- ->withEventDispatcher($eventDispatcher)
- ->withCredentials($credentials)
- ->build();
+ if (!$credentialsProvider->isCredentialsAvailable()) {
+ throw new InvalidArgumentException(
+ 'Application credentials for integration tests are not available. Go to «tests/ApplicationBridge/» and run application bridge.'
+ );
}
+
+ // register event handler for store new tokens
+ $eventDispatcher = new EventDispatcher();
+ $eventDispatcher->addListener(AuthTokenRenewedEvent::class, [
+ $credentialsProvider,
+ 'onAuthTokenRenewedEventListener'
+ ]);
+
+ $credentials = $credentialsProvider->getCredentials(
+ ApplicationProfile::initFromArray($_ENV),
+ $_ENV['BITRIX24_PHP_SDK_APPLICATION_DOMAIN_URL']
+ );
+ return (new CoreBuilder())
+ ->withLogger(self::getLogger())
+ ->withEventDispatcher($eventDispatcher)
+ ->withCredentials($credentials)
+ ->build();
}
return $default;
}
@@ -130,11 +134,12 @@ public static function getLogger(): LoggerInterface
}
/**
- * @return \Bitrix24\SDK\Core\Batch
- * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException
+ * @param bool $isNeedApplicationCredentials
+ * @return Batch
+ * @throws InvalidArgumentException
*/
- public static function getBatchService(): Batch
+ public static function getBatchService(bool $isNeedApplicationCredentials = false): Batch
{
- return new Batch(self::getCore(), self::getLogger());
+ return new Batch(self::getCore($isNeedApplicationCredentials), self::getLogger());
}
}
\ No newline at end of file
diff --git a/tests/Integration/Services/Entity/Entity/Service/EntityTest.php b/tests/Integration/Services/Entity/Entity/Service/EntityTest.php
new file mode 100644
index 00000000..b78671ae
--- /dev/null
+++ b/tests/Integration/Services/Entity/Entity/Service/EntityTest.php
@@ -0,0 +1,128 @@
+
+ *
+ * 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\Entity\Entity\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Entity\Entity\Service\Entity;
+use Bitrix24\SDK\Services\ServiceBuilder;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\Attributes\TestDox;
+use Symfony\Component\Uid\Uuid;
+
+#[CoversClass(Entity::class)]
+#[CoversMethod(Entity::class, 'add')]
+#[CoversMethod(Entity::class, 'get')]
+#[CoversMethod(Entity::class, 'delete')]
+#[CoversMethod(Entity::class, 'rights')]
+#[CoversMethod(Entity::class, 'update')]
+class EntityTest extends TestCase
+{
+ protected ServiceBuilder $sb;
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[TestDox('test Entity::add')]
+ public function testAdd(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->assertTrue($this->sb->getEntityScope()->entity()->delete($entity)->isSuccess());
+ }
+
+ public function testUpdate(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+
+ $newName = Uuid::v7()->toRfc4122();
+
+ $this->assertTrue($this->sb->getEntityScope()->entity()->update($entity, $newName)->isSuccess());
+ $this->assertContains(
+ $newName,
+ array_column($this->sb->getEntityScope()->entity()->get()->getEntities(), 'NAME')
+ );
+
+ $this->assertTrue($this->sb->getEntityScope()->entity()->delete($entity)->isSuccess());
+ }
+
+ public function testGet(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $entities = $this->sb->getEntityScope()->entity()->get()->getEntities();
+ $this->assertContains($entity, array_column($entities, 'ENTITY'));
+
+
+ $this->assertTrue($this->sb->getEntityScope()->entity()->delete($entity)->isSuccess());
+ }
+
+ public function testRights(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->assertEquals('X', current($this->sb->getEntityScope()->entity()->rights($entity)->getRights()));
+ $this->assertTrue($this->sb->getEntityScope()->entity()->delete($entity)->isSuccess());
+ }
+
+ public function testDelete(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->assertTrue($this->sb->getEntityScope()->entity()->delete($entity)->isSuccess());
+
+ $entities = $this->sb->getEntityScope()->entity()->get()->getEntities();
+ $this->assertNotContains($entity, array_column($entities, 'ENTITY'));
+ }
+
+ protected function setUp(): void
+ {
+ $this->sb = Fabric::getServiceBuilder(true);
+ }
+}
\ No newline at end of file
diff --git a/tests/Integration/Services/Entity/Item/Service/BatchTest.php b/tests/Integration/Services/Entity/Item/Service/BatchTest.php
new file mode 100644
index 00000000..384ee611
--- /dev/null
+++ b/tests/Integration/Services/Entity/Item/Service/BatchTest.php
@@ -0,0 +1,239 @@
+
+ *
+ * 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\Entity\Item\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Entity\Item\Service\Batch;
+use Bitrix24\SDK\Services\Entity\Item\Service\Item;
+use Bitrix24\SDK\Services\ServiceBuilder;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Uid\Uuid;
+
+#[CoversClass(Batch::class)]
+#[CoversMethod(Batch::class, 'add')]
+#[CoversMethod(Batch::class, 'delete')]
+#[CoversMethod(Batch::class, 'get')]
+#[CoversMethod(Batch::class, 'update')]
+class BatchTest extends TestCase
+{
+ private ServiceBuilder $sb;
+ /**
+ * @var array
+ */
+ private array $entities;
+
+ protected function setUp(): void
+ {
+ $this->sb = Fabric::getServiceBuilder(true);
+ }
+
+ protected function tearDown(): void
+ {
+ foreach ($this->entities as $entity) {
+ $this->sb->getEntityScope()->entity()->delete($entity);
+ }
+ }
+
+ /**
+ * @throws TransportException
+ * @throws BaseException
+ */
+ public function testGet(): void
+ {
+ $elementsCount = 160;
+ $entity = (string)time();
+
+ $elements = [];
+ for ($i = 0; $i < $elementsCount; $i++) {
+ $elements[] = [
+ 'NAME' => 'name ' . Uuid::v7()->toRfc4122(),
+ ];
+ }
+
+ //create entity
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+ //add items in batch mode
+ $addedItemsIds = [];
+ foreach ($this->sb->getEntityScope()->item()->batch->add($entity, $elements) as $key => $result) {
+ $addedItemsIds[] = $result->getId();
+ }
+ $this->assertCount($elementsCount, $addedItemsIds);
+
+ // read elements in batch mode
+ $resultElements = [];
+ foreach ($this->sb->getEntityScope()->item()->batch->get($entity, [], []) as $key => $item) {
+ $resultElements[] = $item;
+ }
+
+ for ($i = 0; $i < $elementsCount; $i++) {
+ $this->assertArrayHasKey($i, $resultElements);
+ $this->assertEquals($addedItemsIds[$i], $resultElements[$i]->ID);
+ }
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testAdd(): void
+ {
+ $elementsCount = 160;
+ $entity = (string)time();
+
+ $elements = [];
+ for ($i = 0; $i < $elementsCount; $i++) {
+ $elements[] = [
+ 'NAME' => 'name ' . Uuid::v7()->toRfc4122(),
+ ];
+ }
+
+ //create entity
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+ //add items in batch mode
+ $addedItemsIds = [];
+ foreach ($this->sb->getEntityScope()->item()->batch->add($entity, $elements) as $result) {
+ $addedItemsIds[] = $result->getId();
+ }
+ $this->assertCount($elementsCount, $addedItemsIds);
+
+ // delete elements
+ foreach ($this->sb->getEntityScope()->item()->batch->delete($entity, $addedItemsIds) as $result) {
+ $this->assertTrue($result->isSuccess());
+ }
+ }
+
+ public function testDelete(): void
+ {
+ $elementsCount = 160;
+ $entity = (string)time();
+
+ $elements = [];
+ for ($i = 0; $i < $elementsCount; $i++) {
+ $elements[] = [
+ 'NAME' => 'name ' . Uuid::v7()->toRfc4122(),
+ ];
+ }
+
+ //create entity
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+ //add items in batch mode
+ $addedItemsIds = [];
+ foreach ($this->sb->getEntityScope()->item()->batch->add($entity, $elements) as $result) {
+ $addedItemsIds[] = $result->getId();
+ }
+ $this->assertCount($elementsCount, $addedItemsIds);
+
+ // delete elements
+ foreach ($this->sb->getEntityScope()->item()->batch->delete($entity, $addedItemsIds) as $result) {
+ $this->assertTrue($result->isSuccess());
+ }
+ $this->assertEquals([], $this->sb->getEntityScope()->item()->get($entity, [], ['ID' => $addedItemsIds])->getItems());
+ }
+
+ public function testUpdate(): void
+ {
+ $elementsCount = 160;
+ $entity = (string)time();
+
+ $elements = [];
+ for ($i = 0; $i < $elementsCount; $i++) {
+ $elements[] = [
+ 'NAME' => 'name ' . Uuid::v7()->toRfc4122(),
+ ];
+ }
+
+ //create entity
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+ //add items in batch mode
+ $addedItemsIds = [];
+ foreach ($this->sb->getEntityScope()->item()->batch->add($entity, $elements) as $result) {
+ $addedItemsIds[] = $result->getId();
+ }
+ $this->assertCount($elementsCount, $addedItemsIds);
+
+ // read elements in batch mode
+ $resultElements = [];
+ foreach ($this->sb->getEntityScope()->item()->batch->get($entity, [], []) as $key => $item) {
+ $resultElements[] = $item;
+ }
+
+ // prepare data for update
+ $modifiedElements = [];
+ foreach ($resultElements as $key => $item) {
+ $modifiedElements[] = [
+ 'id' => $item->ID,
+ 'NAME' => 'updated name ' . Uuid::v7()->toRfc4122(),
+ ];
+ }
+
+ // batch update elements
+ foreach ($this->sb->getEntityScope()->item()->batch->update($entity, $modifiedElements) as $result) {
+ $this->assertTrue($result->isSuccess());
+ }
+
+ // read elements in batch mode
+ $updatedElements = [];
+ foreach ($this->sb->getEntityScope()->item()->batch->get($entity, [], []) as $key => $item) {
+ $updatedElements[] = $item;
+ }
+
+ for ($i = 0; $i < $elementsCount; $i++) {
+ $this->assertEquals(
+ $modifiedElements[$i]['NAME'],
+ $updatedElements[$i]->NAME,
+ );
+ }
+
+ // delete elements
+ foreach ($this->sb->getEntityScope()->item()->batch->delete($entity, $addedItemsIds) as $result) {
+ $this->assertTrue($result->isSuccess());
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Integration/Services/Entity/Item/Service/ItemTest.php b/tests/Integration/Services/Entity/Item/Service/ItemTest.php
new file mode 100644
index 00000000..81ab125a
--- /dev/null
+++ b/tests/Integration/Services/Entity/Item/Service/ItemTest.php
@@ -0,0 +1,140 @@
+
+ *
+ * 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\Entity\Item\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Entity\Item\Service\Item;
+use Bitrix24\SDK\Services\ServiceBuilder;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Uid\Uuid;
+
+#[CoversClass(Item::class)]
+#[CoversMethod(Item::class, 'add')]
+#[CoversMethod(Item::class, 'get')]
+#[CoversMethod(Item::class, 'delete')]
+#[CoversMethod(Item::class, 'update')]
+class ItemTest extends TestCase
+{
+ private ServiceBuilder $sb;
+ private array $entities;
+
+ protected function setUp(): void
+ {
+ $this->sb = Fabric::getServiceBuilder(true);
+ }
+
+ protected function tearDown(): void
+ {
+ foreach ($this->entities as $entity) {
+ $this->sb->getEntityScope()->entity()->delete($entity);
+ }
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testAdd(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+
+ $name = Uuid::v7()->toRfc4122();
+ $itemId = $this->sb->getEntityScope()->item()->add($entity, $name, [])->getId();
+ $items = $this->sb->getEntityScope()->item()->get($entity, [], ['ID' => $itemId])->getItems();
+ $this->assertEquals($itemId, current(array_column($items, 'ID')));
+ $this->assertEquals($name, current(array_column($items, 'NAME')));
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testGet(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+ $name = Uuid::v7()->toRfc4122();
+ $itemId = $this->sb->getEntityScope()->item()->add($entity, $name, [])->getId();
+
+ $items = $this->sb->getEntityScope()->item()->get($entity, [], ['ID' => $itemId])->getItems();
+ $this->assertEquals($itemId, current(array_column($items, 'ID')));
+ }
+
+ public function testDelete(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+ $name = Uuid::v7()->toRfc4122();
+ $itemId = $this->sb->getEntityScope()->item()->add($entity, $name, [])->getId();
+
+ $this->assertTrue($this->sb->getEntityScope()->item()->delete($entity, $itemId)->isSuccess());
+ $this->assertEquals([], $this->sb->getEntityScope()->item()->get($entity, [], ['ID' => $itemId])->getItems());
+ }
+
+ public function testUpdate(): void
+ {
+ $entity = (string)time();
+ $this->assertTrue(
+ $this->sb->getEntityScope()->entity()->add(
+ $entity,
+ 'test entity',
+ []
+ )->isSuccess()
+ );
+ $this->entities[] = $entity;
+
+ $name = Uuid::v7()->toRfc4122();
+ $itemId = $this->sb->getEntityScope()->item()->add($entity, $name, [])->getId();
+
+ $items = $this->sb->getEntityScope()->item()->get($entity, [], ['ID' => $itemId])->getItems();
+ $this->assertEquals($itemId, current(array_column($items, 'ID')));
+
+ $newName = Uuid::v7()->toRfc4122();
+ $this->assertTrue($this->sb->getEntityScope()->item()->update(
+ $entity,$itemId, ['NAME'=>$newName]
+ )->isSuccess());
+
+ $items = $this->sb->getEntityScope()->item()->get($entity, [], ['ID' => $itemId])->getItems();
+ $this->assertEquals($newName, current(array_column($items, 'NAME')));
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/Stubs/NullBatch.php b/tests/Unit/Stubs/NullBatch.php
index 8b28d0c8..a16e24b8 100644
--- a/tests/Unit/Stubs/NullBatch.php
+++ b/tests/Unit/Stubs/NullBatch.php
@@ -27,8 +27,14 @@ class NullBatch implements BatchOperationsInterface
/**
* @inheritDoc
*/
- public function getTraversableList(string $apiMethod, array $order, array $filter, array $select, ?int $limit = null, ?array $additionalParameters = null): Generator
- {
+ public function getTraversableList(
+ string $apiMethod,
+ array $order,
+ array $filter,
+ array $select,
+ ?int $limit = null,
+ ?array $additionalParameters = null
+ ): Generator {
yield [];
}
@@ -50,15 +56,22 @@ public function getTraversableListWithCount(
*/
public function addEntityItems(string $apiMethod, array $entityItems): Generator
{
- yield new ResponseData([],new Time(0,0,0,0,0, new CarbonImmutable(),new CarbonImmutable(),0,),new Pagination());
+ yield new ResponseData([],
+ new Time(0, 0, 0, 0, 0, new CarbonImmutable(), new CarbonImmutable(), 0,),
+ new Pagination());
}
/**
* @inheritDoc
*/
- public function deleteEntityItems(string $apiMethod, array $entityItemId): Generator
- {
- yield new ResponseData([],new Time(0,0,0,0,0, new CarbonImmutable(),new CarbonImmutable(),0,),new Pagination());
+ public function deleteEntityItems(
+ string $apiMethod,
+ array $entityItemId,
+ ?array $additionalParameters = null
+ ): Generator {
+ yield new ResponseData([],
+ new Time(0, 0, 0, 0, 0, new CarbonImmutable(), new CarbonImmutable(), 0,),
+ new Pagination());
}
/**
@@ -66,6 +79,8 @@ public function deleteEntityItems(string $apiMethod, array $entityItemId): Gener
*/
public function updateEntityItems(string $apiMethod, array $entityItems): Generator
{
- yield new ResponseData([],new Time(0,0,0,0,0, new CarbonImmutable(),new CarbonImmutable(),0,),new Pagination());
+ yield new ResponseData([],
+ new Time(0, 0, 0, 0, 0, new CarbonImmutable(), new CarbonImmutable(), 0,),
+ new Pagination());
}
}
\ No newline at end of file