Coder Social home page Coder Social logo

kontent-ai / delivery-sdk-php Goto Github PK

View Code? Open in Web Editor NEW
46.0 22.0 15.0 1.58 MB

Kontent.ai Delivery SDK for PHP

Home Page: https://kontent.ai

License: MIT License

PHP 100.00%
php php7 delivery-api headless-cms composer packagist hacktoberfest kontent-ai kontent-ai-sample

delivery-sdk-php's Introduction

Kontent.ai Delivery SDK for PHP

Build & Test & Report Packagist codecov Stack Overflow Discord

Summary

The Kontent.ai Delivery PHP SDK is a client library used for retrieving content from Kontent.ai. The best way to use the SDK is to consume it in the form of a Packagist package. The library currently supports only PHP 8 and above.

Sample site

Check out a sample site running on Laravel utilizing this SDK here: https://github.com/kontent-ai/sample-app-php

Installation

The best way to install the client is through a dependency manager called Composer:

composer require kontent-ai/delivery-sdk-php

or adjusting your composer.json file:

{
    "require": {
        "kontent-ai/delivery-sdk-php": "^6.0.0"
    }
}

Autoloading

Writing object-oriented applications requires one PHP source file per class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).

Since the SDK uses Composer dependency manager and specifies autoload information, Composer generates a vendor/autoload.php file. You can simply include this file and start using the namespaces that those libraries offer without any extra work:

require __DIR__ . '/vendor/autoload.php';

Using the DeliveryClient

The DeliveryClient class is the main class of the SDK. Using this class, you can retrieve content from your Kontent.ai projects.

To create an instance of the class, you need to provide a project ID.

use Kontent\Ai\Delivery\DeliveryClient;

// Initializes an instance of the DeliveryClient client
$client = new DeliveryClient('975bf280-fd91-488c-994c-2f04416e5ee3');

There are some other optional parameters that you can use during the DeliveryClient instantiation.

  • $previewApiKey – sets the Delivery Preview API key. The client will automatically start using the preview endpoint for querying. See previewing unpublished content.
  • $securedProductionApiKey – sets the production Delivery API key (do not combine it with the Delivery Preview API key)
  • $waitForLoadingNewContent – makes the client instance wait while fetching updated content, useful when acting upon webhook calls.
  • $debugRequests – switches the HTTP client to debug mode
  • $retryAttempts – number of times the client will retry to connect to the Kontent.ai API on failures per request

Once you create a DeliveryClient, you can start querying your project repository by calling methods on the client instance. See Basic querying for details.

Basic querying

Once you have a DeliveryClient instance, you can start querying your project repository by calling methods on the instance.

// Retrieves a single content item
$item = $client->getItem('about_us');

// Retrieves a list of all content items
$items = $client->getItems();

Filtering retrieved data

The SDK supports full scale of the API querying and filtering capabilities as described in the API reference.

use Kontent\Ai\Delivery\QueryParams;

// Retrieves a list of the specified elements from the first 10 content items of
// the 'brewer' content type, ordered by the 'product_name' element value
$response = $client->getItems((new QueryParams())
  ->equals('system.type', 'brewer')
  ->elements(array('image', 'price', 'product_status','processing'))
  ->limit(10)
  ->orderAsc('elements.product_name'));

Getting localized items

The language selection is just a matter of specifying one additional filtering parameter to the query.

use Kontent\Ai\Delivery\QueryParams;

// Retrieves a list of the specified elements from the first 10 content items of
// the 'brewer' content type, ordered by the 'product_name' element value
$response = $client->getItems((new QueryParams())
  ->language('es-ES')
  ->equals('system.type', 'brewer')
  ->elements(array('image', 'price', 'product_status','processing'))
  ->limit(10)
  ->orderAsc('elements.product_name'));

Working with taxonomies

To retrieve information about your taxonomies, you can use the getTaxonomy and getTaxonomies methods. Additionally, you can specify query parameters.

use Kontent\Ai\Delivery\QueryParams;

// Retrieves a list of the specified taxonomy groups.
$response = $client->getTaxonomies((new QueryParams())
  ->limit(3);

// Retrieves a specific taxonomy group.
$response = $client->getTaxonomy('persona');

Previewing unpublished content

To retrieve unpublished content, you need to create a DeliveryClient with both Project ID and Preview API key. Each Kontent.ai project has its own Preview API key.

// Note: Within a single project, we recommend that you work with only
// either the production or preview Delivery API, not both.
$client = new DeliveryClient('YOUR_PROJECT_ID', 'YOUR_PREVIEW_API_KEY');

For more details, see Previewing unpublished content using the Delivery API.

Response structure

For full description of single and multiple content item JSON response formats, see our API reference.

Single content item response

When retrieving a single content item, you get an instance of the ContentItem class. This class contains a 'system' property (with metadata about the content item, such as code name, display name, type, collection, or sitemap location) and respective content item's elements projected as camelCase properties.

Single item

Multiple content items response

When retrieving a list of content items, you get an instance of the ContentItemsResponse. This class represents the JSON response from the Delivery API endpoint and contains:

  • Pagination property with information about the following:
    • Skip: requested number of content items to skip
    • Limit: requested page size
    • Count: the total number of retrieved content items
    • NextPageUrl: the URL of the next page
  • An array of the requested content items

Properties and their types

  • All properties are named in the camelCase style.
  • If a property contains a collection of objects, it's typed as an array which is indexed by:
    • codenames, if the contained entities have a code name
    • numbers, if they don't have code names. We use zero-based indexing.
  • If a property references linked items (property is of the linked item type), the references are replaced with the respective content items themselves.
  • If a property is of asset, multiple choice option, or taxonomy group type, it's resolved to respective well-known models from the Kontent\Ai\Delivery\Models\Items namespace.
  • All timestamps are typed as \DateTime.
  • All numbers are typed as float.

Mapping custom models

It's possible to instruct the SDK to fill and return your own predefined models. To do that you have to implement:

  • TypeMapperInterface (required) - to provide mapping of Kontent.ai content types to your models
  • PropertyMapperInterface (optional) - to change the default behavior of property mapping (the default property translation works like this: 'content_type' -> 'contentType')
  • ValueConverterInterface (optional) - to change the way content element types are mapped to PHP types
  • ContentLinkUrlResolverInterface (optional) - to change the way the links in Rich text elements are resolved see Resolving links to content items.
  • InlineLinkedItemsResolverInterface (optional) - to change the way content items in Rich text elements are resolved see Resolving content items and components in Rich text.

The default implementation of all the interfaces can be found in a class called DefaultMapper.

Example:

class TetsMapper extends DefaultMapper
{
    public function getTypeClass($typeName)
    {
        switch ($typeName) {
            case 'home':
                return \Kontent\Ai\Tests\E2E\HomeModel::class;
            case 'article':
                return \Kontent\Ai\Tests\E2E\ArticleModel::class;
        }

        return parent::getTypeClass($typeName);
    }
}
...

public function testMethod()
{
    $client = new DeliveryClient('975bf280-fd91-488c-994c-2f04416e5ee3');
    $client->typeMapper = new TetsMapper();
    $item = $client->getItem('on_roasts');
    $this->assertInstanceOf(\Kontent\Ai\Tests\E2E\ArticleModel::class, $item); // Passes
}

The ArticleModel can then look like this (and contain only the properties you need to work with):

class ArticleModel
{
    public $system = null;
    public $title = null;
    public $urlPattern = null;
}

Feedback & Contributing

Check out the contributing page to see the best places to file issues, start discussions, and begin contributing.

  1. Clone the repository
  2. Run composer install to install dependencies
  3. Run phpunit to verify that everything works as expected

Developing on Windows

Have a look at our cool tutorial on developing PHP on Windows with Visual Studio Code!

Developing on Linux

Do you prefer penguins? Check out our tutorials on developing PHP on Linux with PhpStorm!

Wall of Fame

We would like to express our thanks to the following people who contributed and made the project possible:

Would you like to become a hero too? Pick an issue and send us a pull request!

delivery-sdk-php's People

Contributors

dusekdan avatar hisman avatar jancerman avatar jankonas avatar janlenoch avatar juraju-kentico avatar mosnar avatar noodlesnz avatar petrsvihlik avatar simply007 avatar tspencer244 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

delivery-sdk-php's Issues

Fix failing test

Brief bug description

Failing test: https://travis-ci.org/Kentico/delivery-sdk-php/builds/443073860

It's failing due to a removed content item in the sample project. The task is to find another content item that uses a multiple-choice element and adjust the test so that it uses new testing data.

Repro steps

  1. run 'phpunit'

Expected behavior

The library's code's ok. Just the test is missing correct testing data.

SDK tracking header

Motivation:
We'd like to start sending a header for identifying SDKs + their versions with each request from all SDKs. The header would be then tracked by App Insights and should provide us with information valuable for multiple departments in Kentico. App Insights already gather information about the user agent, but that is not always usable or present (there are some screenshots below).

In the future, the tracking should help us:

  • identify trends and make decisions regarding future SDK development like:
    • avoid breaking changes (in APIs that are highly used)
    • identify new SDK opportunities (e.g. we may see that users are making plain calls from a certain platform while not using any SDK)
    • new functionality opportunities (similarly to SDK opportunities, we may discovery that certain part of the API is not covered by SDK)
  • discover misbehavior of certain SDK versions
    • see whether users are using the latest version or if they are stuck
  • send out targeted messages about an SDK version being deprecated
  • save round-trips to customer asking about platform they're using and the SDK version (Support)

Specification:
Send the following header with each request to the Kentico Cloud Delivery API.

  • Header name: X-KC-SDKID
  • Header format: ;;
    • PackageRepositoryHost - HOST part of the package repository URI. The value can be hardcoded.
    • SDKPackageID - ID specific for the package repository. In other words, the identifier that's used when specifying the package as a dependency of the resulting application (typically in a json or xml file - package.json, *.csproj, composer.json, etc.) Sometimes the ID can consist of a vendor name and package name. The value can be hardcoded.
    • SDKVersion - version of the package (typically in a semantic version format). This information needs to be either retrieved programmatically during the runtime or hardcoded and manually updated with every release.

Examples:

X-KC-SDKID: nuget.org;KenticoCloud.Delivery;4.12.0
X-KC-SDKID: packagist.org;kentico-cloud/delivery-sdk-php;0.9.1
X-KC-SDKID: maven.org;com.kenticocloud:delivery-sdk-java;1.0.5
X-KC-SDKID: npmjs.com;kentico-cloud-delivery-typescript-sdk;2.2.2

Detect stale content

Motivation

To improve response times Delivery API might provide stale content. Stale means that there is a more recent version, but it will become available later. This information is important for developers who implement caching because stale content should have a short TTL. Developers can inspect the value of the X-Stale-Content response header. 1 indicates that content is stale. If the header is not present or it has a different value, content is not stale.

Proposed solution

Extend response models with information whether content is stale. For consistency it is recommended to use a has stale content bool property with the proper case type.

SDK timing out on sunra/php-simple-html-dom-parser

I am working on updating Stephenr85's DG sample app to use current SDK version and I have discovered a possible issue in our SDK.

Steps to reproduce:

  1. Clone my fork
  2. Run composer update and then php artisan serve
  3. Visit locally started server (probably 127.0.0.1:8000)

The page will be loading for quite some time (approximately 2*t_max-execution_time + 1-2 seconds). After maximum execution time is reached, you will be able to see PHP Fatal error that preceeds the page finally loading:
image

Research&Implement: Use PHP-DI for Dependency Injection

Dependencies like typeMapper, propertyMapper, valueConverter, *Factory could be injected using DI. If we implemented DI, we could also have a default container and get rid of method such as getModelBinder.

The goal of this task is to:

  • research whether using a DI framework such as PHP-DI for loading the dependencies in a library such as delivery-sdk-php is a good practice and how it could be implemented properly.
  • either close this issue or implement the DI, based on the findings

Resources:

Spike: Make the SDK tracking header load the library version automatically

The SDK sends a version tracking header in the following form: X-KC-SDKID: packagist.org;kentico-kontent/delivery-sdk-php;0.9.1 with every request. This was implemented in #43

Currently, the tracking header is hardcoded in the DeliveryClient.php and needs to be updated with every release

The goal of this task is to find a way of updating this version automatically (using a pre/post build action) or loading it from the composer.json somehow (after packagist sets it up during release).

We are open to any other ideas! :-)

Pagination for Taxonomies

Listing taxonomy groups supports pagination. We need to reflect that in the SDK.

{
  "taxonomies": [
    {
      "system": {
        "id": "f30c7f72-e9ab-8832-2a57-62944a038809",
        "name": "Personas",
        "codename": "personas",
        "last_modified": "2016-10-20T13:24:00.3200182Z"
      },
      "terms": [
        {
          "name": "Coffee expert",
          "codename": "coffee_expert",
          "terms": [
            {
              "name": "Barista",
              "codename": "barista",
              "terms": []
            },
            {
              "name": "Cafe owner",
              "codename": "cafe_owner",
              "terms": []
            }
          ]
        },
        {
          "name": "Coffee enthusiast",
          "codename": "coffee_enthusiast",
          "terms": [
            {
              "name": "Coffee lover",
              "codename": "coffee_lover",
              "terms": []
            },
            {
              "name": "Coffee blogger",
              "codename": "coffee_blogger",
              "terms": []
            }
          ]
        }
      ]
    },
    {
      "system": {
        "id": "d351400e-0290-87b2-1413-6c411d8ae5a4",
        "name": "Processing type",
        "codename": "processing_type",
        "last_modified": "2017-09-04T12:50:20.7857817Z"
      },
      "terms": [
        {
          "name": "Wet (Washed)",
          "codename": "wet__washed_",
          "terms": []
        },
        {
          "name": "Dry (Natural)",
          "codename": "dry__natural_",
          "terms": []
        },
        {
          "name": "Semi-dry",
          "codename": "semi_dry",
          "terms": []
        }
      ]
    },
    {
      "system": {
        "id": "79b1c5b6-30bc-d076-a236-d9ec9f1ff01b",
        "name": "Product status",
        "codename": "product_status",
        "last_modified": "2016-09-15T10:53:25.2233101Z"
      },
      "terms": [
        {
          "name": "On sale",
          "codename": "on_sale",
          "terms": []
        },
        {
          "name": "Bestseller",
          "codename": "bestseller",
          "terms": []
        }
      ]
    }
  ],
  "pagination": {
    "skip": 0,
    "limit": 3,
    "count": 3,
    "next_page": ""
  }
}

DoD:

  • unit (and/or e2e) tests
  • documentation (code examples in the readme or dedicated gh wiki page)

Custom element type support

Motivation

As new element type - Custom element - was added to Delivery output, it's needed to add its support to SDKs.
Actually, it's already added to .NET SDK and code generator

Custom element stores its value as simple string. The format of the string is free and determined by the developer who creates element.

In Delivery output custom element has type "custom"

It should be supported in generator as well.

Proposed solution

The concrete solution depends on concrete SDK implementation.
Generally, you should add Custom Element into list of supported types with type name "custom" and data type "string".
Also you should add Custom element type into tests.

Additional context

An example of Delivery output with Custom element

{

"item": {
    "system": {
        "id": "9acff635-2dc5-4402-ab10-72575d734020",
        "name": "ColorPickerElement",
        "codename": "colorpickerelement",
        "language": "default",
        "type": "colorpickertype",
        "sitemap_locations": [],
        "last_modified": "2019-01-22T09:39:39.3095575Z"
    },
    "elements": {
        "colorpicker": {
            "type": "custom",
            "name": "ColorPicker",
            "value": "#d7e119"
        }
    }
},
"modular_content": {}

}

Add support for includeTotalCount query parameter

Motivation

Allow users to render paging navigation for a list of content items.

Proposed solution

When the item listing request URL includes the includeTotalCount query string parameter, the response contains the total number of content items matching the search criteria. As a result, the client needs only one API call to fetch all information necessary to display a list of content items and the paging navigation.

To return the total number of content items, the includeTotalCount parameter must have value 1 or true or no value at all.

The total number of content items is returned in the pagination section of the response in the total_count property. Please note that if the user does not ask for the total item count, this property is not present.

Add support for the includeTotalCount parameter and also provide the total number of content items, if available. Also, please provide a warning in documentation comments that asking for the total number of content items might increase the response time and, therefore, users should use it only when they need it.

Additional context

For a reference implementation please have a look at https://github.com/Kentico/kontent-delivery-sdk-net/blob/master/Kentico.Kontent.Delivery/QueryParameters/Parameters/IncludeTotalCountParameter.cs

Create README, CONTRIBUTING, etc.

README should contain:

  • download & installation instructions (packagist...)
  • simple usage (instantiation of the client and retrieval of content items)
  • info for contributors (link to CONTRIBUTING)

Added support for content components

Motivation

The goal is to add support for content components (non-reusable content).
From the SDKs point of view, the components behave the same as regular content items. However, they are supported only in the rich-text elements.

<object type="application/kenticocloud" data-type="component" data-codename="n55afed3a_b4a3_018a_8744_3b06301b1f88"></object>

The only difference is that the value of the data-type attribute is not item but component. (There is no new endpoint for Content components in the Delivery API). The components are being sent as a part of the modular content (linked items) dictionary in the same format as the regular modular content.

Sample implementation: https://github.com/Kentico/delivery-sdk-net/pull/131/files

Checklist

  • Code follows coding conventions held in this repo
  • Automated tests have been added
  • Tests are passing
  • Docu has been updated (if applicable)
  • Temporary settings (e.g. project ID used during development and testing) have been reverted to defaults

How to test

Make sure rich-text elements containing components get resolved in the same manner as standard content items.
Testing KC project: https://qa-deliver.global.ssl.fastly.net/ab44e0cc-9302-00c3-14ce-1362a118ad2f/items

Internal reference: DC-544

Get by type then filter by element

How do we get items by type then filter e.g

  getItems((new QueryParams())->type('A') ->equals('name', 'bob'));

Are they any examples ?

Thanks

Variable $contentLink will never exist in else branch (resolveLinksUrls)

On the line 246 of ModelBinder.php, there is a following code:

foreach ($linksElements as $linkElement) {
            $elementId = $linkElement->getAttribute('data-item-id');            
            if (array_key_exists($elementId, $elementLinksMetadata)) {
                $contentLink = new ContentLink($elementId, $elementLinksMetadata[$elementId]);
                $resolvedLink = $this->contentLinkUrlResolver->resolveLinkUrl($contentLink);
            } else {
                $resolvedLink = $this->contentLinkUrlResolver->resolveBrokenLinkUrl($contentLink);
            }
            $linkElement->href = $resolvedLink;
        }

If you look closely on the only line inside else branch, you will notice that it passes $contentLink variable to resolveBrokenLinkUrl method, but the variable is not defined.

Add support for secured access to published (production) content

In coming weeks, the Delivery API will start supporting authenticated access.

In the first version of this feature, content will be secured using an API key. The developer will be able to turn the authenticated access on and off for the whole project. There will be one authentication key for the project, not multiple ones (for various user roles, for example).

Implement support for submitting the key in the form of the "Authorization" request header. The key should be sent via the Bearer scheme (with a "Bearer " prefix).

We'll provide more information once they become available. https://kenticocloud.com/roadmap#secured-delivery-api

Add support for items-feed endpoint

Motivation

Allow developers to fetch all content item variants from the new \items-feed endpoint. This offers developers a way to export an entire project no matter the size.

Proposed solution

The content is is provided in small chunks together with a continuation token for the next chunk. The continuation token is sent in X-Continuation header both for request and response. Should the response from Delivery API contain the token, there are additional items to fetch. If the request does not contain the continuation header, Delivery API will return the first chunk.
Filtering parameters are same as for items endpoint but paging and depth are not supported.
The response has also the similar structure to items endpoint but paging object is missing and modular_content contains only components.

Implementation details for consistency: (name casing should be adapted according to the rest of SDK)
Add a new method to DeliveryClient with a name GetItemsFeed(). The method should support the same filtering parameters as GetItems() except for depth, skip and limit and return a content items variants feed.
The feed contains a bool property HasMoreResults that is true if the first batch was not yet fetched or there are more items to fetch (indicated by a continuation header in the previous response). The feed also contains a method FetchNextBatch() that would retrieve the next response from \items-feed endpoint.

Additional context

See .NET SDK for reference code

Implement Link Resolvers

The goals is to create some kind of interface or event that a developer can hook into to resolve the hyperlinks in rich-text elements.

Similarly to:

DoD:

  • unit (and/or e2e) tests
  • documentation (code examples in the readme or dedicated gh wiki page)

Implement a retry policy

Add a capability of dealing with transient network outages via the following retry policy:

  • The retry policy should be enabled by default.
  • The following should be configurable (preferably via the DeliveryOptions class):
    • enable/disable the retry logic (bool)
    • maximum amount of retry attempts (int)
  • If specified, the Delivery client should retry in exponential retry intervals.
  • The interval, in milliseconds, is always calculated as a power of the number 2. The exponent is the ordinal number of the next attempt. The result is then multiplied by 100. The order is one-based. For instance, the first retry attempt interval equals to (22 * 100), the second equals to (23 * 100), etc.
  • When all retry attempts fail, the SDK should notify the client code about it, preferable via an exception.

Resolve modular content fields

Modular content should be accessible both through generic content item type and through typed models:

  • generic model
  • typed model

Generic (already working)

Imgur

Typed (TODO)

  • currently contains only codenames that need to be resolved to typed models
    Imgur

DoD:

  • unit (and/or e2e) tests
  • documentation (code examples in the readme or dedicated gh wiki page)

Improve retry policy for requests

Motivation

From February 1st, 2020 Delivery API will start enforcing rate limits to ensure fair usage by as many clients as possible. These rate limits should be high enough to work for most clients by default. However, in particular cases Delivery API might respond with 429 Too many requests. These responses will also contain the Retry-After header indicating how long the client should wait before making a follow-up request.

Proposed solution

Implement a retry policy that handles 429 Too many requests and retries the HTTP call using information from an optional Retry-After header. It can contain a date after which to retry or the seconds to delay after the response is received. We recommend a retry policy with exponential backoff and a jitter strategy to overcome peaks of similar retries coming from many clients. The retry policy should handle the following status codes:

  • 408 Request Timeout
  • 429 Too many requests
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout

Please note that both 429 Too many requests and 503 Service Unavailable responses might contain an optional Retry-After header.

Additional context

Rename modular content to linked items

Based on our vision regarding content items, we have to rename "Modular content element" to "Linked items element". From the Delivery SDK's point of view, it means that we are going to rename everything that contains "modularContent" to "linkedItems".

Checklist:

  • updated all members (methods/properties/classes/...)
  • updated .MD files
  • updated tests
  • updated github wiki

Keep in mind, that the Delivery API responses will remain the same. They'll still contain "modular_content".

Example implementation: kontent-ai/delivery-sdk-net#130

Plan your release so that the changes go live on 2018-10-03 and onwards.

Add support for image optimization

Kentico Kontent now supports image optimization. It gives developers the option of transforming images using URL parameters. The goal of this task is to implement a helper class that will make generation of image URLs easy for the developers.

The reference code can be observed in the .NET SDK.

The full specification follows:

Example

Scale
image.jpg?mode=scale&width=300
image.jpg?mode=scale&height=150
image.jpg?mode=fit&height=150&width=300

DPR
image.jpg?mode=scale&width=300&dpr=2.0

Specification

If a developer provides a parameter with invalid value or omits a parameter that is required for desired optimization, the Asset API will either ignore this parameter, or return the original asset without any optimizations.

Also, to keep our sanity, we will transform each image optimization parameter independently from others. Yes, this approach might sometimes produce surprising results. However, both Fastly and imgix are designed to handle a set of parameters that do not make sense and we are not making the situation worse.

Regarding requests to the Asset API, the idea is to go through all parameters, transform the supported ones and get rid of everything else.

To get a grasp of the image optimization You can experiment with two identical images:

rect=x,y,w,h (incompatible with crop)

- -
x is not float Nothing
x < 0.0 Nothing
y is not float Nothing
y < 0.0 Nothing
w is not float Nothing
w <= 0.0 Nothing
h is not float Nothing
h <= 0.0 Nothing
h <= 0.0 Nothing
otherwise crop={w},{h},x{x},y{y}

If the rect parameter is malformed, just ignore it.

fit=crop&crop=focalpoint&fp-x=x&fp-y=y&fp-z=z (incompatible with rect)

- -
x is not float set x as 0.5
y is not float set y as 0.5
z is not float Nothing
z <= 1.0 Nothing
1 / z < 1.0 Nothing
otherwise crop={1 / z},{1 / z},offset-x{(x * z - 0.5) / (z - 1)},offset-y{(y * z - 0.5) / (z - 1) * 100}

Both offset-x and offset-y must be clamped into range from 0 to 100.

imgix supports crop by both rectangle and focal point. Unfortunately, it is not so easy to calculate Fastly parameters. Therefore, let's declare the rect parameter more important. So, if both crop by rectangle and focal point are specified, choose the first.

fm=x

- -
x = gif format=gif
x = png format=png
x = png8 format=png8
x = jpg format=jpg
x = pjpg format=pjpg
x = webp format=webp
otherwise Nothing

fm=webp&lossless=x

- -
x = 1 format=webpll
x = true format=webpll
x = 0 format=webply
x = false format=webply
otherwise format=webp

q=x

- -
x is not float Nothing
otherwise quality={x}\

auto=x

- -
x = format auto=webp
otherwise Nothing

Local variables and related functions will be required to transform parameters.

2nd review

  • do a thorough review of the PHP SDK (especially of the content item retrieval/binding part)

Pagination for Content Types

Listing content types supports pagination. We need to reflect that in the SDK.

{
  "types": [
    {
      "system": {
        "id": "b2c14f2c-6467-460b-a70b-bca17972a33a",
        "name": "About us",
        "codename": "about_us",
        "last_modified": "2017-08-02T07:33:28.2997578Z"
      },
      "elements": {
        "facts": {
          "type": "modular_content",
          "name": "Facts"
        },
        "url_pattern": {
          "type": "url_slug",
          "name": "URL pattern"
        }
      }
    },
    {
      "system": {
        "id": "d9748663-f567-4c51-a922-c24a1d6b935a",
        "name": "Accessory",
        "codename": "accessory",
        "last_modified": "2017-08-02T07:33:39.3620325Z"
      },
      "elements": {
        "product_name": {
          "type": "text",
          "name": "Product name"
        },
        "price": {
          "type": "number",
          "name": "Price"
        },
        "image": {
          "type": "asset",
          "name": "Image"
        },
        "manufacturer": {
          "type": "text",
          "name": "Manufacturer"
        },
        "product_status": {
          "type": "taxonomy",
          "name": "Product status",
          "taxonomy_group": "product_status"
        },
        "short_description": {
          "type": "rich_text",
          "name": "Short description"
        },
        "long_description": {
          "type": "rich_text",
          "name": "Long description"
        },
        "url_pattern": {
          "type": "url_slug",
          "name": "URL pattern"
        }
      }
    },
    {
      "system": {
        "id": "b7aa4a53-d9b1-48cf-b7a6-ed0b182c4b89",
        "name": "Article",
        "codename": "article",
        "last_modified": "2017-08-02T07:33:19.8599559Z"
      },
      "elements": {
        "personas": {
          "type": "taxonomy",
          "name": "Personas",
          "taxonomy_group": "personas"
        },
        "title": {
          "type": "text",
          "name": "Title"
        },
        "teaser_image": {
          "type": "asset",
          "name": "Teaser image"
        },
        "post_date": {
          "type": "date_time",
          "name": "Post date"
        },
        "summary": {
          "type": "text",
          "name": "Summary"
        },
        "body_copy": {
          "type": "rich_text",
          "name": "Body Copy"
        },
        "related_articles": {
          "type": "modular_content",
          "name": "Related articles"
        },
        "meta_keywords": {
          "type": "text",
          "name": "Meta keywords"
        },
        "meta_description": {
          "type": "text",
          "name": "Meta description"
        },
        "url_pattern": {
          "type": "url_slug",
          "name": "URL pattern"
        }
      }
    }
  ],
  "pagination": {
    "skip": 0,
    "limit": 3,
    "count": 3,
    "next_page": "https://deliver.kenticocloud.com/975bf280-fd91-488c-994c-2f04416e5ee3/types?limit=3&skip=3"
  }
}

DoD:

  • unit (and/or e2e) tests
  • documentation (code examples in the readme or dedicated gh wiki page)

Refactor ModelBinder

The method is too complex. It should be possible to cut it to smaller pieces and make it more generic.

  • reduce cyclomatic complexity
  • add more unit tests

Mistake in README

Brief bug description

Customer reported an issue in the Readme file saying:

The "The language selection is just a matter of specifying one additional filtering parameter to the query." was directly copied and pasted into the taxonomy section without changing.

Repro steps

  1. Go to 'delivery-sdk-php/README.md'
  2. Scroll down to 'Working with taxonomies'
  3. The text was just copied from 'Getting localized items'.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.