diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1754c28
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,8 @@
+/.github export-ignore
+/build export-ignore
+/tests export-ignore
+/tests-resources export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+
+*.php diff=php
\ No newline at end of file
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..9385edd
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,56 @@
+name: Tests
+
+on:
+ push:
+ branches:
+ - main
+ - master
+ pull_request:
+ branches:
+ - main
+ - master
+
+jobs:
+ tests:
+ name: PHP ${{ matrix.php }}
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ php:
+ - 7.0
+ - 7.1
+ - 7.2
+ - 7.3
+ - 7.4
+ - 8.0
+ - 8.1
+ - 8.2
+ - 8.3
+ - 8.4
+ - 8.5
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+
+ - id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('composer.json') }}
+
+ - name: Install dependencies
+ run: composer update --prefer-dist --no-interaction
+
+ - name: Audit dependencies
+ run: composer audit || true
+
+ - name: Running unit tests
+ run: php vendor/bin/phpunit --configuration tests-resources/phpunit.dist.xml --testsuite unit
diff --git a/.gitignore b/.gitignore
index 2a0d621..130e21e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
/tests-resources/config/config.yml
+/tests-resources/phpunit.xml
/vendor
/composer.lock
-/phpunit.xml
-/composer.phar
+.phpunit.result.cache
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1edde00..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: php
-php:
-- '7.0'
-- '7.1'
-- '7.2'
-- '7.3'
-- '7.4'
-before_script:
-- composer self-update
-- composer install
-script: ./vendor/bin/phpunit --configuration phpunit.dist.xml --testsuite unit
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b74274..190eb08 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,13 +3,84 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
-## [Unreleased]
+## [3.0.13] - 2026-01-12
+### Added
+- PHP-8.5 support
+
+## [3.0.12] - 2025-07-03
+### Added
+- PHP-8.4 support
+
+## [3.0.11] - 2024-03-27
+### Added
+- service url scheme and host validation
+- service url with port support
+
+### Changed
+- PSR-18 HTTP client related exceptions namespace moved
+
+## [3.0.10] - 2024-01-16
+### Added
+- PHP-8.3 support
+- `SendSmsBag::$timeRestriction` optional parameter
+- `SendSmssBag::$timeRestriction` optional parameter
+- `SendSmsToGroupBag::$timeRestriction` optional parameter
+- `ScheduleSmsBag::$timeRestriction` optional parameter
+- `ScheduleSmssBag::$timeRestriction` optional parameter
+- `ScheduleSmsToGroupBag::$timeRestriction` optional parameter
+### Fixed
+- sending/scheduling smses in large amount
+
+## [3.0.9] - 2024-01-09
+### Fixed
+- expired MFA code verification
+
+## [3.0.8] - 2023-10-18
+### Added
+- `psr/http-message` v2 support
+
+## [3.0.7] - 2022-11-21
+### Fixed
+- dynamic property deprecations
+
+## [3.0.6] - 2022-03-28
+### Fixed
+- HTTP headers parsing, PSR-7 compliant
+
+## [3.0.5] - 2022-03-23
+### Fixed
+- HTTP headers parsing, `HttpClient` issue
+
+## [3.0.4] - 2022-01-17
+### Added
+- `psr/log` v2, v3 support
+
+## [3.0.3] - 2021-07-21
+### Fixed
+- Guzzle PSR7 incompatible URI paths, `The path of a URI with an authority must start with a slash "/" or be empty`
+
+## [3.0.2] - 2021-01-29
+### Added
+- PHP-8 support
+
+## [3.0.1] - 2020-12-08
+### Changed
+- Guzzle HTTP helpers marked as optional dependency
+
+## [3.0.0] - 2020-11-19
+### Added
+- PSR-18 support
+- PSR-17 support
+
### Changed
- utf-8 as default encoding
- `CreateContactBag::withPhone` marked as deprecated
- `PingFeature::ping` returns authorization and service availability status
### Removed
+- built-in proxy support - use own implementation
+- concrete HTTP client dependency (Guzzle 6)
+- `PushFeature`
- `SendSmsBag::setIdx`
- `DeleteSmsBag`
- `FindSendernamesBag`
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 1704bc8..0000000
--- a/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-.PHONY: help
-
-help:
- @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
-
-.DEFAULT_GOAL := help
-
-prepare: ## load dependencies
- docker-compose run -T php /usr/bin/composer update
-
-test: prepare ## run test
- docker-compose run -T php php vendor/bin/phing -f build.xml test
-
-test-suite: prepare ## run test against suite, ex: make test-suite SUITE="unit"
- docker-compose run -T php php vendor/bin/phing -f build.xml test -Dsuite=$(SUITE)
\ No newline at end of file
diff --git a/README.md b/README.md
index b5482c5..95ef8f3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# SMSAPI PHP Client
-[](https://travis-ci.org/smsapi/smsapi-php-client)
+[](https://github.com/smsapi/smsapi-php-client/actions/workflows/tests.yml)
[](https://packagist.org/packages/smsapi/php-client)
[](https://packagist.org/packages/smsapi/php-client)
[](https://packagist.org/packages/smsapi/php-client)
@@ -23,144 +23,181 @@ Execute: `composer require smsapi/php-client`
Depending on which of SMSAPI service your account is, you should pick it calling one of a method from examples below:
-### How to use *SMSAPI.COM* client?
+### PSR-17 and PSR-18
+
+Starting from version 3, SMSAPI PHP Client supports PSR-17 and PSR-18 compliant HTTP clients.
+That way this library is independent of client of your choice.
+You have to provide HTTP client, request factory and stream factory to use our library.
+
+For your convenience we provide an adapter for Curl. To use it you have to enable PHP curl extension and install some HTTP helpers:
+
+```
+composer require guzzlehttp/psr7:^1
+```
+
+Example below shows how to make use of that adapter (pay attention to namespace *Smsapi\Client\Curl*):
```php
smsapiComService($apiToken);
+$client = new SmsapiHttpClient($httpClient, $requestFactory, $streamFactory);
```
-### How to use *SMSAPI.PL* client?
+All following examples consider you have client well-defined in `client.php` file.
+
+### How to use *SMSAPI.COM* service?
```php
smsapiPlService($apiToken);
+$service = $client->smsapiComService($apiToken);
```
-All following examples consider you have a account on SMSAPI.COM.
-
-## How to use a custom URI?
+### How to use *SMSAPI.PL* service?
```php
smsapiComServiceWithUri($apiToken, $uri);
-```
-
-## How to use service business features?
+$service = $client->smsapiPlService($apiToken);
+```
-### How to use ping feature?
+### How to use *SMSAPI.SE* or *SMSAPI.BG* services?
```php
smsapiComService($apiToken);
-$result = $service->pingFeature()
- ->ping();
-
-if ($result->authorized) {
- echo 'Authorized';
-} else {
- echo 'Not authorized';
-}
+$service = $client->smsapiComServiceWithUri($apiToken, $uri);
```
-### How to send a SMS?
+## How to use service business features?
+
+All following examples consider you have an account on SMSAPI.COM and service has been setup in `service.php` file.
+
+### How to use ping feature?
```php
pingFeature()
+ ->ping();
-$service = (new SmsapiHttpClient())
- ->smsapiComService($apiToken);
-$service->smsFeature()
- ->sendSms($sms);
+if ($result->authorized) {
+ echo 'Authorized';
+} else {
+ echo 'Not authorized';
+}
```
-### How to send a SMS with optional from field?
+### How to send a SMS?
```php
from = 'Test';
-$service = (new SmsapiHttpClient())
- ->smsapiComService($apiToken);
$service->smsFeature()
->sendSms($sms);
```
-For more usage examples take a look at client test suite.
-
-### How to use optional request parameters?
+### How to use request parameters?
Request parameters are represented in a form of data transfer object.
DTOs can be found by searching for 'bag' postfixed classes.
Each bag may contain required and optional parameters.
-Required parameters are that class public properties, usually accessible via some form of a setter or named constructor.
-Optional parameters are described by docblock's '@property' annotation.
+#### Required parameters
+
+Required parameters are that class public properties, usually accessible via some form of a setter or named constructor.
Each parameter can be also set directly by setting bag property, as in example:
+##### How to change SMS encoding?
+
```php
encoding = 'utf-8';
```
-## How to use additional features?
+#### Optional parameters
-### How to use proxy server?
+Some of request's optional parameters have been described by docblock's '@property' annotation.
+You can always add any not documented here optional parameter by setting dynamic property to 'bag'.
+Camel case property names are being converted to snake case on the fly.
+
+##### How to send a SMS with optional from field?
```php
from = 'Test';
-(new SmsapiHttpClient())->setProxy($proxyUrl);
+$service->smsFeature()
+ ->sendSms($sms);
```
+For more usage examples take a look at client test suite.
+
+## How to use additional features?
+
+### How to use proxy server?
+
+To use proxy server you have to define it with your HTTP client.
+
### How to log requests and responses?
Set logger to `SmsapiHttpClient` instance.
@@ -202,10 +255,14 @@ declare(strict_types=1);
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerTrait;
+use Smsapi\Client\SmsapiClient;
require_once 'vendor/autoload.php';
-use Smsapi\Client\SmsapiHttpClient;
+/**
+ * @var SmsapiClient $client
+ */
+require_once 'client.php';
$logger = new class() implements LoggerInterface
{
@@ -217,17 +274,54 @@ $logger = new class() implements LoggerInterface
}
};
-(new SmsapiHttpClient())->setLogger($logger);
+$client->setLogger($logger);
+```
+
+## How to test package
+
+Copy `phpunit.dist.xml` to `phpunit.xml`. You may adjust it to your needs then.
+
+Copy `tests-resources/config/config.dist.yml` to `tests-resources/config/config.yml`. Fill in SMSAPI service connection data.
+
+### How to run unit tests
+
+Unit tests are included into package build process and run against its current version on every commit (see workflow Tests).
+You can run those tests locally with ease using provided Docker configuration, simply run:
+
+```shell
+make test-suite SUITE="unit"
```
-## Test package
-1. Download package: `composer create-project smsapi/php-client`
-2. Execute tests: `./vendor/bin/phing`
+### How to run integration tests
+
+Note that integration test works within an account you have configured in `tests-resources/config/config.yml`.
+Although those test have been written to self-cleanup on exit, in case of failure some trash data may stay.
+Use it with caution.
+
+```shell
+make test-suite SUITE="integration"
+```
+
+### How to run feature tests
+
+Feature test groups are defined in `phpunit.dist.xml`. To run tests execute:
+
+```shell
+make test-suite SUITE="feature-contacts"
+```
+
+### How to run tests against PHP8
+
+To run any of mentioned above against PHP8 use make targets with `php8` suffix. See `Makefile.php8`.
## Docs & Infos
* [SMSAPI.COM API documentation](https://www.smsapi.com/docs)
* [SMSAPI.PL API documentation](https://www.smsapi.pl/docs)
-* [Repository on GitHub](https://github.com/smsapi/smsapi-php-client)
-* [Package on Packagist](https://packagist.org/packages/smsapi/php-client)
+* [SMSAPI.SE API documentation](https://www.smsapi.se/docs)
+* [SMSAPI.BG API documentation](https://www.smsapi.bg/docs)
* [SMSAPI.COM web page](https://smsapi.com)
* [SMSAPI.PL web page](https://smsapi.pl)
+* [SMSAPI.SE web page](https://smsapi.se)
+* [SMSAPI.BG web page](https://smsapi.bg)
+* [Repository on GitHub](https://github.com/smsapi/smsapi-php-client)
+* [Package on Packagist](https://packagist.org/packages/smsapi/php-client)
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 8fde3ed..0000000
--- a/build.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build/Makefile b/build/Makefile
new file mode 100644
index 0000000..5d807b1
--- /dev/null
+++ b/build/Makefile
@@ -0,0 +1,46 @@
+.PHONY: help build test
+
+include $(CURDIR)/php-7.0/Makefile
+include $(CURDIR)/php-7.1/Makefile
+include $(CURDIR)/php-7.2/Makefile
+include $(CURDIR)/php-7.3/Makefile
+include $(CURDIR)/php-7.4/Makefile
+include $(CURDIR)/php-8.0/Makefile
+include $(CURDIR)/php-8.1/Makefile
+include $(CURDIR)/php-8.2/Makefile
+include $(CURDIR)/php-8.3/Makefile
+include $(CURDIR)/php-8.4/Makefile
+
+help:
+ @grep -hE '^[a-zA-Z0-9_.-]+:.*?## .*$$' $(MAKEFILE_LIST) \
+ | sort \
+ | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+
+build: ## build php images
+ docker compose build
+
+test: ## test all against all php images
+ $(MAKE) test-php-7.0
+ $(MAKE) test-php-7.1
+ $(MAKE) test-php-7.2
+ $(MAKE) test-php-7.3
+ $(MAKE) test-php-7.4
+ $(MAKE) test-php-8.0
+ $(MAKE) test-php-8.1
+ $(MAKE) test-php-8.2
+ $(MAKE) test-php-8.3
+ $(MAKE) test-php-8.4
+
+test-unit: ## test unit suite against all php images
+ $(MAKE) test-suite-php-7.0 SUITE=unit
+ $(MAKE) test-suite-php-7.1 SUITE=unit
+ $(MAKE) test-suite-php-7.2 SUITE=unit
+ $(MAKE) test-suite-php-7.3 SUITE=unit
+ $(MAKE) test-suite-php-7.4 SUITE=unit
+ $(MAKE) test-suite-php-8.0 SUITE=unit
+ $(MAKE) test-suite-php-8.1 SUITE=unit
+ $(MAKE) test-suite-php-8.2 SUITE=unit
+ $(MAKE) test-suite-php-8.3 SUITE=unit
+ $(MAKE) test-suite-php-8.4 SUITE=unit
+
+.DEFAULT_GOAL := help
diff --git a/build/docker-compose.yml b/build/docker-compose.yml
new file mode 100644
index 0000000..dcbfba0
--- /dev/null
+++ b/build/docker-compose.yml
@@ -0,0 +1,80 @@
+version: '3.5'
+
+services:
+
+ php-7.0:
+ build:
+ context: php-7.0
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.1:
+ build:
+ context: php-7.1
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.2:
+ build:
+ context: php-7.2
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.3:
+ build:
+ context: php-7.3
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.4:
+ build:
+ context: php-7.4
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.0:
+ build:
+ context: php-8.0
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.1:
+ build:
+ context: php-8.1
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.2:
+ build:
+ context: php-8.2
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.3:
+ build:
+ context: php-8.3
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.4:
+ build:
+ context: php-8.4
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.5:
+ build:
+ context: php-8.5
+ volumes:
+ - ..:/app
+ network_mode: host
\ No newline at end of file
diff --git a/Dockerfile b/build/php-7.0/Dockerfile
similarity index 62%
rename from Dockerfile
rename to build/php-7.0/Dockerfile
index f1bf11c..ed516f7 100644
--- a/Dockerfile
+++ b/build/php-7.0/Dockerfile
@@ -1,4 +1,4 @@
-FROM composer:latest as composer
+FROM composer:2.2 as composer
FROM php:7.0-cli-alpine
RUN apk update && \
@@ -8,10 +8,6 @@ RUN apk update && \
g++ \
make
-RUN pecl install xdebug-2.7.2 && \
- pecl clear-cache && \
- docker-php-ext-enable xdebug
-
COPY --from=composer /usr/bin/composer /usr/bin/composer
WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.0/Makefile b/build/php-7.0/Makefile
new file mode 100644
index 0000000..62c467c
--- /dev/null
+++ b/build/php-7.0/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.0 test-php-7.0 test-suite-php-7.0
+
+prepare-php-7.0: ## load dependencies with php 7.0
+ docker compose run -T php-7.0 /usr/bin/composer update
+
+test-php-7.0: prepare-php-7.0 ## run tests against php 7.0
+ docker compose run -T php-7.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.0: prepare-php-7.0 ## run suite tests against php 7.0, ex: make test-suite-php-7.0 SUITE="unit"
+ docker compose run -T php-7.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.1/Dockerfile b/build/php-7.1/Dockerfile
new file mode 100644
index 0000000..2a0487e
--- /dev/null
+++ b/build/php-7.1/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.1-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.1/Makefile b/build/php-7.1/Makefile
new file mode 100644
index 0000000..26cbfad
--- /dev/null
+++ b/build/php-7.1/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.1 test-php-7.1 test-suite-php-7.1
+
+prepare-php-7.1: ## load dependencies with php 7.1
+ docker compose run -T php-7.1 /usr/bin/composer update
+
+test-php-7.1: prepare-php-7.1 ## run tests against php 7.1
+ docker compose run -T php-7.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.1: prepare-php-7.1 ## run suite tests against php 7.1, ex: make test-suite-php-7.1 SUITE="unit"
+ docker compose run -T php-7.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.2/Dockerfile b/build/php-7.2/Dockerfile
new file mode 100644
index 0000000..bd7b230
--- /dev/null
+++ b/build/php-7.2/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.2-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.2/Makefile b/build/php-7.2/Makefile
new file mode 100644
index 0000000..6cb0833
--- /dev/null
+++ b/build/php-7.2/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.2 test-php-7.2 test-suite-php-7.2
+
+prepare-php-7.2: ## load dependencies with php 7.2
+ docker compose run -T php-7.2 /usr/bin/composer update
+
+test-php-7.2: prepare-php-7.2 ## run tests against php 7.2
+ docker compose run -T php-7.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.2: prepare-php-7.2 ## run suite tests against php 7.2, ex: make test-suite-php-7.2 SUITE="unit"
+ docker compose run -T php-7.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.3/Dockerfile b/build/php-7.3/Dockerfile
new file mode 100644
index 0000000..28ef4fc
--- /dev/null
+++ b/build/php-7.3/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.3-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.3/Makefile b/build/php-7.3/Makefile
new file mode 100644
index 0000000..99e7817
--- /dev/null
+++ b/build/php-7.3/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.3 test-php-7.3 test-suite-php-7.3
+
+prepare-php-7.3: ## load dependencies with php 7.3
+ docker compose run -T php-7.3 /usr/bin/composer update
+
+test-php-7.3: prepare-php-7.3 ## run tests against php 7.3
+ docker compose run -T php-7.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.3: prepare-php-7.3 ## run suite tests against php 7.3, ex: make test-suite-php-7.3 SUITE="unit"
+ docker compose run -T php-7.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.4/Dockerfile b/build/php-7.4/Dockerfile
new file mode 100644
index 0000000..d810922
--- /dev/null
+++ b/build/php-7.4/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.4-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.4/Makefile b/build/php-7.4/Makefile
new file mode 100644
index 0000000..d68c343
--- /dev/null
+++ b/build/php-7.4/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.4 test-php-7.4 test-suite-php-7.4
+
+prepare-php-7.4: ## load dependencies with php 7.4
+ docker compose run -T php-7.4 /usr/bin/composer update
+
+test-php-7.4: prepare-php-7.4 ## run tests against php 7.4
+ docker compose run -T php-7.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.4: prepare-php-7.4 ## run suite tests against php 7.4, ex: make test-suite-php-7.4 SUITE="unit"
+ docker compose run -T php-7.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.0/Dockerfile b/build/php-8.0/Dockerfile
new file mode 100644
index 0000000..04a6435
--- /dev/null
+++ b/build/php-8.0/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest as composer
+FROM php:8.0-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.0/Makefile b/build/php-8.0/Makefile
new file mode 100644
index 0000000..b8b7eaf
--- /dev/null
+++ b/build/php-8.0/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.0 test-php-8.0 test-suite-php-8.0
+
+prepare-php-8.0: ## load dependencies with php 8.0
+ docker compose run -T php-8.0 /usr/bin/composer update
+
+test-php-8.0: prepare-php-8.0 ## run tests against php 8.0
+ docker compose run -T php-8.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.0: prepare-php-8.0 ## run suite tests against php 8.0, ex: make test-suite-php-8.0 SUITE="unit"
+ docker compose run -T php-8.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.1/Dockerfile b/build/php-8.1/Dockerfile
new file mode 100644
index 0000000..70aea88
--- /dev/null
+++ b/build/php-8.1/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest as composer
+FROM php:8.1-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.1/Makefile b/build/php-8.1/Makefile
new file mode 100644
index 0000000..607d37b
--- /dev/null
+++ b/build/php-8.1/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.1 test-php-8.1 test-suite-php-8.1
+
+prepare-php-8.1: ## load dependencies with php 8.1
+ docker compose run -T php-8.1 /usr/bin/composer update
+
+test-php-8.1: prepare-php-8.1 ## run tests against php 8.1
+ docker compose run -T php-8.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.1: prepare-php-8.1 ## run suite tests against php 8.1, ex: make test-suite-php-8.1 SUITE="unit"
+ docker compose run -T php-8.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.2/Dockerfile b/build/php-8.2/Dockerfile
new file mode 100644
index 0000000..677d0ad
--- /dev/null
+++ b/build/php-8.2/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest as composer
+FROM php:8.2-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.2/Makefile b/build/php-8.2/Makefile
new file mode 100644
index 0000000..3867be5
--- /dev/null
+++ b/build/php-8.2/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.2 test-php-8.2 test-suite-php-8.2
+
+prepare-php-8.2: ## load dependencies with php 8.2
+ docker compose run -T php-8.2 /usr/bin/composer update
+
+test-php-8.2: prepare-php-8.2 ## run tests against php 8.2
+ docker compose run -T php-8.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.2: prepare-php-8.2 ## run suite tests against php 8.2, ex: make test-suite-php-8.2 SUITE="unit"
+ docker compose run -T php-8.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.3/Dockerfile b/build/php-8.3/Dockerfile
new file mode 100644
index 0000000..94ac096
--- /dev/null
+++ b/build/php-8.3/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest as composer
+FROM php:8.3-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.3/Makefile b/build/php-8.3/Makefile
new file mode 100644
index 0000000..886f5d4
--- /dev/null
+++ b/build/php-8.3/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.3 test-php-8.3 test-suite-php-8.3
+
+prepare-php-8.3: ## load dependencies with php 8.3
+ docker compose run -T php-8.3 /usr/bin/composer update
+
+test-php-8.3: prepare-php-8.3 ## run tests against php 8.3
+ docker compose run -T php-8.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.3: prepare-php-8.3 ## run suite tests against php 8.3, ex: make test-suite-php-8.3 SUITE="unit"
+ docker compose run -T php-8.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.4/Dockerfile b/build/php-8.4/Dockerfile
new file mode 100644
index 0000000..ba691e0
--- /dev/null
+++ b/build/php-8.4/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest AS composer
+FROM php:8.4-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.4/Makefile b/build/php-8.4/Makefile
new file mode 100644
index 0000000..bd4cfd0
--- /dev/null
+++ b/build/php-8.4/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.4 test-php-8.4 test-suite-php-8.4
+
+prepare-php-8.4: ## load dependencies with php 8.4
+ docker compose run -T php-8.4 /usr/bin/composer update
+
+test-php-8.4: prepare-php-8.4 ## run tests against php 8.4
+ docker compose run -T php-8.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.4: prepare-php-8.4 ## run suite tests against php 8.4, ex: make test-suite-php-8.4 SUITE="unit"
+ docker compose run -T php-8.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.5/Dockerfile b/build/php-8.5/Dockerfile
new file mode 100644
index 0000000..c93d62d
--- /dev/null
+++ b/build/php-8.5/Dockerfile
@@ -0,0 +1,6 @@
+FROM composer:latest AS composer
+FROM php:8.5-cli-alpine
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.5/Makefile b/build/php-8.5/Makefile
new file mode 100644
index 0000000..3a38702
--- /dev/null
+++ b/build/php-8.5/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.5 test-php-8.5 test-suite-php-8.5
+
+prepare-php-8.5: ## load dependencies with php 8.5
+ docker compose run -T php-8.5 /usr/bin/composer update
+
+test-php-8.5: prepare-php-8.5 ## run tests against php 8.5
+ docker compose run -T php-8.5 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.5: prepare-php-8.5 ## run suite tests against php 8.5, ex: make test-suite-php-8.5 SUITE="unit"
+ docker compose run -T php-8.5 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/composer.json b/composer.json
index c63aa0a..8c5dad5 100644
--- a/composer.json
+++ b/composer.json
@@ -16,21 +16,26 @@
}
},
"require": {
- "php": "^7",
+ "php": "^7 || ~8.0 || ~8.1 || ~8.2 || ~8.3 || ~8.4 || ~8.5",
"ext-json": "*",
- "psr/log": "^1",
- "psr/http-message": "^1",
+ "psr/log": "^1 || ^2 || ^3",
+ "psr/http-message": "~1.0 || ~1.1 || ~2.0",
"psr/http-client": "^1",
- "guzzlehttp/guzzle": "^6"
+ "psr/http-factory": "^1"
},
"require-dev": {
- "phpunit/phpunit": "^6",
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^6 || ~8.5",
+ "phpspec/prophecy": "^1.7",
"symfony/yaml": "^3",
- "theodorejb/polycast": "^1",
- "marc-mabe/php-enum": "^3",
- "phing/phing": "^2.5",
- "doctrine/instantiator": "1.0.5",
- "phpdocumentor/reflection-docblock": "^4.3",
- "phpdocumentor/type-resolver": "^0.5"
+ "doctrine/instantiator": "1.0.5 || ^1.4.0",
+ "phpdocumentor/reflection-docblock": "^4.3 || ^5.2.0",
+ "phpdocumentor/type-resolver": "^0.5 || ^1.3.0",
+ "guzzlehttp/psr7": "^1 || ^2",
+ "ext-curl": "*"
+ },
+ "suggest": {
+ "ext-curl": "To use Curl HttpClient",
+ "guzzlehttp/psr7": "To use Curl HttpClient and HTTP message factories"
}
}
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index f669f77..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-version: '3.5'
-
-services:
- php:
- build: .
- volumes:
- - .:/app
- network_mode: host
-
diff --git a/phpcs.xml b/phpcs.xml
deleted file mode 100644
index 1a5512f..0000000
--- a/phpcs.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- SMSAPI Coding Standard
-
-
-
-
- */Standards/*/Tests/*\.(inc|css|js)
-
-
-
-
-
- **/tests/Unit/**
- **/tests/Integration/**
-
-
\ No newline at end of file
diff --git a/src/Curl/Discovery/CurlDiscovery.php b/src/Curl/Discovery/CurlDiscovery.php
new file mode 100644
index 0000000..065b9d4
--- /dev/null
+++ b/src/Curl/Discovery/CurlDiscovery.php
@@ -0,0 +1,23 @@
+prepareRequestHttpClient($request);
+
+ $this->prepareRequestMethod($request, $httpClient);
+ $this->prepareRequestBody($request, $httpClient);
+ $this->prepareRequestHeaders($request, $httpClient);
+ $this->prepareResponseOptions($httpClient);
+
+ $response = $this->execute($request, $httpClient);
+
+ $this->closeHttpClient($httpClient);
+
+ return $response;
+ }
+
+ private function prepareRequestHttpClient(RequestInterface $request)
+ {
+ $url = strtr("{scheme}://{host}{port}{path}", [
+ '{scheme}' => $request->getUri()->getScheme(),
+ '{host}' => $request->getUri()->getHost(),
+ '{port}' => $request->getUri()->getPort() ? ':' . $request->getUri()->getPort() : '',
+ '{path}' => $request->getRequestTarget()
+ ]);
+
+ $httpClient = curl_init($url);
+
+ if ($httpClient === false) {
+ throw NetworkException::withRequest(
+ 'Cannot prepare HTTP client: ' . curl_error($httpClient),
+ $request
+ );
+ }
+
+ return $httpClient;
+ }
+
+ private function prepareRequestMethod(RequestInterface $request, $httpClient)
+ {
+ curl_setopt($httpClient, CURLOPT_CUSTOMREQUEST, $request->getMethod());
+ }
+
+ private function prepareRequestBody(RequestInterface $request, $httpClient)
+ {
+ curl_setopt($httpClient, CURLOPT_POSTFIELDS, (string)$request->getBody());
+ }
+
+ private function prepareRequestHeaders(RequestInterface $request, $httpClient)
+ {
+ $headers = [];
+ foreach ($request->getHeaders() as $name => $values) {
+ $headers[] = $name . ': ' . implode(', ', $values);
+ }
+
+ curl_setopt($httpClient, CURLOPT_HTTPHEADER, $headers);
+ }
+
+ private function prepareResponseOptions($httpClient)
+ {
+ curl_setopt($httpClient, CURLOPT_HEADER, true);
+ curl_setopt($httpClient, CURLOPT_RETURNTRANSFER, true);
+ }
+
+ private function execute(RequestInterface $request, $httpClient): ResponseInterface
+ {
+ $response = curl_exec($httpClient);
+
+ if ($response === false) {
+ throw RequestException::withRequest(
+ 'Cannot send request: ' . curl_error($httpClient),
+ $request
+ );
+ }
+
+ $responseStatus = curl_getinfo($httpClient, CURLINFO_HTTP_CODE);
+
+ $headerSize = curl_getinfo($httpClient, CURLINFO_HEADER_SIZE);
+ $headerString = substr($response, 0, $headerSize);
+ $headers = HttpHeadersParser::parse($headerString);
+
+ $body = substr($response, $headerSize);
+
+ return new Response($responseStatus, $headers, $body);
+ }
+
+ private function closeHttpClient($httpClient)
+ {
+ curl_close($httpClient);
+ }
+}
diff --git a/src/Curl/HttpHeadersParser.php b/src/Curl/HttpHeadersParser.php
new file mode 100644
index 0000000..9ae2d69
--- /dev/null
+++ b/src/Curl/HttpHeadersParser.php
@@ -0,0 +1,23 @@
+httpClient = new \Smsapi\Client\SmsapiHttpClient(
+ new HttpClient(),
+ new RequestFactory(),
+ new StreamFactory()
+ );
+ }
+
+ public function smsapiPlService(string $apiToken): SmsapiPlService
+ {
+ return $this->httpClient()->smsapiPlService($apiToken);
+ }
+
+ public function smsapiPlServiceWithUri(string $apiToken, string $uri): SmsapiPlService
+ {
+ return $this->httpClient()->smsapiPlServiceWithUri($apiToken, $uri);
+ }
+
+ public function smsapiComService(string $apiToken): SmsapiComService
+ {
+ return $this->httpClient()->smsapiComService($apiToken);
+ }
+
+ public function smsapiComServiceWithUri(string $apiToken, string $uri): SmsapiComService
+ {
+ return $this->httpClient()->smsapiComServiceWithUri($apiToken, $uri);
+ }
+
+ private function httpClient(): \Smsapi\Client\SmsapiHttpClient
+ {
+ if ($this->logger instanceof LoggerInterface) {
+ $this->httpClient->setLogger($this->logger);
+ }
+
+ return $this->httpClient;
+ }
+}
diff --git a/src/Curl/StreamFactory.php b/src/Curl/StreamFactory.php
new file mode 100644
index 0000000..db5e2a3
--- /dev/null
+++ b/src/Curl/StreamFactory.php
@@ -0,0 +1,31 @@
+dataFactoryProvider = $dataFactoryProvider;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function findContacts(FindContactsBag $findContactsBag = null): array
{
$result = $this->restRequestExecutor->read('contacts', (array)$findContactsBag);
diff --git a/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php b/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php
index 1a45b1c..2269dcc 100644
--- a/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php
+++ b/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php
@@ -8,6 +8,7 @@
* @api
* @property string $type
*/
+#[\AllowDynamicProperties]
class CreateContactFieldBag
{
diff --git a/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php b/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php
index ecdaabb..cbbb706 100644
--- a/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php
+++ b/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteContactFieldBag
{
diff --git a/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php b/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php
index e48acc9..adf4d6d 100644
--- a/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php
+++ b/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactFieldOptionsBag
{
diff --git a/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php b/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php
index 1dd2024..0e5cdbd 100644
--- a/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php
+++ b/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class UpdateContactFieldBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php b/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php
index f4124ad..b51723e 100644
--- a/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class AssignContactToGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php b/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php
index 4770a7c..80e934a 100644
--- a/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php
@@ -10,6 +10,7 @@
* @property string $idx
* @property integer $contactExpireAfter
*/
+#[\AllowDynamicProperties]
class CreateGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php b/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php
index d6f1bdf..cf7da05 100644
--- a/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php
@@ -8,6 +8,7 @@
* @api
* @property bool $deleteContacts
*/
+#[\AllowDynamicProperties]
class DeleteGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php b/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php
index 3c4c8e6..2ecfb43 100644
--- a/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php b/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php
index 9ff20f4..053a7bc 100644
--- a/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php
+++ b/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactGroupsBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/FindGroupBag.php b/src/Feature/Contacts/Groups/Bag/FindGroupBag.php
index 3b17dd4..b169b8a 100644
--- a/src/Feature/Contacts/Groups/Bag/FindGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/FindGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php b/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php
index 550b81d..3b9000d 100644
--- a/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class UnpinContactFromGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php b/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php
index ca9a3e4..2eb918f 100644
--- a/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php
@@ -10,6 +10,7 @@
* @property string $idx
* @property integer $contactExpireAfter
*/
+#[\AllowDynamicProperties]
class UpdateGroupBag
{
diff --git a/src/Feature/Contacts/Groups/ContactsGroupsHttpFeature.php b/src/Feature/Contacts/Groups/ContactsGroupsHttpFeature.php
index 43799b8..da0066f 100644
--- a/src/Feature/Contacts/Groups/ContactsGroupsHttpFeature.php
+++ b/src/Feature/Contacts/Groups/ContactsGroupsHttpFeature.php
@@ -4,7 +4,6 @@
namespace Smsapi\Client\Feature\Contacts\Groups;
-use Smsapi\Client\Feature\Contacts\Groups\Bag\FindGroupsBag;
use Smsapi\Client\Feature\Data\DataFactoryProvider;
use Smsapi\Client\Infrastructure\RequestExecutor\RestRequestExecutor;
use Smsapi\Client\Feature\Contacts\Data\ContactGroup;
diff --git a/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php b/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php
index 5d63613..a8ee959 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php
@@ -15,6 +15,7 @@
* @property string $gender
* @property string $birthdayDate
*/
+#[\AllowDynamicProperties]
class AddContactToGroupByQueryBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php b/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php
index ffa7b02..9238eaa 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactInGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php b/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php
index c7591b5..2d88a19 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php
@@ -15,6 +15,7 @@
* @property string $gender
* @property string $birthdayDate
*/
+#[\AllowDynamicProperties]
class MoveContactToGroupByQueryBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php b/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php
index be2f10a..9fe9cbb 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class PinContactToGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php
index 992a168..50cde48 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class UnpinContactFromGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php
index a7a8cd3..e36d5c8 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php
@@ -15,6 +15,7 @@
* @property string $gender
* @property string $birthdayDate
*/
+#[\AllowDynamicProperties]
class UnpinContactFromGroupByQueryBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php
index 6305d3e..e48404a 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php
@@ -10,6 +10,7 @@
* @property string $write
* @property string $send
*/
+#[\AllowDynamicProperties]
class CreateGroupPermissionBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php
index f6ba1f2..591cad1 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteGroupPermissionBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php
index 4c285e0..150efff 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindGroupPermissionBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php
index e7d2327..384d47e 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindGroupPermissionsBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php
index 4a807e4..54fd14e 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php
@@ -10,6 +10,7 @@
* @property string $write
* @property string $send
*/
+#[\AllowDynamicProperties]
class UpdateGroupPermissionBag
{
diff --git a/src/Feature/Data/DataFactoryProvider.php b/src/Feature/Data/DataFactoryProvider.php
index 5ee2506..ca9044a 100644
--- a/src/Feature/Data/DataFactoryProvider.php
+++ b/src/Feature/Data/DataFactoryProvider.php
@@ -19,12 +19,6 @@
use Smsapi\Client\Feature\Profile\Data\ProfilePriceCountryFactory;
use Smsapi\Client\Feature\Profile\Data\ProfilePriceFactory;
use Smsapi\Client\Feature\Profile\Data\ProfilePriceNetworkFactory;
-use Smsapi\Client\Feature\Push\Data\PushAppFactory;
-use Smsapi\Client\Feature\Push\Data\PushShipmentDispatchDetailsFactory;
-use Smsapi\Client\Feature\Push\Data\PushShipmentFactory;
-use Smsapi\Client\Feature\Push\Data\PushShipmentFallbackFactory;
-use Smsapi\Client\Feature\Push\Data\PushShipmentPayloadFactory;
-use Smsapi\Client\Feature\Push\Data\PushShipmentSummaryFactory;
use Smsapi\Client\Feature\ShortUrl\Data\ShortUrlLinkFactory;
use Smsapi\Client\Feature\Sms\Data\SmsFactory;
use Smsapi\Client\Feature\Mfa\Data\MfaFactory;
@@ -91,17 +85,6 @@ public function provideShortUrlLinkFactory(): ShortUrlLinkFactory
return new ShortUrlLinkFactory();
}
- public function providePushShipmentFactory(): PushShipmentFactory
- {
- return new PushShipmentFactory(
- new PushAppFactory(),
- new PushShipmentPayloadFactory(),
- new PushShipmentSummaryFactory(),
- new PushShipmentDispatchDetailsFactory(),
- new PushShipmentFallbackFactory()
- );
- }
-
public function provideContactFactory(): ContactFactory
{
return new ContactFactory($this->provideContactGroupFactory(), $this->provideConntactCustomFieldFactory());
diff --git a/src/Feature/Data/PointsFactory.php b/src/Feature/Data/PointsFactory.php
index bb18c4f..9ead0d9 100644
--- a/src/Feature/Data/PointsFactory.php
+++ b/src/Feature/Data/PointsFactory.php
@@ -4,12 +4,14 @@
namespace Smsapi\Client\Feature\Data;
+use stdClass;
+
/**
* @internal
*/
class PointsFactory
{
- public function createFromObject(\stdClass $object): Points
+ public function createFromObject(stdClass $object): Points
{
$points = new Points();
$points->fromAccount = $object->from_account;
diff --git a/src/Feature/Hlr/Bag/SendHlrBag.php b/src/Feature/Hlr/Bag/SendHlrBag.php
index fa7428a..991fc60 100644
--- a/src/Feature/Hlr/Bag/SendHlrBag.php
+++ b/src/Feature/Hlr/Bag/SendHlrBag.php
@@ -8,6 +8,7 @@
* @api
* @property string $idx
*/
+#[\AllowDynamicProperties]
class SendHlrBag
{
diff --git a/src/Feature/Mfa/Bag/CreateMfaBag.php b/src/Feature/Mfa/Bag/CreateMfaBag.php
index 05036be..bafdac6 100644
--- a/src/Feature/Mfa/Bag/CreateMfaBag.php
+++ b/src/Feature/Mfa/Bag/CreateMfaBag.php
@@ -10,6 +10,7 @@
* @property string $content
* @property bool $fast
*/
+#[\AllowDynamicProperties]
class CreateMfaBag
{
/**
diff --git a/src/Feature/Mfa/Bag/VerificationMfaBag.php b/src/Feature/Mfa/Bag/VerificationMfaBag.php
index f1c8a7c..ba371e4 100644
--- a/src/Feature/Mfa/Bag/VerificationMfaBag.php
+++ b/src/Feature/Mfa/Bag/VerificationMfaBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class VerificationMfaBag
{
/**
diff --git a/src/Feature/Mms/Bag/SendMmsBag.php b/src/Feature/Mms/Bag/SendMmsBag.php
index e3ce33a..6db03e1 100644
--- a/src/Feature/Mms/Bag/SendMmsBag.php
+++ b/src/Feature/Mms/Bag/SendMmsBag.php
@@ -7,6 +7,7 @@
* @api
* @property bool $test
*/
+#[\AllowDynamicProperties]
class SendMmsBag
{
diff --git a/src/Feature/Push/Bag/SendPushBag.php b/src/Feature/Push/Bag/SendPushBag.php
deleted file mode 100644
index 61e2547..0000000
--- a/src/Feature/Push/Bag/SendPushBag.php
+++ /dev/null
@@ -1,54 +0,0 @@
-appId = $appId;
- $this->data['alert'] = $alert;
- }
-
- public function setFallback(string $message, string $from, int $delay): self
- {
- $this->fallback['message'] = $message;
- $this->fallback['from'] = $from;
- $this->fallback['delay'] = $delay;
-
- return $this;
- }
-
- public function setAndroidData(string $title, string $url): self
- {
- $this->data['from'] = $title;
- $this->data['delay'] = $url;
-
- return $this;
- }
-
- public function setIosData(string $badge, string $sound, string $category, bool $contentAvailable): self
- {
- $this->data['badge'] = $badge;
- $this->data['sound'] = $sound;
- $this->data['category'] = $category;
- $this->data['contentAvailable'] = $contentAvailable;
-
- return $this;
- }
-}
diff --git a/src/Feature/Push/Data/PushApp.php b/src/Feature/Push/Data/PushApp.php
deleted file mode 100644
index b73149a..0000000
--- a/src/Feature/Push/Data/PushApp.php
+++ /dev/null
@@ -1,19 +0,0 @@
-id = $object->id;
- $pushApp->name = $object->name;
-
- if (isset($object->icon)) {
- $pushApp->icon = $object->icon;
- }
-
- return $pushApp;
- }
-}
diff --git a/src/Feature/Push/Data/PushShipment.php b/src/Feature/Push/Data/PushShipment.php
deleted file mode 100644
index 75c3dae..0000000
--- a/src/Feature/Push/Data/PushShipment.php
+++ /dev/null
@@ -1,42 +0,0 @@
-channels = $object->channels;
- $details->deviceIds = $object->device_ids;
- $details->deviceType = $object->device_type;
-
- return $details;
- }
-}
diff --git a/src/Feature/Push/Data/PushShipmentFactory.php b/src/Feature/Push/Data/PushShipmentFactory.php
deleted file mode 100644
index e391a7a..0000000
--- a/src/Feature/Push/Data/PushShipmentFactory.php
+++ /dev/null
@@ -1,50 +0,0 @@
-appFactory = $appFactory;
- $this->payloadFactory = $payloadFactory;
- $this->summaryFactory = $summaryFactory;
- $this->detailsFactory = $detailsFactory;
- $this->fallbackFactory = $fallbackFactory;
- }
-
- public function createFromObject(stdClass $object): PushShipment
- {
- $pushShipment = new PushShipment();
- $pushShipment->id = $object->id;
- $pushShipment->status = $object->status;
- $pushShipment->dateCreated = new DateTime($object->date_created);
- $pushShipment->scheduledDate = new DateTime($object->scheduled_date);
- $pushShipment->app = $this->appFactory->createFromObject($object->app);
- $pushShipment->payload = $this->payloadFactory->createFromObject($object->payload);
- $pushShipment->summary = $this->summaryFactory->createFromObject($object->summary);
- $pushShipment->dispatchDetails = $this->detailsFactory->createFromObject($object->dispatch_details);
- $pushShipment->fallback = $this->fallbackFactory->createFromObject($object->fallback);
-
- return $pushShipment;
- }
-}
diff --git a/src/Feature/Push/Data/PushShipmentFallback.php b/src/Feature/Push/Data/PushShipmentFallback.php
deleted file mode 100644
index 2b05a0d..0000000
--- a/src/Feature/Push/Data/PushShipmentFallback.php
+++ /dev/null
@@ -1,22 +0,0 @@
-message = $object->message;
- $fallback->from = $object->from;
- $fallback->delay = $object->delay;
- $fallback->status = $object->status;
-
- return $fallback;
- }
-}
diff --git a/src/Feature/Push/Data/PushShipmentPayload.php b/src/Feature/Push/Data/PushShipmentPayload.php
deleted file mode 100644
index e7a4feb..0000000
--- a/src/Feature/Push/Data/PushShipmentPayload.php
+++ /dev/null
@@ -1,13 +0,0 @@
-alert = $object->alert;
-
- return $payload;
- }
-}
diff --git a/src/Feature/Push/Data/PushShipmentSummary.php b/src/Feature/Push/Data/PushShipmentSummary.php
deleted file mode 100644
index 36cc8cf..0000000
--- a/src/Feature/Push/Data/PushShipmentSummary.php
+++ /dev/null
@@ -1,19 +0,0 @@
-points = (float)$object->points;
- $summary->recipientsCount = $object->recipients_count;
- $summary->errorCode = $object->error_code;
-
- return $summary;
- }
-}
diff --git a/src/Feature/Push/PushFeature.php b/src/Feature/Push/PushFeature.php
deleted file mode 100644
index bad467f..0000000
--- a/src/Feature/Push/PushFeature.php
+++ /dev/null
@@ -1,16 +0,0 @@
-restRequestExecutor = $restRequestExecutor;
- $this->pushShipmentFactory = $pushShipmentFactory;
- }
-
- /**
- * @param SendPushBag $sendPushBag
- * @return PushShipment
- * @throws SmsapiClientException
- */
- public function createPush(SendPushBag $sendPushBag): PushShipment
- {
- $result = $this->restRequestExecutor->create('push', (array)$sendPushBag);
-
- return $this->pushShipmentFactory->createFromObject($result);
- }
-}
diff --git a/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php b/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php
index 7452f19..05b5e94 100644
--- a/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php
+++ b/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php
@@ -14,12 +14,13 @@
* @property DateTimeInterface $expire
* @property string $description
*/
+#[\AllowDynamicProperties]
class CreateShortUrlLinkBag
{
public static function withUrl(string $url): self
{
- $bag = new self();
+ $bag = new CreateShortUrlLinkBag();
$bag->url = $url;
return $bag;
}
diff --git a/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php b/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php
index 748a5e6..51f6a09 100644
--- a/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php
+++ b/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php
@@ -4,6 +4,10 @@
namespace Smsapi\Client\Feature\Sms\Bag;
+/**
+ * @api
+ */
+#[\AllowDynamicProperties]
class DeleteScheduledSmssBag
{
/** @var array */
diff --git a/src/Feature/Sms/Bag/ScheduleSmsBag.php b/src/Feature/Sms/Bag/ScheduleSmsBag.php
index dc328e9..2ce4b52 100644
--- a/src/Feature/Sms/Bag/ScheduleSmsBag.php
+++ b/src/Feature/Sms/Bag/ScheduleSmsBag.php
@@ -24,7 +24,9 @@
* @property string $param2
* @property string $param3
* @property string $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class ScheduleSmsBag
{
/** @var string */
@@ -65,6 +67,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php b/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php
index 0b39fa5..0981fd2 100644
--- a/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php
+++ b/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php
@@ -20,7 +20,9 @@
* @property bool $normalize
* @property string $notifyUrl
* @property bool $test
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class ScheduleSmsToGroupBag
{
@@ -53,6 +55,9 @@ public static function withTemplateName(DateTimeInterface $scheduleAt, string $g
return $bag;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/ScheduleSmssBag.php b/src/Feature/Sms/Bag/ScheduleSmssBag.php
index 3e5fd10..b214567 100644
--- a/src/Feature/Sms/Bag/ScheduleSmssBag.php
+++ b/src/Feature/Sms/Bag/ScheduleSmssBag.php
@@ -25,10 +25,12 @@
* @property array $param2
* @property array $param3
* @property array $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class ScheduleSmssBag
{
- /** @var array */
+ /** @var array|string */
public $to;
/** @var DateTimeInterface */
@@ -66,6 +68,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(array $idx, bool $checkIdx = null): self
{
$this->idx = $idx;
diff --git a/src/Feature/Sms/Bag/SendSmsBag.php b/src/Feature/Sms/Bag/SendSmsBag.php
index 181a00f..9ac48b5 100644
--- a/src/Feature/Sms/Bag/SendSmsBag.php
+++ b/src/Feature/Sms/Bag/SendSmsBag.php
@@ -24,7 +24,9 @@
* @property string $param2
* @property string $param3
* @property string $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class SendSmsBag
{
/** @var string */
@@ -60,6 +62,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/SendSmsToGroupBag.php b/src/Feature/Sms/Bag/SendSmsToGroupBag.php
index 52adfdf..a6da846 100644
--- a/src/Feature/Sms/Bag/SendSmsToGroupBag.php
+++ b/src/Feature/Sms/Bag/SendSmsToGroupBag.php
@@ -19,7 +19,9 @@
* @property bool $normalize
* @property string $notifyUrl
* @property bool $test
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class SendSmsToGroupBag
{
/** @var string */
@@ -46,6 +48,9 @@ public static function withTemplateName(string $group, string $templateName): se
return $bag;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/SendSmssBag.php b/src/Feature/Sms/Bag/SendSmssBag.php
index fddbf5b..279bc53 100644
--- a/src/Feature/Sms/Bag/SendSmssBag.php
+++ b/src/Feature/Sms/Bag/SendSmssBag.php
@@ -25,10 +25,12 @@
* @property array $param2
* @property array $param3
* @property array $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class SendSmssBag
{
- /** @var array */
+ /** @var array|string */
public $to;
/** @var string */
@@ -61,6 +63,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(array $idx, bool $checkIdx = null): self
{
$this->idx = $idx;
diff --git a/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php b/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php
index 81d6f10..09d40c1 100644
--- a/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class CreateSendernameBag
{
public $sender;
diff --git a/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php b/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php
index 9f54dde..8e34293 100644
--- a/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteSendernameBag
{
public $sender;
diff --git a/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php b/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php
index cf4e58e..60abde0 100644
--- a/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindSendernameBag
{
public $sender;
diff --git a/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php b/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php
index 28539af..991e2d0 100644
--- a/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class MakeSendernameDefaultBag
{
public $sender;
diff --git a/src/Feature/Sms/SmsFeature.php b/src/Feature/Sms/SmsFeature.php
index 8ccddf7..9f3c9fe 100644
--- a/src/Feature/Sms/SmsFeature.php
+++ b/src/Feature/Sms/SmsFeature.php
@@ -11,7 +11,6 @@
use Smsapi\Client\Feature\Sms\Bag\SendSmssBag;
use Smsapi\Client\Feature\Sms\Bag\SendSmsToGroupBag;
use Smsapi\Client\Feature\Sms\Data\Sms;
-use Smsapi\Client\Feature\Mfa\MfaFeature;
use Smsapi\Client\Feature\Sms\Sendernames\SendernamesFeature;
/**
diff --git a/src/Feature/Sms/SmsHttpFeature.php b/src/Feature/Sms/SmsHttpFeature.php
index 5eafd75..b2e2299 100644
--- a/src/Feature/Sms/SmsHttpFeature.php
+++ b/src/Feature/Sms/SmsHttpFeature.php
@@ -3,6 +3,7 @@
namespace Smsapi\Client\Feature\Sms;
+use Psr\Http\Client\ClientInterface;
use Smsapi\Client\Feature\Data\DataFactoryProvider;
use Smsapi\Client\Feature\Sms\Bag\DeleteScheduledSmssBag;
use Smsapi\Client\Feature\Sms\Bag\ScheduleSmsBag;
@@ -12,8 +13,6 @@
use Smsapi\Client\Feature\Sms\Bag\SendSmssBag;
use Smsapi\Client\Feature\Sms\Bag\SendSmsToGroupBag;
use Smsapi\Client\Feature\Sms\Data\Sms;
-use Smsapi\Client\Feature\Mfa\MfaFeature;
-use Smsapi\Client\Feature\Mfa\MfaHttpFeature;
use Smsapi\Client\Feature\Sms\Sendernames\SendernamesFeature;
use Smsapi\Client\Feature\Sms\Sendernames\SendernamesHttpFeature;
use Smsapi\Client\Infrastructure\RequestExecutor\RequestExecutorFactory;
@@ -25,13 +24,16 @@
*/
class SmsHttpFeature implements SmsFeature
{
+ private $externalHttpClient;
private $requestExecutorFactory;
private $dataFactoryProvider;
public function __construct(
+ ClientInterface $externalHttpClient,
RequestExecutorFactory $requestExecutorFactory,
DataFactoryProvider $dataFactoryProvider
) {
+ $this->externalHttpClient = $externalHttpClient;
$this->requestExecutorFactory = $requestExecutorFactory;
$this->dataFactoryProvider = $dataFactoryProvider;
}
@@ -39,7 +41,7 @@ public function __construct(
public function sendernameFeature(): SendernamesFeature
{
return new SendernamesHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
+ $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider->provideSendernameFactory()
);
}
@@ -108,6 +110,8 @@ public function sendFlashSmsToGroup(SendSmsToGroupBag $sendSmsToGroupBag): array
public function sendSmss(SendSmssBag $sendSmssBag): array
{
+ $sendSmssBag->to = implode(',', $sendSmssBag->to);
+
return array_map(
[$this->dataFactoryProvider->provideSmsFactory(), 'createFromObject'],
$this->makeRequest($sendSmssBag)->list
@@ -116,6 +120,8 @@ public function sendSmss(SendSmssBag $sendSmssBag): array
public function sendFlashSmss(SendSmssBag $sendSmssBag): array
{
+ $sendSmssBag->to = implode(',', $sendSmssBag->to);
+
return array_map(
[$this->dataFactoryProvider->provideSmsFactory(), 'createFromObject'],
$this->makeRequest($sendSmssBag)->list
@@ -144,6 +150,7 @@ public function scheduleSms(ScheduleSmsBag $scheduleSmsBag): Sms
public function scheduleSmss(ScheduleSmssBag $scheduleSmssBag): array
{
+ $scheduleSmssBag->to = implode(',', $scheduleSmssBag->to);
$scheduleSmssBag->dateValidate = true;
return array_map(
@@ -216,6 +223,8 @@ public function deleteScheduledSms(DeleteScheduledSmssBag $deleteScheduledSmsBag
*/
private function makeRequest($data): stdClass
{
- return $this->requestExecutorFactory->createLegacyRequestExecutor()->request('sms.do', (array)$data);
+ return $this->requestExecutorFactory
+ ->createLegacyRequestExecutor($this->externalHttpClient)
+ ->request('sms.do', (array)$data);
}
}
diff --git a/src/Feature/Subusers/Bag/CreateSubuserBag.php b/src/Feature/Subusers/Bag/CreateSubuserBag.php
index 2ea4249..a45cb3c 100644
--- a/src/Feature/Subusers/Bag/CreateSubuserBag.php
+++ b/src/Feature/Subusers/Bag/CreateSubuserBag.php
@@ -8,6 +8,7 @@
* @property bool $active
* @property string $description
*/
+#[\AllowDynamicProperties]
class CreateSubuserBag
{
/** @var string */
diff --git a/src/Feature/Subusers/Bag/DeleteSubuserBag.php b/src/Feature/Subusers/Bag/DeleteSubuserBag.php
index 65edc86..b5c741c 100644
--- a/src/Feature/Subusers/Bag/DeleteSubuserBag.php
+++ b/src/Feature/Subusers/Bag/DeleteSubuserBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteSubuserBag
{
public $id;
diff --git a/src/Feature/Subusers/Bag/UpdateSubuserBag.php b/src/Feature/Subusers/Bag/UpdateSubuserBag.php
index f7eea08..fff8f26 100644
--- a/src/Feature/Subusers/Bag/UpdateSubuserBag.php
+++ b/src/Feature/Subusers/Bag/UpdateSubuserBag.php
@@ -11,6 +11,7 @@
* @property bool $active
* @property string $description
*/
+#[\AllowDynamicProperties]
class UpdateSubuserBag
{
/** @var string */
diff --git a/src/Feature/Vms/Bag/SendVmsBag.php b/src/Feature/Vms/Bag/SendVmsBag.php
index a194a28..ef88cef 100644
--- a/src/Feature/Vms/Bag/SendVmsBag.php
+++ b/src/Feature/Vms/Bag/SendVmsBag.php
@@ -13,6 +13,7 @@
* @property bool $checkIdx
* @property bool $test
*/
+#[\AllowDynamicProperties]
class SendVmsBag
{
diff --git a/src/Infrastructure/Client/GuzzleClient.php b/src/Infrastructure/Client/GuzzleClient.php
deleted file mode 100644
index 97c9cc6..0000000
--- a/src/Infrastructure/Client/GuzzleClient.php
+++ /dev/null
@@ -1,48 +0,0 @@
-proxy = $proxy;
- }
-
- public function sendRequest(RequestInterface $request): ResponseInterface
- {
- $guzzleClient = new Client([
- RequestOptions::HTTP_ERRORS => false,
- RequestOptions::PROXY => $this->proxy,
- ]);
-
- try {
- return $guzzleClient->send($request);
- } catch (GuzzleRequestException $e) {
- throw RequestException::create($request, $e);
- } catch (GuzzleTransferException $e) {
- throw NetworkException::create($request, $e);
- } catch (GuzzleException $e) {
- throw ClientException::create($request, $e);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Infrastructure/Client/GuzzleClientFactory.php b/src/Infrastructure/Client/GuzzleClientFactory.php
deleted file mode 100644
index e9980a5..0000000
--- a/src/Infrastructure/Client/GuzzleClientFactory.php
+++ /dev/null
@@ -1,46 +0,0 @@
-logger = new NullLogger();
- $this->apiToken = $apiToken;
- $this->uri = $uri;
- $this->proxy = $proxy;
- }
-
- public function createClient(): ClientInterface
- {
- $client = new GuzzleClient($this->proxy);
- $client = new GuzzleClientLoggerDecorator($client, $this->logger);
- $client = new GuzzleClientBaseUriDecorator($client, $this->uri);
- $client = new GuzzleClientAuthorizationHeaderDecorator($client, $this->apiToken);
- $client = new GuzzleClientUserAgentHeaderDecorator($client);
- $client = new GuzzleClientCorrelationIdHeaderDecorator($client);
-
- return $client;
- }
-}
diff --git a/src/Infrastructure/Client/Exception/ClientException.php b/src/Infrastructure/HttpClient/ClientException.php
similarity index 52%
rename from src/Infrastructure/Client/Exception/ClientException.php
rename to src/Infrastructure/HttpClient/ClientException.php
index c276470..a17f164 100644
--- a/src/Infrastructure/Client/Exception/ClientException.php
+++ b/src/Infrastructure/HttpClient/ClientException.php
@@ -2,23 +2,24 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Exception;
+namespace Smsapi\Client\Infrastructure\HttpClient;
+use Exception;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\RequestInterface;
-use Throwable;
/**
* @api
*/
-class ClientException extends \Exception implements ClientExceptionInterface
+class ClientException extends Exception implements ClientExceptionInterface
{
private $request;
- public static function create(RequestInterface $request, Throwable $previous): self
+ public static function withRequest(string $message, RequestInterface $request): self
{
- $exception = new self($previous->getMessage(), 0, $previous);
+ $exception = new static($message);
$exception->request = $request;
+
return $exception;
}
diff --git a/src/Infrastructure/Client/Decorator/GuzzleClientAcceptJsonHeaderDecorator.php b/src/Infrastructure/HttpClient/Decorator/AcceptJsonHeaderDecorator.php
similarity index 83%
rename from src/Infrastructure/Client/Decorator/GuzzleClientAcceptJsonHeaderDecorator.php
rename to src/Infrastructure/HttpClient/Decorator/AcceptJsonHeaderDecorator.php
index b0d1582..5997a90 100644
--- a/src/Infrastructure/Client/Decorator/GuzzleClientAcceptJsonHeaderDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/AcceptJsonHeaderDecorator.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Decorator;
+namespace Smsapi\Client\Infrastructure\HttpClient\Decorator;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
@@ -11,7 +11,7 @@
/**
* @internal
*/
-class GuzzleClientAcceptJsonHeaderDecorator implements ClientInterface
+class AcceptJsonHeaderDecorator implements ClientInterface
{
private $client;
diff --git a/src/Infrastructure/Client/Decorator/GuzzleClientAuthorizationHeaderDecorator.php b/src/Infrastructure/HttpClient/Decorator/AuthorizationHeaderDecorator.php
similarity index 85%
rename from src/Infrastructure/Client/Decorator/GuzzleClientAuthorizationHeaderDecorator.php
rename to src/Infrastructure/HttpClient/Decorator/AuthorizationHeaderDecorator.php
index 116385e..78a353e 100644
--- a/src/Infrastructure/Client/Decorator/GuzzleClientAuthorizationHeaderDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/AuthorizationHeaderDecorator.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Decorator;
+namespace Smsapi\Client\Infrastructure\HttpClient\Decorator;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
@@ -11,7 +11,7 @@
/**
* @internal
*/
-class GuzzleClientAuthorizationHeaderDecorator implements ClientInterface
+class AuthorizationHeaderDecorator implements ClientInterface
{
private $client;
private $apiToken;
diff --git a/src/Infrastructure/Client/Decorator/GuzzleClientBaseUriDecorator.php b/src/Infrastructure/HttpClient/Decorator/BaseUriDecorator.php
similarity index 51%
rename from src/Infrastructure/Client/Decorator/GuzzleClientBaseUriDecorator.php
rename to src/Infrastructure/HttpClient/Decorator/BaseUriDecorator.php
index decf602..79cc2fc 100644
--- a/src/Infrastructure/Client/Decorator/GuzzleClientBaseUriDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/BaseUriDecorator.php
@@ -2,16 +2,17 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Decorator;
+namespace Smsapi\Client\Infrastructure\HttpClient\Decorator;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
+use Smsapi\Client\Infrastructure\HttpClient\RequestException;
/**
* @internal
*/
-class GuzzleClientBaseUriDecorator implements ClientInterface
+class BaseUriDecorator implements ClientInterface
{
private $client;
private $baseUri;
@@ -33,11 +34,22 @@ private function prependBaseUri(RequestInterface $request): RequestInterface
{
$uri = $request->getUri();
+ if (!filter_var($this->baseUri, FILTER_VALIDATE_URL)) {
+ throw RequestException::withRequest("Invalid Base URI", $request);
+ }
+
$baseUriParts = parse_url($this->baseUri);
- $uri = $uri->withScheme($baseUriParts['scheme'] ?? '');
- $uri = $uri->withHost($baseUriParts['host'] ?? '');
- $uri = $uri->withPath($baseUriParts['path'] . $uri->getPath());
+ $scheme = $baseUriParts['scheme'] ?? '';
+ $host = $baseUriParts['host'] ?? '';
+ $port = $baseUriParts['port'] ?? null;
+ $basePath = $baseUriParts['path'] ?? '';
+ $basePath = rtrim($basePath, '/');
+
+ $uri = $uri->withPath($basePath . '/' . $uri->getPath());
+ $uri = $uri->withPort($port);
+ $uri = $uri->withHost($host);
+ $uri = $uri->withScheme($scheme);
return $request->withUri($uri);
}
diff --git a/src/Infrastructure/Client/Decorator/GuzzleClientCorrelationIdHeaderDecorator.php b/src/Infrastructure/HttpClient/Decorator/CorrelationIdHeaderDecorator.php
similarity index 85%
rename from src/Infrastructure/Client/Decorator/GuzzleClientCorrelationIdHeaderDecorator.php
rename to src/Infrastructure/HttpClient/Decorator/CorrelationIdHeaderDecorator.php
index 86ac269..f54a2e4 100644
--- a/src/Infrastructure/Client/Decorator/GuzzleClientCorrelationIdHeaderDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/CorrelationIdHeaderDecorator.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Decorator;
+namespace Smsapi\Client\Infrastructure\HttpClient\Decorator;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
@@ -11,7 +11,7 @@
/**
* @internal
*/
-class GuzzleClientCorrelationIdHeaderDecorator implements ClientInterface
+class CorrelationIdHeaderDecorator implements ClientInterface
{
private $client;
diff --git a/src/Infrastructure/Client/Decorator/GuzzleClientUserAgentHeaderDecorator.php b/src/Infrastructure/HttpClient/Decorator/HttpClientUserAgentHeaderDecorator.php
similarity index 75%
rename from src/Infrastructure/Client/Decorator/GuzzleClientUserAgentHeaderDecorator.php
rename to src/Infrastructure/HttpClient/Decorator/HttpClientUserAgentHeaderDecorator.php
index b4610cd..6b86a4c 100644
--- a/src/Infrastructure/Client/Decorator/GuzzleClientUserAgentHeaderDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/HttpClientUserAgentHeaderDecorator.php
@@ -2,9 +2,8 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Decorator;
+namespace Smsapi\Client\Infrastructure\HttpClient\Decorator;
-use GuzzleHttp\ClientInterface as GuzzleClientInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
@@ -13,7 +12,7 @@
/**
* @internal
*/
-class GuzzleClientUserAgentHeaderDecorator implements ClientInterface
+class HttpClientUserAgentHeaderDecorator implements ClientInterface
{
private $client;
@@ -37,9 +36,8 @@ private function addUserAgentHeader(RequestInterface $request): RequestInterface
private function createUserAgent(): string
{
return sprintf(
- 'smsapi/php-client:%s;guzzle:%s;php:%s',
+ 'smsapi/php-client:%s;php:%s',
SmsapiClient::VERSION,
- GuzzleClientInterface::VERSION,
PHP_VERSION
);
}
diff --git a/src/Infrastructure/Client/Decorator/GuzzleClientLoggerDecorator.php b/src/Infrastructure/HttpClient/Decorator/LoggerDecorator.php
similarity index 61%
rename from src/Infrastructure/Client/Decorator/GuzzleClientLoggerDecorator.php
rename to src/Infrastructure/HttpClient/Decorator/LoggerDecorator.php
index f033c1a..decd283 100644
--- a/src/Infrastructure/Client/Decorator/GuzzleClientLoggerDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/LoggerDecorator.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Decorator;
+namespace Smsapi\Client\Infrastructure\HttpClient\Decorator;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
@@ -12,7 +12,7 @@
/**
* @internal
*/
-class GuzzleClientLoggerDecorator implements ClientInterface
+class LoggerDecorator implements ClientInterface
{
private $client;
private $logger;
@@ -26,13 +26,20 @@ public function __construct(ClientInterface $client, LoggerInterface $logger)
public function sendRequest(RequestInterface $request): ResponseInterface
{
$this->logger->info('Request', [
+ 'request' => $request,
'method' => $request->getMethod(),
'uri' => $request->getUri(),
+ 'headers' => $request->getHeaders(),
+ 'body' => $request->getBody()->getContents(),
]);
$response = $this->client->sendRequest($request);
- $this->logger->info('Response', ['response' => $response]);
+ $this->logger->info('Response', [
+ 'response' => $response,
+ 'headers' => $response->getHeaders(),
+ 'body' => $response->getBody()->getContents(),
+ ]);
return $response;
}
diff --git a/src/Infrastructure/HttpClient/HttpClientFactory.php b/src/Infrastructure/HttpClient/HttpClientFactory.php
new file mode 100644
index 0000000..2cbf467
--- /dev/null
+++ b/src/Infrastructure/HttpClient/HttpClientFactory.php
@@ -0,0 +1,43 @@
+logger = new NullLogger();
+ $this->apiToken = $apiToken;
+ $this->uri = $uri;
+ }
+
+ public function createClient(ClientInterface $externalClient): ClientInterface
+ {
+ $client = new LoggerDecorator($externalClient, $this->logger);
+ $client = new BaseUriDecorator($client, $this->uri);
+ $client = new AuthorizationHeaderDecorator($client, $this->apiToken);
+ $client = new HttpClientUserAgentHeaderDecorator($client);
+ $client = new CorrelationIdHeaderDecorator($client);
+
+ return $client;
+ }
+}
diff --git a/src/Infrastructure/Client/Exception/NetworkException.php b/src/Infrastructure/HttpClient/NetworkException.php
similarity index 76%
rename from src/Infrastructure/Client/Exception/NetworkException.php
rename to src/Infrastructure/HttpClient/NetworkException.php
index bc49aa8..8464188 100644
--- a/src/Infrastructure/Client/Exception/NetworkException.php
+++ b/src/Infrastructure/HttpClient/NetworkException.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Exception;
+namespace Smsapi\Client\Infrastructure\HttpClient;
use Psr\Http\Client\NetworkExceptionInterface;
diff --git a/src/Infrastructure/Client/Exception/RequestException.php b/src/Infrastructure/HttpClient/RequestException.php
similarity index 76%
rename from src/Infrastructure/Client/Exception/RequestException.php
rename to src/Infrastructure/HttpClient/RequestException.php
index f719a12..2158e32 100644
--- a/src/Infrastructure/Client/Exception/RequestException.php
+++ b/src/Infrastructure/HttpClient/RequestException.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Smsapi\Client\Infrastructure\Client\Exception;
+namespace Smsapi\Client\Infrastructure\HttpClient;
use Psr\Http\Client\RequestExceptionInterface;
diff --git a/src/Infrastructure/RequestAssembler/GuzzleRequestAssembler.php b/src/Infrastructure/RequestAssembler/GuzzleRequestAssembler.php
deleted file mode 100644
index 4dff137..0000000
--- a/src/Infrastructure/RequestAssembler/GuzzleRequestAssembler.php
+++ /dev/null
@@ -1,25 +0,0 @@
-getMethod(),
- $request->getUri(),
- $request->getHeaders(),
- $request->getBody()
- );
- }
-}
diff --git a/src/Infrastructure/RequestAssembler/RequestAssembler.php b/src/Infrastructure/RequestAssembler/RequestAssembler.php
new file mode 100644
index 0000000..1b76a01
--- /dev/null
+++ b/src/Infrastructure/RequestAssembler/RequestAssembler.php
@@ -0,0 +1,41 @@
+requestFactory = $requestFactory;
+ $this->streamFactory = $streamFactory;
+ }
+
+ public function assemble(Request $requestDTO): RequestInterface
+ {
+ $request = $this->requestFactory->createRequest(
+ $requestDTO->getMethod(),
+ $requestDTO->getUri()
+ );
+
+ foreach ($requestDTO->getHeaders() as $header => $value) {
+ $request = $request->withHeader($header, $value);
+ }
+
+ $request = $request->withBody($this->streamFactory->createStream($requestDTO->getBody()));
+
+ return $request;
+ }
+}
diff --git a/src/Infrastructure/RequestExecutor/LegacyRequestExecutor.php b/src/Infrastructure/RequestExecutor/LegacyRequestExecutor.php
index c260e47..8aaec38 100644
--- a/src/Infrastructure/RequestExecutor/LegacyRequestExecutor.php
+++ b/src/Infrastructure/RequestExecutor/LegacyRequestExecutor.php
@@ -5,7 +5,9 @@
namespace Smsapi\Client\Infrastructure\RequestExecutor;
use Psr\Http\Client\ClientInterface;
-use Smsapi\Client\Infrastructure\RequestAssembler\GuzzleRequestAssembler;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+use Smsapi\Client\Infrastructure\RequestAssembler\RequestAssembler;
use Smsapi\Client\Infrastructure\RequestMapper\LegacyRequestMapper;
use Smsapi\Client\Infrastructure\ResponseMapper\LegacyResponseMapper;
use stdClass;
@@ -18,25 +20,28 @@ class LegacyRequestExecutor
private $requestMapper;
private $client;
private $legacyResponseMapper;
- private $requestAssembler;
+ private $requestFactory;
+ private $streamFactory;
public function __construct(
LegacyRequestMapper $requestMapper,
ClientInterface $client,
LegacyResponseMapper $legacyResponseMapper,
- GuzzleRequestAssembler $requestAssembler
+ RequestFactoryInterface $requestFactory,
+ StreamFactoryInterface $streamFactory
) {
$this->requestMapper = $requestMapper;
$this->client = $client;
$this->legacyResponseMapper = $legacyResponseMapper;
- $this->requestAssembler = $requestAssembler;
+ $this->requestFactory = $requestFactory;
+ $this->streamFactory = $streamFactory;
}
public function request(string $path, array $builtInParameters, array $userParameters = []): stdClass
{
$request = $this->requestMapper->map($path, $builtInParameters, $userParameters);
- $assembledRequest = $this->requestAssembler->assemble($request);
+ $assembledRequest = (new RequestAssembler($this->requestFactory, $this->streamFactory))->assemble($request);
$response = $this->client->sendRequest($assembledRequest);
diff --git a/src/Infrastructure/RequestExecutor/RequestExecutorFactory.php b/src/Infrastructure/RequestExecutor/RequestExecutorFactory.php
index 19a1f3e..4be0532 100644
--- a/src/Infrastructure/RequestExecutor/RequestExecutorFactory.php
+++ b/src/Infrastructure/RequestExecutor/RequestExecutorFactory.php
@@ -5,10 +5,11 @@
namespace Smsapi\Client\Infrastructure\RequestExecutor;
use Psr\Http\Client\ClientInterface;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
-use Smsapi\Client\Infrastructure\Client\GuzzleClientFactory;
-use Smsapi\Client\Infrastructure\RequestAssembler\GuzzleRequestAssembler;
+use Smsapi\Client\Infrastructure\HttpClient\HttpClientFactory;
use Smsapi\Client\Infrastructure\RequestMapper\Query\Formatter\ComplexParametersQueryFormatter;
use Smsapi\Client\Infrastructure\ResponseMapper\LegacyResponseMapper;
use Smsapi\Client\Infrastructure\RequestMapper\RestRequestMapper;
@@ -25,19 +26,24 @@ class RequestExecutorFactory
private $queryFormatter;
private $jsonDecode;
- private $requestAssembler;
- private $guzzleClientFactory;
+ private $httpClientFactory;
+ private $requestFactory;
+ private $streamFactory;
- public function __construct(GuzzleClientFactory $guzzleClientFactory)
- {
+ public function __construct(
+ HttpClientFactory $httpClientFactory,
+ RequestFactoryInterface $requestFactory,
+ StreamFactoryInterface $streamFactory
+ ) {
$this->logger = new NullLogger();
$this->queryFormatter = new ComplexParametersQueryFormatter();
$this->jsonDecode = new JsonDecode();
- $this->requestAssembler = new GuzzleRequestAssembler();
- $this->guzzleClientFactory = $guzzleClientFactory;
+ $this->httpClientFactory = $httpClientFactory;
+ $this->requestFactory = $requestFactory;
+ $this->streamFactory = $streamFactory;
}
- public function createRestRequestExecutor(): RestRequestExecutor
+ public function createRestRequestExecutor(ClientInterface $externalClient): RestRequestExecutor
{
$restRequestMapper = new RestRequestMapper($this->queryFormatter);
$restResponseMapper = new RestResponseMapper($this->jsonDecode);
@@ -45,13 +51,14 @@ public function createRestRequestExecutor(): RestRequestExecutor
return new RestRequestExecutor(
$restRequestMapper,
- $this->createGuzzleClient(),
+ $this->createHttpClient($externalClient),
$restResponseMapper,
- $this->requestAssembler
+ $this->requestFactory,
+ $this->streamFactory
);
}
- public function createLegacyRequestExecutor(): LegacyRequestExecutor
+ public function createLegacyRequestExecutor(ClientInterface $externalClient): LegacyRequestExecutor
{
$legacyRequestMapper = new LegacyRequestMapper($this->queryFormatter);
$legacyResponseMapper = new LegacyResponseMapper($this->jsonDecode);
@@ -59,15 +66,16 @@ public function createLegacyRequestExecutor(): LegacyRequestExecutor
return new LegacyRequestExecutor(
$legacyRequestMapper,
- $this->createGuzzleClient(),
+ $this->createHttpClient($externalClient),
$legacyResponseMapper,
- $this->requestAssembler
+ $this->requestFactory,
+ $this->streamFactory
);
}
- private function createGuzzleClient(): ClientInterface
+ private function createHttpClient(ClientInterface $externalHttpClient): ClientInterface
{
- $this->guzzleClientFactory->setLogger($this->logger);
- return $this->guzzleClientFactory->createClient();
+ $this->httpClientFactory->setLogger($this->logger);
+ return $this->httpClientFactory->createClient($externalHttpClient);
}
}
diff --git a/src/Infrastructure/RequestExecutor/RestRequestExecutor.php b/src/Infrastructure/RequestExecutor/RestRequestExecutor.php
index 5914b92..8665951 100644
--- a/src/Infrastructure/RequestExecutor/RestRequestExecutor.php
+++ b/src/Infrastructure/RequestExecutor/RestRequestExecutor.php
@@ -5,8 +5,10 @@
namespace Smsapi\Client\Infrastructure\RequestExecutor;
use Psr\Http\Client\ClientInterface;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
use Smsapi\Client\Infrastructure\Request;
-use Smsapi\Client\Infrastructure\RequestAssembler\GuzzleRequestAssembler;
+use Smsapi\Client\Infrastructure\RequestAssembler\RequestAssembler;
use Smsapi\Client\Infrastructure\RequestMapper\RestRequestMapper;
use Smsapi\Client\Infrastructure\ResponseMapper\RestResponseMapper;
use stdClass;
@@ -19,18 +21,21 @@ class RestRequestExecutor
private $requestMapper;
private $client;
private $restResponseMapper;
- private $requestAssembler;
+ private $requestFactory;
+ private $streamFactory;
public function __construct(
RestRequestMapper $requestMapper,
ClientInterface $client,
RestResponseMapper $restResponseMapper,
- GuzzleRequestAssembler $guzzleRequestAssembler
+ RequestFactoryInterface $requestFactory,
+ StreamFactoryInterface $streamFactory
) {
$this->requestMapper = $requestMapper;
$this->client = $client;
$this->restResponseMapper = $restResponseMapper;
- $this->requestAssembler = $guzzleRequestAssembler;
+ $this->requestFactory = $requestFactory;
+ $this->streamFactory = $streamFactory;
}
public function create(string $path, array $builtInParameters, array $userParameters = []): stdClass
@@ -68,7 +73,7 @@ public function info(string $path, array $builtInParameters, array $userParamete
private function sendRequestAndMapResponse(Request $request): stdClass
{
- $assembledRequest = $this->requestAssembler->assemble($request);
+ $assembledRequest = (new RequestAssembler($this->requestFactory, $this->streamFactory))->assemble($request);
$response = $this->client->sendRequest($assembledRequest);
diff --git a/src/Infrastructure/RequestMapper/LegacyRequestMapper.php b/src/Infrastructure/RequestMapper/LegacyRequestMapper.php
index c59e314..b881e30 100644
--- a/src/Infrastructure/RequestMapper/LegacyRequestMapper.php
+++ b/src/Infrastructure/RequestMapper/LegacyRequestMapper.php
@@ -34,9 +34,7 @@ private function createRequest(
array $builtInParameters,
array $userParameters
): Request {
- $builtInParameters['format'] = 'json';
-
- $parameters = new QueryParametersData($builtInParameters, $userParameters);
+ $parameters = new QueryParametersData(['format' => 'json'] + $builtInParameters, $userParameters);
return new Request($method, $path, $this->queryFormatter->format($parameters));
}
diff --git a/src/Infrastructure/ResponseHttpCode.php b/src/Infrastructure/ResponseHttpCode.php
index 2c201f5..4ef42b5 100644
--- a/src/Infrastructure/ResponseHttpCode.php
+++ b/src/Infrastructure/ResponseHttpCode.php
@@ -13,5 +13,6 @@ class ResponseHttpCode
const CREATED = 201;
const ACCEPTED = 202;
const NO_CONTENT = 204;
+ const REQUEST_TIMEOUT = 408;
const SERVICE_UNAVAILABLE = 503;
}
diff --git a/src/Infrastructure/ResponseMapper/RestResponseMapper.php b/src/Infrastructure/ResponseMapper/RestResponseMapper.php
index fff15e3..04106a3 100644
--- a/src/Infrastructure/ResponseMapper/RestResponseMapper.php
+++ b/src/Infrastructure/ResponseMapper/RestResponseMapper.php
@@ -40,6 +40,8 @@ public function map(ResponseInterface $response): stdClass
return new stdClass();
} elseif ($statusCode == ResponseHttpCode::SERVICE_UNAVAILABLE) {
throw ApiErrorException::withMessageAndStatusCode('Service unavailable', $statusCode);
+ } elseif ($statusCode == ResponseHttpCode::REQUEST_TIMEOUT) {
+ throw ApiErrorException::withMessageAndStatusCode('Request timed out', $statusCode);
} elseif ($contents) {
$object = $this->jsonDecode->decode($contents);
diff --git a/src/Service/HttpDefaultFeatures.php b/src/Service/HttpDefaultFeatures.php
index 61f99ef..0189fe7 100644
--- a/src/Service/HttpDefaultFeatures.php
+++ b/src/Service/HttpDefaultFeatures.php
@@ -10,8 +10,6 @@
use Smsapi\Client\Feature\Data\DataFactoryProvider;
use Smsapi\Client\Feature\Hlr\HlrFeature;
use Smsapi\Client\Feature\Hlr\HlrHttpFeature;
-use Smsapi\Client\Feature\Push\PushFeature;
-use Smsapi\Client\Feature\Push\PushHttpFeature;
use Smsapi\Client\Feature\ShortUrl\ShortUlrHttpFeature;
use Smsapi\Client\Feature\ShortUrl\ShortUrlFeature;
use Smsapi\Client\Feature\Mfa\MfaFeature;
@@ -37,7 +35,7 @@ trait HttpDefaultFeatures
public function pingFeature(): PingFeature
{
- $restRequestExecutor = $this->requestExecutorFactory->createRestRequestExecutor();
+ $restRequestExecutor = $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient);
$pingFactory = $this->dataFactoryProvider->providePingFactory();
return new PingHttpFeature($restRequestExecutor, $pingFactory);
@@ -45,12 +43,16 @@ public function pingFeature(): PingFeature
public function smsFeature(): SmsFeature
{
- return new SmsHttpFeature($this->requestExecutorFactory, $this->dataFactoryProvider);
+ return new SmsHttpFeature(
+ $this->externalHttpClient,
+ $this->requestExecutorFactory,
+ $this->dataFactoryProvider
+ );
}
public function mfaFeature(): MfaFeature
{
- $restRequestExecutor = $this->requestExecutorFactory->createRestRequestExecutor();
+ $restRequestExecutor = $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient);
$mfaFactory = $this->dataFactoryProvider->provideMfaFactory();
return new MfaHttpFeature($restRequestExecutor, $mfaFactory);
@@ -59,7 +61,7 @@ public function mfaFeature(): MfaFeature
public function hlrFeature(): HlrFeature
{
return new HlrHttpFeature(
- $this->requestExecutorFactory->createLegacyRequestExecutor(),
+ $this->requestExecutorFactory->createLegacyRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider->provideHlrFactory()
);
}
@@ -67,7 +69,7 @@ public function hlrFeature(): HlrFeature
public function subusersFeature(): SubusersFeature
{
return new SubusersHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
+ $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider->provideSubuserFactory()
);
}
@@ -75,7 +77,7 @@ public function subusersFeature(): SubusersFeature
public function shortUrlFeature(): ShortUrlFeature
{
return new ShortUlrHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
+ $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider->provideShortUrlLinkFactory()
);
}
@@ -83,23 +85,15 @@ public function shortUrlFeature(): ShortUrlFeature
public function contactsFeature(): ContactsFeature
{
return new ContactsHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
+ $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider
);
}
- public function pushFeature(): PushFeature
- {
- return new PushHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
- $this->dataFactoryProvider->providePushShipmentFactory()
- );
- }
-
public function blacklistFeature(): BlacklistFeature
{
return new BlacklistHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
+ $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider->provideBlacklistedPhoneNumberFactory()
);
}
diff --git a/src/Service/SmsapiComHttpService.php b/src/Service/SmsapiComHttpService.php
index a32742a..39d5816 100644
--- a/src/Service/SmsapiComHttpService.php
+++ b/src/Service/SmsapiComHttpService.php
@@ -4,11 +4,10 @@
namespace Smsapi\Client\Service;
+use Psr\Http\Client\ClientInterface;
use Smsapi\Client\Feature\Data\DataFactoryProvider;
use Smsapi\Client\Feature\Profile\ProfileFeature;
use Smsapi\Client\Feature\Profile\ProfileHttpFeature;
-use Smsapi\Client\Feature\Profile\SmsapiPlProfileFeature;
-use Smsapi\Client\Feature\Profile\SmsapiPlProfileHttpFeature;
use Smsapi\Client\Infrastructure\RequestExecutor\RequestExecutorFactory;
/**
@@ -18,13 +17,16 @@ class SmsapiComHttpService implements SmsapiComService
{
use HttpDefaultFeatures;
+ private $externalHttpClient;
private $requestExecutorFactory;
private $dataFactoryProvider;
public function __construct(
+ ClientInterface $externalHttpClient,
RequestExecutorFactory $requestExecutorFactory,
DataFactoryProvider $dataFactoryProvider
) {
+ $this->externalHttpClient = $externalHttpClient;
$this->requestExecutorFactory = $requestExecutorFactory;
$this->dataFactoryProvider = $dataFactoryProvider;
}
@@ -32,7 +34,7 @@ public function __construct(
public function profileFeature(): ProfileFeature
{
return new ProfileHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
+ $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider
);
}
diff --git a/src/Service/SmsapiComService.php b/src/Service/SmsapiComService.php
index ccb43cc..a86abed 100644
--- a/src/Service/SmsapiComService.php
+++ b/src/Service/SmsapiComService.php
@@ -9,7 +9,6 @@
use Smsapi\Client\Feature\Hlr\HlrFeature;
use Smsapi\Client\Feature\Ping\PingFeature;
use Smsapi\Client\Feature\Profile\ProfileFeature;
-use Smsapi\Client\Feature\Push\PushFeature;
use Smsapi\Client\Feature\ShortUrl\ShortUrlFeature;
use Smsapi\Client\Feature\Mfa\MfaFeature;
use Smsapi\Client\Feature\Sms\SmsFeature;
@@ -36,8 +35,5 @@ public function shortUrlFeature(): ShortUrlFeature;
public function contactsFeature(): ContactsFeature;
- /** @deprecated */
- public function pushFeature(): PushFeature;
-
public function blacklistFeature(): BlacklistFeature;
}
diff --git a/src/Service/SmsapiPlHttpService.php b/src/Service/SmsapiPlHttpService.php
index 4ba8425..17f9772 100644
--- a/src/Service/SmsapiPlHttpService.php
+++ b/src/Service/SmsapiPlHttpService.php
@@ -4,6 +4,7 @@
namespace Smsapi\Client\Service;
+use Psr\Http\Client\ClientInterface;
use Smsapi\Client\Feature\Data\DataFactoryProvider;
use Smsapi\Client\Feature\Mms\MmsFeature;
use Smsapi\Client\Feature\Mms\MmsHttpFeature;
@@ -20,13 +21,16 @@ class SmsapiPlHttpService implements SmsapiPlService
{
use HttpDefaultFeatures;
+ private $externalHttpClient;
private $requestExecutorFactory;
private $dataFactoryProvider;
public function __construct(
+ ClientInterface $externalHttpClient,
RequestExecutorFactory $requestExecutorFactory,
DataFactoryProvider $dataFactoryProvider
) {
+ $this->externalHttpClient = $externalHttpClient;
$this->requestExecutorFactory = $requestExecutorFactory;
$this->dataFactoryProvider = $dataFactoryProvider;
}
@@ -34,7 +38,7 @@ public function __construct(
public function mmsFeature(): MmsFeature
{
return new MmsHttpFeature(
- $this->requestExecutorFactory->createLegacyRequestExecutor(),
+ $this->requestExecutorFactory->createLegacyRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider->provideMmsFactory()
);
}
@@ -42,7 +46,7 @@ public function mmsFeature(): MmsFeature
public function vmsFeature(): VmsFeature
{
return new VmsHttpFeature(
- $this->requestExecutorFactory->createLegacyRequestExecutor(),
+ $this->requestExecutorFactory->createLegacyRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider->provideVmsFactory()
);
}
@@ -50,7 +54,7 @@ public function vmsFeature(): VmsFeature
public function profileFeature(): SmsapiPlProfileFeature
{
return new SmsapiPlProfileHttpFeature(
- $this->requestExecutorFactory->createRestRequestExecutor(),
+ $this->requestExecutorFactory->createRestRequestExecutor($this->externalHttpClient),
$this->dataFactoryProvider
);
}
diff --git a/src/Service/SmsapiPlService.php b/src/Service/SmsapiPlService.php
index 7cf33f4..2f4e9b8 100644
--- a/src/Service/SmsapiPlService.php
+++ b/src/Service/SmsapiPlService.php
@@ -10,7 +10,6 @@
use Smsapi\Client\Feature\Mms\MmsFeature;
use Smsapi\Client\Feature\Ping\PingFeature;
use Smsapi\Client\Feature\Profile\SmsapiPlProfileFeature;
-use Smsapi\Client\Feature\Push\PushFeature;
use Smsapi\Client\Feature\ShortUrl\ShortUrlFeature;
use Smsapi\Client\Feature\Mfa\MfaFeature;
use Smsapi\Client\Feature\Sms\SmsFeature;
@@ -38,9 +37,6 @@ public function shortUrlFeature(): ShortUrlFeature;
public function contactsFeature(): ContactsFeature;
- /** @deprecated */
- public function pushFeature(): PushFeature;
-
public function mmsFeature(): MmsFeature;
public function vmsFeature(): VmsFeature;
diff --git a/src/SmsapiClient.php b/src/SmsapiClient.php
index b7bd2c7..1c2bc2b 100644
--- a/src/SmsapiClient.php
+++ b/src/SmsapiClient.php
@@ -12,9 +12,7 @@
*/
interface SmsapiClient extends LoggerAwareInterface
{
- const VERSION = 'Unreleased';
-
- public function setProxy(string $proxy): self;
+ const VERSION = '3.0.13';
public function smsapiPlService(string $apiToken): SmsapiPlService;
diff --git a/src/SmsapiClientException.php b/src/SmsapiClientException.php
index 07bd9b1..3581dea 100644
--- a/src/SmsapiClientException.php
+++ b/src/SmsapiClientException.php
@@ -3,9 +3,11 @@
namespace Smsapi\Client;
+use Exception;
+
/**
* @api
*/
-class SmsapiClientException extends \Exception
+class SmsapiClientException extends Exception
{
}
diff --git a/src/SmsapiHttpClient.php b/src/SmsapiHttpClient.php
index 9723bc6..00b8967 100644
--- a/src/SmsapiHttpClient.php
+++ b/src/SmsapiHttpClient.php
@@ -4,10 +4,13 @@
namespace Smsapi\Client;
+use Psr\Http\Client\ClientInterface;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
use Smsapi\Client\Feature\Data\DataFactoryProvider;
-use Smsapi\Client\Infrastructure\Client\GuzzleClientFactory;
+use Smsapi\Client\Infrastructure\HttpClient\HttpClientFactory;
use Smsapi\Client\Infrastructure\RequestExecutor\RequestExecutorFactory;
use Smsapi\Client\Service\SmsapiComService;
use Smsapi\Client\Service\SmsapiComHttpService;
@@ -21,22 +24,24 @@ class SmsapiHttpClient implements SmsapiClient
{
use LoggerAwareTrait;
+ private $httpClient;
+ private $requestFactory;
+ private $streamFactory;
+
private $smsapiPlUri = 'https://api.smsapi.pl';
private $smsapiComUri = 'https://api.smsapi.com';
- private $proxy = '';
private $dataFactoryProvider;
- public function __construct()
- {
+ public function __construct(
+ ClientInterface $httpClient,
+ RequestFactoryInterface $requestFactory,
+ StreamFactoryInterface $streamFactory
+ ) {
+ $this->httpClient = $httpClient;
+ $this->requestFactory = $requestFactory;
$this->dataFactoryProvider = new DataFactoryProvider();
$this->logger = new NullLogger();
- }
-
- public function setProxy(string $proxy): SmsapiClient
- {
- $this->proxy = $proxy;
-
- return $this;
+ $this->streamFactory = $streamFactory;
}
public function smsapiPlService(string $apiToken): SmsapiPlService
@@ -47,6 +52,7 @@ public function smsapiPlService(string $apiToken): SmsapiPlService
public function smsapiPlServiceWithUri(string $apiToken, string $uri): SmsapiPlService
{
return new SmsapiPlHttpService(
+ $this->httpClient,
$this->createRequestExecutorFactory($apiToken, $uri),
$this->dataFactoryProvider
);
@@ -60,6 +66,7 @@ public function smsapiComService(string $apiToken): SmsapiComService
public function smsapiComServiceWithUri(string $apiToken, string $uri): SmsapiComService
{
return new SmsapiComHttpService(
+ $this->httpClient,
$this->createRequestExecutorFactory($apiToken, $uri),
$this->dataFactoryProvider
);
@@ -67,8 +74,8 @@ public function smsapiComServiceWithUri(string $apiToken, string $uri): SmsapiCo
private function createRequestExecutorFactory(string $apiToken, string $uri): RequestExecutorFactory
{
- $guzzleClientFactory = new GuzzleClientFactory($apiToken, $uri, $this->proxy);
- $requestExecutorFactory = new RequestExecutorFactory($guzzleClientFactory);
+ $httpClientFactory = new HttpClientFactory($apiToken, $uri);
+ $requestExecutorFactory = new RequestExecutorFactory($httpClientFactory, $this->requestFactory, $this->streamFactory);
$requestExecutorFactory->setLogger($this->logger);
return $requestExecutorFactory;
diff --git a/tests-resources/config/config.dist.yml b/tests-resources/config/config.dist.yml
index c3da0b8..7f9437f 100644
--- a/tests-resources/config/config.dist.yml
+++ b/tests-resources/config/config.dist.yml
@@ -1,3 +1,3 @@
Service name: SMSAPI.PL
API URI: https://api.smsapi.pl
-logger: false
+API token: 0000000000000000000000000000000000000000
diff --git a/tests-resources/config/config.yml.example b/tests-resources/config/config.yml.example
index ffbe66d..f93b66c 100644
--- a/tests-resources/config/config.yml.example
+++ b/tests-resources/config/config.yml.example
@@ -1,4 +1,3 @@
Service name: "SMSAPI.PL" OR "SMSAPI.COM"
API token: 40-characters length string generated in SMSAPI Panel
API URI: "https://api.smsapi.pl", "https://api.smsapi.com", "https://api2.smsapi.pl" or "https://api2.smsapi.com"
-logger: true
diff --git a/phpunit.dist.xml b/tests-resources/phpunit.dist.xml
similarity index 53%
rename from phpunit.dist.xml
rename to tests-resources/phpunit.dist.xml
index 95cb746..4d4acd5 100644
--- a/phpunit.dist.xml
+++ b/tests-resources/phpunit.dist.xml
@@ -1,7 +1,7 @@
- tests
+ ../tests
- tests/Unit
+ ../tests/Unit
- tests/Integration
+ ../tests/Integration
- tests/Integration/Feature/Contacts
- tests/Unit/Feature/Contacts
+ ../tests/Integration/Feature/Contacts
+ ../tests/Unit/Feature/Contacts
- tests/Integration/Feature/Hlr
+ ../tests/Integration/Feature/Hlr
- tests/Integration/Feature/Mms
+ ../tests/Integration/Feature/Mms
- tests/Integration/Feature/Ping
+ ../tests/Integration/Feature/Ping
- tests/Integration/Feature/Profile
+ ../tests/Integration/Feature/Profile
- tests/Unit/Feature/Push
+ ../tests/Unit/Feature/Push
- tests/Integration/Feature/Sendernames
+ ../tests/Integration/Feature/Sendernames
- tests/Integration/Feature/ShortUrl
+ ../tests/Integration/Feature/ShortUrl
- tests/Integration/Feature/Sms
- tests/Unit/Feature/Sms
+ ../tests/Integration/Feature/Sms
+ ../tests/Unit/Feature/Sms
- tests/Integration/Feature/Mfa
+ ../tests/Integration/Feature/Mfa
- tests/Integration/Feature/Subusers
+ ../tests/Integration/Feature/Subusers
- tests/Integration/Feature/Vms
+ ../tests/Integration/Feature/Vms
- tests/Integration/Feature/Blacklist
+ ../tests/Integration/Feature/Blacklist
+
+
+
+
+
+
diff --git a/tests/Config.php b/tests/Config.php
index 05e94b3..541ac50 100644
--- a/tests/Config.php
+++ b/tests/Config.php
@@ -20,9 +20,4 @@ public static function get(string $key)
return $config[$key] ?? null;
}
-
- public static function getServiceName(): ServiceName
- {
- return ServiceName::byValue(self::get('Service name'));
- }
}
diff --git a/tests/Fixture/GuzzleClientFactoryMother.php b/tests/Fixture/GuzzleClientFactoryMother.php
deleted file mode 100644
index 9fcfceb..0000000
--- a/tests/Fixture/GuzzleClientFactoryMother.php
+++ /dev/null
@@ -1,15 +0,0 @@
-responseStatusCode, [], $this->responseBody);
+ }
+
+ public function mockResponse(int $responseStatusCode, string $responseBody)
+ {
+ $this->responseStatusCode = $responseStatusCode;
+ $this->responseBody = $responseBody;
+ }
+}
\ No newline at end of file
diff --git a/tests/Helper/HttpClient/HttpClientRequestSpy.php b/tests/Helper/HttpClient/HttpClientRequestSpy.php
new file mode 100644
index 0000000..375e984
--- /dev/null
+++ b/tests/Helper/HttpClient/HttpClientRequestSpy.php
@@ -0,0 +1,27 @@
+lastSentRequest = $request;
+
+ return new Response();
+ }
+
+ public function getLastSentRequest(): RequestInterface
+ {
+ return $this->lastSentRequest;
+ }
+}
\ No newline at end of file
diff --git a/tests/Integration/Feature/Contacts/Fields/ContactsFieldsFeatureTest.php b/tests/Integration/Feature/Contacts/Fields/ContactsFieldsFeatureTest.php
index 09aae76..b365387 100644
--- a/tests/Integration/Feature/Contacts/Fields/ContactsFieldsFeatureTest.php
+++ b/tests/Integration/Feature/Contacts/Fields/ContactsFieldsFeatureTest.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Smsapi\Client\Tests\Integration\Contacts;
+namespace Smsapi\Client\Tests\Integration\Feature\Contacts\Fields;
use Smsapi\Client\Feature\Contacts\Bag\CreateContactBag;
use Smsapi\Client\Feature\Contacts\Bag\DeleteContactBag;
diff --git a/tests/Integration/Feature/Mfa/MfaFeatureTest.php b/tests/Integration/Feature/Mfa/MfaFeatureTest.php
index 7fdbc3c..1a01cfb 100644
--- a/tests/Integration/Feature/Mfa/MfaFeatureTest.php
+++ b/tests/Integration/Feature/Mfa/MfaFeatureTest.php
@@ -32,7 +32,7 @@ public function it_should_create_mfa()
/**
* @test
*/
- public function it_should_not_create_mfa_for_an_ivalid_mobile_phone_number()
+ public function it_should_not_create_mfa_for_an_invalid_mobile_phone_number()
{
//given
$mfaFeature = self::$smsapiService->mfaFeature();
@@ -97,7 +97,7 @@ public function it_should_not_verify_invalid_code()
{
//given
$mfaFeature = self::$smsapiService->mfaFeature();
- $verificationMfaBag = new VerificationMfaBag('123 456', PhoneNumberFixture::anyValidMobile());
+ $verificationMfaBag = new VerificationMfaBag('invalid', PhoneNumberFixture::anyValidMobile());
//expect
$this->expectException(SmsapiClientException::class);
$this->expectExceptionMessage('MFA code has invalid format');
diff --git a/tests/Integration/Feature/Ping/PingFeatureTest.php b/tests/Integration/Feature/Ping/PingFeatureTest.php
index 548ac3f..11b8df1 100644
--- a/tests/Integration/Feature/Ping/PingFeatureTest.php
+++ b/tests/Integration/Feature/Ping/PingFeatureTest.php
@@ -3,7 +3,6 @@
namespace Smsapi\Client\Tests\Integration\Feature\Ping;
-use Smsapi\Client\Feature\Ping\Data\Ping;
use Smsapi\Client\Tests\SmsapiClientIntegrationTestCase;
class PingFeatureTest extends SmsapiClientIntegrationTestCase
diff --git a/tests/Integration/Feature/Sms/SmsFeatureTest.php b/tests/Integration/Feature/Sms/SmsFeatureTest.php
index e9b056e..c5051f8 100644
--- a/tests/Integration/Feature/Sms/SmsFeatureTest.php
+++ b/tests/Integration/Feature/Sms/SmsFeatureTest.php
@@ -48,7 +48,7 @@ public function it_should_send_sms_with_external_id()
/**
* @test
*/
- public function it_should_receive_details_for_single_sms()
+ public function it_should_receive_content_details_for_single_sms()
{
$smsFeature = self::$smsapiService->smsFeature();
$sendSmsBag = $this->givenSmsToSend();
@@ -82,12 +82,12 @@ public function it_should_send_flash_sms()
public function it_should_send_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $sendSmssBag = $this->givenSmssToSend();
+ $sendSmssBag = $this->givenSmssToSend(2);
$sendSmssBag->test = true;
$results = $smsFeature->sendSmss($sendSmssBag);
- $this->assertCount(count($sendSmssBag->to), $results);
+ $this->assertCount(2, $results);
}
/**
@@ -96,27 +96,28 @@ public function it_should_send_smss()
public function it_should_send_flash_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $sendSmssBag = $this->givenSmssToSend();
+ $sendSmssBag = $this->givenSmssToSend(2);
$sendSmssBag->test = true;
$results = $smsFeature->sendFlashSmss($sendSmssBag);
- $this->assertCount(count($sendSmssBag->to), $results);
+ $this->assertCount(2, $results);
}
/**
* @test
*/
- public function it_should_not_receive_details_for_smss()
+ public function it_should_not_receive_content_details_for_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $sendSmsesBag = $this->givenSmssToSend();
+ $sendSmsesBag = $this->givenSmssToSend(2);
$sendSmsesBag->test = true;
+ /** @var Sms[] $results */
$results = $smsFeature->sendSmss($sendSmsesBag);
foreach ($results as $result) {
- $this->assertNull($result->details);
+ $this->assertNull($result->content);
}
}
@@ -141,12 +142,12 @@ public function it_should_schedule_sms()
public function it_should_schedule_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $scheduleSmssBag = $this->givenSmssToSchedule();
+ $scheduleSmssBag = $this->givenSmssToSchedule(2);
$scheduleSmssBag->test = true;
$results = $smsFeature->scheduleSmss($scheduleSmssBag);
- $this->assertCount(count($scheduleSmssBag->to), $results);
+ $this->assertCount(2, $results);
}
/**
@@ -170,7 +171,7 @@ public function it_should_schedule_flash_sms()
public function it_should_delete_scheduled_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $scheduleSmssBag = $this->givenSmssToSchedule();
+ $scheduleSmssBag = $this->givenSmssToSchedule(2);
$results = $smsFeature->scheduleSmss($scheduleSmssBag);
$smsIds = array_map(function (Sms $sms) {
@@ -189,12 +190,9 @@ private function givenSmsToSend(): SendSmsBag
return SendSmsBag::withMessage($someReceiver, 'some message');
}
- private function givenSmssToSend(): SendSmssBag
+ private function givenSmssToSend(int $x): SendSmssBag
{
- $receivers = [
- PhoneNumberFixture::anyValidMobile(),
- PhoneNumberFixture::anyValidMobile(),
- ];
+ $receivers = PhoneNumberFixture::xValidMobile($x);
return SendSmssBag::withMessage($receivers, 'some message');
}
@@ -205,13 +203,10 @@ private function givenSmsToSchedule(): ScheduleSmsBag
return ScheduleSmsBag::withMessage($someDate, $someReceiver, 'some message');
}
- private function givenSmssToSchedule(): ScheduleSmssBag
+ private function givenSmssToSchedule(int $x): ScheduleSmssBag
{
$someDate = new DateTime('+1 day noon');
- $receivers = [
- PhoneNumberFixture::anyValidMobile(),
- PhoneNumberFixture::anyValidMobile(),
- ];
+ $receivers = PhoneNumberFixture::xValidMobile($x);
return ScheduleSmssBag::withMessage($someDate, $receivers, 'some message');
}
}
diff --git a/tests/Integration/Feature/Sms/SmsToContactsGroupFeatureTest.php b/tests/Integration/Feature/Sms/SmsToContactsGroupFeatureTest.php
index 9869b0e..0997dad 100644
--- a/tests/Integration/Feature/Sms/SmsToContactsGroupFeatureTest.php
+++ b/tests/Integration/Feature/Sms/SmsToContactsGroupFeatureTest.php
@@ -27,7 +27,10 @@ class SmsToContactsGroupFeatureTest extends SmsapiClientIntegrationTestCase
/** @var ContactGroup */
private $contactGroup;
- protected function setUp()
+ /**
+ * @before
+ */
+ public function createContacts()
{
$this->phoneNumber = PhoneNumberFixture::anyValidMobile();
@@ -42,7 +45,10 @@ protected function setUp()
self::$smsapiService->contactsFeature()->groupsFeature()->assignContactToGroup($assignContactToGroupBag);
}
- protected function tearDown()
+ /**
+ * @after
+ */
+ public function removeContacts()
{
$contactsHelper = new ContactsHelper(self::$smsapiService->contactsFeature());
$contactsHelper->deleteContact($this->contact->id);
diff --git a/tests/ServiceName.php b/tests/ServiceName.php
index 69f4eef..9a2dab5 100644
--- a/tests/ServiceName.php
+++ b/tests/ServiceName.php
@@ -3,14 +3,7 @@
namespace Smsapi\Client\Tests;
-use MabeEnum\Enum;
-
-/**
- * @method static ServiceName SMSAPI_PL
- * @method static ServiceName SMSAPI_COM
- * @method static ServiceName byValue($value)
- */
-class ServiceName extends Enum
+class ServiceName
{
const SMSAPI_PL = 'SMSAPI.PL';
const SMSAPI_COM = 'SMSAPI.COM';
diff --git a/tests/SmsapiClientIntegrationTestCase.php b/tests/SmsapiClientIntegrationTestCase.php
index 68c7eb9..09cc561 100644
--- a/tests/SmsapiClientIntegrationTestCase.php
+++ b/tests/SmsapiClientIntegrationTestCase.php
@@ -4,9 +4,9 @@
namespace Smsapi\Client\Tests;
use RuntimeException;
+use Smsapi\Client\Curl\SmsapiHttpClient;
use Smsapi\Client\Service\SmsapiComService;
use Smsapi\Client\Service\SmsapiPlService;
-use Smsapi\Client\SmsapiHttpClient;
class SmsapiClientIntegrationTestCase extends SmsapiClientTestCase
{
@@ -27,19 +27,12 @@ public static function prepare()
$apiUri = Config::get('API URI');
- if (!filter_var($apiUri, FILTER_VALIDATE_URL)) {
- throw new RuntimeException('Invalid API URI');
- }
-
$smsapiHttpClient = new SmsapiHttpClient();
- if (Config::get('logger')) {
- $smsapiHttpClient->setLogger(new TestLogger());
- }
-
- if (Config::getServiceName()->is(ServiceName::SMSAPI_PL)) {
+ $serviceName = Config::get('Service name');
+ if ($serviceName === ServiceName::SMSAPI_PL) {
self::$smsapiService = $smsapiHttpClient->smsapiPlServiceWithUri(self::$apiToken, $apiUri);
- } elseif (Config::getServiceName()->is(ServiceName::SMSAPI_COM)) {
+ } elseif ($serviceName === ServiceName::SMSAPI_COM) {
self::$smsapiService = $smsapiHttpClient->smsapiComServiceWithUri(self::$apiToken, $apiUri);
}
}
diff --git a/tests/SmsapiClientUnitTestCase.php b/tests/SmsapiClientUnitTestCase.php
index c7bffa5..eb84c6e 100644
--- a/tests/SmsapiClientUnitTestCase.php
+++ b/tests/SmsapiClientUnitTestCase.php
@@ -3,15 +3,9 @@
namespace Smsapi\Client\Tests;
-use GuzzleHttp\Client;
-use GuzzleHttp\Handler\MockHandler;
-use GuzzleHttp\HandlerStack;
-use GuzzleHttp\Psr7\Response;
-use Psr\Http\Client\ClientInterface;
-use Psr\Http\Message\RequestInterface;
-use Psr\Http\Message\ResponseInterface;
use Smsapi\Client\Feature\Data\DataFactoryProvider;
-use Smsapi\Client\Infrastructure\RequestAssembler\GuzzleRequestAssembler;
+use Smsapi\Client\Curl\RequestFactory;
+use Smsapi\Client\Curl\StreamFactory;
use Smsapi\Client\Infrastructure\RequestExecutor\LegacyRequestExecutor;
use Smsapi\Client\Infrastructure\RequestExecutor\RequestExecutorFactory;
use Smsapi\Client\Infrastructure\RequestExecutor\RestRequestExecutor;
@@ -22,65 +16,59 @@
use Smsapi\Client\Infrastructure\ResponseMapper\LegacyResponseMapper;
use Smsapi\Client\Infrastructure\ResponseMapper\RestResponseMapper;
use Smsapi\Client\Service\SmsapiPlHttpService;
+use Smsapi\Client\Tests\Helper\HttpClient\HttpClientMock;
class SmsapiClientUnitTestCase extends SmsapiClientTestCase
{
- /** @var MockHandler */
- private $mockHandler;
+ /** @var HttpClientMock */
+ private $httpClient;
/**
* @before
*/
public function prepare()
{
- $this->mockHandler = new MockHandler();
-
- $guzzleHttp = new class($this->mockHandler) implements ClientInterface {
- private $handler;
-
- public function __construct(MockHandler $handler)
- {
- $this->handler = $handler;
- }
-
- public function sendRequest(RequestInterface $request): ResponseInterface
- {
- $guzzleClient = new Client(['handler' => HandlerStack::create($this->handler)]);
-
- return $guzzleClient->send($request);
- }
- };
+ $this->httpClient = new HttpClientMock();
+ $requestFactory = new RequestFactory();
+ $streamFactory = new StreamFactory();
$queryFormatter = new ComplexParametersQueryFormatter();
$jsonDecode = new JsonDecode();
+ /** @var RequestExecutorFactory $requestExecutorFactory */
$requestExecutorFactory = $this->prophesize(RequestExecutorFactory::class);
$requestExecutorFactory
- ->createLegacyRequestExecutor()
+ ->createLegacyRequestExecutor($this->httpClient)
->willReturn(
new LegacyRequestExecutor(
new LegacyRequestMapper($queryFormatter),
- $guzzleHttp,
+ $this->httpClient,
new LegacyResponseMapper($jsonDecode),
- new GuzzleRequestAssembler()
+ $requestFactory,
+ $streamFactory
)
);
$requestExecutorFactory
- ->createRestRequestExecutor()
+ ->createRestRequestExecutor($this->httpClient)
->willReturn(
new RestRequestExecutor(
new RestRequestMapper($queryFormatter),
- $guzzleHttp,
+ $this->httpClient,
new RestResponseMapper($jsonDecode),
- new GuzzleRequestAssembler()
+ $requestFactory,
+ $streamFactory
)
);
- self::$smsapiService = new SmsapiPlHttpService($requestExecutorFactory->reveal(), new DataFactoryProvider());
+ self::$smsapiService = new SmsapiPlHttpService(
+ $this->httpClient,
+ $requestExecutorFactory->reveal(),
+ new DataFactoryProvider()
+ );
}
protected function mockResponse(int $statusCode, string $body)
{
- $this->mockHandler->append(new Response($statusCode, [], $body));
+ $this->httpClient->mockResponse($statusCode, $body);
}
}
diff --git a/tests/TestLogger.php b/tests/TestLogger.php
deleted file mode 100644
index 3ff6519..0000000
--- a/tests/TestLogger.php
+++ /dev/null
@@ -1,37 +0,0 @@
- $value) {
- if ($value instanceof RequestInterface) {
- $context[$item] = [
- 'headers' => $value->getHeaders(),
- 'uri' => $value->getUri()->__toString(),
- 'method' => $value->getMethod(),
- 'contents' => $value->getBody()->__toString(),
- ];
- } elseif ($value instanceof ResponseInterface) {
- $context[$item] = [
- 'headers' => $value->getHeaders(),
- 'status_code' => $value->getStatusCode(),
- 'contents' => $value->getBody()->__toString(),
- ];
- }
- }
-
- echo sprintf("[%s] %s (%s)\n", $level, $message, print_r($context));
- }
-}
diff --git a/tests/Unit/Curl/HttpHeadersParserTest.php b/tests/Unit/Curl/HttpHeadersParserTest.php
new file mode 100644
index 0000000..cdfdbd8
--- /dev/null
+++ b/tests/Unit/Curl/HttpHeadersParserTest.php
@@ -0,0 +1,85 @@
+assertArrayNotHasKey('HTTP/1.1 202 OK', $headers);
+ $this->assertNotContains('HTTP/1.1 202 OK', $headers);
+ }
+
+ /**
+ * @test
+ */
+ public function not_bypass_non_http_status_line_first_line()
+ {
+ $rawHeaders = "Header1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertArrayHasKey('Header1', $headers);
+ }
+
+ /**
+ * @test
+ */
+ public function bypass_empty_line()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertCount(2, array_keys($headers));
+ }
+
+ /**
+ * @test
+ */
+ public function add_all_headers()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertArrayHasKey('Header1', $headers);
+ $this->assertArrayHasKey('Header2', $headers);
+ }
+
+ /**
+ * @test
+ */
+ public function add_single_value_headers()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertEquals('any', $headers['Header1']);
+ }
+
+ /**
+ * @test
+ */
+ public function add_multi_value_headers()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertEquals('any, other', $headers['Header2']);
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/Feature/Contacts/Data/ContactFactoryTest.php b/tests/Unit/Feature/Contacts/Data/ContactFactoryTest.php
index bc690c5..d281731 100644
--- a/tests/Unit/Feature/Contacts/Data/ContactFactoryTest.php
+++ b/tests/Unit/Feature/Contacts/Data/ContactFactoryTest.php
@@ -4,19 +4,19 @@
namespace Smsapi\Client\Tests\Unit\Feature\Contacts\Data;
+use DateTime;
use PHPUnit\Framework\TestCase;
use Smsapi\Client\Feature\Contacts\Data\ContactCustomFieldFactory;
use Smsapi\Client\Feature\Contacts\Data\ContactFactory;
use Smsapi\Client\Feature\Contacts\Data\ContactGroupFactory;
use Smsapi\Client\Feature\Contacts\Groups\Permissions\Data\GroupPermissionFactory;
+use stdClass;
class ContactFactoryTest extends TestCase
{
- private $contactFactory;
-
- protected function setUp()
+ private function createContactsFactory()
{
- $this->contactFactory = new ContactFactory(
+ return new ContactFactory(
new ContactGroupFactory(new GroupPermissionFactory()),
new ContactCustomFieldFactory()
);
@@ -27,7 +27,7 @@ protected function setUp()
*/
public function it_should_convert_mandatory_built_in_contact_fields()
{
- $contactData = new \stdClass();
+ $contactData = new stdClass();
$contactData->id = 'any';
$contactData->date_created = '2020-05-11';
$contactData->date_updated = '2020-05-12';
@@ -36,11 +36,11 @@ public function it_should_convert_mandatory_built_in_contact_fields()
$this->assertTrue(true);
- $contact = $this->contactFactory->createFromObject($contactData);
+ $contact = $this->createContactsFactory()->createFromObject($contactData);
$this->assertEquals('any', $contact->id);
- $this->assertEquals(new \DateTime('2020-05-11'), $contact->dateCreated);
- $this->assertEquals(new \DateTime('2020-05-12'), $contact->dateUpdated);
+ $this->assertEquals(new DateTime('2020-05-11'), $contact->dateCreated);
+ $this->assertEquals(new DateTime('2020-05-12'), $contact->dateUpdated);
$this->assertEquals('M', $contact->gender);
}
@@ -50,26 +50,26 @@ public function it_should_convert_mandatory_built_in_contact_fields()
public function it_should_convert_optional_built_in_contact_fields()
{
$contactData = $this->givenAnyContactData();
- $contact = $this->contactFactory->createFromObject($contactData);
+ $contact = $this->createContactsFactory()->createFromObject($contactData);
$this->assertNull($contact->email);
$this->assertNull($contact->phoneNumber);
$this->assertNull($contact->country);
$this->assertNull($contact->undeliveredMessages);
$contactData->email = 'any@example.com';
- $contact = $this->contactFactory->createFromObject($contactData);
+ $contact = $this->createContactsFactory()->createFromObject($contactData);
$this->assertEquals('any@example.com', $contact->email);
$contactData->phone_number = '123123123';
- $contact = $this->contactFactory->createFromObject($contactData);
+ $contact = $this->createContactsFactory()->createFromObject($contactData);
$this->assertEquals('123123123', $contact->phoneNumber);
$contactData->country = 'any';
- $contact = $this->contactFactory->createFromObject($contactData);
+ $contact = $this->createContactsFactory()->createFromObject($contactData);
$this->assertEquals('any', $contact->country);
$contactData->undelivered_messages = 1;
- $contact = $this->contactFactory->createFromObject($contactData);
+ $contact = $this->createContactsFactory()->createFromObject($contactData);
$this->assertEquals(1, $contact->undeliveredMessages);
}
@@ -83,7 +83,7 @@ public function it_should_convert_custom_fields()
$contactData->custom_field_1 = 'any1';
$contactData->custom_field_2 = 'any2';
- $contact = $this->contactFactory->createFromObject($contactData);
+ $contact = $this->createContactsFactory()->createFromObject($contactData);
$this->assertEquals('custom_field_1', $contact->customFields[0]->name);
$this->assertEquals('any1', $contact->customFields[0]->value);
@@ -91,9 +91,9 @@ public function it_should_convert_custom_fields()
$this->assertEquals('any2', $contact->customFields[1]->value);
}
- private function givenAnyContactData(): \stdClass
+ private function givenAnyContactData(): stdClass
{
- $contactData = new \stdClass();
+ $contactData = new stdClass();
$contactData->id = 'any';
$contactData->date_created = '2020-05-11';
$contactData->date_updated = '2020-05-12';
diff --git a/tests/Unit/Feature/Push/PushFeatureTest.php b/tests/Unit/Feature/Push/PushFeatureTest.php
deleted file mode 100644
index a40bf6e..0000000
--- a/tests/Unit/Feature/Push/PushFeatureTest.php
+++ /dev/null
@@ -1,75 +0,0 @@
-mockResponse(ResponseHttpCode::OK, $body);
- $pushShipment = json_decode($body);
- $pushFeature = self::$smsapiService->pushFeature();
- $sendPushBag = new SendPushBag('1', $pushShipment->payload->alert);
-
- $result = $pushFeature->createPush($sendPushBag);
-
- $this->assertPushShipment($pushShipment, $result);
- }
-
- private function assertPushShipment(stdClass $expected, PushShipment $actual)
- {
- $pushShipment = new PushShipment();
- $pushShipment->id = $expected->id;
- $pushShipment->status = $expected->status;
- $pushShipment->dateCreated = new DateTime($expected->date_created);
- $pushShipment->scheduledDate = new DateTime($expected->scheduled_date);
-
- $pushShipment->app = new PushApp();
- $pushShipment->app->id = $expected->app->id;
- $pushShipment->app->name = $expected->app->name;
- $pushShipment->app->icon = $expected->app->icon;
-
- $pushShipment->payload = new PushShipmentPayload();
- $pushShipment->payload->alert = $expected->payload->alert;
-
- $pushShipment->summary = new PushShipmentSummary();
- $pushShipment->summary->points = to_float($expected->summary->points);
- $pushShipment->summary->recipientsCount = $expected->summary->recipients_count;
- $pushShipment->summary->errorCode = $expected->summary->error_code;
-
- $pushShipment->dispatchDetails = new PushShipmentDispatchDetails();
- $pushShipment->dispatchDetails->channels = $expected->dispatch_details->channels;
- $pushShipment->dispatchDetails->deviceIds = $expected->dispatch_details->device_ids;
- $pushShipment->dispatchDetails->deviceType = $expected->dispatch_details->device_type;
-
- $pushShipment->fallback = new PushShipmentFallback();
- $pushShipment->fallback->message = $expected->fallback->message;
- $pushShipment->fallback->from = $expected->fallback->from;
- $pushShipment->fallback->delay = $expected->fallback->delay;
- $pushShipment->fallback->status = $expected->fallback->status;
-
- $this->assertEquals($pushShipment, $actual);
- }
-}
diff --git a/tests/Unit/Infrastructure/HttpClient/Decorator/BaseUriDecoratorTest.php b/tests/Unit/Infrastructure/HttpClient/Decorator/BaseUriDecoratorTest.php
new file mode 100644
index 0000000..0e538bd
--- /dev/null
+++ b/tests/Unit/Infrastructure/HttpClient/Decorator/BaseUriDecoratorTest.php
@@ -0,0 +1,162 @@
+sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestSchema, $sentRequestSpy->getLastSentRequest()->getUri()->getScheme());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["example.com"]
+ * ["example.com/base/"]
+ * ["example.com:80"]
+ * ["example.com:80/base/"]
+ * ["any://"]
+ * ["any:///"]
+ * ["any://:80/"]
+ */
+ public function dont_send_request_without_base_schema_or_host(string $baseUri)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->expectException(RequestException::class);
+ $this->expectExceptionMessage('Invalid Base URI');
+ $this->sendRequestToAnyEndpoint($decorator);
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com", "any://example.com/endpoint", "example.com"]
+ * ["any://example.com:80", "any://example.com:80/endpoint", "example.com"]
+ * ["any://example", "any://example/endpoint", "example"]
+ * ["any://example:80", "any://example:80/endpoint", "example"]
+ */
+ public function send_request_with_base_host(string $baseUri, string $expectedRequestUri, string $expectedRequestHost)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestHost, $sentRequestSpy->getLastSentRequest()->getUri()->getHost());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com:80", "any://example.com:80/endpoint", "80"]
+ * ["any://example:80", "any://example:80/endpoint", "80"]
+ */
+ public function send_request_with_base_port(string $baseUri, string $expectedRequestUri, string $expectedRequestPort)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestPort, $sentRequestSpy->getLastSentRequest()->getUri()->getPort());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com", "any://example.com/endpoint"]
+ * ["any://example", "any://example/endpoint"]
+ * ["any://example.com/base", "any://example.com/base/endpoint"]
+ * ["any://example/base", "any://example/base/endpoint"]
+ */
+ public function send_request_without_base_port(string $baseUri, string $expectedRequestUri)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals('', $sentRequestSpy->getLastSentRequest()->getUri()->getPort());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com/base", "any://example.com/base/endpoint", "/base/endpoint"]
+ * ["any://example.com:80/base/", "any://example.com:80/base/endpoint", "/base/endpoint"]
+ * ["any://example:80/base", "any://example:80/base/endpoint", "/base/endpoint"]
+ * ["any://example.com/base/", "any://example.com/base/endpoint", "/base/endpoint"]
+ * ["any://example/base/", "any://example/base/endpoint", "/base/endpoint"]
+ * ["any://example.com:80/base/", "any://example.com:80/base/endpoint", "/base/endpoint"]
+ * ["any://example:80/base", "any://example:80/base/endpoint", "/base/endpoint"]
+ */
+ public function send_request_with_base_path(string $baseUri, string $expectedRequestUri, string $expectedRequestPath)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestPath, $sentRequestSpy->getLastSentRequest()->getUri()->getPath());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com", "any://example.com/endpoint", "/endpoint"]
+ * ["any://example", "any://example/endpoint", "/endpoint"]
+ * ["any://example.com:80", "any://example.com:80/endpoint", "/endpoint"]
+ * ["any://example:80", "any://example:80/endpoint", "/endpoint"]
+ * ["any://example.com/", "any://example.com/endpoint", "/endpoint"]
+ * ["any://example/", "any://example/endpoint", "/endpoint"]
+ * ["any://example.com:80/", "any://example.com:80/endpoint", "/endpoint"]
+ * ["any://example:80/", "any://example:80/endpoint", "/endpoint"]
+ */
+ public function send_request_without_base_path(string $baseUri, string $expectedRequestUri, string $expectedRequestPath)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestPath, $sentRequestSpy->getLastSentRequest()->getUri()->getPath());
+ }
+
+ private function sendRequestToAnyEndpoint(BaseUriDecorator $decorator)
+ {
+ $request = new Request('ANY', 'endpoint');
+ $decorator->sendRequest($request);
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/Infrastructure/RequestExecutor/GuzzleClientFactoryTest.php b/tests/Unit/Infrastructure/RequestExecutor/GuzzleClientFactoryTest.php
deleted file mode 100644
index 02d99c5..0000000
--- a/tests/Unit/Infrastructure/RequestExecutor/GuzzleClientFactoryTest.php
+++ /dev/null
@@ -1,24 +0,0 @@
-createClient();
-
- $this->assertInstanceOf(ClientInterface::class, $result);
- }
-}
diff --git a/tests/Unit/Infrastructure/RequestExecutor/RequestExecutorFactoryTest.php b/tests/Unit/Infrastructure/RequestExecutor/RequestExecutorFactoryTest.php
deleted file mode 100644
index 47befd6..0000000
--- a/tests/Unit/Infrastructure/RequestExecutor/RequestExecutorFactoryTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
-createRestRequestExecutor();
-
- $this->assertInstanceOf(RestRequestExecutor::class, $result);
- }
-
- /**
- * @test
- */
- public function it_should_create_legacy_request_executor()
- {
- $requestExecutorFactory = new RequestExecutorFactory(GuzzleClientFactoryMother::any());
-
- $result = $requestExecutorFactory->createLegacyRequestExecutor();
-
- $this->assertInstanceOf(LegacyRequestExecutor::class, $result);
- }
-}
diff --git a/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php b/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php
index 63f910f..9b5246a 100644
--- a/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php
+++ b/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php
@@ -25,10 +25,69 @@ public function init()
/**
* @test
*/
- public function it_should_create_post_request_with_parameters()
+ public function it_should_use_path_as_request_uri()
{
$path = 'anyPath';
+ $request = $this->mapper->map($path, []);
+
+ $this->assertEquals($path, $request->getUri());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_send_request_as_post()
+ {
+ $request = $this->mapper->map('anyPath', []);
+
+ $this->assertEquals(RequestHttpMethod::POST, $request->getMethod());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_always_set_format_json_parameter()
+ {
+ $builtInParameters = [];
+ $userParameters = [];
+
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
+
+ $this->assertEquals('format=json', $request->getBody());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_prepend_format_parameter_to_built_in_parameters_when_none()
+ {
+ $builtInParameters = [];
+ $userParameters = ['any2' => 'any'];
+
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
+
+ $this->assertEquals('format=json&any2=any', $request->getBody());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_prepend_format_parameter_to_built_in_parameters_when_set()
+ {
+ $builtInParameters = ['any1' => 'any'];
+ $userParameters = [];
+
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
+
+ $this->assertEquals('format=json&any1=any', $request->getBody());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_merge_both_built_in_and_user_parameters()
+ {
$builtInParameters = [
'any1' => 'any',
];
@@ -36,11 +95,8 @@ public function it_should_create_post_request_with_parameters()
'any2' => 'any',
];
- $request = $this->mapper->map($path, $builtInParameters, $userParameters);
-
- $this->assertEquals($path, $request->getUri());
- $this->assertEquals(RequestHttpMethod::POST, $request->getMethod());
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
- $this->assertEquals('any1=any&format=json&any2=any', $request->getBody());
+ $this->assertEquals('format=json&any1=any&any2=any', $request->getBody());
}
}
diff --git a/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/BuiltInParametersQueryFormatterTest.php b/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/BuiltInParametersQueryFormatterTest.php
index 95c0d43..9acd9d0 100644
--- a/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/BuiltInParametersQueryFormatterTest.php
+++ b/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/BuiltInParametersQueryFormatterTest.php
@@ -4,6 +4,7 @@
namespace Smsapi\Client\Tests\Unit\Infrastructure\RequestMapper\Query\Formatter;
+use DateTime;
use PHPUnit\Framework\TestCase;
use Smsapi\Client\Infrastructure\RequestMapper\Query\Formatter\BuiltInParametersQueryFormatter;
use Smsapi\Client\Infrastructure\RequestMapper\Query\QueryParametersData;
@@ -72,7 +73,7 @@ public function it_should_change_camel_case_parameter_name_to_underscore()
*/
public function it_should_format_datetime_values()
{
- $date = new \DateTime();
+ $date = new DateTime();
$dateEncoded = rawurlencode($date->format('c'));
$builtInParameters = [
diff --git a/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/ComplexParametersQueryFormatterTest.php b/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/ComplexParametersQueryFormatterTest.php
index 27d7dea..44973ce 100644
--- a/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/ComplexParametersQueryFormatterTest.php
+++ b/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/ComplexParametersQueryFormatterTest.php
@@ -4,6 +4,7 @@
namespace Smsapi\Client\Tests\Unit\Infrastructure\RequestMapper\Query\Formatter;
+use DateTime;
use PHPUnit\Framework\TestCase;
use Smsapi\Client\Infrastructure\RequestMapper\Query\Formatter\ComplexParametersQueryFormatter;
use Smsapi\Client\Infrastructure\RequestMapper\Query\QueryParametersData;
@@ -153,7 +154,7 @@ public function it_should_not_change_camel_case_parameter_name_to_underscore()
*/
public function it_should_format_datetime_values()
{
- $date = new \DateTime();
+ $date = new DateTime();
$dateEncoded = rawurlencode($date->format('c'));
$builtInParameters = [
diff --git a/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/UserParametersQueryFormatterTest.php b/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/UserParametersQueryFormatterTest.php
index f54bc88..91760f9 100644
--- a/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/UserParametersQueryFormatterTest.php
+++ b/tests/Unit/Infrastructure/RequestMapper/Query/Formatter/UserParametersQueryFormatterTest.php
@@ -4,6 +4,7 @@
namespace Smsapi\Client\Tests\Unit\Infrastructure\RequestMapper\Query\Formatter;
+use DateTime;
use PHPUnit\Framework\TestCase;
use Smsapi\Client\Infrastructure\RequestMapper\Query\Formatter\UserParametersQueryFormatter;
use Smsapi\Client\Infrastructure\RequestMapper\Query\QueryParametersData;
@@ -73,7 +74,7 @@ public function it_should_not_change_camel_case_parameter_name_to_underscore()
*/
public function it_should_format_datetime_values()
{
- $date = new \DateTime();
+ $date = new DateTime();
$dateEncoded = rawurlencode($date->format('c'));
$userParameters = [
diff --git a/tests/Unit/Infrastructure/ResponseMapper/LegacyResponseMapperTest.php b/tests/Unit/Infrastructure/ResponseMapper/LegacyResponseMapperTest.php
index 2eecaed..809e1ab 100644
--- a/tests/Unit/Infrastructure/ResponseMapper/LegacyResponseMapperTest.php
+++ b/tests/Unit/Infrastructure/ResponseMapper/LegacyResponseMapperTest.php
@@ -6,6 +6,7 @@
use GuzzleHttp\Psr7\Response;
use Smsapi\Client\Infrastructure\ResponseHttpCode;
+use Smsapi\Client\Infrastructure\ResponseMapper\ApiErrorException;
use Smsapi\Client\Infrastructure\ResponseMapper\JsonDecode;
use Smsapi\Client\Infrastructure\ResponseMapper\LegacyResponseMapper;
use Smsapi\Client\Tests\SmsapiClientUnitTestCase;
@@ -40,24 +41,24 @@ public function it_should_return_decoded_body_on_ok()
/**
* @test
- * @expectedException \Smsapi\Client\Infrastructure\ResponseMapper\ApiErrorException
*/
public function it_should_return_error_on_ok_with_message_and_error()
{
$bodyWithMessageAndError = '{"message":"some message","error":1}';
$responseWithOkMessageAndError = $this->createResponse(ResponseHttpCode::OK, $bodyWithMessageAndError);
+ $this->expectException(ApiErrorException::class);
$this->legacyResponseMapper->map($responseWithOkMessageAndError);
}
/**
* @test
- * @expectedException \Smsapi\Client\Infrastructure\ResponseMapper\ApiErrorException
*/
public function it_should_throw_exception_on_unrecognized_status()
{
$responseWithUnrecognizedStatus = new Response(400);
+ $this->expectException(ApiErrorException::class);
$this->legacyResponseMapper->map($responseWithUnrecognizedStatus);
}
diff --git a/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php b/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php
index db60d89..9419e90 100644
--- a/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php
+++ b/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php
@@ -6,6 +6,7 @@
use GuzzleHttp\Psr7\Response;
use Smsapi\Client\Infrastructure\ResponseHttpCode;
+use Smsapi\Client\Infrastructure\ResponseMapper\ApiErrorException;
use Smsapi\Client\Infrastructure\ResponseMapper\JsonDecode;
use Smsapi\Client\Infrastructure\ResponseMapper\RestResponseMapper;
use Smsapi\Client\Tests\SmsapiClientUnitTestCase;
@@ -81,24 +82,36 @@ public function it_should_return_empty_object_on_no_content()
/**
* @test
- * @expectedException \Smsapi\Client\Infrastructure\ResponseMapper\ApiErrorException
- * @expectedExceptionMessage Service unavailable
*/
public function it_should_throw_exception_on_service_unavailable()
{
$responseWithServiceUnavailable = new Response(ResponseHttpCode::SERVICE_UNAVAILABLE);
+ $this->expectException(ApiErrorException::class);
+ $this->expectExceptionMessage("Service unavailable");
+ $this->restResponseMapper->map($responseWithServiceUnavailable);
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_throw_exception_on_request_timeout()
+ {
+ $responseWithServiceUnavailable = new Response(ResponseHttpCode::REQUEST_TIMEOUT);
+
+ $this->expectException(ApiErrorException::class);
+ $this->expectExceptionMessage("Request timed out");
$this->restResponseMapper->map($responseWithServiceUnavailable);
}
/**
* @test
- * @expectedException \Smsapi\Client\Infrastructure\ResponseMapper\ApiErrorException
*/
public function it_should_throw_exception_on_unrecognized_status()
{
$responseWithUnrecognizedStatus = new Response(400);
+ $this->expectException(ApiErrorException::class);
$this->restResponseMapper->map($responseWithUnrecognizedStatus);
}
diff --git a/tests/Unit/SmsapiHttpClientTest.php b/tests/Unit/SmsapiHttpClientTest.php
index 6e08d17..b16d1be 100644
--- a/tests/Unit/SmsapiHttpClientTest.php
+++ b/tests/Unit/SmsapiHttpClientTest.php
@@ -24,7 +24,7 @@ private function grabVersionFromChangelog()
{
$changelog = file_get_contents(dirname(dirname(__DIR__)) . '/CHANGELOG.md');
- preg_match('/^## \[(?Unreleased|\d+.\d+.\d+)\]/m', $changelog, $matches);
+ preg_match('/^## \[(?Unreleased|\d+.\d+.\d+)]/m', $changelog, $matches);
$this->assertArrayHasKey('version', $matches);