Documentation

Installation

This SDK can be installed with composer

composer require affilinet/productdata-php-sdk

If you have not yet worked with composer and Packagist we strongly suggest you to start with it right now!
There are a lot of great tutorials on how to install and use composer. Furthermore we suggest you to update your coding knowledge by reading the current best practices of writing PHP.


Please note: This package requires PHP 5.6 or greater.

Examples

First of all you have to create the client object. It is used to send all requests to the affilinet API.

1
2
3
4
5
6
7
<?php
$config = [
    'publisher_id' => {PUBLISHER ID},
    'product_webservice_password' => {PRODUCT WEBSERVICE PASSWORD}
];

$affilinet = new \Affilinet\ProductData\AffilinetClient($config);

This SDK uses Guzzle as internal HttpClient. You can create your own guzzle object and inject it as config parameter named 'http_client'. If 'http_client' is an array, this array will be used as config array for the guzzle client.

All examples use the affilinet client object named $affilinet as created above.

List of Shops

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// create a  ShopsRequest Object
$shopsRequest = new \Affilinet\ProductData\Requests\ShopsRequest($affilinet);

$shopsRequest
    ->addShopLogoWithSize50px()     // to include a shop logo with 50px width
    ->onlyShopsMatchingKeyword('Zalando') // only shops which match this keyword
    ->onlyShopsUpdatedAfter(new \DateTime('last month')); // only shops that have updated their products after this date


// send the query and get the response
$response = $shopsRequest->send();

echo 'Total results : ' . $response->totalRecords();

// display some information about the found shops
foreach ($response->getShops() as $shop) {
    echo $shop->getName();
    echo $shop->getId();
    echo $shop->getProductCount();
    echo $shop->getLastUpdate()->format('dmY h:i:s');
    echo $shop->getUrl();
}

To see a list of all shops create an empty ShopsRequest like this:

1
2
3
4
<?php
$shopsRequest = new \Affilinet\ProductData\Requests\ShopsRequest($affilinet);
$allShops = $shopsRequest->send();
echo 'You have ' . $response->totalRecords() . ' shops with an active partnership';

Search Products

All search requests for products use the class ProductsRequest.

Find Products

Request a single product by its productID

1
2
3
4
5
6
7
8
<?php

$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);

// will directly return a Product Object
$product = $productsRequest->findOne('123456789');
echo $product->getProductName();
echo $product->getPriceInformation()->getDisplayPrice();

Request several products by their productIDs

1
2
3
4
5
6
7
8
9
10
11
<?php

$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);

// will return a Product Response Object
$productResponse = $productsRequest->find(['123', 65, 15651]);

foreach ($productResponse->products() as $product) {
    echo $product->getProductName();
    echo $product->getPriceInformation()->getDisplayPrice();
}

Extended search with pagination

There are a lot of filters for each ProductsRequest. Have a look at the ProductsRequestInterface to see all available filter methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$productsRequest
    ->onlyWithImage() // only include results with images
    ->addProductImage() // include the original image of the product
    ->excludeShopIds([123]) // do not include products from Shop with id 123
    ->addShopLogoWithSize90px() // also include a shop logo with a specific width of 90px
    ->maxPrice(100.01) // maximum price 100 euro and one cent
    ->minPrice(1)   // minimum price: one euro
    ->page(2) // show the second result page page (page parameter starts counting at 1)
    ->pageSize(20) // 20 results per page

    /**
     * Possible Sorting Parameters defined as class constants:
     * SORT_BY_RELEVANCE, SORT_BY_PRODUCT_NAME, SORT_BY_LAST_PROGRAM_LIST_UPDATE
     **/
    ->sort(\Affilinet\ProductData\Requests\ProductsRequest::SORT_BY_PRICE, true);
    ->addRawQuery('tshirt')
    ;

// will return a Product Response Object
$productResponse = $productsRequest->send();

foreach ($productResponse->products() as $product) {
    echo $product->getProductName();
    echo $product->getPriceInfor;
}

Query Builder for complex searches

The SDK provides a Query Builder to easily generate complex SQL-like search requests.

The Query Builder should not be combined with the facet querystring generator.

Include terms

<?php
$query = new \Affilinet\ProductData\Requests\Helper\Query();

$query->where(
        $query->expr()->containsAllOf('ipad', 'apple')
);

$productsRequest
    ->query($query)
    ->send();


Alternativly you can chain expressions

<?php
$query = new \Affilinet\ProductData\Requests\Helper\Query();
$query->where(
    $query->expr()
        ->contains('ipad')
        ->contains('apple')
);

$productsRequest
    ->query($query)
    ->send();


Exactly match a term

<?php
$query = new \Affilinet\ProductData\Requests\Helper\Query();
// will include apple but not applejuice
$query->where(
    $query
        ->expr()
        ->exactly('apple')
);


Combine terms with OR

<?php
$query = new \Affilinet\ProductData\Requests\Helper\Query();
// will include results matching apple or samsung
$query->where(
    $query
        ->expr()
        // you can add as many parameters as you like or an array
        ->containsOneOf('apple', 'samsung')
);


Exclude terms

<?php
$query = new \Affilinet\ProductData\Requests\Helper\Query();
$query->where(
    $query
        ->expr()
        // you can add as many parameters as you like or an array
        ->containsNot('ipad', 'apple')
);


Examples
Get all products containing "apple" but not containing "ipod", "iphone", "mac"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$query = new \Affilinet\ProductData\Requests\Helper\Query();
$query
    ->where(
        $query
            ->expr()
            ->contains('apple')
            // you can add as many parameters as you like or an array
            ->containsNot('ipod', 'iphone', 'mac', 'iPad' )
    );
$productsRequest->query($query);

$response = $productsRequest->send();


Get all products containing "apple" and "ipad"

<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$query = new \Affilinet\ProductData\Requests\Helper\Query();
$query
    ->where(
        $query
            ->expr()
            ->contains('apple')
            ->contains('ipad')
    );
$response = $productsRequest->query($query)->send();


Chain Query Expressions

For better code legibility both methods where() and andWhere() can be used. They provide the same functionality..

Chaining with AND

<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$productsRequest->query($query
->where($query->expr()
->contains('apple')
)
->andWhere($query->expr()
->exactly('iphone')
)
);
$response = $productsRequest->query($query)->send();


Combine with OR: Find (apple and "iphone") or (samsung and "galaxy")

<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$query = new \Affilinet\ProductData\Requests\Helper\Query();
$query
    ->where($query->epxr()
        ->contains('apple')
        ->exactly('iphone')
    )
    ->orWhere($query->expr()
        ->contains('samsung')
        ->exactly('galaxy')
    );
$response = $productsRequest->query($query)->send();


Combine OR with AND. The SQL would look

    ( "t-mobile")

    AND
    (
        (  apple AND "iphone" )
        OR
        (  samsung AND "galaxy" )

    )
<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$query = new \Affilinet\ProductData\Requests\Helper\Query();
$query
    ->where($query->expr()
        ->contains('apple')
        ->exactly('iphone')
        ->exactly('t-mobile')
    )
    ->orWhere($query->expr()
        ->contains('samsung')
        ->exactly('galaxy')
        ->exactly('t-mobile')
    )
);
$response = $productsRequest->query($query)->send();


Limitations
It is not possible to nest where statements: "No where() inside of where() methods. They only accept expression statements "expr()".

<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$query = new \Affilinet\ProductData\Requests\Helper\Query();

// invalid code!
$query->where(
    $query
        ->expr()
        ->contains('apple')
        // next line will not work:
        ->orWhere(
            $query
                ->expr()
                ->contains('samsung')
        );


It is not possible to chain expressions inside a where() with OR.

<?php
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$query = new \Affilinet\ProductData\Requests\Helper\Query();

// invalid code!
$query->where(
    $query
        ->expr()
        ->contains('apple')
        ->orContains('samsung) // !!! method not defined !!!
);

// correct code:
$query->where(
    $query
        ->expr()
        ->containsOneOf('apple', 'samsung')

);

// alternate correct code:
$query
    ->where($query->expr()->contains('apple'));
    ->orWhere($query->expr()->contains('samsung'));

);

Write queries by yourself
Instead of using the query builder you can write queries by yourself and attach them via
$productsRequest->addRawQuery(YOUR_QUERY_STRING)
The keyword(s) you want the products to match. Can be any length. The following search operators are supported:

  • AND (both query tokens must be contained in the product, but not necessarily next to one another)
  • OR (any of the query tokens must be contained in the product)
  • NOT (e.g. with “ipod AND NOT nano”, you will get products, which match the query “ipod”, but at the same time don’t match “nano”)
  • " (phrase match: all query tokens inclosed with double quotes must be contained in the found products in that order)
  • () Parentheses, to group expressions
So you can formulate a query like this:
"apple ipod" ((touch OR classic) NOT nano) AND "32 GB"
ProductsRequest supports the wildcard ‘*’ for suffix matching, that is: a query ‘bott*’ will match for products, which contain the word “bottle” or the word “bottom”. Search operators “AND”, “OR” and “NOT” must be in capital letters.

<?php
$productsRequest
    ->addRawQuery(
        ' "apple ipod" ((touch OR classic) NOT nano) AND  "32 GB"'
    );


Faceted Search

Many names refer to the same thing. Faceting is sometimes also called “Faceted Search”, “Parameter Search”, “Faceted Navigation” and others. What it is about is best explained with a common use case of our context:
If you send off a ProductRequest with a facet “Brand”, then you not only get back the products that match the search criteria, but on top an overview, what brands occur among all found products and how often. Up to 50 different brands will be returned, together with the quantity of products for each brand - depending on the input parameter $facetValueLimit. By default 20 Facet values will be returned

Each facet type has a corresponding FilterQuery. A Filter Query is used to filter results to one facet value.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
$productsRequest->addRawQuery( 'tshirt');

// add the band facet and show a maximum of 15 different brands
$productsRequest->addFacetBrand(15);

// will return a ProductsResponse Object
$productsResponse = $productsRequest->send();

// display the brand and the number of results for each brand
foreach ($productsResponse->getFacets() as $facet) {
    echo $facet->getName();

    foreach ($facet->getValues() as $facetValue) {
        echo $facetValue->getDisplayValue(). ' (' .$facetValue->getResultCount() . ')';
    }
}

// show the results
foreach ($productsResponse->products() as $product) {
    echo $product->getProductName();
    echo $product->getPriceInformation()->getDisplayPrice();
}

Facets can not only be added for Brand. You can choose up to four of these facets

  • $productsRequest->addFacetArticleNumber()
  • $productsRequest->addFacetBrand()
  • $productsRequest->addFacetDistributor()
  • $productsRequest->addFacetEAN()
  • $productsRequest->addFacetManufacturer()
  • $productsRequest->addFacetShopId()
  • $productsRequest->addFacetAffilinetCategoryId()
  • $productsRequest->addFacetAffilinetCategoryPath()
  • $productsRequest->addFacetShopCategoryId()
  • $productsRequest->addFacetShopCategoryPath()
  • Deprecated: $productsRequest->addFacetShopName()
  • Deprecated: $productsRequest->addFacetProgramId()


Generating Facet Links

By now we just displayed the result count for each facet. For sure you want to use these facets as a filter on your page.
To make this work you will have to convert each facet into an URL. There are several ways to achieve this.

You should use your own implementation to generate facet URLs. The method generateQueryString() is just included for your convenience.

Generate Facet Links with the querystring generator
1
2
3
4
5
6
7
8
9
10
11
12
<?php

foreach ($productResponse->getFacets() as $facet) {
    echo $facet->getName();

    foreach ($facet->getValues() as $facetValue) {
        // generate a query string and attach it to your URL
        $url = '/' . $facetValue->generateQueryString($productsRequest);

        echo "<a href='$url'> ". $facetValue->getDisplayValue() . '</a><br>';
    }
}
Generate Facet Links with a custom router (the better way)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

foreach ($productResponse->getFacets() as $facet) {
    echo $facet->getName();

    foreach ($facet->getValues() as $facetValue) {
        // generate a new ProductsRequest for each facetValue
        $newProductsRequestString = $facetValue->generateSerializedProductsRequest($productsRequest);

        // use the serialized Object to generate the ProductsRequest object
        $newProductsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);
        $newProductsRequest->unserialize($newProductsRequestString);

        // use  $newProductsRequest or $newProductsRequestString to generate an URL with your router
        $url = YourRouter::generateURL($newProductsRequest);

        echo "<a href='$url'> ". $facetValue->getDisplayValue() . '</a><br>';
    }
}


Generate the resultpage for facet links

To actually display the results behind these links you will have to extract the information from the URL and create a new ProductsRequest. For testing purposes you can create a ProductsRequest directly from the query string

1
2
3
4
5
6
7
8
9
<?php
// create a ProductsRequest Object
$productsRequest = new \Affilinet\ProductData\Requests\ProductsRequest($affilinet);

$queryString = $_SERVER['QUERY_STRING']
// do not forget to sanatize the query string!
$productsRequest->unserialize($queryString);

$products = $productsRequest->send();


Matching Facets and FilterQueries

In your own solution you should use addFilterQuery($name, $value) to filter results according to the selected facets

Example:
  • You have added the "Brand" Facet with $productsRequest->addFacetBrand().
  • A User clicks on on the facet with value "Adidas"
  • On the resultpage you will have to add a filterQuery: $productsRequest->addFilterQuery('Brand', 'Adidas')
  • The results will be filtered to 'Brand' === 'Adidas'


Facets and their corresponding Filter Query

Facet FilterQuery
addFacetArticleNumber() addFilterQuery('ArticleNumber', VALUE)
addFacetBrand() addFilterQuery('Brand', VALUE)
addFacetDistributor() addFilterQuery('Distributor', VALUE)
addFacetEAN() addFilterQuery('EAN', VALUE)
addFacetManufacturer() addFilterQuery('Manufacturer', VALUE)
addFacetShopId() addFilterQuery('ShopId', VALUE)
addFacetAffilinetCategoryId() addFilterQuery('AffilinetCategoryId', VALUE)
addFacetAffilinetCategoryPath() addFilterQuery('AffilinetCategoryPath', VALUE)
addFacetShopCategoryId() addFilterQuery('ShopCategoryId', VALUE)
addFacetShopCategoryPath() addFilterQuery('ShopCategoryPath', VALUE)
addFacetShopName() addFilterQuery('ShopName', VALUE)
addFacetProgramId() addFilterQuery('ProgramId', VALUE)

Product Response

Most ProductsRequest will generate a ProductResponse Object.

If just one Product was requested with $productsRequest->find(PRODUCT_ID) the response will be a Product object instead of a ProductResponse.

Meta Data

Get some general information about the response for pagination.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

// number of total results
$productResponse->totalRecords();

// Number of pages (Pages are "1 based", there is no page with number 0)
$productResponse->totalPages()

// Number of results on this page
$productResponse->pageSize()

// number of currentPage (Pages are "1 based", there is no page with number 0)
$productResponse->pageNumber()

Facets

Facets must explicitly be requested in your ProductsRequest.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

// get the array of Facet objects
$facets = $productResponse->getFacets();

foreach( $facets as $facet) {

    // each $facet is a "Facet" object
    $facet->getName();  // for example "ShopCategoryPathFacet"

    foreach ($facet->getValues() as $facetValue) {
        // $facetValue is a "FacetValue" Object

        // to display always use getDisplayValue
        $facetValue->getDisplayValue() // => "Shoes"

        // the "real" value of this facet
        $facetValue->getValue()  // => 987654^Shoes^12345>987654^Clothing>Shoes

        // the number of results for "Adidas"
        $facetValue->getResultCount(); // => 21

        /**
         * To get the results behind this facet value, generate a new ProductsRequest
         * $productsRequest is the original request of this page
         * Can be used to generate a URL for the facet
         **/
        $facetValue->generateSerializedProductsRequest($productsRequest)

        /**
         * returns a new ProductsRequest serialized as a query string
         * $productsRequest is the original request of this page
         * Can be used to generate a URL for the facet
         **/
        $facetValue->generateQueryString($productsRequest)

    }
}

Product Object

Each ProductResponse Object contains several Product Objects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

// get the array of Product objects
$products = $productResponse->getProducts();

foreach( $products as $product) {

    $product->getProductName();

    /**
    * This is the ready-to-use string to display the price. E.g.
    * “For a limited time only 15.99 GBP plus shipping”.
    */
    $product->getPriceInformation()->getDisplayPrice()
}


A Product has a lot of attributes, most are self-explanatory. Have a look at the interface below. There are just a few things to keep in mind:

Always use $product->getPriceInformation()->getDisplayPrice() to show prices!
Images are not contained by default, they must be requested in the ProductsRequest.
Add the product to the users' cart by using $product->getDeeplinkWithWithProductAddedToCart(true). If no "add-to-cart"-deeplink is provided it will return the normal deeplink as fallback.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<?php

/*
 * This file is part of the affilinet Product Data PHP SDK.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Affilinet\ProductData\Responses\ResponseElements;

interface ProductInterface
{
    /**
     * @return string
     */
    public function getArticleNumber();

    /**
     * @return \DateTime
     */
    public function getLastShopUpdate();

    /**
     * @return \DateTime
     */
    public function getLastProductChange();

    /**
     * @return float
     */
    public function getScore();

    /**
     * @return integer
     */
    public function getProductId();

    /**
     * @return integer
     */
    public function getShopId();

    /**
     * @return string
     */
    public function getShopTitle();

    /**
     * @return string
     */
    public function getProductName();

    /**
     * @return string
     */
    public function getDescription();

    /**
     * @return string
     */
    public function getDescriptionShort();

    /**
     * @return integer
     */
    public function getShopCategoryId();

    /**
     * @return integer
     */
    public function getAffilinetCategoryId();

    /**
     * @return string
     */
    public function getShopCategoryPath();

    /**
     * @return string
     */
    public function getAffilinetCategoryPath();

    /**
     * @return string
     */
    public function getShopCategoryIdPath();

    /**
     * @return string
     */
    public function getAffilinetCategoryIdPath();

    /**
     * @return string
     */
    public function getDeeplink();

    /**
     * @return boolean
     */
    public function hasDeeplinkWithProductAddedToCart();

    /**
     * @param $useDeeplinkAsFallback
     * @return mixed
     */
    public function getDeeplinkWithWithProductAddedToCart($useDeeplinkAsFallback = false);

    /**
     * @return string
     */
    public function getBrand();

    /**
     * @return string
     */
    public function getManufacturer();

    /**
     * @return string
     */
    public function getDistributor();

    /**
     * @return string
     */
    public function getEAN();

    /**
     * @return string
     */
    public function getKeywords();

    /**
     * @return Price
     */
    public function getPriceInformation();

    /**
     * @return Image[]
     */
    public function getImages();

    /**
     * @return Image[]
     */
    public function getLogos();

    /**
     * @return array
     */
    public function getProperties();

    /**
     * @param $propertyName string
     * @return bool
     */
    public function hasProperty($propertyName);

    /**
     * @param $propertyName string
     * @return string
     */
    public function getProperty($propertyName);

    /**
     * @return integer
     */
    public function getProgramId();

}

Search Shops

Every product belongs to a shop. To access a shops products you need to have an active partnership with this shop.

Find shops

By default an empty ShopsRequest will always return all shops you have an active partnership with

To see a list of all shops create an empty ShopsRequest like this:

1
2
3
4
5
<?php
$shopsRequest = new \Affilinet\ProductData\Requests\ShopsRequest($affilinet);
$shopsResponse = $shopsRequest->send();

echo 'You have ' . $shopsResponse->totalRecords() . ' shops with an active partnership';

Find Shops by Keyword

1
2
3
4
5
6
7
8
9
10
11
<?php
// create a  ShopsRequest Object
$shopsRequest = new \Affilinet\ProductData\Requests\ShopsRequest($affilinet);


$shopsRequest
   ->onlyShopsMatchingKeyword('Zalando') // only shops which match "Zalando"

$shopsResponse = $shopsRequest->send();

echo 'Shops matching "Zalando": ' . $shopsResponse->totalRecords();


Include a Shop Logo
You can request one logo to be returned for each shop. You can choose between 5 sizes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// create a  ShopsRequest Object
$shopsRequest = new \Affilinet\ProductData\Requests\ShopsRequest($affilinet);

// add a logo of 468px width
$shopsRequest->addShopLogoWithSize468px();

// or: $shopsRequest->addShopLogoWithSize90px()
// or: $shopsRequest->addShopLogoWithSize120px();
// or: $shopsRequest->addShopLogoWithSize150px();

// or: $shopsRequest->addShopLogoWithSize50px();

$shopsResponse = $shopsRequest->send();

Shop Response

Every ShopsRequest returns a Affilinet\ProductData\Responses\ShopsResponse Object. Which consists of a list of shops and some meta information.

Meta information:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
// number of total shops found
$shopsResponse->totalRecords();

// Number of pages (Pages are "1 based", there is no page with number 0)
$shopsResponse->totalPages()

// Number of shops on this page
$shopsResponse->pageSize()

// number of currentPage (Pages are "1 based", there is no page with number 0)
$shopsResponse->pageNumber()


Shop Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
// get all shops with active partnership
$shopsRequest = new \Affilinet\ProductData\Requests\ShopsRequest($affilinet);
$shopsRequest->addShopLogoWithSize50px()
$shopsResponse = $shopsRequest->send();

// get the shopList (an array of Shop objects)

$shops  = $shopsResponse->getShops();

foreach ($shops as $shop) {

   /** @var $shop Affilinet\ProductData\Responses\ResponseElements\ShopInterface */
   $shop->getProductCount(); // number of all products
   $shop->getProgramId();    // the affilinet program ID
   $shop->getName();         // the shop name (for example "zalando.de - Schuhe und Fashion online"
   $shop->getUrl();          // the shop URL (for example https://www.zalando.de/ )
   $shop->getLastUpdate();   // \DateTime when the shop products where last updated
   $shop->getLogo();         // an Image Object of the requested shop logo
}

Shop Properties

Shops can define custom properties for filtering their products.
Advertisers can provide us with 3 types of data for each product:

  • obligatory fields (e.g. price or deeplink)
  • optional fields (e.g. brand or distributor)
  • custom fields (which we call “product properties” or "shop properties").

The latter type is very flexible: every additional column which a shop delivers to us, is handed out to the publishers with un-altered name. So a shoe shop can provide us with custom fields / product properties like “size” or “material”, while a notebook shop can send us “HDD capacity”, “Screen Size”, “CPU speed” etc...
With this method, you can specify a ShopId and we send back to you, what properties this shop has and how many of its products have this property set.

Get Shop Properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
// create a ShopPropertiesRequest Object
$shopPropertiesRequest = new \Affilinet\ProductData\Requests\ShopPropertiesRequest($affilinet);

$shopPropertiesRequest->setShopId('123456'); // where '123456' has to be the valid shopId of course

$shopPropertiesResponse = $shopPropertiesRequest->send();

echo 'Total Shop Properties : ' . $shopPropertiesResponse->totalProperties();
echo 'Total Shop Properties : ' . $shopPropertiesResponse->totalRecords(); // alias function

$shopPropertiesResponse->hasProperty('size'); // will return true if you can use "size" as a filter for this shop

// get all shop properties
foreach ($shopPropertiesResponse->getProperties() as $shopProperty) {
   /** @var $shopProperty Affilinet\ProductData\Responses\ResponseElements\ShopProperty
   $shopProperty->getPropertyName();   // the name of this filter for example "size"
   $shopProperty->getTotalCount();     // the number of total results where this filter is set
}

Shop Categories

Every shop matches its products into the generic affilinet product categories. But most shops also provide custom categories.

Custom Shop Categories
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
// create a ShopPropertiesRequest Object
$categoriesRequest = new \Affilinet\ProductData\Requests\CategoriesRequest($affilinet);

$categoriesRequest->setShopId('123456'); // where '123456' has to be the valid shopId of course

$categoriesResponse = $categoriesRequest->send();

// iterate over the categories
foreach ($categoriesResponse->getCategories() as $category) {
    /**
     * @var $category Affilinet\ProductData\Responses\ResponseElements\CategoryInterface
     */
    // the category ID
    $category->getId();

    // the name of this category for example "Menswear"
    $category->getName();

    /**
     * A string representing the hierarchical position of this category within the
     * category tree, top down: if e.g. “987>1111>3235” is returned, this reads
     * “this category (3235) has the parent category 1111, which has the
     * parent category 987, which does NOT have a parent category (in other
     * words: 987 is a top category).
     */
    $category->getIdPath();


    /**
     * The titles of all categories along the path from the root node to this category, separated by ‘>’.
     * e.g. “Clothing & Accessories>Menswear”.
     */
    $category->getNamePath();


    // Number of products in this category
    $category->getProductCount();

}

Use a shop category to filter a Product Request
$prodReq->addFilterQuery('ShopCategoryPath', $category->getNamePath() )
or
$prodReq->addFilterQuery('ShopCategoryId', $category->getId() )

affilinet Categories
The affilinet categories are always the same, only the product result counts will change

1
2
3
4
5
6
7
8
9
10
<?php
// create a ShopPropertiesRequest Object
$categoriesRequest = new \Affilinet\ProductData\Requests\CategoriesRequest($affilinet);

$categoriesRequest->getAffilinetCategories()

// this would also return affilinet categories
// $categoriesRequest->setShopId(0);

$categoriesResponse = $categoriesRequest->send();

You can use a affilinet category to filter a Product Request
$prodReq->addFilterQuery('AffilinetCategoryPath', $category->getNamePath() )
or
$prodReq->addFilterQuery('AffilinetCategoryId', $category->getId() )

Tests

All tests rely on composer. Please run composer install before running the tests.

phpunit tests include some integration tests. To run these tests you need to provide a publisherId and productWebservicePassword.

Copy Tests/AffilinetTestCredentials.php.dist to Tests/AffilinetTestCredentials.php and enter your PUBLISHER_ID and PRODUCT_WEBSERVICE_PASSWORD

License

Please see the license file for more information.