diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 0137cbe9..bb8210c7 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: php-version: - - "7.4" + - "8.1" dependencies: [ highest ] steps: @@ -36,7 +36,6 @@ jobs: ini-values: variables_order=EGPCS env: BITRIX24_PHP_SDK_PLAYGROUND_WEBHOOK: ${{ secrets.BITRIX24_PHP_SDK_PLAYGROUND_WEBHOOK }} - TEST2_ENV: 12345 - name: "Install dependencies" run: | diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index ea58e758..d2826503 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -13,8 +13,8 @@ jobs: fail-fast: false matrix: php-version: - - "7.4" - - "8.0" + - "8.1" + - "8.2" dependencies: - "lowest" - "highest" diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 725bb64a..e1512640 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -16,7 +16,8 @@ jobs: strategy: matrix: php-version: - - "7.4" + - "8.1" + - "8.2" dependencies: [ highest ] steps: diff --git a/.github/workflows/vendor-check.yml b/.github/workflows/vendor-check.yml index 802c6d45..beaa80f5 100644 --- a/.github/workflows/vendor-check.yml +++ b/.github/workflows/vendor-check.yml @@ -20,6 +20,7 @@ jobs: matrix: php-version: - "8.1" + - "8.2" dependencies: [ highest ] steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6286db57..ea66c7ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,16 +3,33 @@ ## 2.0-beta.1 — 10.11.2022 ### Added + * add `Symfony\Component\Uid\Uuid` requirements -* add contracts for bitrix24 applications based on bitrix24-php-sdk - `Bitrix24\SDK\Application\Contracts`, now added `Bitrix24Account` +* add contracts for bitrix24 applications based on bitrix24-php-sdk - `Bitrix24\SDK\Application\Contracts`, now added `Bitrix24Account` * add [service builder factory](https://github.com/mesilov/bitrix24-php-sdk/issues/328) +* add method `Bitrix24\SDK\Core\Credentials\Scope::initFromString` +* add method `Bitrix24\SDK\Application\ApplicationStatus::initFromString` +* ❗️add php 8.2 support ### Changed -* ❗️Batch interface `BatchInterface` [renamed](https://github.com/mesilov/bitrix24-php-sdk/issues/324) to `Bitrix24\SDK\Core\Contracts\BatchOperationsInterface` + +* ❗️Batch interface `BatchInterface` [renamed](https://github.com/mesilov/bitrix24-php-sdk/issues/324) + to `Bitrix24\SDK\Core\Contracts\BatchOperationsInterface` +* ❗`Bitrix24\SDK\Services\Telephony\Requests\Events` moved to separated namespaces: + * from `Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallInit` + to `Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallInit\OnVoximplantCallInit` + * from `Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallStart` + to `Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallStart\OnVoximplantCallStart` + * from `Bitrix24\SDK\Services\Telephony\Requests\Events\OnExternalCallStart` + to `Bitrix24\SDK\Services\Telephony\Requests\Events\OnExternalCallStart\OnExternalCallStart` + * from `Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallEnd` + to `Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallEnd\OnVoximplantCallEnd` ### Bugfix + * fix [typehint at ContactItemResult](https://github.com/mesilov/bitrix24-php-sdk/issues/320) * fix [return types in DealCategoryItemResult](https://github.com/mesilov/bitrix24-php-sdk/issues/322) +* fix [add auth node in telephony voximplant events requests](https://github.com/mesilov/bitrix24-php-sdk/issues/331) ### etc @@ -62,10 +79,10 @@ * method `Services\Main\Service::getAllMethods` marks as deprecated * method `Services\Main\Service::getMethodsByScope` marks as deprecated * ❗️fabric methods `Bitrix24\SDK\Core\Credentials` - renamed and now are [consistent](https://github.com/mesilov/bitrix24-php-sdk/issues/303): `createFromWebhook`, `createFromOAuth` + renamed and now are [consistent](https://github.com/mesilov/bitrix24-php-sdk/issues/303): `createFromWebhook`, `createFromOAuth` , `createFromPlacementRequest` * ❗️deleted [unused class](https://github.com/mesilov/bitrix24-php-sdk/issues/303) `Bitrix24\SDK\Core\Response\DTO\ResponseDataCollection` -* ❗️deleted [redundant class](https://github.com/mesilov/bitrix24-php-sdk/issues/303) `Bitrix24\SDK\Core\Response\DTO\Result` +* ❗️deleted [redundant class](https://github.com/mesilov/bitrix24-php-sdk/issues/303) `Bitrix24\SDK\Core\Response\DTO\Result` * ❗️deleted [method](https://github.com/mesilov/bitrix24-php-sdk/issues/303) `CoreBuilder::withWebhookUrl`, use method `CoreBuilder::withCredentials` diff --git a/composer.json b/composer.json index 82df0352..e2dc8095 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ } ], "require": { - "php": "8.1.*", + "php": "8.1.* || 8.2.*", "ext-json": "*", "ext-bcmath": "*", "ext-curl": "*", @@ -33,7 +33,7 @@ "symfony/event-dispatcher": "5.4.* || 6.*", "ramsey/uuid": "^4.2.3", "moneyphp/money": "3.* || 4.*", - "symfony/uid": "^6.0", + "symfony/uid": "6.*", "ext-intl": "*" }, "require-dev": { @@ -44,8 +44,7 @@ "phpstan/phpstan": "1.*", "phpunit/phpunit": "9.5.*", "symfony/stopwatch": "5.4.* || 6.*", - "roave/security-advisories": "dev-master", - "ext-intl": "*" + "roave/security-advisories": "dev-master" }, "autoload": { "psr-4": { diff --git a/src/Application/ApplicationStatus.php b/src/Application/ApplicationStatus.php index 54500ccf..fc65ebc4 100644 --- a/src/Application/ApplicationStatus.php +++ b/src/Application/ApplicationStatus.php @@ -20,7 +20,7 @@ class ApplicationStatus /** * @param string $statusShortCode * - * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException + * @throws InvalidArgumentException */ public function __construct(string $statusShortCode) { @@ -107,13 +107,24 @@ public function getStatusCode(): string } /** - * @param \Symfony\Component\HttpFoundation\Request $request + * @param Request $request * * @return self - * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException + * @throws InvalidArgumentException */ public static function initFromRequest(Request $request): self { return new self($request->request->getAlpha('status')); } + + /** + * @param string $shortStatusCode + * + * @return self + * @throws InvalidArgumentException + */ + public static function initFromString(string $shortStatusCode): self + { + return new self($shortStatusCode); + } } \ No newline at end of file diff --git a/src/Core/Credentials/Scope.php b/src/Core/Credentials/Scope.php index 123eb06c..6e64d1aa 100644 --- a/src/Core/Credentials/Scope.php +++ b/src/Core/Credentials/Scope.php @@ -100,4 +100,12 @@ public function getScopeCodes(): array { return $this->currentScope; } + + /** + * @throws \Bitrix24\SDK\Core\Exceptions\UnknownScopeCodeException + */ + public static function initFromString(string $scope): self + { + return new self(str_replace(' ', '', explode(',', $scope))); + } } \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/Auth.php b/src/Services/Telephony/Requests/Events/Auth.php new file mode 100644 index 00000000..a0a3dadd --- /dev/null +++ b/src/Services/Telephony/Requests/Events/Auth.php @@ -0,0 +1,41 @@ + Scope::initFromString((string)$this->data[$offset]), + 'status' => ApplicationStatus::initFromString((string)$this->data[$offset]), + 'user_id', 'expires_in', 'expires' => (int)$this->data[$offset], + default => parent::__get($offset), + }; + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnExternalCallStart.php b/src/Services/Telephony/Requests/Events/OnExternalCallStart.php deleted file mode 100644 index 6361a3c1..00000000 --- a/src/Services/Telephony/Requests/Events/OnExternalCallStart.php +++ /dev/null @@ -1,95 +0,0 @@ -eventPayload['data']['USER_ID']; - } - - /** - * @return string Outbound call ID. - */ - public function getPhoneNumber(): string - { - return $this->eventPayload['data']['PHONE_NUMBER']; - } - - /** - * @return string - */ - public function getPhoneNumberInternational(): string - { - return $this->eventPayload['data']['PHONE_NUMBER_INTERNATIONAL']; - } - - /** - * @return \Bitrix24\SDK\Services\Telephony\Common\CrmEntityType - * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException - */ - public function getCrmEntityType(): CrmEntityType - { - return CrmEntityType::initByCode($this->eventPayload['data']['CRM_ENTITY_TYPE']); - } - - /** - * @return int The CRM object ID, which type is specified in CRM_ENTITY_TYPE. - */ - public function getCrmEntityId(): int - { - return (int)$this->eventPayload['data']['CRM_ENTITY_ID']; - } - - /** - * @return int Call list ID, if the call is made from the call list. - */ - public function getCallListId(): int - { - return (int)$this->eventPayload['data']['CALL_LIST_ID']; - } - - /** - * @return string External line number, via which the the call is requested. - */ - public function getLineNumber(): string - { - return $this->eventPayload['data']['LINE_NUMBER']; - } - - /** - * @return string Call ID from the telephony.externalcall.register method. - */ - public function getCallId(): string - { - return $this->eventPayload['data']['CALL_ID']; - } - - /** - * @return string - */ - public function getExtension(): string - { - return $this->eventPayload['data']['EXTENSION']; - } - - /** - * @return bool Defines call as initiated from the mobile app. - */ - public function isMobile(): bool - { - return !($this->eventPayload['data']['IS_MOBILE'] === '0'); - } -} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnExternalCallStart/CallData.php b/src/Services/Telephony/Requests/Events/OnExternalCallStart/CallData.php new file mode 100644 index 00000000..6a876d0d --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnExternalCallStart/CallData.php @@ -0,0 +1,42 @@ + (int)$this->data[$offset] !== 0, + 'CALL_TYPE' => CallType::initByTypeCode((int)$this->data[$offset]), + 'CRM_ENTITY_TYPE' => (string)$this->data[$offset], + 'REST_APP_ID', 'CALL_LIST_ID', 'CRM_CREATED_LEAD', 'CRM_ENTITY_ID', 'USER_ID' => (int)$this->data[$offset], + default => parent::__get($offset), + }; + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnExternalCallStart/OnExternalCallStart.php b/src/Services/Telephony/Requests/Events/OnExternalCallStart/OnExternalCallStart.php new file mode 100644 index 00000000..a15f1318 --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnExternalCallStart/OnExternalCallStart.php @@ -0,0 +1,30 @@ +eventPayload['data']); + } + + /** + * @return \Bitrix24\SDK\Services\Telephony\Requests\Events\Auth + */ + public function getAuth(): Auth + { + return new Auth($this->eventPayload['auth']); + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd.php deleted file mode 100644 index ff0229f4..00000000 --- a/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd.php +++ /dev/null @@ -1,114 +0,0 @@ -eventPayload['data']['CALL_ID']; - } - - /** - * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException - */ - public function getCallType(): CallType - { - return CallType::initByTypeCode((int)$this->eventPayload['data']['CALL_TYPE']); - } - - /** - * @return string Number used by the subscriber to make a call (if call type is: 2 – Inbound) or number called by the operator (if call type is: 1 – Outbound). - */ - public function getPhoneNumber(): string - { - return $this->eventPayload['data']['PHONE_NUMBER']; - } - - /** - * @return string Number receiving the call (if call type is: 2 – Inbound) or number from which the call was made (if call type is: 1 – Outbound). - */ - public function getPortalNumber(): string - { - return $this->eventPayload['data']['PORTAL_NUMBER']; - } - - /** - * @return int Responding operator ID (if call type is: 2 – Inbound) or identifier of the calling operator (if call type is: 1 – Outbound). - */ - public function getPortalUserId(): int - { - return (int)$this->eventPayload['data']['PORTAL_USER_ID']; - } - - /** - * @return int Call duration. - */ - public function getCallDuration(): int - { - return (int)$this->eventPayload['data']['CALL_DURATION']; - } - - /** - * @return \DateTimeImmutable Date in ISO format. - */ - public function getCallStartDate(): DateTimeImmutable - { - return DateTimeImmutable::createFromFormat(DATE_ATOM, $this->eventPayload['data']['CALL_START_DATE']); - } - - /** - * @return \Money\Money Call cost. - */ - public function getCost(): Money - { - if ($this->eventPayload['COST'] === '') { - return new Money(0, new Currency($this->eventPayload['data']['COST_CURRENCY'])); - } - - return (new DecimalMoneyParser(new ISOCurrencies()))->parse( - $this->eventPayload['data']['COST'], - $this->eventPayload['data']['COST_CURRENCY'] - ); - } - - /** - * @return int Call code (See Call Code Table). - */ - public function getCallFailedCode(): int - { - return (int)$this->eventPayload['data']['CALL_FAILED_CODE']; - } - - /** - * @return string Call code textual description (Latin letters). - */ - public function getCallFailedReason(): string - { - return $this->eventPayload['data']['CALL_FAILED_REASON']; - } - - /** - * @return int - */ - public function getCrmActivityId(): int - { - return (int)$this->eventPayload['data']['CRM_ACTIVITY_ID']; - } -} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd/CallData.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd/CallData.php new file mode 100644 index 00000000..b8ddfbd0 --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd/CallData.php @@ -0,0 +1,68 @@ +data[$offset]; + case 'CALL_START_DATE': + return new \DateTimeImmutable((string)$this->data[$offset]); + case 'CALL_TYPE': + return CallType::initByTypeCode((int)$this->data[$offset]); + case 'CALL_DURATION': + case 'CALL_FAILED_CODE': + case 'CRM_ACTIVITY_ID': + case 'PORTAL_USER_ID': + return (int)$this->data[$offset]; + case 'COST_CURRENCY': + return new Currency($this->data[$offset]); + case 'COST': + if ($this->data[$offset] === null) { + return new Money(0, new Currency($this->data['COST_CURRENCY'])); + } + + return (new DecimalMoneyParser(new ISOCurrencies()))->parse( + $this->data[$offset], + new Currency($this->data['COST_CURRENCY']) + ); + default: + return parent::__get($offset); + } + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd/OnVoximplantCallEnd.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd/OnVoximplantCallEnd.php new file mode 100644 index 00000000..1b0697ad --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnVoximplantCallEnd/OnVoximplantCallEnd.php @@ -0,0 +1,35 @@ +eventPayload['auth']); + } + + /** + * @return \Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallEnd\CallData + */ + public function getCallData(): CallData + { + return new CallData($this->eventPayload['data']); + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallInit.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallInit.php deleted file mode 100644 index 753f2d67..00000000 --- a/src/Services/Telephony/Requests/Events/OnVoximplantCallInit.php +++ /dev/null @@ -1,54 +0,0 @@ -eventPayload['data']['CALL_ID']; - } - - /** - * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException - */ - public function getCallType(): CallType - { - return CallType::initByTypeCode((int)$this->eventPayload['data']['CALL_TYPE']); - } - - /** - * @return string Line ID (numeric for leased PBX, regXXX for cloud hosted PBX, and sipXXX for office PBX). - */ - public function getAccountSearchId(): string - { - return $this->eventPayload['data']['ACCOUNT_SEARCH_ID']; - } - - /** - * @return string Number called by the operator (if call type is: 1 – Outbound) or number called by the subscriber (if call type is: 2 – Inbound). - */ - public function getPhoneNumber(): string - { - return $this->eventPayload['data']['PHONE_NUMBER']; - } - - /** - * @return string Line identifier (if call type is: 1 – Outbound) or telephone number used to make a call to the portal (if call type is: 2 – Inbound). - */ - public function getCallerId(): string - { - return $this->eventPayload['data']['CALLER_ID']; - } -} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallInit/CallData.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallInit/CallData.php new file mode 100644 index 00000000..383db9bb --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnVoximplantCallInit/CallData.php @@ -0,0 +1,35 @@ + CallType::initByTypeCode((int)$this->data[$offset]), + 'REST_APP_ID' => (int)$this->data[$offset], + default => parent::__get($offset), + }; + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallInit/OnVoximplantCallInit.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallInit/OnVoximplantCallInit.php new file mode 100644 index 00000000..2e0c2889 --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnVoximplantCallInit/OnVoximplantCallInit.php @@ -0,0 +1,32 @@ +eventPayload['auth']); + } + + /** + * @return \Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallInit\CallData + */ + public function getCallData(): CallData + { + return new CallData($this->eventPayload['data']); + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallStart.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallStart.php deleted file mode 100644 index 11df4201..00000000 --- a/src/Services/Telephony/Requests/Events/OnVoximplantCallStart.php +++ /dev/null @@ -1,29 +0,0 @@ -eventPayload['data']['CALL_ID']; - } - - /** - * @return int Identifier of the user who responded the call. - */ - public function getUserId(): int - { - return (int)$this->eventPayload['data']['USER_ID']; - } -} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallStart/CallData.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallStart/CallData.php new file mode 100644 index 00000000..86a08f01 --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnVoximplantCallStart/CallData.php @@ -0,0 +1,28 @@ + (int)$this->data[$offset], + default => parent::__get($offset), + }; + } +} \ No newline at end of file diff --git a/src/Services/Telephony/Requests/Events/OnVoximplantCallStart/OnVoximplantCallStart.php b/src/Services/Telephony/Requests/Events/OnVoximplantCallStart/OnVoximplantCallStart.php new file mode 100644 index 00000000..6138ac4f --- /dev/null +++ b/src/Services/Telephony/Requests/Events/OnVoximplantCallStart/OnVoximplantCallStart.php @@ -0,0 +1,29 @@ +eventPayload['auth']); + } + /** + * @return \Bitrix24\SDK\Services\Telephony\Requests\Events\OnVoximplantCallStart\CallData + */ + public function getCallData(): CallData + { + return new CallData($this->eventPayload['data']); + } +} \ No newline at end of file diff --git a/tests/Unit/Application/ApplicationStatusTest.php b/tests/Unit/Application/ApplicationStatusTest.php index cdf70fb6..d768b0e4 100644 --- a/tests/Unit/Application/ApplicationStatusTest.php +++ b/tests/Unit/Application/ApplicationStatusTest.php @@ -19,7 +19,7 @@ class ApplicationStatusTest extends TestCase * @dataProvider statusDataProvider * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException */ - public function testGetStatusCode(string $shortCode, string $longCode) + public function testGetStatusCode(string $shortCode, string $longCode): void { $this->assertEquals( $longCode, @@ -36,6 +36,16 @@ public function testInvalidStatusCode(): void new ApplicationStatus('foo'); } + /** + * @return void + * @throws \Bitrix24\SDK\Core\Exceptions\InvalidArgumentException + * @covers \Bitrix24\SDK\Application\ApplicationStatus::initFromString + */ + public function testInitFromString(): void + { + $this->assertTrue(ApplicationStatus::initFromString('F')->isFree()); + } + /** * @return \Generator */ diff --git a/tests/Unit/Core/Credentials/ScopeTest.php b/tests/Unit/Core/Credentials/ScopeTest.php index 5ffd952d..d7d37b32 100644 --- a/tests/Unit/Core/Credentials/ScopeTest.php +++ b/tests/Unit/Core/Credentials/ScopeTest.php @@ -82,4 +82,16 @@ public function testWrongScopeCode(): void $this->assertEquals(['crm', 'call', 'im'], $scope->getScopeCodes()); } + + /** + * @return void + * @throws \Bitrix24\SDK\Core\Exceptions\UnknownScopeCodeException + * @covers \Bitrix24\SDK\Core\Credentials\Scope::initFromString + * @testdox Test init Scope from string + */ + public function testInitFromString(): void + { + $scope = Scope::initFromString('crm,telephony,call,user_basic,placement,im,imopenlines'); + $this->assertEquals(['crm', 'telephony', 'call', 'user_basic', 'placement', 'im', 'imopenlines'], $scope->getScopeCodes()); + } }