diff --git a/README.md b/README.md index d10e795..f353352 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,11 @@ $oro->setAccessToken($res->access_token); $product = $oro->products->get(100); ``` +#### Get a single product with related entities included +```php +$oro->products->get(1, ['include' => 'names,descriptions']); +``` + #### Get a list of products ```php $products = $oro->products->page(); diff --git a/examples/products/get_product_names.php b/examples/products/get_product_names.php index 7b57300..71ec56a 100644 --- a/examples/products/get_product_names.php +++ b/examples/products/get_product_names.php @@ -3,7 +3,7 @@ try { require "../initialize.php"; - $product = $oro->products->get(116); + $product = $oro->products->get(1); echo '' . $product->type . ' ' . $product->id . '
'; diff --git a/examples/products/get_product_with_includes.php b/examples/products/get_product_with_includes.php new file mode 100644 index 0000000..db8d0b1 --- /dev/null +++ b/examples/products/get_product_with_includes.php @@ -0,0 +1,22 @@ +products->get(1, ['include' => 'names,descriptions']); + + echo '' . $product->type . ' ' . $product->id . '

'; + + foreach ($product->included as $include) { + echo $include->type . "
"; + echo $include->id . "
"; + + foreach ($include->attributes as $key => $val) { + echo $key . ": " . $val . "
"; + } + + echo "
"; + } +} catch (\Digitalprint\Oro\Api\Exceptions\ApiException $e) { + echo "API call failed: " . $e->getMessage(); +} diff --git a/src/Endpoints/AddressEndpoint.php b/src/Endpoints/AddressEndpoint.php index cd443b5..2ac967e 100644 --- a/src/Endpoints/AddressEndpoint.php +++ b/src/Endpoints/AddressEndpoint.php @@ -16,28 +16,24 @@ class AddressEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/addresses"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Address */ - protected function getResourceObject(): Address + protected function getResourceObject(array $included = []): Address { - return new Address($this->client); + return new Address($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return AddressCollection */ - protected function getResourceCollectionObject(stdClass $links): AddressCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): AddressCollection { - return new AddressCollection($this->client, $links); + return new AddressCollection($this->client, $links, $included); } - /** * @param array|null $data * @return Address diff --git a/src/Endpoints/AddresstypeEndpoint.php b/src/Endpoints/AddresstypeEndpoint.php index 7b4516e..0566fc9 100644 --- a/src/Endpoints/AddresstypeEndpoint.php +++ b/src/Endpoints/AddresstypeEndpoint.php @@ -2,8 +2,10 @@ namespace Digitalprint\Oro\Api\Endpoints; +use BadMethodCallException; use Digitalprint\Oro\Api\Exceptions\ApiException; use Digitalprint\Oro\Api\Resources\Addresstype; +use Digitalprint\Oro\Api\Resources\BaseCollection; class AddresstypeEndpoint extends EndpointAbstract { @@ -13,13 +15,22 @@ class AddresstypeEndpoint extends EndpointAbstract protected string $resourcePath = "api/addresstypes"; /** + * @param array $included * @return Addresstype */ - protected function getResourceObject(): Addresstype + protected function getResourceObject(array $included = []): Addresstype { return new Addresstype($this->client); } + /** + * @return BaseCollection + */ + protected function getResourceCollectionObject(): BaseCollection + { + throw new BadMethodCallException('not implemented'); + } + /** * @param string $addresstypeId * @param array $filter diff --git a/src/Endpoints/AsyncoperationEndpoint.php b/src/Endpoints/AsyncoperationEndpoint.php index 06478d6..0ca4ef5 100644 --- a/src/Endpoints/AsyncoperationEndpoint.php +++ b/src/Endpoints/AsyncoperationEndpoint.php @@ -2,21 +2,30 @@ namespace Digitalprint\Oro\Api\Endpoints; +use BadMethodCallException; use Digitalprint\Oro\Api\Exceptions\ApiException; use Digitalprint\Oro\Api\Resources\Asyncoperation; +use Digitalprint\Oro\Api\Resources\BaseCollection; class AsyncoperationEndpoint extends EndpointAbstract { protected string $resourcePath = "api/asyncoperations"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Asyncoperation */ - protected function getResourceObject(): Asyncoperation + protected function getResourceObject(array $included = []): Asyncoperation { - return new Asyncoperation($this->client); + return new Asyncoperation($this->client, $included); + } + + /** + * @return BaseCollection + */ + protected function getResourceCollectionObject(): BaseCollection + { + throw new BadMethodCallException('not implemented'); } /** diff --git a/src/Endpoints/AuthorizationEndpoint.php b/src/Endpoints/AuthorizationEndpoint.php index 0ea8d00..7830314 100644 --- a/src/Endpoints/AuthorizationEndpoint.php +++ b/src/Endpoints/AuthorizationEndpoint.php @@ -25,11 +25,12 @@ protected function getResourceCollectionObject(): BaseCollection } /** + * @param array $included * @return Authorization */ - protected function getResourceObject(): Authorization + protected function getResourceObject(array $included = []): Authorization { - return new Authorization($this->client); + return new Authorization($this->client, $included); } /** diff --git a/src/Endpoints/CollectionEndpointAbstract.php b/src/Endpoints/CollectionEndpointAbstract.php index 0dd5463..11324e5 100644 --- a/src/Endpoints/CollectionEndpointAbstract.php +++ b/src/Endpoints/CollectionEndpointAbstract.php @@ -8,11 +8,9 @@ abstract class CollectionEndpointAbstract extends EndpointAbstract { /** - * Get the collection object that is used by this API endpoint. Every API endpoint uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return BaseCollection */ - abstract protected function getResourceCollectionObject(stdClass $links): BaseCollection; + abstract protected function getResourceCollectionObject(stdClass $links, array $included = []): BaseCollection; } diff --git a/src/Endpoints/EndpointAbstract.php b/src/Endpoints/EndpointAbstract.php index cae9c2c..03f77ea 100644 --- a/src/Endpoints/EndpointAbstract.php +++ b/src/Endpoints/EndpointAbstract.php @@ -102,7 +102,7 @@ protected function rest_create(array $body): BaseResource $this->parseRequestBody($body) ); - return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject()); + return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject($result->included ?? [])); } /** @@ -125,7 +125,7 @@ protected function rest_read(string $id, array $filter): BaseResource $this->getResourcePath() . "/" . $id . $this->buildQueryString($filter) ); - return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject()); + return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject($result->included ?? [])); } /** @@ -149,10 +149,10 @@ protected function rest_list(int $number = null, int $size = null, array $filter ); /** @var BaseCollection $collection */ - $collection = $this->getResourceCollectionObject($result->links); + $collection = $this->getResourceCollectionObject($result->links, $result->included ?? []); foreach ($result->data as $dataResult) { - $collection[] = ResourceFactory::createFromApiResult($dataResult, $this->getResourceObject()); + $collection[] = ResourceFactory::createFromApiResult($dataResult, $this->getResourceObject($result->included ?? [])); } return $collection; @@ -176,7 +176,7 @@ protected function rest_update(array $body = []): ?BaseResource return null; } - return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject()); + return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject($result->included ?? [])); } /** @@ -197,15 +197,14 @@ protected function rest_delete(array $filter = []): ?BaseResource return null; } - return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject()); + return ResourceFactory::createFromApiResult($result->data, $this->getResourceObject($result->included ?? [])); } /** - * Get the object that is used by this API endpoint. Every API endpoint uses one type of object. - * + * @param array $included * @return BaseResource */ - abstract protected function getResourceObject(): BaseResource; + abstract protected function getResourceObject(array $included = []): BaseResource; /** * @param string $resourcePath diff --git a/src/Endpoints/ProductEndpoint.php b/src/Endpoints/ProductEndpoint.php index 0419cbf..c2347ac 100644 --- a/src/Endpoints/ProductEndpoint.php +++ b/src/Endpoints/ProductEndpoint.php @@ -8,9 +8,6 @@ use JsonException; use stdClass; -/** - * - */ class ProductEndpoint extends CollectionEndpointAbstract { /** @@ -19,25 +16,22 @@ class ProductEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/products"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Product */ - protected function getResourceObject(): Product + protected function getResourceObject(array $included = []): Product { - return new Product($this->client); + return new Product($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return ProductCollection */ - protected function getResourceCollectionObject(stdClass $links): ProductCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): ProductCollection { - return new ProductCollection($this->client, $links); + return new ProductCollection($this->client, $links, $included); } /** diff --git a/src/Endpoints/ProductdescriptionEndpoint.php b/src/Endpoints/ProductdescriptionEndpoint.php index b6d4227..f2ab95d 100644 --- a/src/Endpoints/ProductdescriptionEndpoint.php +++ b/src/Endpoints/ProductdescriptionEndpoint.php @@ -8,9 +8,6 @@ use JsonException; use stdClass; -/** - * - */ class ProductdescriptionEndpoint extends CollectionEndpointAbstract { /** @@ -19,25 +16,22 @@ class ProductdescriptionEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/productdescriptions"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Productdescription */ - protected function getResourceObject(): Productdescription + protected function getResourceObject(array $included = []): Productdescription { - return new Productdescription($this->client); + return new Productdescription($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return ProductdescriptionCollection */ - protected function getResourceCollectionObject(stdClass $links): ProductdescriptionCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): ProductdescriptionCollection { - return new ProductdescriptionCollection($this->client, $links); + return new ProductdescriptionCollection($this->client, $links, $included); } /** diff --git a/src/Endpoints/ProductimageEndpoint.php b/src/Endpoints/ProductimageEndpoint.php index 9c944e9..48696c9 100644 --- a/src/Endpoints/ProductimageEndpoint.php +++ b/src/Endpoints/ProductimageEndpoint.php @@ -8,9 +8,6 @@ use JsonException; use stdClass; -/** - * - */ class ProductimageEndpoint extends CollectionEndpointAbstract { /** @@ -19,25 +16,22 @@ class ProductimageEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/productimages"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Productimage */ - protected function getResourceObject(): Productimage + protected function getResourceObject(array $included = []): Productimage { - return new Productimage($this->client); + return new Productimage($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return ProductimageCollection */ - protected function getResourceCollectionObject(stdClass $links): ProductimageCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): ProductimageCollection { - return new ProductimageCollection($this->client, $links); + return new ProductimageCollection($this->client, $links, $included); } /** diff --git a/src/Endpoints/ProductnameEndpoint.php b/src/Endpoints/ProductnameEndpoint.php index 6684326..617e22a 100644 --- a/src/Endpoints/ProductnameEndpoint.php +++ b/src/Endpoints/ProductnameEndpoint.php @@ -8,9 +8,6 @@ use JsonException; use stdClass; -/** - * - */ class ProductnameEndpoint extends CollectionEndpointAbstract { /** @@ -19,25 +16,22 @@ class ProductnameEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/productnames"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Productname */ - protected function getResourceObject(): Productname + protected function getResourceObject(array $included = []): Productname { - return new Productname($this->client); + return new Productname($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return ProductnameCollection */ - protected function getResourceCollectionObject(stdClass $links): ProductnameCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): ProductnameCollection { - return new ProductnameCollection($this->client, $links); + return new ProductnameCollection($this->client, $links, $included); } /** diff --git a/src/Endpoints/ProductpriceEndpoint.php b/src/Endpoints/ProductpriceEndpoint.php index 6dd926c..0610b84 100644 --- a/src/Endpoints/ProductpriceEndpoint.php +++ b/src/Endpoints/ProductpriceEndpoint.php @@ -16,25 +16,22 @@ class ProductpriceEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/productprices"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Productprice */ - protected function getResourceObject(): Productprice + protected function getResourceObject(array $included = []): Productprice { - return new Productprice($this->client); + return new Productprice($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return ProductpriceCollection */ - protected function getResourceCollectionObject(stdClass $links): ProductpriceCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): ProductpriceCollection { - return new ProductpriceCollection($this->client, $links); + return new ProductpriceCollection($this->client, $links, $included); } /** diff --git a/src/Endpoints/UserEndpoint.php b/src/Endpoints/UserEndpoint.php index e01f511..a6cce68 100644 --- a/src/Endpoints/UserEndpoint.php +++ b/src/Endpoints/UserEndpoint.php @@ -16,25 +16,22 @@ class UserEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/users"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return User */ - protected function getResourceObject(): User + protected function getResourceObject(array $included = []): User { - return new User($this->client); + return new User($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return UserCollection */ - protected function getResourceCollectionObject(stdClass $links): UserCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): UserCollection { - return new UserCollection($this->client, $links); + return new UserCollection($this->client, $links, $included); } /** diff --git a/src/Endpoints/UserroleEndpoint.php b/src/Endpoints/UserroleEndpoint.php index 8ba571e..da9d03a 100644 --- a/src/Endpoints/UserroleEndpoint.php +++ b/src/Endpoints/UserroleEndpoint.php @@ -16,25 +16,22 @@ class UserroleEndpoint extends CollectionEndpointAbstract protected string $resourcePath = "api/userroles"; /** - * Get the object that is used by this API. Every API uses one type of object. - * + * @param array $included * @return Userrole */ - protected function getResourceObject(): Userrole + protected function getResourceObject(array $included = []): Userrole { - return new Userrole($this->client); + return new Userrole($this->client, $included); } /** - * Get the collection object that is used by this API. Every API uses one type of collection object. - * * @param stdClass $links - * + * @param array $included * @return UserroleCollection */ - protected function getResourceCollectionObject(stdClass $links): UserroleCollection + protected function getResourceCollectionObject(stdClass $links, array $included = []): UserroleCollection { - return new UserroleCollection($this->client, $links); + return new UserroleCollection($this->client, $links, $included); } /** diff --git a/src/Resources/Authorization.php b/src/Resources/Authorization.php index 87a8f86..014933d 100644 --- a/src/Resources/Authorization.php +++ b/src/Resources/Authorization.php @@ -26,15 +26,13 @@ class Authorization extends BaseResource /** * @param array $options - * @param array $filters - * - * @return self + * @return $this * @throws ApiException * @throws JsonException */ - public function create(array $options = [], array $filters = []): self + public function create(array $options = []): self { - return $this->client->authorization->create($this->withPresetOptions($options), $filters); + return $this->client->authorization->create($this->withPresetOptions($options)); } /** diff --git a/src/Resources/BaseCollection.php b/src/Resources/BaseCollection.php index 21265c5..81b6f42 100644 --- a/src/Resources/BaseCollection.php +++ b/src/Resources/BaseCollection.php @@ -8,17 +8,24 @@ abstract class BaseCollection extends ArrayObject { + /** + * @var array + */ + public array $included; + /** * @var stdClass */ - public $links; + public stdClass $links; /** * @param stdClass $links + * @param array $included */ - public function __construct($links) + public function __construct(stdClass $links, array $included = []) { $this->links = $links; + $this->included = $included; parent::__construct(); } diff --git a/src/Resources/BaseResource.php b/src/Resources/BaseResource.php index ba018f8..6ac3080 100644 --- a/src/Resources/BaseResource.php +++ b/src/Resources/BaseResource.php @@ -29,23 +29,30 @@ abstract class BaseResource /** * @var object */ - public object $links; + public object $attributes; /** * @var object */ - public object $attributes; + public object $relationships; /** * @var object */ - public object $relationships; + public object $links; + + /** + * @var array + */ + public array $included; /** * @param OroApiClient $client + * @param array $included */ - public function __construct(OroApiClient $client) + public function __construct(OroApiClient $client, array $included = []) { + $this->included = $included; $this->client = $client; } } diff --git a/src/Resources/CursorCollection.php b/src/Resources/CursorCollection.php index ce96431..d194ead 100644 --- a/src/Resources/CursorCollection.php +++ b/src/Resources/CursorCollection.php @@ -4,20 +4,22 @@ use Digitalprint\Oro\Api\Exceptions\ApiException; use Digitalprint\Oro\Api\OroApiClient; -use stdClass; abstract class CursorCollection extends BaseCollection { - protected $client; + /** + * @var OroApiClient + */ + protected OroApiClient $client; /** * @param $client - * @param stdClass $links + * @param $links + * @param $included */ - final public function __construct($client, $links) + final public function __construct($client, $links, $included = []) { - parent::__construct($links); - + parent::__construct($links, $included); $this->client = $client; } diff --git a/src/Resources/ResourceFactory.php b/src/Resources/ResourceFactory.php index 25480f1..f8832e6 100644 --- a/src/Resources/ResourceFactory.php +++ b/src/Resources/ResourceFactory.php @@ -41,7 +41,7 @@ public static function createBaseResourceCollection( $resourceCollectionClass = $resourceCollectionClass ?: $resourceClass . 'Collection'; $data = $data ?: []; - $result = new $resourceCollectionClass(count($data), $_links); + $result = new $resourceCollectionClass($_links); foreach ($data as $item) { $result[] = static::createFromApiResult($item, new $resourceClass($client)); } @@ -67,10 +67,10 @@ public static function createCursorResourceCollection( if (null === $resourceCollectionClass) { $resourceCollectionClass = $resourceClass.'Collection'; } - - $data = new $resourceCollectionClass($client, count($input), $_links); + + $data = new $resourceCollectionClass($client, $_links); foreach ($input as $item) { - $data[] = static::createFromApiResult($item, new $resourceClass($client)); + $data[] = static::createFromApiResult($item, new $resourceClass($client, [])); } return $data; diff --git a/tests/Digitalprint/Oro/API/Endpoints/ProductEndpointTest.php b/tests/Digitalprint/Oro/API/Endpoints/ProductEndpointTest.php index 687823b..5d7209e 100644 --- a/tests/Digitalprint/Oro/API/Endpoints/ProductEndpointTest.php +++ b/tests/Digitalprint/Oro/API/Endpoints/ProductEndpointTest.php @@ -1226,6 +1226,44 @@ public function testGetProduct(): void $product = $this->apiClient->products->get("1"); $this->assertProduct($product); + + $this->assertIsArray($product->included); + + $includedArray = (object) + [ + "type" => "productnames", + "id" => "19", + "links" => (object)[ + "self" => "https://myoroproxy.local/admin/api/productnames/19", + ], + "attributes" => (object)[ + "string" => "Product 1", + "fallback" => null, + ], + "relationships" => (object)[ + "product" => (object)[ + "links" => (object)[ + "self" => "https://myoroproxy.local/admin/api/productnames/19/relationships/product", + "related" => "https://myoroproxy.local/admin/api/productnames/19/product", + ], + "data" => (object)[ + "type" => "products", + "id" => "7", + ], + ], + "localization" => (object)[ + "links" => (object)[ + "self" => "https://myoroproxy.local/admin/api/productnames/19/relationships/localization", + "related" => "https://myoroproxy.local/admin/api/productnames/19/localization", + ], + "data" => null, + ], + ], + + ]; + + $this->assertEquals($includedArray, $product->included[0]); + } /** @@ -1267,6 +1305,44 @@ public function testListProduct(): void "next" => "https://myoroproxy.local/admin/api/products?page%5Bnumber%5D=2&page%5Bsize%5D=1&sort=id", ]; $this->assertEquals($linksObject, $products->links); + + $this->assertIsArray($products->included); + + $includedArray = (object) + [ + "type" => "productnames", + "id" => "19", + "links" => (object)[ + "self" => "https://myoroproxy.local/admin/api/productnames/19", + ], + "attributes" => (object)[ + "string" => "Product 1", + "fallback" => null, + ], + "relationships" => (object)[ + "product" => (object)[ + "links" => (object)[ + "self" => "https://myoroproxy.local/admin/api/productnames/19/relationships/product", + "related" => "https://myoroproxy.local/admin/api/productnames/19/product", + ], + "data" => (object)[ + "type" => "products", + "id" => "7", + ], + ], + "localization" => (object)[ + "links" => (object)[ + "self" => "https://myoroproxy.local/admin/api/productnames/19/relationships/localization", + "related" => "https://myoroproxy.local/admin/api/productnames/19/localization", + ], + "data" => null, + ], + ], + + ]; + + $this->assertEquals($includedArray, $products->included[0]); + } /** @@ -1708,6 +1784,200 @@ protected function getProductResponse(): string } } }, + "included": [ + { + "type": "productnames", + "id": "19", + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/19" + }, + "attributes": { + "string": "Product 1", + "fallback": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/19/relationships/product", + "related": "https://myoroproxy.local/admin/api/productnames/19/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/19/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productnames/19/localization" + }, + "data": null + } + } + }, + { + "type": "productnames", + "id": "20", + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/20" + }, + "attributes": { + "string": "Product 2", + "fallback": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/20/relationships/product", + "related": "https://myoroproxy.local/admin/api/productnames/20/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/20/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productnames/20/localization" + }, + "data": { + "type": "localizations", + "id": "1" + } + } + } + }, + { + "type": "productnames", + "id": "21", + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/21" + }, + "attributes": { + "string": null, + "fallback": "system" + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/21/relationships/product", + "related": "https://myoroproxy.local/admin/api/productnames/21/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/21/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productnames/21/localization" + }, + "data": { + "type": "localizations", + "id": "2" + } + } + } + }, + { + "type": "productdescriptions", + "id": "104", + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/104" + }, + "attributes": { + "fallback": null, + "wysiwyg": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/104/relationships/product", + "related": "https://myoroproxy.local/admin/api/productdescriptions/104/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/104/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productdescriptions/104/localization" + }, + "data": null + } + } + }, + { + "type": "productdescriptions", + "id": "13", + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/13" + }, + "attributes": { + "fallback": "system", + "wysiwyg": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/13/relationships/product", + "related": "https://myoroproxy.local/admin/api/productdescriptions/13/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/13/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productdescriptions/13/localization" + }, + "data": { + "type": "localizations", + "id": "1" + } + } + } + }, + { + "type": "productdescriptions", + "id": "14", + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/14" + }, + "attributes": { + "fallback": "system", + "wysiwyg": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/14/relationships/product", + "related": "https://myoroproxy.local/admin/api/productdescriptions/14/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/14/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productdescriptions/14/localization" + }, + "data": { + "type": "localizations", + "id": "2" + } + } + } + } + ], "links": { "self": "https://myoroproxy.local/admin/api/products" } @@ -2082,6 +2352,200 @@ protected function getProductCollectionResponse(): string } } ], + "included": [ + { + "type": "productnames", + "id": "19", + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/19" + }, + "attributes": { + "string": "Product 1", + "fallback": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/19/relationships/product", + "related": "https://myoroproxy.local/admin/api/productnames/19/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/19/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productnames/19/localization" + }, + "data": null + } + } + }, + { + "type": "productnames", + "id": "20", + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/20" + }, + "attributes": { + "string": "Product 2", + "fallback": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/20/relationships/product", + "related": "https://myoroproxy.local/admin/api/productnames/20/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/20/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productnames/20/localization" + }, + "data": { + "type": "localizations", + "id": "1" + } + } + } + }, + { + "type": "productnames", + "id": "21", + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/21" + }, + "attributes": { + "string": null, + "fallback": "system" + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/21/relationships/product", + "related": "https://myoroproxy.local/admin/api/productnames/21/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productnames/21/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productnames/21/localization" + }, + "data": { + "type": "localizations", + "id": "2" + } + } + } + }, + { + "type": "productdescriptions", + "id": "104", + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/104" + }, + "attributes": { + "fallback": null, + "wysiwyg": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/104/relationships/product", + "related": "https://myoroproxy.local/admin/api/productdescriptions/104/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/104/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productdescriptions/104/localization" + }, + "data": null + } + } + }, + { + "type": "productdescriptions", + "id": "13", + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/13" + }, + "attributes": { + "fallback": "system", + "wysiwyg": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/13/relationships/product", + "related": "https://myoroproxy.local/admin/api/productdescriptions/13/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/13/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productdescriptions/13/localization" + }, + "data": { + "type": "localizations", + "id": "1" + } + } + } + }, + { + "type": "productdescriptions", + "id": "14", + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/14" + }, + "attributes": { + "fallback": "system", + "wysiwyg": null + }, + "relationships": { + "product": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/14/relationships/product", + "related": "https://myoroproxy.local/admin/api/productdescriptions/14/product" + }, + "data": { + "type": "products", + "id": "7" + } + }, + "localization": { + "links": { + "self": "https://myoroproxy.local/admin/api/productdescriptions/14/relationships/localization", + "related": "https://myoroproxy.local/admin/api/productdescriptions/14/localization" + }, + "data": { + "type": "localizations", + "id": "2" + } + } + } + } + ], "links": { "self": "https://myoroproxy.local/admin/api/products", "first": "https://myoroproxy.local/admin/api/products?page%5Bsize%5D=1&sort=id",