├── .circleci └── config.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENCE.txt ├── Makefile ├── README.md ├── composer.json ├── composer.lock ├── docker-compose.yml.dist ├── ecs.php ├── phpspec.yml.dist ├── phpunit.xml.dist ├── rector.php ├── spec ├── AkeneoPimClientSpec.php ├── Api │ ├── AppCatalog │ │ ├── AppCatalogApiSpec.php │ │ └── AppCatalogProductApiSpec.php │ ├── AssetApiSpec.php │ ├── AssetCategoryApiSpec.php │ ├── AssetReferenceFileApiSpec.php │ ├── AssetTagApiSpec.php │ ├── AssetVariationFileApiSpec.php │ ├── AssociationTypeApiSpec.php │ ├── AttributeApiSpec.php │ ├── AttributeGroupApiSpec.php │ ├── AttributeOptionApiSpec.php │ ├── AuthenticationApiSpec.php │ ├── CategoryApiSpec.php │ ├── CategoryMediaFileApiSpec.php │ ├── ChannelApiSpec.php │ ├── CurrencyApiSpec.php │ ├── FamilyApiSpec.php │ ├── FamilyVariantApiSpec.php │ ├── LocaleApiSpec.php │ ├── MeasureFamilyApiSpec.php │ ├── MeasurementFamilyApiSpec.php │ ├── ProductApiSpec.php │ ├── ProductDraftApiSpec.php │ ├── ProductDraftUuidApiSpec.php │ ├── ProductMediaFileApiSpec.php │ ├── ProductModelApiSpec.php │ ├── ProductModelDraftApiSpec.php │ ├── ProductUuidApiSpec.php │ ├── PublishedProductApiSpec.php │ ├── ReferenceEntityApiSpec.php │ ├── ReferenceEntityAttributeApiSpec.php │ ├── ReferenceEntityAttributeOptionApiSpec.php │ ├── ReferenceEntityMediaFileApiSpec.php │ ├── ReferenceEntityRecordApiSpec.php │ └── SystemInformationApiSpec.php ├── Client │ ├── AuthenticatedHttpClientSpec.php │ ├── HttpClientSpec.php │ ├── HttpExceptionHandlerSpec.php │ └── ResourceClientSpec.php ├── Exception │ ├── HttpExceptionSpec.php │ └── UnprocessableEntityHttpExceptionSpec.php ├── Pagination │ ├── PageFactorySpec.php │ ├── PageSpec.php │ ├── ResourceCursorFactorySpec.php │ └── ResourceCursorSpec.php ├── Routing │ └── UriGeneratorSpec.php ├── Search │ └── SearchBuilderSpec.php ├── Security │ └── AuthenticationSpec.php └── Stream │ ├── LineStreamReaderSpec.php │ ├── MultipartStreamBuilderFactorySpec.php │ ├── UpsertResourceListResponseFactorySpec.php │ └── UpsertResourceListResponseSpec.php ├── src ├── AkeneoPimClient.php ├── AkeneoPimClientBuilder.php ├── AkeneoPimClientInterface.php ├── Api │ ├── AppCatalog │ │ ├── AppCatalogApi.php │ │ ├── AppCatalogApiInterface.php │ │ ├── AppCatalogProductApi.php │ │ └── AppCatalogProductApiInterface.php │ ├── AssetApi.php │ ├── AssetApiInterface.php │ ├── AssetCategoryApi.php │ ├── AssetCategoryApiInterface.php │ ├── AssetManager │ │ ├── AssetApi.php │ │ ├── AssetApiInterface.php │ │ ├── AssetAttributeApi.php │ │ ├── AssetAttributeApiInterface.php │ │ ├── AssetAttributeOptionApi.php │ │ ├── AssetAttributeOptionApiInterface.php │ │ ├── AssetFamilyApi.php │ │ ├── AssetFamilyApiInterface.php │ │ ├── AssetMediaFileApi.php │ │ └── AssetMediaFileApiInterface.php │ ├── AssetReferenceFileApi.php │ ├── AssetReferenceFileApiInterface.php │ ├── AssetTagApi.php │ ├── AssetTagApiInterface.php │ ├── AssetVariationFileApi.php │ ├── AssetVariationFileApiInterface.php │ ├── AssociationTypeApi.php │ ├── AssociationTypeApiInterface.php │ ├── AttributeApi.php │ ├── AttributeApiInterface.php │ ├── AttributeGroupApi.php │ ├── AttributeGroupApiInterface.php │ ├── AttributeOptionApi.php │ ├── AttributeOptionApiInterface.php │ ├── AuthenticationApi.php │ ├── AuthenticationApiInterface.php │ ├── CategoryApi.php │ ├── CategoryApiInterface.php │ ├── CategoryMediaFileApi.php │ ├── ChannelApi.php │ ├── ChannelApiInterface.php │ ├── CurrencyApi.php │ ├── CurrencyApiInterface.php │ ├── FamilyApi.php │ ├── FamilyApiInterface.php │ ├── FamilyVariantApi.php │ ├── FamilyVariantApiInterface.php │ ├── LocaleApi.php │ ├── LocaleApiInterface.php │ ├── MeasureFamilyApi.php │ ├── MeasureFamilyApiInterface.php │ ├── MeasurementFamilyApi.php │ ├── MeasurementFamilyApiInterface.php │ ├── MediaFileApiInterface.php │ ├── Operation │ │ ├── CreatableResourceInterface.php │ │ ├── DeletableResourceInterface.php │ │ ├── DownloadableResourceInterface.php │ │ ├── GettableResourceInterface.php │ │ ├── ListableResourceInterface.php │ │ ├── UpsertableResourceInterface.php │ │ └── UpsertableResourceListInterface.php │ ├── ProductApi.php │ ├── ProductApiInterface.php │ ├── ProductDraftApi.php │ ├── ProductDraftApiInterface.php │ ├── ProductDraftUuidApi.php │ ├── ProductDraftUuidApiInterface.php │ ├── ProductMediaFileApi.php │ ├── ProductModelApi.php │ ├── ProductModelApiInterface.php │ ├── ProductModelDraftApi.php │ ├── ProductModelDraftApiInterface.php │ ├── ProductUuidApi.php │ ├── ProductUuidApiInterface.php │ ├── PublishedProductApi.php │ ├── PublishedProductApiInterface.php │ ├── ReferenceEntityApi.php │ ├── ReferenceEntityApiInterface.php │ ├── ReferenceEntityAttributeApi.php │ ├── ReferenceEntityAttributeApiInterface.php │ ├── ReferenceEntityAttributeOptionApi.php │ ├── ReferenceEntityAttributeOptionApiInterface.php │ ├── ReferenceEntityMediaFileApi.php │ ├── ReferenceEntityMediaFileApiInterface.php │ ├── ReferenceEntityRecordApi.php │ ├── ReferenceEntityRecordApiInterface.php │ ├── SystemInformationApi.php │ └── SystemInformationApiInterface.php ├── Cache │ ├── CacheInterface.php │ └── LRUCache.php ├── Client │ ├── AuthenticatedHttpClient.php │ ├── CachedResourceClient.php │ ├── ClientInterface.php │ ├── HttpClient.php │ ├── HttpClientInterface.php │ ├── HttpExceptionHandler.php │ ├── Options.php │ ├── ResourceClient.php │ └── ResourceClientInterface.php ├── Exception │ ├── BadRequestHttpException.php │ ├── ClientErrorHttpException.php │ ├── ExceptionInterface.php │ ├── ForbiddenHttpException.php │ ├── HttpException.php │ ├── InvalidArgumentException.php │ ├── MethodNotAllowedHttpException.php │ ├── NotAcceptableHttpException.php │ ├── NotFoundHttpException.php │ ├── RedirectionHttpException.php │ ├── RuntimeException.php │ ├── ServerErrorHttpException.php │ ├── TooManyRequestsHttpException.php │ ├── UnauthorizedHttpException.php │ ├── UnprocessableEntityHttpException.php │ ├── UnreadableFileException.php │ ├── UnsupportedMediaTypeHttpException.php │ └── UploadAssetReferenceFileErrorException.php ├── FileSystem │ ├── FileSystemInterface.php │ └── LocalFileSystem.php ├── MultipartStream │ └── MultipartStreamBuilder.php ├── Pagination │ ├── Page.php │ ├── PageFactory.php │ ├── PageFactoryInterface.php │ ├── PageInterface.php │ ├── PaginationParameter.php │ ├── ResourceCursor.php │ ├── ResourceCursorFactory.php │ ├── ResourceCursorFactoryInterface.php │ └── ResourceCursorInterface.php ├── Routing │ ├── UriGenerator.php │ └── UriGeneratorInterface.php ├── Search │ ├── Operator.php │ └── SearchBuilder.php ├── Security │ └── Authentication.php └── Stream │ ├── LineStreamReader.php │ ├── MultipartStreamBuilderFactory.php │ ├── UpsertResourceListResponse.php │ └── UpsertResourceListResponseFactory.php └── tests ├── Api ├── ApiTestCase.php ├── AppCatalog │ ├── CreateAppCatalogIntegration.php │ ├── DeleteAppCatalogIntegration.php │ ├── GetAppCatalogIntegration.php │ ├── ListAppCatalogIntegration.php │ └── UpsertAppCatalogIntegration.php ├── AppCatalogProduct │ └── ListAppCatalogProductIntegration.php ├── Asset │ ├── GetAssetIntegration.php │ ├── ListAllAssetsIntegration.php │ ├── UpsertAssetIntegration.php │ └── UpsertListAssetIntegration.php ├── AssetAttribute │ ├── GetAssetFamilyAttributeIntegration.php │ ├── ListAllAssetFamilyAttributesIntegration.php │ └── UpsertAssetFamilyAttributeIntegration.php ├── AssetAttributeOption │ ├── GetAssetFamilyAttributeOptionIntegration.php │ ├── ListAllAssetFamilyAttributeOptionsIntegration.php │ └── UpsertAssetFamilyAttributeOptionIntegration.php ├── AssetFamily │ ├── GetAssetFamilyIntegration.php │ ├── ListAllAssetFamiliesIntegration.php │ └── UpsertAssetFamilyIntegration.php ├── AssetMediaFile │ └── CreateAssetMediaFileIntegration.php ├── AssetReferenceFile │ ├── DownloadAssetReferenceFileIntegration.php │ └── UploadAssetReferenceFileIntegration.php ├── AssetVariationFile │ ├── DownloadAssetVariationFileApiIntegration.php │ └── UploadAssetVariationFileApiIntegration.php ├── CreateProductMediaFileTest.php ├── CreateProductTest.php ├── DeleteProductModelTest.php ├── DeleteProductTest.php ├── DownloadCategoryMediaFileTest.php ├── DownloadProductMediaFileTest.php ├── GetProductTest.php ├── ListPerPageProductTest.php ├── ProductDraftUuid │ └── GetProductDraftUuidIntegration.php ├── ProductUuid │ ├── CreateProductUuidIntegration.php │ ├── DeleteProductUuidIntegration.php │ ├── GetProductUuidIntegration.php │ ├── ListPerPageProductUuidIntegration.php │ ├── UpsertListProductUuidIntegration.php │ └── UpsertProductUuidIntegration.php ├── ReferenceEntity │ ├── GetReferenceEntityIntegration.php │ ├── ListAllReferenceEntitiesIntegration.php │ └── UpsertReferenceEntityIntegration.php ├── ReferenceEntityMediaFile │ └── CreateReferenceEntityMediaFileIntegration.php ├── ReferenceEntityRecord │ ├── GetReferenceEntityRecordIntegration.php │ ├── ListAllReferenceEntityRecordsIntegration.php │ ├── UpsertListReferenceEntityRecordIntegration.php │ └── UpsertReferenceEntityRecordIntegration.php ├── UpsertListProductTest.php └── UpsertProductTest.php ├── Cache ├── AkeneoPimClientBuilderTest.php └── LRUCacheTest.php ├── Client ├── CachedResourceClientTest.php └── OptionsTest.php ├── Exception └── TooManyRequestsHttpExceptionTest.php └── fixtures ├── akeneo-logo.pdf ├── akeneo.png ├── unicorn.png ├── ziggy-certification.jpg └── ziggy.png /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | vendor 3 | docker-compose.yml 4 | tests/etc/parameters.yml 5 | phpspec.yml 6 | phpunit.xml 7 | .php_cs.cache 8 | .php-cs-fixer.cache 9 | 10 | ### PhpStorm ### 11 | .idea 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 5.0.0 2 | 3 | ## BC Breaks 4 | 5 | Use PSR-7, PSR-17 and PSR-18 instead of HttpPlug. 6 | 7 | - Change the type of the first parameter of `Akeneo\Pim\ApiClientAkeneoPimClientBuilder::setHttpClient` from `Http\Client\HttpClient` to `Psr\Http\Client\ClientInterface` 8 | - Change the type of the first parameter of `Akeneo\Pim\ApiClientAkeneoPimClientBuilder::setRequestFactory` from `Http\Message\RequestFactory` to `Psr\Http\Message\RequestFactoryInterface` 9 | - Change the type of the first parameter of `Akeneo\Pim\ApiClientAkeneoPimClientBuilder::setStreamFactory` from `Http\Message\StreamFactory` to `Psr\Http\Message\StreamFactoryInterface` 10 | 11 | Factory implementations are necessary as dependency. 12 | For example, with Guzzle: 13 | 14 | ```bash 15 | $ php composer.phar require akeneo/api-php-client php-http/guzzle6-adapter:^2.0 http-interop/http-factory-guzzle:^1.0 16 | ``` 17 | 18 | # 4.0.2 (2019-06-13) 19 | 20 | - Add support for PHP 7.1. This is done for some connectors thar are still using it. 21 | 22 | Be careful, this PHP version is EOL in december 2020. 23 | 24 | # 4.0.0 (2019-02-15) 25 | 26 | ## BC Breaks 27 | 28 | Drop support for PHP 5.6, PHP 7.0 and PHP 7.1 29 | 30 | Change the response type from `StreamInterface` to `Response` for `\Akeneo\Pim\ApiClient\Api\MediaFileApiInterface::download` 31 | 32 | It allows to get the filename from the response, and also the Mime type. 33 | 34 | # 3.0.0 (2018-06-26) 35 | 36 | # 2.0.1 (2018-05-03) 37 | 38 | ## Improvements 39 | 40 | - API-592: Handle error when the response is a redirection 41 | 42 | # 2.0.0 (2018-02-15) 43 | 44 | ## Improvements 45 | 46 | - API-487: Isolate files manipulation in a dedicated service 47 | - API-562: upsert a list of attribute options 48 | - API-543: Create a new media file and associate it to a product model 49 | 50 | ## BC Breaks 51 | 52 | - Change the constructor of `Akeneo\Pim\ApiClient\Api\ProductMediaFileApi` to add `Akeneo\Pim\ApiClient\FileSystem\FileSystemInterface` 53 | - Add method `Akeneo\Pim\ApiClient\Api\AttributeOptionApiInterface::upsertList` 54 | 55 | # 1.0.x 56 | 57 | ## Bug Fixes 58 | 59 | - API-599: fix const not supported by PHP 5.6 60 | 61 | # 1.0.1 (2018-04-05) 62 | 63 | ## Improvements 64 | 65 | - API-592: Handle error when the response is a redirection (https://github.com/akeneo/api-php-client/issues/72) 66 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Want to do your bit for our PHP client? All contributions are warmly welcomed! 4 | 5 | ## Contribution process 6 | 7 | First and foremost, please accept and sign our [Contributor License Agreement](https://www.akeneo.com/contributor-license-agreement/). 8 | 9 | And then, do your magic : 10 | * Fork our repository 11 | * Create a branch (choose a descriptive name) 12 | * Work on your own code (don't forget to add necessessaries tests) 13 | * Commit your branch and submit a pull request to our projet 14 | 15 | At this moment, the ball is in our court: we will check your PR and add comments or suggestions if needed. 16 | 17 | When everything is ok, we merge your work. 18 | 19 | Congratulations, you are officially a contributor to our dear PHP client! 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye-slim 2 | 3 | # Install some useful packages 4 | RUN apt-get update && \ 5 | apt-get --no-install-recommends --no-install-suggests --yes --quiet install \ 6 | apt-transport-https \ 7 | bash-completion \ 8 | ca-certificates \ 9 | curl \ 10 | git \ 11 | gnupg \ 12 | imagemagick \ 13 | less \ 14 | make \ 15 | perceptualdiff \ 16 | procps \ 17 | ssh-client \ 18 | sudo \ 19 | unzip \ 20 | vim \ 21 | wget && \ 22 | apt-get clean && apt-get --yes --quiet autoremove --purge && \ 23 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ 24 | /usr/share/doc/* /usr/share/groff/* /usr/share/info/* /usr/share/linda/* \ 25 | /usr/share/lintian/* /usr/share/locale/* /usr/share/man/* 26 | 27 | # Install PHP 8.2 with some extensions 28 | RUN wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg && \ 29 | sh -c 'echo "deb https://packages.sury.org/php/ bullseye main" > /etc/apt/sources.list.d/php.list' && \ 30 | apt-get update && \ 31 | apt-get --no-install-recommends --no-install-suggests --yes --quiet install \ 32 | php8.2-cli \ 33 | php8.2-apcu \ 34 | php8.2-mbstring \ 35 | php8.2-curl \ 36 | php8.2-gd \ 37 | php8.2-imagick \ 38 | php8.2-intl \ 39 | php8.2-bcmath \ 40 | php8.2-xdebug \ 41 | php8.2-xml \ 42 | php8.2-zip && \ 43 | apt-get clean && apt-get --yes --quiet autoremove --purge && \ 44 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ 45 | /usr/share/doc/* /usr/share/groff/* /usr/share/info/* /usr/share/linda/* \ 46 | /usr/share/lintian/* /usr/share/locale/* /usr/share/man/* 47 | 48 | # Add a "docker" user 49 | RUN useradd docker --shell /bin/bash --create-home \ 50 | && usermod --append --groups sudo docker \ 51 | && echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers \ 52 | && echo 'docker:secret' | chpasswd 53 | 54 | WORKDIR /home/docker/ 55 | 56 | # Install composer 57 | COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer 58 | 59 | ENV PATH=bin:vendor/bin:$PATH 60 | -------------------------------------------------------------------------------- /LICENCE.txt: -------------------------------------------------------------------------------- 1 | Akeneo PIM PHP Client 2 | 3 | The Open Software License version 3.0 4 | 5 | Copyright (c) 2013-2017, Akeneo SAS. 6 | 7 | Full license is at: http://opensource.org/licenses/OSL-3.0 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DOCKER_RUN ?= DOCKER_BUILDKIT=1 docker compose run php_client 2 | 3 | .PHONY: help 4 | help: 5 | @grep -E '(^[a-zA-Z_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-25s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/' 6 | 7 | .PHONY: build-image 8 | build-image: ## Build docker image 9 | DOCKER_BUILDKIT=1 docker compose build 10 | 11 | .PHONY: 12 | .PHONY: dependencies 13 | dependencies: ## Install composer dependencies 14 | cp docker-compose.yml.dist docker-compose.yml 15 | rm -rf composer.lock vendor/ 16 | $(DOCKER_RUN) composer install 17 | 18 | .PHONY: tests 19 | tests: unit spec cs ## Run PHPUnit & PHPSpec tests, and code style check 20 | 21 | .PHONY: unit 22 | unit: ## Run PHPUnit tests 23 | @echo "-----------" 24 | @echo "- PHPUnit -" 25 | @echo "-----------" 26 | $(DOCKER_RUN) bin/phpunit -c phpunit.xml.dist 27 | 28 | .PHONY: spec 29 | spec: ## Run PHPSpec tests 30 | @echo "-----------" 31 | @echo "- PHPSpec -" 32 | @echo "-----------" 33 | $(DOCKER_RUN) bin/phpspec run 34 | 35 | .PHONY: cs 36 | cs: ## Run code style check 37 | @echo "------------------" 38 | @echo "- PHP code style -" 39 | @echo "------------------" 40 | $(DOCKER_RUN) bin/ecs 41 | 42 | .PHONY: fix-cs 43 | fix-cs: ## Fix PHP code style 44 | $(DOCKER_RUN) bin/ecs --fix 45 | 46 | .PHONY: rector 47 | rector: ## Run rector 48 | $(DOCKER_RUN) bin/rector 49 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "akeneo/api-php-client", 3 | "description": "Akeneo PIM client for the API", 4 | "license": "OSL-3.0", 5 | "minimum-stability": "stable", 6 | "authors": [ 7 | { 8 | "name": "Akeneo", 9 | "homepage": "http://www.akeneo.com" 10 | } 11 | ], 12 | "autoload": { 13 | "psr-4": { 14 | "Akeneo\\Pim\\ApiClient\\": "src/" 15 | } 16 | }, 17 | "autoload-dev": { 18 | "psr-4": { 19 | "Akeneo\\Pim\\ApiClient\\tests\\": "tests/" 20 | } 21 | }, 22 | "require": { 23 | "php": ">=8.2", 24 | "psr/http-message": "^2.0", 25 | "psr/http-client": "^1.0", 26 | "psr/http-factory": "^1.0", 27 | "psr/http-message-implementation": "^1.0|^2.0", 28 | "php-http/httplug": "^2.0", 29 | "php-http/discovery": "^1.6", 30 | "php-http/multipart-stream-builder": "^1.0", 31 | "symfony/options-resolver": "^5.4|^6.0|^7.0" 32 | }, 33 | "require-dev": { 34 | "friendsofphp/php-cs-fixer": "^3.5", 35 | "phpunit/phpunit": "^8.0", 36 | "phpspec/phpspec": "^7.1", 37 | "symfony/yaml": "^4.2", 38 | "donatj/mock-webserver": "^2.0", 39 | "http-interop/http-factory-guzzle": "^1.0", 40 | "php-http/guzzle7-adapter": "^1.0", 41 | "rector/rector": "^0.14.6", 42 | "symplify/easy-coding-standard": "^11.1" 43 | }, 44 | "config": { 45 | "bin-dir": "bin", 46 | "platform": { 47 | "php": "8.2" 48 | }, 49 | "allow-plugins": { 50 | "php-http/discovery": false 51 | } 52 | }, 53 | "suggest": { 54 | "php-http/guzzle7-adapter": "In order to use Guzzle v7 as the HTTP client" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /docker-compose.yml.dist: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | php_client: 4 | build: . 5 | environment: 6 | COMPOSER_HOME: /home/docker/.composer 7 | PHP_IDE_CONFIG: 'serverName=akeneo-client' 8 | PHP_XDEBUG_ENABLED: 0 9 | PHP_XDEBUG_IDE_KEY: XDEBUG_IDE_KEY 10 | PHP_XDEBUG_REMOTE_HOST: xxx.xxx.xxx.xxx 11 | XDEBUG_CONFIG: 'remote_host=xxx.xxx.xxx.xxx' 12 | user: docker 13 | volumes: 14 | - ./:/home/docker/client 15 | - ~/.composer:/home/docker/.composer 16 | working_dir: /home/docker/client 17 | -------------------------------------------------------------------------------- /ecs.php: -------------------------------------------------------------------------------- 1 | paths([ 11 | __DIR__ . '/src', 12 | __DIR__ . '/tests', 13 | ]); 14 | 15 | $ecsConfig->sets([SetList::PSR_12]); 16 | 17 | $ecsConfig->ruleWithConfiguration(ArraySyntaxFixer::class, [ 18 | 'syntax' => 'short', 19 | ]); 20 | 21 | $ecsConfig->ruleWithConfiguration(LineLengthFixer::class, [ 22 | LineLengthFixer::LINE_LENGTH => 140, 23 | LineLengthFixer::INLINE_SHORT_LINES => false, 24 | LineLengthFixer::BREAK_LONG_LINES => true, 25 | ]); 26 | 27 | $ecsConfig->rule(StandaloneLinePromotedPropertyFixer::class); 28 | }; 29 | -------------------------------------------------------------------------------- /phpspec.yml.dist: -------------------------------------------------------------------------------- 1 | ## Rename this file in phpspec.yml to customize the phpspec configuration 2 | suites: 3 | AkeneoPimClient: 4 | namespace: Akeneo\Pim\ApiClient 5 | psr4_prefix: Akeneo\Pim\ApiClient 6 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | tests/ 16 | tests/ 17 | 18 | 19 | 20 | 21 | src 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | paths([ 13 | __DIR__ . '/src', 14 | __DIR__ . '/tests', 15 | __DIR__ . '/spec' 16 | ]); 17 | 18 | $rectorConfig->skip([ 19 | JsonThrowOnErrorRector::class 20 | ]); 21 | 22 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); 23 | 24 | $rectorConfig->sets([ 25 | SetList::CODE_QUALITY, 26 | LevelSetList::UP_TO_PHP_80 27 | ]); 28 | }; 29 | -------------------------------------------------------------------------------- /spec/Api/CategoryMediaFileApiSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($resourceClient); 19 | } 20 | 21 | function it_is_initializable() 22 | { 23 | $this->shouldHaveType(CategoryMediaFileApi::class); 24 | $this->shouldImplement(DownloadableResourceInterface::class); 25 | } 26 | 27 | function it_downloads_a_media_file($resourceClient, ResponseInterface $response, StreamInterface $streamBody) 28 | { 29 | $resourceClient 30 | ->getStreamedResource(CategoryMediaFileApi::MEDIA_FILE_DOWNLOAD_URI, ['42.jpg']) 31 | ->willReturn($response); 32 | 33 | $this->download('42.jpg')->shouldReturn($response); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/Api/MeasurementFamilyApiSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($resourceClient); 14 | } 15 | 16 | function it_is_initializable() 17 | { 18 | $this->shouldHaveType(MeasurementFamilyApi::class); 19 | $this->shouldImplement(MeasurementFamilyApiInterface::class); 20 | } 21 | 22 | function it_returns_all_measurement_families($resourceClient) { 23 | $resourceClient->getResource(MeasurementFamilyApi::MEASUREMENT_FAMILIES_URI)->willReturn([]); 24 | $this->all()->shouldReturn([]); 25 | } 26 | 27 | function it_upserts_a_list_of_measurement_families($resourceClient) 28 | { 29 | $resourceClient->upsertJsonResourceList( 30 | MeasurementFamilyApi::MEASUREMENT_FAMILIES_URI, 31 | [], 32 | [ 33 | ['code' => 'measurement_family_1'], 34 | ['code' => 'measurement_family_2'], 35 | ['code' => 'measurement_family_3'], 36 | ] 37 | )->willReturn([]); 38 | 39 | $this->upsertList( 40 | [ 41 | ['code' => 'measurement_family_1'], 42 | ['code' => 'measurement_family_2'], 43 | ['code' => 'measurement_family_3'], 44 | ] 45 | )->shouldReturn([]); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /spec/Api/ProductDraftApiSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($resourceClient, $pageFactory, $cursorFactory); 21 | } 22 | 23 | function it_is_initializable() 24 | { 25 | $this->shouldHaveType(ProductDraftApi::class); 26 | $this->shouldImplement(ProductDraftApiInterface::class); 27 | $this->shouldImplement(GettableResourceInterface::class); 28 | } 29 | 30 | function it_gets_a_product_draft($resourceClient) 31 | { 32 | $draft = [ 33 | 'identifier' => 'foo', 34 | 'family' => 'bar', 35 | 'parent' => null, 36 | 'groups' => [], 37 | 'categories' => [], 38 | 'enabled' => true, 39 | 'values' => [], 40 | 'created' => 'this is a date formatted to ISO-8601', 41 | 'updated' => 'this is a date formatted to ISO-8601', 42 | 'associations' => [], 43 | 'metadata' => [ 44 | 'workflow_status' => 'draft_in_progress', 45 | ], 46 | ]; 47 | 48 | $resourceClient->getResource(ProductDraftApi::PRODUCT_DRAFT_URI, ['foo'])->willReturn($draft); 49 | 50 | $this->get('foo')->shouldReturn($draft); 51 | } 52 | 53 | function it_submits_a_product_draft_for_approval($resourceClient) 54 | { 55 | $resourceClient->createResource(ProductDraftApi::PRODUCT_PROPOSAL_URI, ['foo'])->willReturn(201); 56 | 57 | $this->submitForApproval('foo')->shouldReturn(201); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /spec/Api/ProductDraftUuidApiSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($resourceClient, $pageFactory, $cursorFactory); 21 | } 22 | 23 | function it_is_initializable() 24 | { 25 | $this->shouldHaveType(ProductDraftUuidApi::class); 26 | $this->shouldImplement(ProductDraftUuidApiInterface::class); 27 | $this->shouldImplement(GettableResourceInterface::class); 28 | } 29 | 30 | function it_gets_a_product_draft($resourceClient) 31 | { 32 | $draft = [ 33 | 'uuid' => '944ca210-d8e0-4c57-9529-741e17e95c8d', 34 | 'family' => 'bar', 35 | 'parent' => null, 36 | 'groups' => [], 37 | 'categories' => [], 38 | 'enabled' => true, 39 | 'values' => [], 40 | 'created' => 'this is a date formatted to ISO-8601', 41 | 'updated' => 'this is a date formatted to ISO-8601', 42 | 'associations' => [], 43 | 'metadata' => [ 44 | 'workflow_status' => 'draft_in_progress', 45 | ], 46 | ]; 47 | 48 | $resourceClient->getResource(ProductDraftUuidApi::PRODUCT_DRAFT_UUID_URI, ['944ca210-d8e0-4c57-9529-741e17e95c8d'])->willReturn($draft); 49 | 50 | $this->get('944ca210-d8e0-4c57-9529-741e17e95c8d')->shouldReturn($draft); 51 | } 52 | 53 | function it_submits_a_product_draft_for_approval($resourceClient) 54 | { 55 | $resourceClient->createResource(ProductDraftUuidApi::PRODUCT_PROPOSAL_UUID_URI, ['944ca210-d8e0-4c57-9529-741e17e95c8d'])->willReturn(201); 56 | 57 | $this->submitForApproval('944ca210-d8e0-4c57-9529-741e17e95c8d')->shouldReturn(201); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /spec/Api/ProductModelDraftApiSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($resourceClient, $pageFactory, $cursorFactory); 21 | } 22 | 23 | function it_is_initializable() 24 | { 25 | $this->shouldHaveType(ProductModelDraftApi::class); 26 | $this->shouldImplement(ProductModelDraftApiInterface::class); 27 | $this->shouldImplement(GettableResourceInterface::class); 28 | } 29 | 30 | function it_gets_a_product_model_draft($resourceClient) 31 | { 32 | $draft = [ 33 | 'identifier' => 'a_product_model', 34 | 'family_variant' => 'bar', 35 | 'parent' => null, 36 | 'values' => [], 37 | 'created' => 'this is a date formatted to ISO-8601', 38 | 'updated' => 'this is a date formatted to ISO-8601', 39 | 'associations' => [], 40 | 'metadata' => [ 41 | 'workflow_status' => 'draft_in_progress', 42 | ], 43 | ]; 44 | 45 | $resourceClient->getResource(ProductModelDraftApi::PRODUCT_MODEL_DRAFT_URI, ['a_product_model'])->willReturn($draft); 46 | 47 | $this->get('a_product_model')->shouldReturn($draft); 48 | } 49 | 50 | function it_submits_a_product_model_draft_for_approval($resourceClient) 51 | { 52 | $resourceClient->createResource(ProductModelDraftApi::PRODUCT_MODEL_PROPOSAL_URI, ['a_product_model'])->willReturn(201); 53 | 54 | $this->submitForApproval('a_product_model')->shouldReturn(201); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /spec/Api/ReferenceEntityMediaFileApiSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($resourceClient, $fileSystem); 18 | } 19 | 20 | function it_is_a_reference_entity_media_file_api() 21 | { 22 | $this->shouldImplement(ReferenceEntityMediaFileApiInterface::class); 23 | } 24 | 25 | function it_downloads_a_reference_entity_media_file(ResourceClientInterface $resourceClient, ResponseInterface $response) 26 | { 27 | $resourceClient 28 | ->getStreamedResource(ReferenceEntityMediaFileApi::MEDIA_FILE_DOWNLOAD_URI, ['images/starck.jpg']) 29 | ->willReturn($response); 30 | 31 | $this->download('images/starck.jpg')->shouldReturn($response); 32 | } 33 | 34 | function it_creates_a_reference_entity_media_file( 35 | ResourceClientInterface $resourceClient, 36 | FileSystemInterface $fileSystem, 37 | ResponseInterface $response 38 | ) { 39 | $fileResource = fopen('php://memory', 'r'); 40 | $fileSystem->getResourceFromPath(Argument::any())->shouldNotBeCalled(); 41 | 42 | $requestParts = [ 43 | [ 44 | 'name' => 'file', 45 | 'contents' => $fileResource, 46 | ] 47 | ]; 48 | 49 | $response->getHeader('Reference-entities-media-file-code')->shouldBeCalled()->willReturn( 50 | [ 51 | '0/f/b/f/0fbffddc95c3d610b39e3f3797b14c6c33e98a4f_starck.jpg' 52 | ] 53 | ); 54 | 55 | $resourceClient 56 | ->createMultipartResource(ReferenceEntityMediaFileApi::MEDIA_FILE_CREATE_URI, [], $requestParts) 57 | ->shouldBeCalled() 58 | ->willReturn($response); 59 | 60 | $this->create($fileResource) 61 | ->shouldReturn('0/f/b/f/0fbffddc95c3d610b39e3f3797b14c6c33e98a4f_starck.jpg'); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /spec/Api/SystemInformationApiSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($resourceClient, $pageFactory, $cursorFactory); 20 | } 21 | 22 | function it_is_initializable() 23 | { 24 | $this->shouldHaveType(SystemInformationApi::class); 25 | $this->shouldImplement(SystemInformationApiInterface::class); 26 | } 27 | 28 | function it_returns_system_information($resourceClient) 29 | { 30 | $systemInformation = [ 31 | 'code' => 'foo', 32 | 'attributes' => ['sku'], 33 | 'sort_order' => 1, 34 | 'labels' => [ 35 | 'en_US' => 'Foo', 36 | ], 37 | ]; 38 | 39 | $resourceClient 40 | ->getResource(SystemInformationApi::SYSTEM_INFORMATION_URI) 41 | ->willReturn($systemInformation); 42 | 43 | $this->get()->shouldReturn($systemInformation); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /spec/Exception/HttpExceptionSpec.php: -------------------------------------------------------------------------------- 1 | getStatusCode()->willReturn($aStatusCode); 17 | 18 | $this->beConstructedWith('message', $request, $response); 19 | } 20 | 21 | function it_is_initializable() 22 | { 23 | $this->shouldHaveType(HttpException::class); 24 | $this->shouldImplement(ExceptionInterface::class); 25 | } 26 | 27 | function it_exposes_the_status_code_of_the_response($response) 28 | { 29 | $response->getStatusCode()->willReturn(200); 30 | $this->getCode()->shouldReturn(200); 31 | } 32 | 33 | function it_exposes_the_response($response) 34 | { 35 | $this->getResponse()->shouldReturn($response); 36 | } 37 | 38 | function it_exposes_the_request($request) 39 | { 40 | $this->getRequest()->shouldReturn($request); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /spec/Pagination/ResourceCursorFactorySpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType(ResourceCursorFactory::class); 16 | $this->shouldImplement(ResourceCursorFactoryInterface::class); 17 | } 18 | 19 | function it_creates_a_resource_cursor(PageInterface $page) 20 | { 21 | $this->createCursor(10, $page)->shouldBeLike( 22 | new ResourceCursor(10, $page->getWrappedObject()) 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spec/Routing/UriGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith(static::BASE_URI); 14 | } 15 | 16 | function it_generates_uri_without_having_parameters() 17 | { 18 | $this 19 | ->generate('/api') 20 | ->shouldReturn(static::BASE_URI.'api'); 21 | } 22 | 23 | function it_generates_uri_having_uri_parameters() 24 | { 25 | $this 26 | ->generate('/api/%s/name/%s', ['foo', 'bar']) 27 | ->shouldReturn(static::BASE_URI.'api/foo/name/bar'); 28 | } 29 | 30 | function it_generates_uri_having_uri_parameters_needing_encoding() 31 | { 32 | $this 33 | ->generate('/api/%s', ['na&? %me']) 34 | ->shouldReturn(static::BASE_URI.'api/na%26%3F%20%25me'); 35 | } 36 | 37 | function it_generates_uri_having_uri_parameters_without_encoding_slashes() 38 | { 39 | $this 40 | ->generate('/api/%s', ['na/me']) 41 | ->shouldReturn(static::BASE_URI.'api/na/me'); 42 | } 43 | 44 | function it_generates_uri_having_query_parameters() 45 | { 46 | $this 47 | ->generate('/api', [], ['limit' => 10, 'with_count' => true]) 48 | ->shouldReturn(static::BASE_URI.'api?limit=10&with_count=true'); 49 | } 50 | 51 | function it_generates_uri_with_boolean_as_string() 52 | { 53 | $this 54 | ->generate('/api', [], ['foo' => true, 'bar' => false]) 55 | ->shouldReturn(static::BASE_URI.'api?foo=true&bar=false'); 56 | } 57 | 58 | function it_generates_uri_having_query_parameters_needing_encoding() 59 | { 60 | $queryParameters = [ 61 | 'test' => '=a&', 62 | 'many' => [ 63 | '?1/', 64 | '[2]', 65 | ] 66 | ]; 67 | 68 | $this 69 | ->generate('/api', [], $queryParameters) 70 | ->shouldReturn(static::BASE_URI.'api?test=%3Da%26&many%5B0%5D=%3F1%2F&many%5B1%5D=%5B2%5D'); 71 | } 72 | 73 | function it_generates_uri_having_search_parameter_encoded_in_json() 74 | { 75 | $queryParameters = [ 76 | 'search' => ['categories' => [['operator' => 'IN', 'value' => 'master']]], 77 | ]; 78 | 79 | $this 80 | ->generate('/api', [], $queryParameters) 81 | ->shouldReturn(static::BASE_URI.'api?search=%7B%22categories%22%3A%5B%7B%22operator%22%3A%22IN%22%2C%22value%22%3A%22master%22%7D%5D%7D'); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /spec/Security/AuthenticationSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedThrough('fromPassword', ['client_id', 'secret', 'Julia', 'Julia_pwd']); 13 | $this->shouldHaveType(Authentication::class); 14 | 15 | $this->getClientId()->shouldReturn('client_id'); 16 | $this->getSecret()->shouldReturn('secret'); 17 | $this->getUsername()->shouldReturn('Julia'); 18 | $this->getPassword()->shouldReturn('Julia_pwd'); 19 | $this->getAccessToken()->shouldReturn(null); 20 | $this->getRefreshToken()->shouldReturn(null); 21 | } 22 | 23 | function it_is_initializable_from_a_token() 24 | { 25 | $this->beConstructedThrough('fromToken', ['client_id', 'secret', 'token', 'refresh_token']); 26 | $this->shouldHaveType(Authentication::class); 27 | 28 | $this->getClientId()->shouldReturn('client_id'); 29 | $this->getSecret()->shouldReturn('secret'); 30 | $this->getUsername()->shouldReturn(null); 31 | $this->getPassword()->shouldReturn(null); 32 | $this->getAccessToken()->shouldReturn('token'); 33 | $this->getRefreshToken()->shouldReturn('refresh_token'); 34 | } 35 | 36 | function it_is_initializable_from_an_app_token() 37 | { 38 | $this->beConstructedThrough('fromAppToken', ['a_token']); 39 | $this->shouldHaveType(Authentication::class); 40 | 41 | $this->getClientId()->shouldReturn(null); 42 | $this->getSecret()->shouldReturn(null); 43 | $this->getUsername()->shouldReturn(null); 44 | $this->getPassword()->shouldReturn(null); 45 | $this->getAccessToken()->shouldReturn('a_token'); 46 | $this->getRefreshToken()->shouldReturn(null); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /spec/Stream/LineStreamReaderSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType(LineStreamReader::class); 14 | } 15 | 16 | public function it_gets_next_line(StreamInterface $stream) 17 | { 18 | $stream->isReadable()->willReturn(true); 19 | 20 | $stream->eof()->willReturn(false, false, false, false, false, false, true); 21 | $stream->read(1)->willReturn('{', '}', PHP_EOL, '{', 'a', '}'); 22 | 23 | $this->getNextLine($stream)->shouldReturn('{}'); 24 | } 25 | 26 | public function it_gets_last_line(StreamInterface $stream) 27 | { 28 | $stream->isReadable()->willReturn(true); 29 | 30 | $stream->eof()->willReturn(false, false, false, false, true); 31 | $stream->read(1)->willReturn('{', 'a', '}'); 32 | 33 | $this->getNextLine($stream)->shouldReturn('{a}'); 34 | } 35 | 36 | public function it_returns_null_if_stream_is_not_readable(StreamInterface $stream) 37 | { 38 | $stream->isReadable()->willReturn(false); 39 | 40 | $this->getNextLine($stream)->shouldReturn(null); 41 | } 42 | 43 | public function it_returns_null_if_stream_is_at_the_end(StreamInterface $stream) 44 | { 45 | $stream->isReadable()->willReturn(true); 46 | $stream->eof()->willReturn(true); 47 | 48 | $this->getNextLine($stream)->shouldReturn(null); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /spec/Stream/MultipartStreamBuilderFactorySpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($streamFactory); 15 | } 16 | 17 | function it_is_initializable() 18 | { 19 | $this->shouldHaveType(MultipartStreamBuilderFactory::class); 20 | } 21 | 22 | function it_creates_a_multipart_stream_builder() 23 | { 24 | $this 25 | ->create() 26 | ->shouldReturnAnInstanceOf(MultipartStreamBuilder::class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spec/Stream/UpsertResourceListResponseFactorySpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType(UpsertResourceListResponseFactory::class); 16 | } 17 | 18 | public function it_creates_an_upsert_resource_list_response(StreamInterface $stream) 19 | { 20 | $this->create($stream)->shouldBeLike( 21 | new UpsertResourceListResponse($stream->getWrappedObject(), new LineStreamReader()) 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Api/AppCatalog/AppCatalogApiInterface.php: -------------------------------------------------------------------------------- 1 | resourceClient->getResources( 33 | static::APP_CATALOG_PRODUCT_URI, 34 | [$catalogId], 35 | $limit, 36 | false, 37 | $queryParameters 38 | ); 39 | 40 | $firstPage = $this->pageFactory->createPage($data); 41 | 42 | return $this->cursorFactory->createCursor(null, $firstPage); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Api/AppCatalog/AppCatalogProductApiInterface.php: -------------------------------------------------------------------------------- 1 | 17 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 18 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 19 | * @deprecated Route unavailable in latest PIM versions. Class will be removed in v12.0.0. 20 | * @see \Akeneo\Pim\ApiClient\Api\AssetManager\AssetApiInterface instead. 21 | */ 22 | interface AssetApiInterface extends 23 | GettableResourceInterface, 24 | ListableResourceInterface, 25 | CreatableResourceInterface, 26 | UpsertableResourceInterface, 27 | UpsertableResourceListInterface 28 | { 29 | } 30 | -------------------------------------------------------------------------------- /src/Api/AssetCategoryApiInterface.php: -------------------------------------------------------------------------------- 1 | 17 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 18 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 19 | * @deprecated Route unavailable in latest PIM versions. Class will be removed in v12.0.0. 20 | * @see \Akeneo\Pim\ApiClient\Api\AssetManager\AssetFamilyApiInterface instead. 21 | */ 22 | interface AssetCategoryApiInterface extends 23 | GettableResourceInterface, 24 | ListableResourceInterface, 25 | UpsertableResourceInterface, 26 | UpsertableResourceListInterface, 27 | CreatableResourceInterface 28 | { 29 | } 30 | -------------------------------------------------------------------------------- /src/Api/AssetManager/AssetAttributeApi.php: -------------------------------------------------------------------------------- 1 | resourceClient->getResource(static::ASSET_ATTRIBUTE_URI, [$assetFamilyCode, $attributeCode]); 27 | } 28 | 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | public function all(string $assetFamilyCode, array $queryParameters = []): array 33 | { 34 | return $this->resourceClient->getResource(static::ASSET_ATTRIBUTES_URI, [$assetFamilyCode]); 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function upsert(string $assetFamilyCode, string $attributeCode, array $data = []): int 41 | { 42 | return $this->resourceClient->upsertResource(static::ASSET_ATTRIBUTE_URI, [$assetFamilyCode, $attributeCode], $data); 43 | } 44 | 45 | /** 46 | * {@inheritdoc} 47 | */ 48 | public function upsertAsync(string $assetFamilyCode, string $attributeCode, array $data = []): PromiseInterface|Promise 49 | { 50 | return $this->resourceClient->upsertAsyncResource(static::ASSET_ATTRIBUTE_URI, [$assetFamilyCode, $attributeCode], $data); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Api/AssetManager/AssetAttributeApiInterface.php: -------------------------------------------------------------------------------- 1 | resourceClient->getResource( 27 | static::ASSET_ATTRIBUTE_OPTION_URI, 28 | [$assetFamilyCode, $attributeCode, $attributeOptionCode] 29 | ); 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function all(string $assetFamilyCode, string $attributeCode): array 36 | { 37 | return $this->resourceClient->getResource( 38 | static::ASSET_ATTRIBUTE_OPTIONS_URI, 39 | [$assetFamilyCode, $attributeCode] 40 | ); 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function upsert(string $assetFamilyCode, string $attributeCode, string $attributeOptionCode, array $data = []): int 47 | { 48 | return $this->resourceClient->upsertResource( 49 | static::ASSET_ATTRIBUTE_OPTION_URI, 50 | [$assetFamilyCode, $attributeCode, $attributeOptionCode], 51 | $data 52 | ); 53 | } 54 | 55 | /** 56 | * {@inheritdoc} 57 | */ 58 | public function upsertAsync( 59 | string $assetFamilyCode, 60 | string $attributeCode, 61 | string $attributeOptionCode, 62 | array $data = [] 63 | ): PromiseInterface|Promise { 64 | return $this->resourceClient->upsertAsyncResource( 65 | static::ASSET_ATTRIBUTE_OPTION_URI, 66 | [$assetFamilyCode, $attributeCode, $attributeOptionCode], 67 | $data 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Api/AssetManager/AssetAttributeOptionApiInterface.php: -------------------------------------------------------------------------------- 1 | resourceClient->getResource(static::ASSET_FAMILY_URI, [$code]); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function all(array $queryParameters = []): ResourceCursorInterface 38 | { 39 | $data = $this->resourceClient->getResources( 40 | static::ASSET_FAMILIES_URI, 41 | [], 42 | null, 43 | false, 44 | $queryParameters 45 | ); 46 | 47 | $firstPage = $this->pageFactory->createPage($data); 48 | 49 | return $this->cursorFactory->createCursor(null, $firstPage); 50 | } 51 | 52 | /** 53 | * {@inheritdoc} 54 | */ 55 | public function upsert(string $code, array $data = []): int 56 | { 57 | return $this->resourceClient->upsertResource(static::ASSET_FAMILY_URI, [$code], $data); 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public function upsertAsync(string $code, array $data = []): PromiseInterface|Promise 64 | { 65 | return $this->resourceClient->upsertAsyncResource(static::ASSET_FAMILY_URI, [$code], $data); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Api/AssetManager/AssetFamilyApiInterface.php: -------------------------------------------------------------------------------- 1 | resourceClient->getStreamedResource(static::MEDIA_FILE_DOWNLOAD_URI, [$code]); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function create($mediaFile): string 35 | { 36 | if (is_string($mediaFile)) { 37 | $mediaFile = $this->fileSystem->getResourceFromPath($mediaFile); 38 | } 39 | 40 | $requestParts = [ 41 | [ 42 | 'name' => 'file', 43 | 'contents' => $mediaFile, 44 | ] 45 | ]; 46 | 47 | $response = $this->resourceClient->createMultipartResource(static::MEDIA_FILE_CREATE_URI, [], $requestParts); 48 | 49 | return $this->extractCodeFromCreationResponse($response); 50 | } 51 | 52 | /** 53 | * Extracts the code of a media-file from a creation response. 54 | * 55 | * @throws RuntimeException if unable to extract the code 56 | */ 57 | private function extractCodeFromCreationResponse(ResponseInterface $response): string 58 | { 59 | $header = $response->getHeader('asset-media-file-code'); 60 | 61 | if (empty($header)) { 62 | throw new RuntimeException('The response does not contain the code of the created media-file.'); 63 | } 64 | 65 | return (string) $header[0]; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Api/AssetManager/AssetMediaFileApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | * @deprecated Route unavailable in latest PIM versions. Class will be removed in v12.0.0. 18 | */ 19 | interface AssetTagApiInterface extends GettableResourceInterface, ListableResourceInterface, UpsertableResourceInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /src/Api/AssociationTypeApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | interface AssociationTypeApiInterface extends 19 | GettableResourceInterface, 20 | ListableResourceInterface, 21 | CreatableResourceInterface, 22 | UpsertableResourceInterface, 23 | UpsertableResourceListInterface 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/Api/AttributeApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | interface AttributeApiInterface extends 19 | ListableResourceInterface, 20 | GettableResourceInterface, 21 | CreatableResourceInterface, 22 | UpsertableResourceInterface, 23 | UpsertableResourceListInterface 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/Api/AttributeGroupApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | interface AttributeGroupApiInterface extends 19 | GettableResourceInterface, 20 | ListableResourceInterface, 21 | CreatableResourceInterface, 22 | UpsertableResourceInterface, 23 | UpsertableResourceListInterface 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/Api/AuthenticationApi.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | class AuthenticationApi implements AuthenticationApiInterface 16 | { 17 | public const TOKEN_URI = 'api/oauth/v1/token'; 18 | 19 | public function __construct( 20 | protected HttpClient $httpClient, 21 | protected UriGeneratorInterface $uriGenerator 22 | ) { 23 | } 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function authenticateByPassword($clientId, $secret, $username, $password): array 29 | { 30 | $requestBody = [ 31 | 'grant_type' => 'password', 32 | 'username' => $username, 33 | 'password' => $password, 34 | ]; 35 | 36 | return $this->authenticate($clientId, $secret, $requestBody); 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function authenticateByRefreshToken($clientId, $secret, $refreshToken): array 43 | { 44 | $requestBody = [ 45 | 'grant_type' => 'refresh_token', 46 | 'refresh_token' => $refreshToken 47 | ]; 48 | 49 | return $this->authenticate($clientId, $secret, $requestBody); 50 | } 51 | 52 | /** 53 | * Authenticates the client by requesting the access token and the refresh token. 54 | * 55 | * @param string $clientId client id 56 | * @param string $secret secret associated to the client id 57 | * @param array $requestBody body of the request to authenticate 58 | * 59 | * @return array returns the body of the response containing access token and refresh token 60 | */ 61 | protected function authenticate($clientId, $secret, array $requestBody): array 62 | { 63 | $headers = [ 64 | 'Content-Type' => 'application/json', 65 | 'Authorization' => sprintf('Basic %s', base64_encode($clientId . ':' . $secret)), 66 | ]; 67 | 68 | $uri = $this->uriGenerator->generate(static::TOKEN_URI); 69 | 70 | $response = $this->httpClient->sendRequest('POST', $uri, $headers, json_encode($requestBody)); 71 | 72 | return json_decode($response->getBody()->getContents(), true); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Api/AuthenticationApiInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | interface AuthenticationApiInterface 13 | { 14 | /** 15 | * Authenticates with the password grant type. 16 | * 17 | * @param string $clientId 18 | * @param string $secret 19 | * @param string $username 20 | * @param string $password 21 | * 22 | * @return array 23 | */ 24 | public function authenticateByPassword($clientId, $secret, $username, $password): array; 25 | 26 | /** 27 | * Authenticates with the refresh token grant type. 28 | * 29 | * @param string $clientId 30 | * @param string $secret 31 | * @param string $refreshToken 32 | * 33 | * @return array 34 | */ 35 | public function authenticateByRefreshToken($clientId, $secret, $refreshToken): array; 36 | } 37 | -------------------------------------------------------------------------------- /src/Api/CategoryApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | interface CategoryApiInterface extends 19 | GettableResourceInterface, 20 | ListableResourceInterface, 21 | CreatableResourceInterface, 22 | UpsertableResourceInterface, 23 | UpsertableResourceListInterface 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/Api/CategoryMediaFileApi.php: -------------------------------------------------------------------------------- 1 | resourceClient->getStreamedResource(static::MEDIA_FILE_DOWNLOAD_URI, [$code]); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Api/ChannelApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | interface ChannelApiInterface extends 19 | ListableResourceInterface, 20 | GettableResourceInterface, 21 | CreatableResourceInterface, 22 | UpsertableResourceInterface, 23 | UpsertableResourceListInterface 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/Api/CurrencyApi.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class CurrencyApi implements CurrencyApiInterface 19 | { 20 | public const CURRENCY_URI = 'api/rest/v1/currencies/%s'; 21 | public const CURRENCIES_URI = 'api/rest/v1/currencies'; 22 | 23 | public function __construct( 24 | protected ResourceClientInterface $resourceClient, 25 | protected PageFactoryInterface $pageFactory, 26 | protected ResourceCursorFactoryInterface $cursorFactory 27 | ) { 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function get(string $code): array 34 | { 35 | return $this->resourceClient->getResource(static::CURRENCY_URI, [$code]); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function listPerPage(int $limit = 100, bool $withCount = false, array $queryParameters = []): PageInterface 42 | { 43 | $data = $this->resourceClient->getResources(static::CURRENCIES_URI, [], $limit, $withCount, $queryParameters); 44 | 45 | return $this->pageFactory->createPage($data); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function all(int $pageSize = 100, array $queryParameters = []): ResourceCursorInterface 52 | { 53 | $firstPage = $this->listPerPage($pageSize, false, $queryParameters); 54 | 55 | return $this->cursorFactory->createCursor($pageSize, $firstPage); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Api/CurrencyApiInterface.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | interface CurrencyApiInterface extends GettableResourceInterface, ListableResourceInterface 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Api/FamilyApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | interface FamilyApiInterface extends 19 | ListableResourceInterface, 20 | GettableResourceInterface, 21 | CreatableResourceInterface, 22 | UpsertableResourceInterface, 23 | UpsertableResourceListInterface 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/Api/LocaleApi.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class LocaleApi implements LocaleApiInterface 19 | { 20 | public const LOCALES_URI = 'api/rest/v1/locales'; 21 | public const LOCALE_URI = 'api/rest/v1/locales/%s'; 22 | 23 | public function __construct( 24 | protected ResourceClientInterface $resourceClient, 25 | protected PageFactoryInterface $pageFactory, 26 | protected ResourceCursorFactoryInterface $cursorFactory 27 | ) { 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function get(string $code): array 34 | { 35 | return $this->resourceClient->getResource(static::LOCALE_URI, [$code]); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function listPerPage(int $limit = 100, bool $withCount = false, array $queryParameters = []): PageInterface 42 | { 43 | $data = $this->resourceClient->getResources(static::LOCALES_URI, [], $limit, $withCount, $queryParameters); 44 | 45 | return $this->pageFactory->createPage($data); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function all(int $pageSize = 100, array $queryParameters = []): ResourceCursorInterface 52 | { 53 | $firstPage = $this->listPerPage($pageSize, false, $queryParameters); 54 | 55 | return $this->cursorFactory->createCursor($pageSize, $firstPage); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Api/LocaleApiInterface.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | interface LocaleApiInterface extends ListableResourceInterface, GettableResourceInterface 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Api/MeasureFamilyApi.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class MeasureFamilyApi implements MeasureFamilyApiInterface 19 | { 20 | public const MEASURE_FAMILY_URI = 'api/rest/v1/measure-families/%s'; 21 | public const MEASURE_FAMILIES_URI = 'api/rest/v1/measure-families'; 22 | 23 | public function __construct( 24 | protected ResourceClientInterface $resourceClient, 25 | protected PageFactoryInterface $pageFactory, 26 | protected ResourceCursorFactoryInterface $cursorFactory 27 | ) { 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function get(string $code): array 34 | { 35 | return $this->resourceClient->getResource(static::MEASURE_FAMILY_URI, [$code]); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function listPerPage(int $limit = 100, bool $withCount = false, array $queryParameters = []): PageInterface 42 | { 43 | $data = $this->resourceClient->getResources(static::MEASURE_FAMILIES_URI, [], $limit, $withCount, $queryParameters); 44 | 45 | return $this->pageFactory->createPage($data); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function all(int $pageSize = 100, array $queryParameters = []): ResourceCursorInterface 52 | { 53 | $firstPage = $this->listPerPage($pageSize, false, $queryParameters); 54 | 55 | return $this->cursorFactory->createCursor($pageSize, $firstPage); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Api/MeasureFamilyApiInterface.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | interface MeasureFamilyApiInterface extends GettableResourceInterface, ListableResourceInterface 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Api/MeasurementFamilyApi.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2020 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class MeasurementFamilyApi implements MeasurementFamilyApiInterface 15 | { 16 | public const MEASUREMENT_FAMILIES_URI = 'api/rest/v1/measurement-families'; 17 | 18 | public function __construct( 19 | protected ResourceClientInterface $resourceClient 20 | ) { 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function all(): array 27 | { 28 | return $this->resourceClient->getResource(static::MEASUREMENT_FAMILIES_URI); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function upsertList($resources): array 35 | { 36 | return $this->resourceClient->upsertJsonResourceList(static::MEASUREMENT_FAMILIES_URI, [], $resources); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Api/MeasurementFamilyApiInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2020 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | interface MeasurementFamilyApiInterface 15 | { 16 | /** 17 | * Gets a cursor to iterate over all the measurement families 18 | * 19 | * @throws HttpException If the request failed. 20 | * 21 | * @return array 22 | */ 23 | public function all(): array; 24 | 25 | /** 26 | * Updates or creates several resources. 27 | * 28 | * @param array $resources array object containing the measurement families to create or update 29 | * 30 | * @throws HttpException 31 | * 32 | * @return array returns an array, each entry corresponding to the response of the upserted measurement families 33 | */ 34 | public function upsertList($resources): array; 35 | } 36 | -------------------------------------------------------------------------------- /src/Api/MediaFileApiInterface.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | interface MediaFileApiInterface extends 19 | ListableResourceInterface, 20 | GettableResourceInterface, 21 | DownloadableResourceInterface 22 | { 23 | /** 24 | * Creates a new media file and associates it to a resource. 25 | * 26 | * @param string|resource $mediaFile File path or resource of the media file 27 | * @param array $data The data of the resource to which the media file will be associated 28 | * 29 | * @throws HttpException If the request failed. 30 | * @throws RuntimeException If the file could not be opened. 31 | * 32 | * @return string returns the code of created media file 33 | */ 34 | public function create($mediaFile, array $data): string; 35 | } 36 | -------------------------------------------------------------------------------- /src/Api/Operation/CreatableResourceInterface.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | interface CreatableResourceInterface 16 | { 17 | /** 18 | * Creates a resource. 19 | * 20 | * @param string $code code of the resource to create 21 | * @param array $data data of the resource to create 22 | * 23 | * @throws HttpException If the request failed. 24 | * @throws InvalidArgumentException If the parameter "code" is defined in the data parameter. 25 | * 26 | * @return int Status code 201 indicating that the resource has been well created. 27 | */ 28 | public function create(string $code, array $data = []): int; 29 | } 30 | -------------------------------------------------------------------------------- /src/Api/Operation/DeletableResourceInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | interface DeletableResourceInterface 15 | { 16 | /** 17 | * Deletes a resource. 18 | * 19 | * @param string $code code of the resource to delete 20 | * 21 | * @throws HttpException 22 | * 23 | * @return int Status code 204 indicating that the resource has been well deleted. 24 | */ 25 | public function delete(string $code): int; 26 | } 27 | -------------------------------------------------------------------------------- /src/Api/Operation/DownloadableResourceInterface.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | interface DownloadableResourceInterface 16 | { 17 | /** 18 | * Downloads a resource by its code 19 | * 20 | * @param string $code Code of the resource 21 | * 22 | * @throws HttpException 23 | * 24 | * @return ResponseInterface 25 | */ 26 | public function download(string $code): ResponseInterface; 27 | } 28 | -------------------------------------------------------------------------------- /src/Api/Operation/GettableResourceInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | interface GettableResourceInterface 15 | { 16 | /** 17 | * Gets a resource by its code 18 | * 19 | * @param string $code Code of the resource 20 | * 21 | * @throws HttpException If the request failed. 22 | * 23 | * @return array 24 | */ 25 | public function get(string $code): array; 26 | } 27 | -------------------------------------------------------------------------------- /src/Api/Operation/ListableResourceInterface.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | interface ListableResourceInterface 17 | { 18 | /** 19 | * Gets a list of resources by returning the first page. 20 | * Consequently, this method does not return all the resources. 21 | * 22 | * @param int $limit The maximum number of resources to return. 23 | * Do note that the server has a maximum limit allowed. 24 | * @param bool $withCount Set to true to return the total count of resources. 25 | * This parameter could decrease drastically the performance when set to true. 26 | * @param array $queryParameters Additional query parameters to pass in the request. 27 | * 28 | * @throws HttpException If the request failed. 29 | * 30 | * @return PageInterface 31 | */ 32 | public function listPerPage(int $limit = 100, bool $withCount = false, array $queryParameters = []): PageInterface; 33 | 34 | /** 35 | * Gets a cursor to iterate over a list of resources. 36 | * 37 | * @param int $pageSize The size of the page returned by the server. 38 | * Do note that the server has a maximum limit allowed. 39 | * @param array $queryParameters Additional query parameters to pass in the request 40 | * 41 | * @throws HttpException If the request failed. 42 | * 43 | * @return ResourceCursorInterface 44 | */ 45 | public function all(int $pageSize = 100, array $queryParameters = []): ResourceCursorInterface; 46 | } 47 | -------------------------------------------------------------------------------- /src/Api/Operation/UpsertableResourceInterface.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | interface UpsertableResourceInterface 17 | { 18 | /** 19 | * Creates a resource if it does not exist yet, otherwise updates partially the resource. 20 | * 21 | * @param string $code code of the resource to create or update 22 | * @param array $data data of the resource to create or update 23 | * 24 | * @throws HttpException If the request failed. 25 | * 26 | * @return int Status code 201 indicating that the resource has been well created. 27 | * Status code 204 indicating that the resource has been well updated. 28 | */ 29 | public function upsert(string $code, array $data = []): int; 30 | 31 | /** 32 | * Creates a resource if it does not exist yet, otherwise updates partially the resource. 33 | * 34 | * @param string $code code of the resource to create or update 35 | * @param array $data data of the resource to create or update 36 | * 37 | * @throws HttpException If the request failed. 38 | * 39 | * @return Promise 40 | */ 41 | public function upsertAsync(string $code, array $data = []): PromiseInterface|Promise; 42 | } 43 | -------------------------------------------------------------------------------- /src/Api/Operation/UpsertableResourceListInterface.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | interface UpsertableResourceListInterface 18 | { 19 | /** 20 | * Updates or creates several resources. 21 | * 22 | * @param array|StreamInterface $resources array or StreamInterface object containing the resources to create or update 23 | * 24 | * @throws HttpException 25 | * 26 | * @return \Traversable returns an iterable object, each entry corresponding to the response of the upserted resource 27 | */ 28 | public function upsertList(array|StreamInterface $resources): \Traversable; 29 | 30 | /** 31 | * Updates or creates several resources. 32 | * 33 | * @param array|StreamInterface $resources array or StreamInterface object containing the resources to create or update 34 | * 35 | * @throws HttpException 36 | * 37 | * @return PromiseInterface|Promise returns a Promise 38 | */ 39 | public function upsertAsyncList(array|StreamInterface $resources): PromiseInterface|Promise; 40 | } 41 | -------------------------------------------------------------------------------- /src/Api/ProductApiInterface.php: -------------------------------------------------------------------------------- 1 | 17 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 18 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 19 | */ 20 | interface ProductApiInterface extends 21 | ListableResourceInterface, 22 | GettableResourceInterface, 23 | CreatableResourceInterface, 24 | UpsertableResourceInterface, 25 | UpsertableResourceListInterface, 26 | DeletableResourceInterface 27 | { 28 | /** 29 | * Gets a resource by its code 30 | * 31 | * @param string $code Code of the resource 32 | * @param array $queryParameters Additional query parameters to pass in the request. 33 | * 34 | * @throws HttpException If the request failed. 35 | * 36 | * @return array 37 | */ 38 | public function get(string $code, array $queryParameters = []): array; 39 | } 40 | -------------------------------------------------------------------------------- /src/Api/ProductDraftApi.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class ProductDraftApi implements ProductDraftApiInterface 19 | { 20 | public const PRODUCT_DRAFT_URI = '/api/rest/v1/products/%s/draft'; 21 | public const PRODUCT_PROPOSAL_URI = '/api/rest/v1/products/%s/proposal'; 22 | 23 | public function __construct( 24 | protected ResourceClientInterface $resourceClient, 25 | protected PageFactoryInterface $pageFactory, 26 | protected ResourceCursorFactoryInterface $cursorFactory 27 | ) { 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function get(string $code): array 34 | { 35 | return $this->resourceClient->getResource(static::PRODUCT_DRAFT_URI, [$code]); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function submitForApproval($code) 42 | { 43 | return $this->resourceClient->createResource(static::PRODUCT_PROPOSAL_URI, [$code]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Api/ProductDraftApiInterface.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | interface ProductDraftApiInterface extends GettableResourceInterface 17 | { 18 | /** 19 | * Submits a product draft for approval, by its code. 20 | * 21 | * @param string $code 22 | * 23 | * @return int 24 | */ 25 | public function submitForApproval($code); 26 | } 27 | -------------------------------------------------------------------------------- /src/Api/ProductDraftUuidApi.php: -------------------------------------------------------------------------------- 1 | resourceClient->getResource(static::PRODUCT_DRAFT_UUID_URI, [$uuid]); 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function submitForApproval(string $uuid): int 39 | { 40 | return $this->resourceClient->createResource(static::PRODUCT_PROPOSAL_UUID_URI, [$uuid]); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Api/ProductDraftUuidApiInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | interface ProductModelApiInterface extends 20 | GettableResourceInterface, 21 | CreatableResourceInterface, 22 | UpsertableResourceInterface, 23 | UpsertableResourceListInterface, 24 | ListableResourceInterface, 25 | DeletableResourceInterface 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /src/Api/ProductModelDraftApi.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class ProductModelDraftApi implements ProductModelDraftApiInterface 19 | { 20 | public const PRODUCT_MODEL_DRAFT_URI = '/api/rest/v1/product-models/%s/draft'; 21 | public const PRODUCT_MODEL_PROPOSAL_URI = '/api/rest/v1/product-models/%s/proposal'; 22 | 23 | public function __construct( 24 | protected ResourceClientInterface $resourceClient, 25 | protected PageFactoryInterface $pageFactory, 26 | protected ResourceCursorFactoryInterface $cursorFactory 27 | ) { 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function get(string $code): array 34 | { 35 | return $this->resourceClient->getResource(static::PRODUCT_MODEL_DRAFT_URI, [$code]); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function submitForApproval($code) 42 | { 43 | return $this->resourceClient->createResource(static::PRODUCT_MODEL_PROPOSAL_URI, [$code]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Api/ProductModelDraftApiInterface.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | interface ProductModelDraftApiInterface extends GettableResourceInterface 17 | { 18 | /** 19 | * Submits a product model draft for approval, by its code. 20 | * 21 | * @param string $code 22 | * 23 | * @return int 24 | */ 25 | public function submitForApproval($code); 26 | } 27 | -------------------------------------------------------------------------------- /src/Api/ProductUuidApiInterface.php: -------------------------------------------------------------------------------- 1 | 17 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 18 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 19 | */ 20 | class PublishedProductApi implements PublishedProductApiInterface 21 | { 22 | public const PUBLISHED_PRODUCTS_URI = 'api/rest/v1/published-products'; 23 | public const PUBLISHED_PRODUCT_URI = 'api/rest/v1/published-products/%s'; 24 | 25 | public function __construct( 26 | protected ResourceClientInterface $resourceClient, 27 | protected PageFactoryInterface $pageFactory, 28 | protected ResourceCursorFactoryInterface $cursorFactory 29 | ) { 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function get(string $code): array 36 | { 37 | return $this->resourceClient->getResource(static::PUBLISHED_PRODUCT_URI, [$code]); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function listPerPage(int $limit = 100, bool $withCount = false, array $queryParameters = []): PageInterface 44 | { 45 | $data = $this->resourceClient->getResources( 46 | static::PUBLISHED_PRODUCTS_URI, 47 | [], 48 | $limit, 49 | $withCount, 50 | $queryParameters 51 | ); 52 | 53 | return $this->pageFactory->createPage($data); 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function all(int $pageSize = 100, array $queryParameters = []): ResourceCursorInterface 60 | { 61 | $queryParameters['pagination_type'] = 'search_after'; 62 | 63 | $firstPage = $this->listPerPage($pageSize, false, $queryParameters); 64 | 65 | return $this->cursorFactory->createCursor($pageSize, $firstPage); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Api/PublishedProductApiInterface.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | interface PublishedProductApiInterface extends 18 | ListableResourceInterface, 19 | GettableResourceInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /src/Api/ReferenceEntityApi.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | class ReferenceEntityApi implements ReferenceEntityApiInterface 20 | { 21 | public const REFERENCE_ENTITY_URI = 'api/rest/v1/reference-entities/%s'; 22 | public const REFERENCE_ENTITIES_URI = 'api/rest/v1/reference-entities'; 23 | 24 | public function __construct( 25 | private ResourceClientInterface $resourceClient, 26 | private PageFactoryInterface $pageFactory, 27 | private ResourceCursorFactoryInterface $cursorFactory 28 | ) { 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function get(string $referenceEntityCode): array 35 | { 36 | return $this->resourceClient->getResource(static::REFERENCE_ENTITY_URI, [$referenceEntityCode]); 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function all(array $queryParameters = []): ResourceCursorInterface 43 | { 44 | $data = $this->resourceClient->getResources( 45 | static::REFERENCE_ENTITIES_URI, 46 | [], 47 | null, 48 | false, 49 | $queryParameters 50 | ); 51 | 52 | $firstPage = $this->pageFactory->createPage($data); 53 | 54 | return $this->cursorFactory->createCursor(null, $firstPage); 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | public function upsert(string $referenceEntityCode, array $data = []): int 61 | { 62 | return $this->resourceClient->upsertResource(static::REFERENCE_ENTITY_URI, [$referenceEntityCode], $data); 63 | } 64 | 65 | public function upsertAsync(string $referenceEntityCode, array $data = []): PromiseInterface|Promise 66 | { 67 | return $this->resourceClient->upsertAsyncResource(static::REFERENCE_ENTITY_URI, [$referenceEntityCode], $data); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Api/ReferenceEntityApiInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | interface ReferenceEntityApiInterface 20 | { 21 | /** 22 | * Gets a single reference entity. 23 | * 24 | * @param string $referenceEntityCode Code of the reference entity 25 | * 26 | * @throws HttpException If the request failed. 27 | * 28 | * @return array 29 | */ 30 | public function get(string $referenceEntityCode): array; 31 | 32 | /** 33 | * Gets a cursor to iterate over the list of reference entities 34 | * 35 | * @param array $queryParameters Additional query parameters to pass in the request 36 | * 37 | * @throws HttpException If the request failed. 38 | * 39 | * @return ResourceCursorInterface 40 | */ 41 | public function all(array $queryParameters = []): ResourceCursorInterface; 42 | 43 | /** 44 | * Creates a reference entity if it does not exist yet, otherwise updates partially the reference entity. 45 | * 46 | * @param string $referenceEntityCode Code of the reference entity 47 | * @param array $data Data of the reference entity to create or update 48 | * 49 | * @throws HttpException If the request failed. 50 | * 51 | * @return int Status code 201 indicating that the reference entity has been well created. 52 | * Status code 204 indicating that the reference entity has been well updated. 53 | */ 54 | public function upsert(string $referenceEntityCode, array $data = []): int; 55 | 56 | /** 57 | * Creates a reference entity if it does not exist yet, otherwise updates partially the reference entity. 58 | * 59 | * @param string $referenceEntityCode Code of the reference entity 60 | * @param array $data Data of the reference entity to create or update 61 | * 62 | * @throws HttpException If the request failed. 63 | * 64 | * @return Promise 65 | */ 66 | public function upsertAsync(string $referenceEntityCode, array $data = []): PromiseInterface|Promise; 67 | } 68 | -------------------------------------------------------------------------------- /src/Api/ReferenceEntityAttributeApi.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | class ReferenceEntityAttributeApi implements ReferenceEntityAttributeApiInterface 17 | { 18 | public const REFERENCE_ENTITY_ATTRIBUTE_URI = 'api/rest/v1/reference-entities/%s/attributes/%s'; 19 | public const REFERENCE_ENTITY_ATTRIBUTES_URI = 'api/rest/v1/reference-entities/%s/attributes'; 20 | 21 | public function __construct( 22 | private ResourceClientInterface $resourceClient 23 | ) { 24 | } 25 | 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function get(string $referenceEntityCode, string $attributeCode): array 30 | { 31 | return $this->resourceClient->getResource(static::REFERENCE_ENTITY_ATTRIBUTE_URI, [$referenceEntityCode, $attributeCode]); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function all(string $referenceEntityCode, array $queryParameters = []): array 38 | { 39 | return $this->resourceClient->getResource(static::REFERENCE_ENTITY_ATTRIBUTES_URI, [$referenceEntityCode]); 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function upsert(string $referenceEntityCode, string $attributeCode, array $data = []): int 46 | { 47 | return $this->resourceClient->upsertResource(static::REFERENCE_ENTITY_ATTRIBUTE_URI, [$referenceEntityCode, $attributeCode], $data); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function upsertAsync(string $referenceEntityCode, string $attributeCode, array $data = []): PromiseInterface|Promise 54 | { 55 | return $this->resourceClient->upsertAsyncResource( 56 | static::REFERENCE_ENTITY_ATTRIBUTE_URI, 57 | [$referenceEntityCode, $attributeCode], 58 | $data 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Api/ReferenceEntityAttributeOptionApi.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | class ReferenceEntityAttributeOptionApi implements ReferenceEntityAttributeOptionApiInterface 17 | { 18 | public const REFERENCE_ENTITY_ATTRIBUTE_OPTION_URI = 'api/rest/v1/reference-entities/%s/attributes/%s/options/%s'; 19 | public const REFERENCE_ENTITY_ATTRIBUTE_OPTIONS_URI = 'api/rest/v1/reference-entities/%s/attributes/%s/options'; 20 | 21 | public function __construct( 22 | private ResourceClientInterface $resourceClient 23 | ) { 24 | } 25 | 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function get(string $referenceEntityCode, string $attributeCode, string $attributeOptionCode): array 30 | { 31 | return $this->resourceClient->getResource( 32 | static::REFERENCE_ENTITY_ATTRIBUTE_OPTION_URI, 33 | [$referenceEntityCode, $attributeCode, $attributeOptionCode] 34 | ); 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function all(string $referenceEntityCode, string $attributeCode): array 41 | { 42 | return $this->resourceClient->getResource( 43 | static::REFERENCE_ENTITY_ATTRIBUTE_OPTIONS_URI, 44 | [$referenceEntityCode, $attributeCode] 45 | ); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function upsert(string $referenceEntityCode, string $attributeCode, string $attributeOptionCode, array $data = []): int 52 | { 53 | return $this->resourceClient->upsertResource( 54 | static::REFERENCE_ENTITY_ATTRIBUTE_OPTION_URI, 55 | [$referenceEntityCode, $attributeCode, $attributeOptionCode], 56 | $data 57 | ); 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public function upsertAsync( 64 | string $referenceEntityCode, 65 | string $attributeCode, 66 | string $attributeOptionCode, 67 | array $data = [] 68 | ): PromiseInterface|Promise { 69 | return $this->resourceClient->upsertAsyncResource( 70 | static::REFERENCE_ENTITY_ATTRIBUTE_OPTION_URI, 71 | [$referenceEntityCode, $attributeCode, $attributeOptionCode], 72 | $data 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Api/ReferenceEntityMediaFileApi.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | class ReferenceEntityMediaFileApi implements ReferenceEntityMediaFileApiInterface 18 | { 19 | public const MEDIA_FILE_DOWNLOAD_URI = 'api/rest/v1/reference-entities-media-files/%s'; 20 | public const MEDIA_FILE_CREATE_URI = 'api/rest/v1/reference-entities-media-files'; 21 | 22 | public function __construct( 23 | private ResourceClientInterface $resourceClient, 24 | private FileSystemInterface $fileSystem 25 | ) { 26 | } 27 | 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | public function download($code): ResponseInterface 32 | { 33 | return $this->resourceClient->getStreamedResource(static::MEDIA_FILE_DOWNLOAD_URI, [$code]); 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function create($mediaFile): string 40 | { 41 | if (is_string($mediaFile)) { 42 | $mediaFile = $this->fileSystem->getResourceFromPath($mediaFile); 43 | } 44 | 45 | $requestParts = [ 46 | [ 47 | 'name' => 'file', 48 | 'contents' => $mediaFile, 49 | ] 50 | ]; 51 | 52 | $response = $this->resourceClient->createMultipartResource(static::MEDIA_FILE_CREATE_URI, [], $requestParts); 53 | 54 | return $this->extractCodeFromCreationResponse($response); 55 | } 56 | 57 | /** 58 | * Extracts the code of a media-file from a creation response. 59 | * 60 | * @throws RuntimeException if unable to extract the code 61 | */ 62 | private function extractCodeFromCreationResponse(ResponseInterface $response): string 63 | { 64 | $header = $response->getHeader('Reference-entities-media-file-code'); 65 | 66 | if (empty($header)) { 67 | throw new RuntimeException('The response does not contain the code of the created media-file.'); 68 | } 69 | 70 | return (string)$header[0]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Api/ReferenceEntityMediaFileApiInterface.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | interface ReferenceEntityMediaFileApiInterface 17 | { 18 | /** 19 | * Downloads a reference entity media file by its code 20 | * 21 | * @param string $code Code of the media file 22 | * 23 | * @throws HttpException If the request failed. 24 | * 25 | * @return ResponseInterface 26 | */ 27 | public function download($code): ResponseInterface; 28 | 29 | /** 30 | * Creates a new reference entity media file. 31 | * 32 | * @param string|resource $mediaFile File path or resource of the media file 33 | * 34 | * @throws HttpException If the request failed. 35 | * @throws RuntimeException If the file could not be opened. 36 | * 37 | * @return string returns the code of the created media file 38 | */ 39 | public function create($mediaFile): string; 40 | } 41 | -------------------------------------------------------------------------------- /src/Api/SystemInformationApi.php: -------------------------------------------------------------------------------- 1 | resourceClient->getResource(static::SYSTEM_INFORMATION_URI); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Api/SystemInformationApiInterface.php: -------------------------------------------------------------------------------- 1 | items[$key])) { 25 | return null; 26 | } 27 | 28 | $entry = $this->items[$key]; 29 | 30 | unset($this->items[$key]); 31 | $this->items[$key] = $entry; 32 | 33 | return $entry; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function set(string $key, $value): void 40 | { 41 | $this->items[$key] = $value; 42 | 43 | $diff = count($this->items) - $this->maxItems; 44 | 45 | if ($diff <= 0) { 46 | return; 47 | } 48 | for ($i = 0; $i < $diff; $i++) { 49 | unset($this->items[array_key_first($this->items)]); 50 | next($this->items); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Client/ClientInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | interface HttpClientInterface 20 | { 21 | /** 22 | * Sends a request. 23 | * 24 | * @param string $httpMethod HTTP method to use 25 | * @param string|UriInterface $uri URI of the request 26 | * @param array $headers headers of the request 27 | * @param string|StreamInterface|null $body body of the request 28 | * 29 | * @throws HttpException If the request failed. 30 | * 31 | * @return ResponseInterface 32 | */ 33 | public function sendRequest(string $httpMethod, $uri, array $headers = [], $body = null): ResponseInterface; 34 | 35 | /** 36 | * Sends a request. 37 | * 38 | * @param string $httpMethod HTTP method to use 39 | * @param string|UriInterface $uri URI of the request 40 | * @param array $headers headers of the request 41 | * @param string|StreamInterface|null $body body of the request 42 | * 43 | * @throws HttpException If the request failed. 44 | * 45 | * @return PromiseInterface|Promise 46 | */ 47 | public function sendAsync( 48 | string $httpMethod, 49 | $uri, 50 | array $headers = [], 51 | $body = null 52 | ): PromiseInterface|Promise; 53 | } 54 | -------------------------------------------------------------------------------- /src/Client/Options.php: -------------------------------------------------------------------------------- 1 | setDefaults([ 21 | 'headers' => [], 22 | ]); 23 | $resolver->setAllowedTypes('headers', 'string[]'); 24 | 25 | $options = $resolver->resolve($options); 26 | 27 | return new self($options); 28 | } 29 | 30 | public function hasHeaders(): bool 31 | { 32 | return [] !== $this->options['headers']; 33 | } 34 | 35 | /** 36 | * @return string[] 37 | */ 38 | public function getHeaders(): array 39 | { 40 | return $this->options['headers']; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Exception/BadRequestHttpException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class BadRequestHttpException extends ClientErrorHttpException 13 | { 14 | protected function getAdditionalInformationMessage(): string 15 | { 16 | return '(see https://api.akeneo.com/php-client/exception.html#bad-request-exception)'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Exception/ClientErrorHttpException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class ClientErrorHttpException extends HttpException 13 | { 14 | protected function getAdditionalInformationMessage(): string 15 | { 16 | return '(see https://api.akeneo.com/php-client/exception.html#client-exception)'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Exception/ExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | interface ExceptionInterface 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/Exception/ForbiddenHttpException.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | class HttpException extends RuntimeException 16 | { 17 | /** @var ResponseInterface */ 18 | protected $response; 19 | 20 | public function __construct( 21 | string $message, 22 | protected RequestInterface $request, 23 | ResponseInterface $response, 24 | ?\Exception $previous = null 25 | ) { 26 | $message .= ' ' . $this->getAdditionalInformationMessage(); 27 | 28 | parent::__construct($message, $response->getStatusCode(), $previous); 29 | $this->response = $response; 30 | } 31 | 32 | /** 33 | * Returns the request. 34 | */ 35 | public function getRequest(): RequestInterface 36 | { 37 | return $this->request; 38 | } 39 | 40 | /** 41 | * Returns the response. 42 | */ 43 | public function getResponse(): ResponseInterface 44 | { 45 | return $this->response; 46 | } 47 | 48 | protected function getAdditionalInformationMessage(): string 49 | { 50 | return '(see https://api.akeneo.com/php-client/exception.html#http-exception)'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/Exception/MethodNotAllowedHttpException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class NotFoundHttpException extends ClientErrorHttpException 13 | { 14 | protected function getAdditionalInformationMessage(): string 15 | { 16 | return '(see https://api.akeneo.com/php-client/exception.html#not-found-exception)'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Exception/RedirectionHttpException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2018 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class RedirectionHttpException extends ClientErrorHttpException 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/Exception/RuntimeException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class RuntimeException extends \RuntimeException implements ExceptionInterface 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/Exception/ServerErrorHttpException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class ServerErrorHttpException extends HttpException 13 | { 14 | protected function getAdditionalInformationMessage(): string 15 | { 16 | return '(see https://api.akeneo.com/php-client/exception.html#server-exception)'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Exception/TooManyRequestsHttpException.php: -------------------------------------------------------------------------------- 1 | getResponse(); 17 | 18 | if (!$response->hasHeader('Retry-After')) { 19 | throw new RuntimeException('Cannot find Retry-After header.'); 20 | } 21 | 22 | $retryAfter = $response->getHeader('Retry-After')[0]; 23 | 24 | if (preg_match('/^\d+$/', $retryAfter)) { 25 | return (int) $retryAfter; 26 | } 27 | 28 | throw new RuntimeException('Cannot parse Retry-After header. Value must be seconds.'); 29 | } 30 | 31 | protected function getAdditionalInformationMessage(): string 32 | { 33 | return '(see https://api.akeneo.com/php-client/exception.html#too-many-requests-exception)'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Exception/UnauthorizedHttpException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class UnauthorizedHttpException extends ClientErrorHttpException 13 | { 14 | protected function getAdditionalInformationMessage(): string 15 | { 16 | return '(see https://api.akeneo.com/php-client/exception.html#unauthorized-exception)'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Exception/UnprocessableEntityHttpException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class UnprocessableEntityHttpException extends ClientErrorHttpException 13 | { 14 | /** 15 | * Returns the errors of the response if there are any 16 | */ 17 | public function getResponseErrors(): array 18 | { 19 | $responseBody = $this->response->getBody(); 20 | 21 | $responseBody->rewind(); 22 | $decodedBody = json_decode($responseBody->getContents(), true); 23 | $responseBody->rewind(); 24 | 25 | return isset($decodedBody['errors']) ? $decodedBody['errors'] : []; 26 | } 27 | 28 | protected function getAdditionalInformationMessage(): string 29 | { 30 | return '(see https://api.akeneo.com/php-client/exception.html#unprocessable-entity-exception)'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Exception/UnreadableFileException.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class UnreadableFileException extends RuntimeException 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/Exception/UnsupportedMediaTypeHttpException.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | class UploadAssetReferenceFileErrorException extends RuntimeException 16 | { 17 | /** 18 | * @param string $message 19 | */ 20 | public function __construct( 21 | $message, 22 | private array $errors 23 | ) { 24 | parent::__construct($message); 25 | } 26 | 27 | public function getErrors(): array 28 | { 29 | return $this->errors; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/FileSystem/FileSystemInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | interface FileSystemInterface 15 | { 16 | /** 17 | * Gets the resource of a file from its path. 18 | * 19 | * @param string $filePath Path of the file 20 | * 21 | * @throws UnreadableFileException if the file doesn't exists or is not readable 22 | * 23 | * @return resource 24 | */ 25 | public function getResourceFromPath(string $filePath); 26 | } 27 | -------------------------------------------------------------------------------- /src/FileSystem/LocalFileSystem.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class LocalFileSystem implements FileSystemInterface 15 | { 16 | /** 17 | * {@inheritdoc} 18 | */ 19 | public function getResourceFromPath(string $filePath) 20 | { 21 | if (!is_readable($filePath)) { 22 | throw new UnreadableFileException(sprintf('The file "%s" could not be read.', $filePath)); 23 | } 24 | 25 | $fileResource = fopen($filePath, 'rb'); 26 | 27 | if (!is_resource($fileResource)) { 28 | throw new \RuntimeException(sprintf('The file "%s" could not be opened.', $filePath)); 29 | } 30 | 31 | return $fileResource; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Pagination/PageFactory.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class PageFactory implements PageFactoryInterface 15 | { 16 | public function __construct( 17 | protected HttpClientInterface $httpClient 18 | ) { 19 | } 20 | 21 | /** 22 | * {@inheritdoc} 23 | */ 24 | public function createPage(array $data): PageInterface 25 | { 26 | $nextLink = isset($data['_links']['next']['href']) ? $data['_links']['next']['href'] : null; 27 | $previousLink = isset($data['_links']['previous']['href']) ? $data['_links']['previous']['href'] : null; 28 | $firstLink = $data['_links']['first']['href']; 29 | 30 | $count = isset($data['items_count']) ? $data['items_count'] : null; 31 | 32 | $items = $data['_embedded']['items']; 33 | 34 | return new Page(new PageFactory($this->httpClient), $this->httpClient, $firstLink, $previousLink, $nextLink, $count, $items); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Pagination/PageFactoryInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | interface PageFactoryInterface 13 | { 14 | /** 15 | * Creates a page object from body. 16 | */ 17 | public function createPage(array $data): PageInterface; 18 | } 19 | -------------------------------------------------------------------------------- /src/Pagination/PageInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | interface PageInterface 13 | { 14 | /** 15 | * Returns the first page of the list of resources. 16 | */ 17 | public function getFirstPage(): PageInterface; 18 | 19 | /** 20 | * Returns the previous page of the list of resources if it exists, null otherwise. 21 | */ 22 | public function getPreviousPage(): ?PageInterface; 23 | 24 | /** 25 | * Returns the next page of the list of resources if it exists, null otherwise. 26 | */ 27 | public function getNextPage(): ?PageInterface; 28 | 29 | /** 30 | * Gets the total count of resources, not just the number of items in the page. 31 | * It returns null if the option to process it has not been send in the request. 32 | */ 33 | public function getCount(): ?int; 34 | 35 | /** 36 | * Returns the array of resources in the page. 37 | */ 38 | public function getItems(): array; 39 | 40 | /** 41 | * Returns true if a next page exists, false either. 42 | */ 43 | public function hasNextPage(): bool; 44 | 45 | /** 46 | * Returns true if a previous page exists, false either. 47 | */ 48 | public function hasPreviousPage(): bool; 49 | 50 | /** 51 | * Gets the link of the next page. 52 | * Returns null if there is not next page. 53 | */ 54 | public function getNextLink(): ?string; 55 | 56 | /** 57 | * Gets the link of the previous page. 58 | * Returns null if there is not previous page. 59 | */ 60 | public function getPreviousLink(): ?string; 61 | } 62 | -------------------------------------------------------------------------------- /src/Pagination/PaginationParameter.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | final class PaginationParameter 13 | { 14 | public const SEARCH = 'search'; 15 | public const LIMIT = 'limit'; 16 | public const WITH_COUNT = 'with_count'; 17 | } 18 | -------------------------------------------------------------------------------- /src/Pagination/ResourceCursor.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class ResourceCursor implements ResourceCursorInterface 13 | { 14 | protected PageInterface $currentPage; 15 | protected int $currentIndex = 0; 16 | protected int $totalIndex = 0; 17 | 18 | public function __construct( 19 | protected ?int $pageSize, 20 | protected PageInterface $firstPage 21 | ) { 22 | $this->currentPage = $firstPage; 23 | } 24 | 25 | /** 26 | * {@inheritdoc} 27 | * @return mixed 28 | */ 29 | #[\ReturnTypeWillChange] 30 | public function current() 31 | { 32 | return $this->currentPage->getItems()[$this->currentIndex]; 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function next(): void 39 | { 40 | $this->currentIndex++; 41 | $this->totalIndex++; 42 | 43 | $items = $this->currentPage->getItems(); 44 | 45 | if (!isset($items[$this->currentIndex]) && $this->currentPage->hasNextPage()) { 46 | $this->currentIndex = 0; 47 | $this->currentPage = $this->currentPage->getNextPage(); 48 | } 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | #[\ReturnTypeWillChange] 55 | public function key() 56 | { 57 | return $this->totalIndex; 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public function valid(): bool 64 | { 65 | return isset($this->currentPage->getItems()[$this->currentIndex]); 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | */ 71 | public function rewind(): void 72 | { 73 | $this->totalIndex = 0; 74 | $this->currentIndex = 0; 75 | $this->currentPage = $this->firstPage; 76 | } 77 | 78 | /** 79 | * {@inheritdoc} 80 | */ 81 | public function getPageSize(): ?int 82 | { 83 | return $this->pageSize; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Pagination/ResourceCursorFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 8 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 9 | */ 10 | class ResourceCursorFactory implements ResourceCursorFactoryInterface 11 | { 12 | /** 13 | * {@inheritdoc} 14 | */ 15 | public function createCursor(?int $pageSize, PageInterface $firstPage): ResourceCursorInterface 16 | { 17 | return new ResourceCursor($pageSize, $firstPage); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Pagination/ResourceCursorFactoryInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | interface ResourceCursorFactoryInterface 13 | { 14 | /** 15 | * Creates a cursor from the first page of resources. 16 | */ 17 | public function createCursor(?int $pageSize, PageInterface $firstPage): ResourceCursorInterface; 18 | } 19 | -------------------------------------------------------------------------------- /src/Pagination/ResourceCursorInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | interface ResourceCursorInterface extends \Iterator 13 | { 14 | /** 15 | * Get the number of resources per page. 16 | */ 17 | public function getPageSize(): ?int; 18 | } 19 | -------------------------------------------------------------------------------- /src/Routing/UriGeneratorInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | interface UriGeneratorInterface 15 | { 16 | /** 17 | * Generate an uri from a path, by adding host and port. 18 | * 19 | * @param string $path Path of the endpoint 20 | * @param array $uriParameters List of the parameters to generate the endpoint 21 | * @param array $queryParameters List of the query parameters added to the endpoint 22 | * 23 | * @return UriInterface 24 | */ 25 | public function generate($path, array $uriParameters = [], array $queryParameters = []); 26 | } 27 | -------------------------------------------------------------------------------- /src/Search/Operator.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | final class Operator 13 | { 14 | public const EQUAL = '='; 15 | public const NOT_EQUAL = '!='; 16 | public const GREATER_THAN = '>'; 17 | public const GREATER_THAN_OR_EQUAL = '>='; 18 | public const LOWER_THAN = '<'; 19 | public const LOWER_THAN_OR_EQUAL = '<='; 20 | public const IN = 'IN'; 21 | public const NOT_IN = 'NOT IN'; 22 | public const IN_OR_UNCLASSIFIED = 'IN OR UNCLASSIFIED'; 23 | public const IN_CHILDREN = 'IN CHILDREN'; 24 | public const NOT_IN_CHILDREN = 'NOT IN CHILDREN'; 25 | public const UNCLASSIFIED = 'UNCLASSIFIED'; 26 | public const GREATER_THAN_ON_ALL_LOCALES = 'GREATER THAN ON ALL LOCALES'; 27 | public const GREATER_OR_EQUALS_THAN_ON_ALL_LOCALES = 'GREATER OR EQUALS THAN ON ALL LOCALES'; 28 | public const LOWER_THAN_ON_ALL_LOCALES = 'LOWER THAN ON ALL LOCALES'; 29 | public const LOWER_OR_EQUALS_THAN_ON_ALL_LOCALES = 'LOWER OR EQUALS THAN ON ALL LOCALES'; 30 | public const IS_EMPTY = 'EMPTY'; 31 | public const NOT_EMPTY = 'NOT EMPTY'; 32 | public const BETWEEN = 'BETWEEN'; 33 | public const NOT_BETWEEN = 'NOT BETWEEN'; 34 | public const SINCE_LAST_N_DAYS = 'SINCE LAST N DAYS'; 35 | public const STARTS_WITH = 'STARTS WITH'; 36 | public const ENDS_WITH = 'ENDS WITH'; 37 | public const CONTAINS = 'CONTAINS'; 38 | public const DOES_NOT_CONTAIN = 'DOES NOT CONTAIN'; 39 | public const AT_LEAST_COMPLETE = 'AT LEAST COMPLETE'; 40 | public const AT_LEAST_INCOMPLETE = 'AT LEAST INCOMPLETE'; 41 | public const ALL_COMPLETE = 'ALL COMPLETE'; 42 | public const ALL_INCOMPLETE = 'ALL INCOMPLETE'; 43 | } 44 | -------------------------------------------------------------------------------- /src/Search/SearchBuilder.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 11 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 12 | */ 13 | class SearchBuilder 14 | { 15 | /** @var array */ 16 | protected $filters = []; 17 | 18 | /** 19 | * Add a filter on a property with an operator and a value. 20 | * 21 | * @see https://api.akeneo.com/documentation/filter.html for the list of properties and operators. 22 | * 23 | * @param string $property property on which the filter will be applied. 24 | * @param string $operator operator of the filter. 25 | * @param mixed|null $value value of the filter. Should not be defined for certain specifics operators. 26 | * @param array $options optionals parameters to apply to the filter (as scope or locale). 27 | */ 28 | public function addFilter(string $property, string $operator, $value = null, array $options = []): self 29 | { 30 | $filter = ['operator' => $operator]; 31 | 32 | if (null !== $value) { 33 | $filter['value'] = $value; 34 | } 35 | 36 | $this->filters[$property][] = $filter + $options; 37 | 38 | return $this; 39 | } 40 | 41 | public function getFilters(): array 42 | { 43 | return $this->filters; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Stream/LineStreamReader.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class LineStreamReader 15 | { 16 | /** 17 | * Gets the next line of a stream. 18 | * 19 | * @return string|null returns the line, or null if the stream is not readable or at the end 20 | */ 21 | public function getNextLine(StreamInterface $stream): ?string 22 | { 23 | if (!$stream->isReadable() || $stream->eof()) { 24 | return null; 25 | } 26 | 27 | $line = ''; 28 | $isEol = false; 29 | while (!$stream->eof() && !$isEol) { 30 | $character = $stream->read(1); 31 | $isEol = PHP_EOL === $character; 32 | 33 | if (!$isEol) { 34 | $line .= $character; 35 | } 36 | } 37 | 38 | return $line; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Stream/MultipartStreamBuilderFactory.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 13 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 14 | */ 15 | class MultipartStreamBuilderFactory 16 | { 17 | public function __construct( 18 | protected StreamFactoryInterface $streamFactory 19 | ) { 20 | } 21 | 22 | public function create(): MultipartStreamBuilder 23 | { 24 | return new MultipartStreamBuilder($this->streamFactory); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Stream/UpsertResourceListResponse.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | class UpsertResourceListResponse implements \Iterator 20 | { 21 | /** @var int */ 22 | protected $lineNumber = 1; 23 | 24 | /** @var string */ 25 | protected $line; 26 | 27 | public function __construct( 28 | protected StreamInterface $bodyStream, 29 | protected LineStreamReader $streamReader 30 | ) { 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function current(): array 37 | { 38 | return json_decode($this->line, true); 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function next(): void 45 | { 46 | $this->line = $this->streamReader->getNextLine($this->bodyStream); 47 | $this->lineNumber++; 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function key(): int 54 | { 55 | return $this->lineNumber; 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function valid(): bool 62 | { 63 | return null !== $this->line; 64 | } 65 | 66 | /** 67 | * {@inheritdoc} 68 | */ 69 | public function rewind(): void 70 | { 71 | $this->bodyStream->rewind(); 72 | $this->lineNumber = 1; 73 | $this->line = $this->streamReader->getNextLine($this->bodyStream); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Stream/UpsertResourceListResponseFactory.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class UpsertResourceListResponseFactory 15 | { 16 | public function create(StreamInterface $bodyStream): UpsertResourceListResponse 17 | { 18 | return new UpsertResourceListResponse($bodyStream, new LineStreamReader()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Api/ApiTestCase.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2017 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | abstract class ApiTestCase extends TestCase 19 | { 20 | protected MockWebServer $server; 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | protected function setUp(): void 26 | { 27 | $this->server = new MockWebServer(8081, '127.0.0.1'); 28 | $this->server->start(); 29 | 30 | $this->server->setResponseOfPath( 31 | '/' . AuthenticationApi::TOKEN_URI, 32 | new ResponseStack( 33 | new Response($this->getAuthenticatedJson()) 34 | ) 35 | ); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | protected function tearDown(): void 42 | { 43 | $this->server->stop(); 44 | } 45 | 46 | protected function createClientByPassword(): AkeneoPimClientInterface 47 | { 48 | $clientBuilder = new AkeneoPimClientBuilder($this->server->getServerRoot()); 49 | 50 | return $clientBuilder->buildAuthenticatedByPassword( 51 | 'client_id', 52 | 'secret', 53 | 'username', 54 | 'password' 55 | ); 56 | } 57 | 58 | protected function createClientByToken(): AkeneoPimClientInterface 59 | { 60 | $clientBuilder = new AkeneoPimClientBuilder($this->server->getServerRoot()); 61 | 62 | return $clientBuilder->buildAuthenticatedByToken( 63 | 'client_id', 64 | 'secret', 65 | 'a_token', 66 | 'a_refresh_token' 67 | ); 68 | } 69 | 70 | protected function createClientByAppToken(): AkeneoPimClientInterface 71 | { 72 | $clientBuilder = new AkeneoPimClientBuilder($this->server->getServerRoot()); 73 | 74 | return $clientBuilder->buildAuthenticatedByAppToken('a_token'); 75 | } 76 | 77 | private function getAuthenticatedJson(): string 78 | { 79 | return << 'A catalog name']; 23 | $expectedJson = <<server->setResponseOfPath( 32 | '/' . AppCatalogApi::APP_CATALOGS_URI, 33 | new ResponseStack( 34 | new Response($expectedJson, [], HttpClient::HTTP_CREATED) 35 | ) 36 | ); 37 | 38 | $api = $this->createClientByPassword()->getAppCatalogApi(); 39 | $response = $api->create($catalogData); 40 | 41 | Assert::assertSame(json_decode($expectedJson, true), $response); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Api/AppCatalog/DeleteAppCatalogIntegration.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 26 | '/' . sprintf(AppCatalogApi::APP_CATALOG_URI, $catalogId), 27 | new ResponseStack( 28 | new Response('', [], HttpClient::HTTP_NO_CONTENT) 29 | ) 30 | ); 31 | 32 | $api = $this->createClientByPassword()->getAppCatalogApi(); 33 | $response = $api->delete($catalogId); 34 | 35 | Assert::assertSame('DELETE', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 36 | Assert::assertSame(HttpClient::HTTP_NO_CONTENT, $response); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Api/AppCatalog/GetAppCatalogIntegration.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 26 | '/' . sprintf(AppCatalogApi::APP_CATALOG_URI, $catalogId), 27 | new ResponseStack( 28 | new Response($this->getACatalog(), [], HttpClient::HTTP_OK) 29 | ) 30 | ); 31 | 32 | $api = $this->createClientByPassword()->getAppCatalogApi(); 33 | $asset = $api->get($catalogId); 34 | 35 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 36 | Assert::assertEquals($asset, json_decode($this->getACatalog(), true)); 37 | } 38 | 39 | private function getACatalog(): string 40 | { 41 | return << 'A catalog name']; 25 | $expectedJson = <<server->setResponseOfPath( 34 | '/' . sprintf(AppCatalogApi::APP_CATALOG_URI, $catalogId), 35 | new ResponseStack( 36 | new Response($expectedJson, [], HttpClient::HTTP_OK) 37 | ) 38 | ); 39 | 40 | $api = $this->createClientByPassword()->getAppCatalogApi(); 41 | $response = $api->upsert($catalogId, $catalogData); 42 | 43 | Assert::assertSame(json_decode($expectedJson, true), $response); 44 | } 45 | 46 | public function test_upsert_async_catalog() 47 | { 48 | $catalogId = '12351d98-200e-4bbc-aa19-7fdda1bd14f2'; 49 | $catalogData = ['name' => 'A catalog name']; 50 | $expectedJson = <<server->setResponseOfPath( 59 | '/' . sprintf(AppCatalogApi::APP_CATALOG_URI, $catalogId), 60 | new ResponseStack( 61 | new Response($expectedJson, [], HttpClient::HTTP_OK) 62 | ) 63 | ); 64 | 65 | $api = $this->createClientByPassword()->getAppCatalogApi(); 66 | $promise = $api->upsertAsync($catalogId, $catalogData); 67 | Assert::assertInstanceOf(PromiseInterface::class, $promise); 68 | 69 | $response = json_decode($promise->wait()->getBody()->getContents(), true); 70 | 71 | Assert::assertSame(json_decode($expectedJson, true), $response); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/Api/Asset/GetAssetIntegration.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 19 | '/' . sprintf(AssetApi::ASSET_URI, 'packshot', 'battleship'), 20 | new ResponseStack( 21 | new Response($this->getAsset(), [], 200) 22 | ) 23 | ); 24 | 25 | $api = $this->createClientByPassword()->getAssetManagerApi(); 26 | $asset = $api->get('packshot', 'battleship'); 27 | 28 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD], 'GET'); 29 | Assert::assertEquals($asset, json_decode($this->getAsset(), true)); 30 | } 31 | 32 | public function test_get_unknown_asset() 33 | { 34 | $this->server->setResponseOfPath( 35 | '/' . sprintf(AssetApi::ASSET_URI, 'packshot', 'peace-sheep'), 36 | new ResponseStack( 37 | new Response('{"code": 404, "message":"Asset \"peace-sheep\" does not exist."}', [], 404) 38 | ) 39 | ); 40 | 41 | $this->expectException(\Akeneo\Pim\ApiClient\Exception\NotFoundHttpException::class); 42 | $this->expectExceptionMessage('Asset "peace-sheep" does not exist.'); 43 | 44 | $api = $this->createClientByPassword()->getAssetManagerApi(); 45 | $api->get('packshot', 'peace-sheep'); 46 | } 47 | 48 | private function getAsset(): string 49 | { 50 | return <<server->setResponseOfPath( 20 | '/' . sprintf(AssetAttributeApi::ASSET_ATTRIBUTE_URI, 'packshot', 'media_preview'), 21 | new ResponseStack( 22 | new Response($this->getPackshotPreviewAttribute(), [], 200) 23 | ) 24 | ); 25 | 26 | $api = $this->createClientByPassword()->getAssetAttributeApi(); 27 | $familyAttribute = $api->get('packshot', 'media_preview'); 28 | 29 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD], 'GET'); 30 | Assert::assertEquals($familyAttribute, json_decode($this->getPackshotPreviewAttribute(), true)); 31 | } 32 | 33 | public function test_get_unknown_asset_family_attribute() 34 | { 35 | $this->server->setResponseOfPath( 36 | '/' . sprintf(AssetAttributeApi::ASSET_ATTRIBUTE_URI, 'packshot', 'foo'), 37 | new ResponseStack( 38 | new Response('{"code": 404, "message":"Resource `foo` does not exist."}', [], 404) 39 | ) 40 | ); 41 | 42 | $api = $this->createClientByPassword()->getAssetAttributeApi(); 43 | 44 | $this->expectException(NotFoundHttpException::class); 45 | $this->expectExceptionMessage('Resource `foo` does not exist.'); 46 | 47 | $api->get('packshot', 'foo'); 48 | } 49 | 50 | private function getPackshotPreviewAttribute(): string 51 | { 52 | return <<server->setResponseOfPath( 20 | '/' . sprintf(AssetAttributeOptionApi::ASSET_ATTRIBUTE_OPTION_URI, 'packshot', 'wearing_model_size', 'small'), 21 | new ResponseStack( 22 | new Response($this->getPackshotAttributeOption(), [], 200) 23 | ) 24 | ); 25 | 26 | $api = $this->createClientByPassword()->getAssetAttributeOptionApi(); 27 | $familyAttributeOption = $api->get('packshot', 'wearing_model_size', 'small'); 28 | 29 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD], 'GET'); 30 | Assert::assertEquals($familyAttributeOption, json_decode($this->getPackshotAttributeOption(), true)); 31 | } 32 | 33 | public function test_get_unknown_asset_family_attribute_option() 34 | { 35 | $this->server->setResponseOfPath( 36 | '/' . sprintf(AssetAttributeOptionApi::ASSET_ATTRIBUTE_OPTION_URI, 'packshot', 'wearing_model_size', 'XLS'), 37 | new ResponseStack( 38 | new Response('{"code": 404, "message":"Resource `XLS` does not exist."}', [], 404) 39 | ) 40 | ); 41 | 42 | $api = $this->createClientByPassword()->getAssetAttributeOptionApi(); 43 | 44 | $this->expectException(NotFoundHttpException::class); 45 | $this->expectExceptionMessage('Resource `XLS` does not exist.'); 46 | 47 | $api->get('packshot', 'wearing_model_size', 'XLS'); 48 | } 49 | 50 | private function getPackshotAttributeOption(): string 51 | { 52 | return <<server->setResponseOfPath( 19 | '/' . sprintf( 20 | AssetAttributeOptionApi::ASSET_ATTRIBUTE_OPTIONS_URI, 21 | 'packshot', 22 | 'wearing_model_size' 23 | ), 24 | new ResponseStack( 25 | new Response($this->getAssetFamilyAttributeOptions(), [], 200) 26 | ) 27 | ); 28 | 29 | $api = $this->createClientByPassword()->getAssetAttributeOptionApi(); 30 | $assetFamilyAttributeOptions = $api->all('packshot', 'wearing_model_size'); 31 | 32 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD], 'GET'); 33 | Assert::assertEquals($assetFamilyAttributeOptions, json_decode($this->getAssetFamilyAttributeOptions(), true)); 34 | } 35 | 36 | private function getAssetFamilyAttributeOptions(): string 37 | { 38 | return <<server->setResponseOfPath( 20 | '/' . sprintf(AssetFamilyApi::ASSET_FAMILY_URI, 'packshot'), 21 | new ResponseStack( 22 | new Response($this->getPackshot(), [], 200) 23 | ) 24 | ); 25 | 26 | $api = $this->createClientByPassword()->getAssetFamilyApi(); 27 | $product = $api->get('packshot'); 28 | 29 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD], 'GET'); 30 | Assert::assertEquals($product, json_decode($this->getPackshot(), true)); 31 | } 32 | 33 | public function test_get_unknown_asset_family() 34 | { 35 | $this->server->setResponseOfPath( 36 | '/' . sprintf(AssetFamilyApi::ASSET_FAMILY_URI, 'foo'), 37 | new ResponseStack( 38 | new Response('{"code": 404, "message":"Asset family \"foo\" does not exist."}', [], 404) 39 | ) 40 | ); 41 | 42 | $api = $this->createClientByPassword()->getAssetFamilyApi(); 43 | 44 | $this->expectException(NotFoundHttpException::class); 45 | $this->expectExceptionMessage('Asset family "foo" does not exist.'); 46 | 47 | $api->get('foo'); 48 | } 49 | 50 | private function getPackshot(): string 51 | { 52 | return <<server->setResponseOfPath( 18 | '/' . sprintf(AssetFamilyApi::ASSET_FAMILY_URI, 'packshot'), 19 | new ResponseStack( 20 | new Response('', [], 201) 21 | ) 22 | ); 23 | 24 | $assetFamily = [ 25 | 'code' => 'packshot', 26 | 'labels' => [ 27 | 'en_US' => 'Packshots' 28 | ] 29 | ]; 30 | 31 | $api = $this->createClientByPassword()->getAssetFamilyApi(); 32 | $response = $api->upsert('packshot', $assetFamily); 33 | 34 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_INPUT], json_encode($assetFamily)); 35 | Assert::assertSame(201, $response); 36 | } 37 | 38 | public function test_upsert_async_asset_family() 39 | { 40 | $this->server->setResponseOfPath( 41 | '/' . sprintf(AssetFamilyApi::ASSET_FAMILY_URI, 'packshot'), 42 | new ResponseStack( 43 | new Response('', [], 201) 44 | ) 45 | ); 46 | 47 | $assetFamily = [ 48 | 'code' => 'packshot', 49 | 'labels' => [ 50 | 'en_US' => 'Packshots' 51 | ] 52 | ]; 53 | 54 | $api = $this->createClientByPassword()->getAssetFamilyApi(); 55 | $promise = $api->upsertAsync('packshot', $assetFamily); 56 | Assert::assertInstanceOf(PromiseInterface::class, $promise); 57 | 58 | $response = $promise->wait(); 59 | 60 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_INPUT], json_encode($assetFamily)); 61 | Assert::assertSame(201, $response->getStatusCode()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Api/AssetMediaFile/CreateAssetMediaFileIntegration.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 17 | '/' . AssetMediaFileApi::MEDIA_FILE_CREATE_URI, 18 | new ResponseStack( 19 | new Response('', ['Asset-media-file-code' => 'my-asset-media-code'], 201) 20 | ) 21 | ); 22 | $mediaFile = realpath(__DIR__ . '/../../fixtures/unicorn.png'); 23 | $response = $this->createClientByPassword()->getAssetMediaFileApi()->create($mediaFile); 24 | 25 | Assert::assertNotEmpty($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']); 26 | Assert::assertSame( 27 | $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']['name'], 28 | 'unicorn.png' 29 | ); 30 | Assert::assertSame( 31 | $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']['type'], 32 | 'image/png' 33 | ); 34 | Assert::assertSame( 35 | $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']['size'], 36 | 11255 37 | ); 38 | Assert::assertSame('my-asset-media-code', $response); 39 | } 40 | 41 | public function test_get_asset_media_file_code_regardless_of_the_header_case() 42 | { 43 | $this->server->setResponseOfPath( 44 | '/' . AssetMediaFileApi::MEDIA_FILE_CREATE_URI, 45 | new ResponseStack( 46 | new Response('', ['Asset-Media-File-Code' => 'my-asset-media-code'], 201) 47 | ) 48 | ); 49 | $mediaFile = realpath(__DIR__ . '/../../fixtures/unicorn.png'); 50 | $response = $this->createClientByPassword()->getAssetMediaFileApi()->create($mediaFile); 51 | 52 | Assert::assertSame('my-asset-media-code', $response); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Api/DeleteProductModelTest.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 16 | '/' . sprintf(ProductModelApi::PRODUCT_MODEL_URI, 'docks_white'), 17 | new ResponseStack( 18 | new Response('', [], 204) 19 | ) 20 | ); 21 | 22 | $api = $this->createClientByPassword()->getProductModelApi(); 23 | 24 | $response = $api->delete('docks_white'); 25 | 26 | Assert::assertSame('DELETE', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 27 | Assert::assertSame(204, $response); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Api/DeleteProductTest.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 16 | '/' . sprintf(ProductApi::PRODUCT_URI, 'docks_white'), 17 | new ResponseStack( 18 | new Response('', [], 204) 19 | ) 20 | ); 21 | 22 | $api = $this->createClientByPassword()->getProductApi(); 23 | 24 | $response = $api->delete('docks_white'); 25 | 26 | Assert::assertSame('DELETE', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 27 | Assert::assertSame(204, $response); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Api/DownloadCategoryMediaFileTest.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 19 | '/' . sprintf(CategoryMediaFileApi::MEDIA_FILE_DOWNLOAD_URI, '/f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png'), 20 | new ResponseStack( 21 | new Response(file_get_contents($expectedMediaFilePath), [], 201) 22 | ) 23 | ); 24 | 25 | $api = $this->createClientByPassword()->getCategoryMediaFileApi(); 26 | $mediaFile = $api->download('/f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png'); 27 | 28 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 29 | Assert::assertInstanceOf(ResponseInterface::class, $mediaFile); 30 | Assert::assertSame(file_get_contents($expectedMediaFilePath), $mediaFile->getBody()->getContents()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Api/DownloadProductMediaFileTest.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 19 | '/' . sprintf(ProductMediaFileApi::MEDIA_FILE_DOWNLOAD_URI, '/f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png'), 20 | new ResponseStack( 21 | new Response(file_get_contents($expectedMediaFilePath), [], 201) 22 | ) 23 | ); 24 | 25 | $api = $this->createClientByPassword()->getProductMediaFileApi(); 26 | $mediaFile = $api->download('/f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png'); 27 | 28 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 29 | Assert::assertInstanceOf(ResponseInterface::class, $mediaFile); 30 | Assert::assertSame(file_get_contents($expectedMediaFilePath), $mediaFile->getBody()->getContents()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Api/GetProductTest.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 16 | '/' . sprintf(ProductApi::PRODUCT_URI, 'black_sneakers'), 17 | new ResponseStack( 18 | new Response($this->getProduct(), [], 200) 19 | ) 20 | ); 21 | 22 | $api = $this->createClientByPassword()->getProductApi(); 23 | 24 | $product = $api->get('black_sneakers'); 25 | 26 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 27 | Assert::assertEquals($product, json_decode($this->getProduct(), true)); 28 | } 29 | 30 | public function test_get_unknow_product() 31 | { 32 | $this->server->setResponseOfPath( 33 | '/' . sprintf(ProductApi::PRODUCT_URI, 'black_sneakers'), 34 | new ResponseStack( 35 | new Response('{"code": 404, "message":"Resource `black_sneakers` does not exist."}', [], 404) 36 | ) 37 | ); 38 | 39 | $this->expectException(\Akeneo\Pim\ApiClient\Exception\NotFoundHttpException::class); 40 | $this->expectExceptionMessage('Resource `black_sneakers` does not exist.'); 41 | 42 | $api = $this->createClientByPassword()->getProductApi(); 43 | $api->get('black_sneakers'); 44 | } 45 | 46 | private function getProduct(): string 47 | { 48 | return <<server->setResponseOfPath( 22 | '/' . sprintf(ProductUuidApi::PRODUCT_UUID_URI, '12951d98-210e-4bRC-ab18-7fdgf1bd14f3'), 23 | new ResponseStack( 24 | new Response('', [], HttpClient::HTTP_NO_CONTENT) 25 | ) 26 | ); 27 | 28 | $api = $this->createClientByPassword()->getProductUuidApi(); 29 | 30 | $response = $api->delete('12951d98-210e-4bRC-ab18-7fdgf1bd14f3'); 31 | 32 | Assert::assertSame('DELETE', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 33 | Assert::assertSame(HttpClient::HTTP_NO_CONTENT, $response); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/Api/ReferenceEntity/GetReferenceEntityIntegration.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 19 | '/' . sprintf(ReferenceEntityApi::REFERENCE_ENTITY_URI, 'brand'), 20 | new ResponseStack( 21 | new Response($this->getBrand(), [], 200) 22 | ) 23 | ); 24 | 25 | $api = $this->createClientByPassword()->getReferenceEntityApi(); 26 | $product = $api->get('brand'); 27 | 28 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 29 | Assert::assertEquals($product, json_decode($this->getBrand(), true)); 30 | } 31 | 32 | public function test_get_unknown_reference_entity() 33 | { 34 | $this->server->setResponseOfPath( 35 | '/' . sprintf(ReferenceEntityApi::REFERENCE_ENTITY_URI, 'foo'), 36 | new ResponseStack( 37 | new Response('{"code": 404, "message":"Reference entity \"foo\" does not exist."}', [], 404) 38 | ) 39 | ); 40 | 41 | $this->expectException(\Akeneo\Pim\ApiClient\Exception\NotFoundHttpException::class); 42 | $this->expectExceptionMessage('Reference entity "foo" does not exist.'); 43 | 44 | $api = $this->createClientByPassword()->getReferenceEntityApi(); 45 | $api->get('foo'); 46 | } 47 | 48 | private function getBrand(): string 49 | { 50 | return <<server->setResponseOfPath( 18 | '/' . sprintf(ReferenceEntityApi::REFERENCE_ENTITY_URI, 'brand'), 19 | new ResponseStack( 20 | new Response('', [], 204) 21 | ) 22 | ); 23 | 24 | $referenceEntity = [ 25 | 'code' => 'brand', 26 | 'labels' => [ 27 | 'en_US' => 'Brand' 28 | ] 29 | ]; 30 | 31 | $api = $this->createClientByPassword()->getReferenceEntityApi(); 32 | $response = $api->upsert('brand', $referenceEntity); 33 | 34 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_INPUT], json_encode($referenceEntity)); 35 | Assert::assertSame(204, $response); 36 | } 37 | 38 | public function test_upsert_async_reference_entity() 39 | { 40 | $this->server->setResponseOfPath( 41 | '/' . sprintf(ReferenceEntityApi::REFERENCE_ENTITY_URI, 'brand'), 42 | new ResponseStack( 43 | new Response('', [], 204) 44 | ) 45 | ); 46 | 47 | $referenceEntity = [ 48 | 'code' => 'brand', 49 | 'labels' => [ 50 | 'en_US' => 'Brand' 51 | ] 52 | ]; 53 | 54 | $api = $this->createClientByPassword()->getReferenceEntityApi(); 55 | $promise = $api->upsertAsync('brand', $referenceEntity); 56 | 57 | Assert::assertInstanceOf(PromiseInterface::class, $promise); 58 | 59 | $response = $promise->wait(); 60 | 61 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_INPUT], json_encode($referenceEntity)); 62 | Assert::assertSame(204, $response->getStatusCode()); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/Api/ReferenceEntityMediaFile/CreateReferenceEntityMediaFileIntegration.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 23 | '/' . ReferenceEntityMediaFileApi::MEDIA_FILE_CREATE_URI, 24 | new ResponseStack( 25 | new Response('', ['Reference-entities-media-file-code' => 'my-media-code'], 201) 26 | ) 27 | ); 28 | $mediaFile = realpath(__DIR__ . '/../../fixtures/unicorn.png'); 29 | $response = $this->createClientByPassword()->getReferenceEntityMediaFileApi()->create($mediaFile); 30 | 31 | Assert::assertNotEmpty($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']); 32 | Assert::assertSame( 33 | 'unicorn.png', 34 | $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']['name'] 35 | ); 36 | Assert::assertSame( 37 | 'image/png', 38 | $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']['type'] 39 | ); 40 | Assert::assertSame( 41 | 11255, 42 | $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_FILES]['file']['size'] 43 | ); 44 | Assert::assertSame('my-media-code', $response); 45 | } 46 | 47 | public function test_get_media_file_code_regardless_of_the_header_case() 48 | { 49 | $this->server->setResponseOfPath( 50 | '/' . ReferenceEntityMediaFileApi::MEDIA_FILE_CREATE_URI, 51 | new ResponseStack( 52 | new Response('', ['Reference-Entities-Media-File-Code' => 'my-media-code'], 201) 53 | ) 54 | ); 55 | $mediaFile = realpath(__DIR__ . '/../../fixtures/unicorn.png'); 56 | $response = $this->createClientByPassword()->getReferenceEntityMediaFileApi()->create($mediaFile); 57 | 58 | Assert::assertSame('my-media-code', $response); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/Api/ReferenceEntityRecord/GetReferenceEntityRecordIntegration.php: -------------------------------------------------------------------------------- 1 | server->setResponseOfPath( 19 | '/' . sprintf(ReferenceEntityRecordApi::REFERENCE_ENTITY_RECORD_URI, 'designer', 'starck'), 20 | new ResponseStack( 21 | new Response($this->getStarckRecord(), [], 200) 22 | ) 23 | ); 24 | 25 | $api = $this->createClientByPassword()->getReferenceEntityRecordApi(); 26 | $product = $api->get('designer', 'starck'); 27 | 28 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 29 | Assert::assertEquals($product, json_decode($this->getStarckRecord(), true)); 30 | } 31 | 32 | public function test_get_unknow_product() 33 | { 34 | $this->expectExceptionMessage("Record \"foo\" does not exist for the reference entity \"designer\"."); 35 | $this->expectException(\Akeneo\Pim\ApiClient\Exception\NotFoundHttpException::class); 36 | $this->server->setResponseOfPath( 37 | '/' . sprintf(ReferenceEntityRecordApi::REFERENCE_ENTITY_RECORD_URI, 'designer', 'foo'), 38 | new ResponseStack( 39 | new Response('{"code": 404, "message":"Record \"foo\" does not exist for the reference entity \"designer\"."}', [], 404) 40 | ) 41 | ); 42 | 43 | $api = $this->createClientByPassword()->getReferenceEntityRecordApi(); 44 | $api->get('designer', 'foo'); 45 | } 46 | 47 | private function getStarckRecord(): string 48 | { 49 | return <<server->setResponseOfPath( 17 | '/' . sprintf(ProductApi::PRODUCT_URI, 'docks_black'), 18 | new ResponseStack( 19 | new Response('', [], 204) 20 | ) 21 | ); 22 | 23 | $api = $this->createClientByPassword()->getProductApi(); 24 | 25 | $parameters = [ 26 | 'enabled' => false, 27 | 'values' => [ 28 | 'name' => [ 29 | [ 30 | 'locale' => 'en_US', 31 | 'scope' => null, 32 | 'data' => 'Black Docks', 33 | ], 34 | ], 35 | ] 36 | ]; 37 | $response = $api->upsert('docks_black', $parameters); 38 | 39 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_INPUT], json_encode($parameters)); 40 | 41 | Assert::assertSame(204, $response); 42 | } 43 | 44 | public function test_upsert_product_async() 45 | { 46 | $this->server->setResponseOfPath( 47 | '/' . sprintf(ProductApi::PRODUCT_URI, 'docks_black'), 48 | new ResponseStack( 49 | new Response('', [], 204) 50 | ) 51 | ); 52 | $api = $this->createClientByPassword()->getProductApi(); 53 | $parameters = [ 54 | 'enabled' => false, 55 | 'values' => [ 56 | 'name' => [ 57 | [ 58 | 'locale' => 'en_US', 59 | 'scope' => null, 60 | 'data' => 'Black Docks', 61 | ], 62 | ], 63 | ] 64 | ]; 65 | 66 | $promise = $api->upsertAsync('docks_black', $parameters); 67 | Assert::assertInstanceOf(PromiseInterface::class, $promise); 68 | 69 | $response = $promise->wait(); 70 | 71 | Assert::assertSame($this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_INPUT], json_encode($parameters)); 72 | Assert::assertSame(204, $response->getStatusCode()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/Cache/AkeneoPimClientBuilderTest.php: -------------------------------------------------------------------------------- 1 | setGetProductResponse(); 19 | $api = $this->createClientByPassword()->getProductApi(); 20 | 21 | $product = $api->get('black_sneakers'); 22 | 23 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 24 | Assert::assertEquals($product, json_decode($this->getProduct(), true)); 25 | } 26 | 27 | public function test_get_product_with_create_client_by_token() 28 | { 29 | $this->setGetProductResponse(); 30 | $api = $this->createClientByToken()->getProductApi(); 31 | 32 | $product = $api->get('black_sneakers'); 33 | 34 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 35 | Assert::assertEquals($product, json_decode($this->getProduct(), true)); 36 | } 37 | 38 | public function test_get_product_with_create_client_by_app_token() 39 | { 40 | $this->setGetProductResponse(); 41 | $api = $this->createClientByAppToken()->getProductApi(); 42 | 43 | $product = $api->get('black_sneakers'); 44 | 45 | Assert::assertSame('GET', $this->server->getLastRequest()->jsonSerialize()[RequestInfo::JSON_KEY_METHOD]); 46 | Assert::assertEquals($product, json_decode($this->getProduct(), true)); 47 | } 48 | 49 | private function setGetProductResponse(): void 50 | { 51 | $this->server->setResponseOfPath( 52 | '/' . sprintf(ProductApi::PRODUCT_URI, 'black_sneakers'), 53 | new ResponseStack( 54 | new Response($this->getProduct(), [], 200) 55 | ) 56 | ); 57 | } 58 | 59 | private function getProduct(): string 60 | { 61 | return <<set('a', [1]); 16 | $cache->set('b', [2]); 17 | $cache->set('c', [3]); 18 | $cache->set('d', [4]); 19 | $cache->set('e', [5]); 20 | $this->assertNull($cache->get('a')); 21 | $this->assertNull($cache->get('b')); 22 | $this->assertSame([3], $cache->get('c')); 23 | $this->assertSame([4], $cache->get('d')); 24 | $this->assertSame([5], $cache->get('e')); 25 | } 26 | 27 | public function testRemovesLru(): void 28 | { 29 | $cache = new LRUCache(3); 30 | $cache->set('a', [1]); 31 | $cache->set('b', [2]); 32 | $cache->set('c', [3]); 33 | $cache->get('a'); // Puts a back on the end 34 | $cache->set('d', [4]); 35 | $cache->set('e', [5]); 36 | $this->assertNull($cache->get('b')); 37 | $this->assertNull($cache->get('c')); 38 | $this->assertSame([1], $cache->get('a')); 39 | $this->assertSame([4], $cache->get('d')); 40 | $this->assertSame([5], $cache->get('e')); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Client/CachedResourceClientTest.php: -------------------------------------------------------------------------------- 1 | createMock(ResourceClientInterface::class); 17 | $mockCache = $this->createMock(CacheInterface::class); 18 | 19 | $uri = 'uri'; 20 | $uriParameters = ['uriParameter']; 21 | 22 | $cacheKey = md5($uri . implode('', $uriParameters)); 23 | 24 | $mockCache 25 | ->expects(self::exactly(2)) 26 | ->method('get') 27 | ->with($cacheKey) 28 | ->willReturnOnConsecutiveCalls(null, ['cachedValue']); 29 | 30 | $resourceClient 31 | ->expects(self::once()) 32 | ->method('getResource') 33 | ->with($uri, $uriParameters)->willReturn(['resource']); 34 | 35 | $mockCache 36 | ->expects(self::once()) 37 | ->method('set') 38 | ->with($cacheKey, ['resource']); 39 | 40 | $cachedResourceClient = new CachedResourceClient($resourceClient, $mockCache); 41 | 42 | self::assertSame(['resource'], $cachedResourceClient->getResource($uri, $uriParameters)); 43 | self::assertSame(['cachedValue'], $cachedResourceClient->getResource($uri, $uriParameters)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/Client/OptionsTest.php: -------------------------------------------------------------------------------- 1 | expectException(\InvalidArgumentException::class); 13 | 14 | Options::fromArray(['unknown_option' => 'unknown_value']); 15 | } 16 | 17 | /** 18 | * @dataProvider validHeadersOptionProvider 19 | */ 20 | public function testHeadersOption(array $inputOptions, array $expectedHeadersOption, bool $hasHeaders): void 21 | { 22 | $options = Options::fromArray($inputOptions); 23 | 24 | $this->assertSame($hasHeaders, $options->hasHeaders()); 25 | $this->assertSame($expectedHeadersOption, $options->getHeaders()); 26 | } 27 | 28 | public function validHeadersOptionProvider(): array 29 | { 30 | return [ 31 | 'empty array' => [ 32 | [], 33 | [], 34 | false, 35 | ], 36 | 'empty headers option' => [ 37 | ['headers' => []], 38 | [], 39 | false, 40 | ], 41 | 'filled headers option' => [ 42 | ['headers' => ['X-HEADER' => 'content']], 43 | ['X-HEADER' => 'content'], 44 | true, 45 | ], 46 | ]; 47 | } 48 | 49 | /** 50 | * @dataProvider invalidHeadersOptionProvider 51 | */ 52 | public function testInvalidHeadersOption($invalidValue): void 53 | { 54 | $this->expectException(\InvalidArgumentException::class); 55 | 56 | Options::fromArray(['headers' => $invalidValue]); 57 | } 58 | 59 | public function invalidHeadersOptionProvider(): array 60 | { 61 | return [ 62 | [10], 63 | [10.45], 64 | [true], 65 | [new \StdClass()], 66 | [['X-HEADER' => 10]], 67 | [['X-HEADER' => 10.45]], 68 | [['X-HEADER' => true]], 69 | [['X-HEADER' => new \StdClass()]], 70 | ]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/Exception/TooManyRequestsHttpExceptionTest.php: -------------------------------------------------------------------------------- 1 | request = $this->createMock(RequestInterface::class); 18 | } 19 | 20 | public function testRetryAfter(): void 21 | { 22 | $response = $this->createMock(ResponseInterface::class); 23 | $response->method('hasHeader')->willReturn(true); 24 | $response->method('getHeader')->willReturn(['10']); 25 | 26 | $exception = new TooManyRequestsHttpException('Too Many Requests', $this->request, $response, null); 27 | 28 | $this->assertSame( 29 | 10, 30 | $exception->getRetryAfter() 31 | ); 32 | } 33 | 34 | public function testCannotFindRetryAfterHeader(): void 35 | { 36 | $response = $this->createMock(ResponseInterface::class); 37 | $response->method('hasHeader')->willReturn(false); 38 | 39 | $exception = new TooManyRequestsHttpException('Too Many Requests', $this->request, $response, null); 40 | 41 | $this->expectException(RuntimeException::class); 42 | 43 | $exception->getRetryAfter(); 44 | } 45 | 46 | public function testCannotParseRetryAfterHeader(): void 47 | { 48 | $response = $this->createMock(ResponseInterface::class); 49 | $response->method('hasHeader')->willReturn(true); 50 | $response->method('getHeader')->willReturn([0 => 'Wed, 21 Oct 2015 07:28:00 GMT']); 51 | 52 | $exception = new TooManyRequestsHttpException('Too Many Requests', $this->request, $response, null); 53 | 54 | $this->expectException(RuntimeException::class); 55 | 56 | $exception->getRetryAfter(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/fixtures/akeneo-logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeneo/api-php-client/9b021124a24f1b1e6b2440c232ba6a676f2dfcb0/tests/fixtures/akeneo-logo.pdf -------------------------------------------------------------------------------- /tests/fixtures/akeneo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeneo/api-php-client/9b021124a24f1b1e6b2440c232ba6a676f2dfcb0/tests/fixtures/akeneo.png -------------------------------------------------------------------------------- /tests/fixtures/unicorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeneo/api-php-client/9b021124a24f1b1e6b2440c232ba6a676f2dfcb0/tests/fixtures/unicorn.png -------------------------------------------------------------------------------- /tests/fixtures/ziggy-certification.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeneo/api-php-client/9b021124a24f1b1e6b2440c232ba6a676f2dfcb0/tests/fixtures/ziggy-certification.jpg -------------------------------------------------------------------------------- /tests/fixtures/ziggy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeneo/api-php-client/9b021124a24f1b1e6b2440c232ba6a676f2dfcb0/tests/fixtures/ziggy.png --------------------------------------------------------------------------------