Configuration

Imbo ships with a default configuration file that will be automatically loaded. You will have to create one or more configuration files of your own that will be automatically merged with the default configuration by Imbo. You should never have to edit the default configuration file provided by Imbo.

The configuration file(s) you need to create should simply return arrays with configuration data. All available configuration options are covered in this chapter.

Using callables in configuration

Imbo supports callables for certain configuration options: accessControl, database, eventListeners[name], resource, storage and transformationPresets. The callable receives two arguments ($request and $response) which map to the active request and response objects.

By using a callable you can extend Imbo with custom logic for most configuration options (or provide the $request or $response objects to your implementing class), such as switching storage modules based on which user performed the request. Using callables will also delay the instantiation of the classes until they are first accessed, instead of when the configuration files are loaded.

Imbo access control - accessControl

Imbo catalogs stored images under a user. To add an image to a given user, you need a public and private key pair. This pair is used to sign requests to Imbo’s API and ensures that the API can’t be accessed without knowing the private key.

Multiple public keys can be given access to a user, and you can also configure a public key to have access to several users. It’s important to note that a user does not have to be created in any way - as long as a public key is defined to have access to a given user, you’re ready to start adding images.

Public keys can be configured to have varying degrees of access. For instance, you might want one public key for write operations (such as adding and deleting images) and a different public key for read operations (such as viewing images and applying transformations to them). Access is defined on a resource basis - which basically translates to an API endpoint and an HTTP method. To retrieve an image, for instance, you would give access to the image.get resource.

Specifying a long list of resources can get tedious, so Imbo also supports resource groups - basically just a list of different resources. When creating access rules for a public key, these can be used instead of specifying specific resources.

For the private keys you can for instance use a SHA-256 hash of a random value. The private key is used by clients to sign requests, and if you accidentally give away your private key users can use it to delete all your images (given the public key it belongs to has write access). Make sure not to generate a private key that is easy to guess (like for instance the MD5 or SHA-256 hash of the public key). Imbo does not require the private key to be in a specific format, so you can also use regular passwords if you want. The key itself should never be a part of the payload sent to/from the server.

Imbo ships with a small command line tool that can be used to generate private keys for you using PHP’s openssl_random_pseudo_bytes function. The tool is located in the bin directory of the Imbo installation:

$ ./bin/imbo generate-private-key
3b98dde5f67989a878b8b268d82f81f0858d4f1954597cc713ae161cdffcc84a

Both the public and private key can be changed whenever you want as long as you remember to change them in both the server configuration and in the client you use. The user can not be changed easily as database and storage adapters use it when storing/fetching images and metadata.

Access control is managed by adapters. The simplest adapter is the Imbo\Auth\AccessControl\Adapter\SimpleArrayAdapter, which has a number of trade-offs in favor of being easy to set up. Mainly, it expects the public key to have the same name as the user it should have access to, and that the public key should be given full read+write access to all resources belonging to that user.

Note

It’s not recommended that you use the same public key for both read and write operations. Read on to see how you can create different public keys for read and read/write access.

The adapter is set up using the accessControl key in your configuration file:

<?php
return [
    // ...

    'accessControl' => new Imbo\Auth\AccessControl\Adapter\SimpleArrayAdapter([
        'some-user' => 'my-super-secret-private-key',
        'other-user' => 'other-super-secret-private-key',
    ]),

    // ...
];

It’s usually a good idea to have separate public keys for read-only and read+write operations. You can achieve this by using a more flexible access control adapter, such as the Imbo\Auth\AccessControl\Adapter\ArrayAdapter:

<?php
return [
    // ...

    'accessControl' => new Imbo\Auth\AccessControl\Adapter\ArrayAdapter([
        [
            'publicKey' => 'some-read-only-pubkey',
            'privateKey' => 'some-private-key',
            'acl' => [[
                'resources' => Imbo\Resource::getReadOnlyResources(),
                'users' => ['some-user']
            ]]
        ],
        [
            'publicKey' => 'some-read-write-pubkey',
            'privateKey' => 'some-other-private-key',
            'acl' => [[
                'resources' => Imbo\Resource::getReadWriteResources(),
                'users' => ['some-user']
            ]]
        ]
    ]),

    // ...
];

As you can see, the Imbo\Auth\AccessControl\Adapter\ArrayAdapter is much more flexible than the Imbo\Auth\AccessControl\Adapter\SimpleArrayAdapter. The above example only shows part of this flexibility. You can also provide resource groups and multiple access control rules per public key. The following example shows this more clearly:

<?php
return [
    // ...

    'accessControl' => new Imbo\Auth\AccessControl\Adapter\ArrayAdapter([
        [
            // A unique public key matching the following regular expression: [A-Za-z0-9_-]{1,}
            'publicKey' => 'some-pubkey',

            // Some form of private key
            'privateKey' => 'some-private-key',

            // Array of rules for this public key
            'acl' => [
                [
                    // An array of different resource names that the public key should have
                    // access to - see AdapterInterface::RESOURCE_* for available options.
                    'resources' => Imbo\Resource::getReadOnlyResources(),

                    // Names of the users which the public key should have access to.
                    'users' => ['some', 'users'],
                ],

                // Multiple rules can be applied in order to make a single public key have
                // different access rights on different users
                [
                    'resources' => Imbo\Resource::getReadWriteResources(),
                    'users' => ['different-user'],
                ],

                // You can also specify resource groups instead of explicitly setting them like
                // in the above examples. Note that you cannot specify both resources and group
                // in the same rule.
                [
                    'group' => 'read-stats',
                    'users' => ['user1', 'user2']
                ]
            ]
        ]
    ], [
        // Second argument to the ArrayAdapter being the available resource groups
        // Format: 'name' => ['resource1', 'resource2']
        'read-stats' => ['user.get', 'user.head', 'user.options'],
    ]),

    // ...
];

Imbo also ships with a MongoDB access control adapter, which is mutable. This means you can manipulate the access control rules on the fly, using Imbo’s API. The adapter uses the MongoDB PECL extension and the MongoDB PHP library. The following parameters are supported:

databaseName

Name of the database to use. Defaults to imbo.

server

The server string to use when connecting. Defaults to mongodb://localhost:27017.

options

Options passed to the underlying adapter. Defaults to ['connect' => true, 'timeout' => 1000]. See the manual for the MongoDB PHP library for more information.

<?php
return [
    // ...

    'accessControl' => new Imbo\Auth\AccessControl\Adapter\MongoDB(),

    // ...
];

When using a mutable access control adapter, you will need to create an initial public key that can subsequently be used to create other public keys. The easiest way to create public keys when using a mutable adapter is to utilize the add-public-key command provided by the CLI tool that Imbo is shipped with.

Database configuration - database

The database adapter you decide to use is responsible for storing metadata and basic image information, like width and height for example, along with the generated short URLs. Imbo ships with some different database adapters that you can use. Remember that you will not be able to switch the adapter whenever you want and expect all data to be automatically transferred. Choosing a database adapter should be a long term commitment unless you have migration scripts available.

In the default configuration file the MongoDB database adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a database adapter directly, or specify a closure that will return an instance of a database adapter when executed. Which database adapter to use is specified in the database key in the configuration array:

<?php
return [
    // ...

    'database' => new Imbo\Database\MongoDB(),

    // ...
);

Below you will find documentation on the different database adapters Imbo ships with.

Doctrine

This adapter uses the Doctrine Database Abstraction Layer. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the documentation for Doctrine DBAL. When using this adapter you need to create the required tables in the RDBMS first, as specified in the Database setup section.

Example

<?php
return [
    // ...

    'database' => new Imbo\Database\Doctrine([
        'dbname' => 'database',
        'user' => 'username',
        'password' => 'password',
        'host' => 'hostname',
        'driver' => 'pdo_mysql'
    ]),

    // ...
];

MongoDB

This adapter use the MongoDB PECL extension and the MongoDB PHP library to store data in MongoDB. The following parameters are supported:

databaseName

Name of the database to use. Defaults to imbo.

server

The server string to use when connecting. Defaults to mongodb://localhost:27017.

options

Options passed to the underlying adapter. Defaults to ['connect' => true, 'timeout' => 1000]. See the manual for the MongoDB PHP library for more information.

Examples

  1. Connect to a local MongoDB instance using the default databaseName:

<?php
return [
    // ...

    'database' => new Imbo\Database\MongoDB(),

    // ...
];
  1. Connect to a MongoDB replica set:

<?php
return [
    // ...

    'database' => new Imbo\Database\MongoDB([
        'server' => 'mongodb://server1,server2,server3/?replicaSet=nameOfReplicaSet',
    ]),

    // ...
];

Custom database adapter

If you need to create your own database adapter you need to create a class that implements the Imbo\Database\DatabaseInterface interface, and then specify that adapter in the configuration:

<?php
return [
    // ...

    'database' => new My\Custom\DatabaseAdapter(),

    // ...
];

You can read more about how to achieve this in the Implement your own database and/or storage adapter chapter.

Storage configuration - storage

Storage adapters are responsible for storing the original images you put into Imbo. As with the database adapter it is not possible to simply switch the adapter without having migration scripts available to move the stored images. Choose an adapter with care.

In the default configuration file the GridFS storage adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a storage adapter directly, or specify a closure that will return an instance of a storage adapter when executed. Which storage adapter to use is specified in the storage key in the configuration array:

<?php
return [
    // ...

    'storage' => new Imbo\Storage\Filesystem([
        'dataDir' => '/path/to/images',
    ]),

    // ...
];

Below you will find documentation on the different storage adapters Imbo ships with.

Amazon Simple Storage Service

This adapter stores your images in a bucket in Amazon S3. The parameters are:

key

Your AWS access key.

secret

Your AWS secret key.

bucket

The name of the bucket you want to store your images in. Imbo will not create this for you automatically.

region

The name of the region your bucket resides in.

This adapter creates subdirectories in the bucket in the same fashion as the Filesystem storage adapter stores the files on the local filesystem.

Examples

<?php
return [
    // ...

    'storage' => new Imbo\Storage\S3([
        'key' => '<aws access key>',
        'secret' => '<aws secret key>',
        'bucket' => 'my-imbo-bucket',
        'region' => 'eu-central-1',
    ]),

    // ...
];

Backblaze B2 Cloud Storage

This adapter stores your images in a bucket in the Backblaze B2 Cloud Storage. The parameters are:

accountId

Your B2 account ID.

applicationKey

Your B2 application key.

bucket

The name of the bucket you want to store your images in.

bucketId

The ID of the bucket.

Examples

<?php
return [
    // ...

    'storage' => new Imbo\Storage\B2([
        'accountId' => '<b2 account ID>',
        'applicationKey' => '<b2 application key>',
        'bucket' => 'my-imbo-bucket',
        'bucketId' => '<bucket ID>',
    ]),

    // ...
];

Filesystem

This adapter simply stores all images on the file system. It has a single parameter, and that is the base directory of where you want your images stored:

dataDir

The base path where the images are stored.

This adapter is configured to create subdirectories inside of dataDir based on the user and the checksum of the images added to Imbo. The algorithm that generates the path simply takes the three first characters of the user and creates directories for each of them, then the complete user, then a directory of each of the first characters in the image identifier, and lastly it stores the image in a file with a filename equal to the image identifier itself. For instance, an image stored under the user foobar with the image identifier 5c01e554-9fca-4231-bb95-a6eabf259b64 would be stored as <dataDir>/f/o/o/foobar/5/c/0/5c01e554-9fca-4231-bb95-a6eabf259b64.

Examples

  1. Store images in /path/to/images:

<?php
return [
    // ...

    'storage' => new Imbo\Storage\Filesystem([
        'dataDir' => '/path/to/images',
    ]),

    // ...
];

GridFS

The GridFS adapter is used to store the images in MongoDB using GridFS. This adapter has the following parameters:

databaseName

The name of the database to store the images in. Defaults to imbo_storage.

server

The server string to use when connecting to MongoDB. Defaults to mongodb://localhost:27017.

options

Options passed to the underlying adapter. Defaults to ['connect' => true, 'timeout' => 1000]. See the manual for the MongoDB PHP library for available options.

Examples

  1. Connect to a local MongoDB instance using the default databaseName:

<?php
return [
    // ...

    'storage' => new Imbo\Storage\GridFS(),

    // ...
];
  1. Connect to a replica set:

<?php
return [
    // ...

    'storage' => new Imbo\Storage\GridFS([
        'server' => 'mongodb://server1,server2,server3/?replicaSet=nameOfReplicaSet',
    ]),

    // ...
];

Custom storage adapter

If you need to create your own storage adapter you need to create a class that implements the Imbo\Storage\StorageInterface interface, and then specify that adapter in the configuration:

<?php
return [
    // ...

    'storage' => new My\Custom\StorageAdapter(),

    // ...
];

You can read more about how to achieve this in the Implement your own database and/or storage adapter chapter.

Image identifier generation - imageIdentifierGenerator

By default, Imbo will generate a random string of characters as the image identifier for added images. These are in the RegExp range [A-Za-z0-9_-] and by default, the identifier will be 12 characters long.

You can easily change the generation process to a different method.

Random string

The default, as stated above. This generator has the following parameters:

length

The length of the randomly generated string. Defaults to 12.

Usage:

<?php
return [
    // ...

    'imageIdentifierGenerator' => new Imbo\Image\Identifier\Generator\RandomString(),

    // ...
];

UUID

Generates 36-character v4 UUIDs, for instance f47ac10b-58cc-4372-a567-0e02b2c3d479. This generator does not have any parameters.

Usage:

<?php
return [
    // ...

    'imageIdentifierGenerator' => new Imbo\Image\Identifier\Generator\Uuid(),

    // ...
];

Custom generators

To create your own custom image identifier generators, simply create a class that implements Imbo\Image\Identifier\Generator\GeneratorInterface and ensure that the identifiers generated are in the character range [A-Za-z0-9_-] and are between one and 255 characters long.

HTTP cache headers - httpCacheHeaders

Imbo ships with reasonable defaults for which HTTP cache header settings it sends to clients. For some resources, however, it can be difficult to figure out a good middle ground between clients asking too often and too rarely. For instance, the images resource will change every time a new image has been added - but whether that happens once a second or once a year is hard to know.

To ensure that clients get fresh responses, Imbo sends max-age=0, must-revalidate on these kind of resources. You can however override these defaults in the configuration. For instance, if you wanted to set the max-age to 30 seconds, leave it up to the client if it should re-validate and tell intermediary proxies that this response is private, you could set the configuration to the following:

<?php
return [
    // ...

    'httpCacheHeaders' => [
        'maxAge' => 30,
        'mustRevalidate' => false,
        'public' => false,
    ],

    // ...
];

Content negotiation for images - contentNegotiateImages

By default, Imbo will do content negotiation for images. In other words, if a request is sent for an image with the Accept-header image/jpeg, it will try to deliver the image in JPEG-format.

If what you want is for images to be delivered in the format they were uploaded in, you can set contentNegotiateImages to false in the configuration. This will also ensure Imbo does not include Accept in the Vary-header for image requests, which will make caching behind reverse proxies more efficient.

You are still able to convert between formats by specifying an extension when requesting the image (.jpg, .png, .gif etc).

Rethrow any non-handled general exceptions - rethrowFinalException

If an exception occurs internally while Imbo is processing a request, the exception will be caught by the main application entry point and an appropriate error will be generated. This does however hide implementation details that can be useful if you’re doing actual development on Imbo. This value is false by default.

Setting this value to true will make Imbo rethrow the exception instead of swallowing the original exception and triggering an error. In the latter case the actual stack trace will be lost, and seeing which part of the code that actually failed will be harder in a log file.

<?php
return [
    // ...

    'rethrowFinalException' => true,

    // ...
];

Trusted proxies - trustedProxies

If you find yourself behind some sort of reverse proxy (like a load balancer), certain header information may be sent to you using special X-Forwarded-* headers. For example, the Host HTTP-header is usually used to return the requested host. But when you’re behind a proxy, the true host may be stored in an X-Forwarded-Host header.

Since HTTP headers can be spoofed, Imbo does not trust these proxy headers by default. If you are behind a proxy, you should manually whitelist your proxy. This can be done by defining the proxies IP addresses and/or using CIDR notations. Example:

<?php
return [
    // ...

    'trustedProxies' => ['192.0.0.1', '10.0.0.0/8'],

    // ...
];

Note

Not all proxies set the required X-Forwarded-* headers by default. A search for X-Forwarded-Proto <your proxy here> usually gives helpful answers to how you can add them to incoming requests.

Authentication protocol - authentication

Imbo generates access tokens and authentication signatures based on the incoming URL, and includes the protocol (by default). This can sometimes be problematic, for instance when Imbo is behind a load balancer which does not send X-Forwarded-Proto header, or if you want to use protocol-less image URLs on the client side (//imbo.host/users/some-user/images/img).

Setting the protocol option under authentication allows you to control how Imbo’s authentication should behave. The option has the following possible values:

incoming

Will try to detect the incoming protocol - this is based on $_SERVER['HTTPS'] or the X-Forwarded-Proto header (given the trustedProxies option is configured). This is the default value.

both

Will try to match based on both HTTP and HTTPS protocols and allow the request if any of them yields the correct signature/access token.

http

Will always use http as the protocol, replacing https with http in the incoming URL, if that is the case.

https

Will always use https as the protocol, replacing http with https in the incoming URL, if that is the case.

Example usage:

<?php
return [
    // ...

    'authentication' => [
        'protocol' => 'both',
    ],

    // ...
];

Event listeners - eventListeners

Imbo support event listeners that you can use to hook into Imbo at different phases without having to edit Imbo itself. An event listener is simply a piece of code that will be executed when a certain event is triggered from Imbo. Event listeners are added to the eventListeners part of the configuration array as associative arrays. If you want to disable some of the default event listeners simply specify the same key in your configuration file and set the value to null or false. Keep in mind that not all event listeners should be disabled.

Event listeners can be configured in the following ways:

  1. A string representing a class name of a class implementing the Imbo\EventListener\ListenerInteface interface:

<?php
return [
    // ...

    'eventListeners' => [
        'accessToken' => 'Imbo\EventListener\AccessToken',
    ],

    // ...
];
  1. Use an instance of a class implementing the Imbo\EventListener\ListenerInterface interface:

<?php
return [
    // ...

    'eventListeners' => [
        'accessToken' => new Imbo\EventListener\AccessToken(),
    ],

    // ...
];
  1. A closure returning an instance of a class implementing the Imbo\EventListener\ListenerInterface interface:

<?php
return [
    // ...

    'eventListeners' => [
        'accessToken' => function() {
            return new Imbo\EventListener\AccessToken();
        },
    ],

    // ...
];
  1. Use a class implementing the Imbo\EventListener\ListenerInterface interface together with an optional user filter:

<?php
return [
    // ...

    'eventListeners' => [
        'maxImageSize' => [
            'listener' => new Imbo\EventListener\MaxImageSize(1024, 768),
            'users' => [
                'whitelist' => ['user'],
                // 'blacklist' => ['someotheruser'],
            ],
            // 'params' => [ ... ]
        ],
    ],

    // ...
];

where listener is one of the following:

  1. a string representing a class name of a class implementing the Imbo\EventListener\ListenerInterface interface

  2. an instance of the Imbo\EventListener\ListenerInterface interface

  3. a closure returning an instance Imbo\EventListener\ListenerInterface

The users element is an array that you can use if you want your listener to only be triggered for some users. The value of this is an array with two elements, whitelist and blacklist, where whitelist is an array of users you want your listener to trigger for, and blacklist is an array of users you don’t want your listener to trigger for. users is optional, and per default the listener will trigger for all users.

There also exists a params key that can be used to specify parameters for the event listener, if you choose to specify the listener as a string in the listener key:

<?php
return [
    // ...

    'eventListeners' => [
        'maxImageSize' => [
            'listener' => 'Imbo\EventListener\MaxImageSize',
            'users' => [
                'whitelist' => ['user'],
                // 'blacklist' => ['someotheruser'],
            ],
            'params' => [
                'width' => 1024,
                'height' => 768,
            ]
        ],
    ],

    // ...
];

The value of the params array will be sent to the constructor of the event listener class.

  1. Use a closure directly:

<?php
return [
    // ...

    'eventListeners' => [
        'customListener' => [
            'callback' => function(Imbo\EventManager\EventInterface $event) {
                // Custom code
            },
            'events' => ['image.get'],
            'priority' => 1,
            'users' => [
                'whitelist' => ['user'],
                // 'blacklist' => ['someotheruser'],
            ],
        ],
    ],

    // ...
];

where callback is the code you want executed, and events is an array of the events you want it triggered for. priority is the priority of the listener and defaults to 0. The higher the number, the earlier in the chain your listener will be triggered. This number can also be negative. Imbo’s internal event listeners uses numbers between 0 and 100. users uses the same format as described above. If you use this method, and want your callback to trigger for multiple events with different priorities, specify an associative array in the events element, where the keys are the event names, and the values are the priorities for the different events. This way of attaching event listeners should mostly be used for quick and temporary solutions.

All event listeners will receive an event object (which implements Imbo\EventManager\EventInterface), that is described in detail in the The event object section.

Listeners added by default

The default configuration file includes some event listeners by default:

as well as event listeners for image transformations:

Read more about these listeners (and more) in the Customize your Imbo installation with event listeners and Transforming images on the fly chapters. If you want to disable any of these you could do so in your configuration file in the following way:

<?php
return [
    // ...

    'eventListeners' => [
        'accessToken' => null,
        'auth' => null,
        'statsAccess' => null,
    ],

    // ...
];

Warning

Do not disable the event listeners used in the example above unless you are absolutely sure about the consequences. Your images can potentially be deleted by anyone.

Warning

Disabling image transformation event listeners is not recommended.

Event listener initializers - eventListenerInitializers

Some event listeners might require custom initialization, and if you don’t want to do this in-line in the configuration, Imbo supports event listener initializer classes. This is handled via the eventListenerInitializers key. The value of this element is an associative array where the keys identify the initializers (only used in the configuration itself), and the values are strings representing class names, or implementations of the Imbo\EventListener\Initializer\InitializerInterface interface. If you specify strings the classes you refer to must also implement this interface.

The interface has a single method called initialize and receives instances of event listeners implementing the Imbo\EventListener\ListenerInterface interface. This method is called once for each event listener instantiated by Imbo’s event manager. Example:

<?php
// Some event listener
class Listener implements Imbo\EventListener\ListenerInterface {
    public function setDependency($dependency) {
        // ...
    }

    // ...
}

class OtherListener implements Imbo\EventListener\ListenerInterface {
    public function setDependency($dependency) {
        // ...
    }

    // ...
}

// Event listener initializer
class Initializer implements Imbo\EventListener\Initializer\InitializerInterface {
    private $dependency;

    public function __construct() {
        $this->dependency = new SomeDependency();
    }

    public function initialize(Imbo\EventListener\ListenerInterface $listener) {
        if ($listener instanceof Listener || $listener instanceof OtherListener) {
            $listener->setDependency($this->dependency);
        }
    }
}

// Configuration
return [
    'eventListeners' => [
        'customListener' => 'Listener',
        'otherCustomListener' => 'OtherListener',
    ],

    'eventListenerInitializers' => [
        'initializerForCustomListener' => 'Initializer',
    ],
];

In the above example the Initializer class will be instantiated by Imbo, and in the __construct method it will create an instance of some dependency. When the event manager creates the instances of the two event listeners these will in turn be sent to the initialize method, and the same dependency will be injected into both listeners. An alternative way to accomplish this by using Closures in the configuration could look something like this:

<?php
$dependency = new SomeDependency();

return [
    'eventListeners' => [
        'customListener' => function() use ($dependency) {
            $listener = new Listener();
            $listener->setDependency($dependency);

            return $listener;
        },
        'otherCustomListener' => function() use ($dependency) {
            $listener = new OtherListener();
            $listener->setDependency($dependency);

            return $listener;
        },
    ],
];

Imbo itself includes an event listener initializer in the default configuration that is used to inject the same instance of Imagick to all image transformations.

Note

Only event listeners specified as strings (class names) in the configuration will be instantiated by Imbo, so event listeners instantiated in the configuration array, either directly or via a Closures, will not be initialized by the configured event listener initializers.

Image transformation presets - transformationPresets

Through the configuration you can also combine image transformations to make presets (transformation chains). This is done via the transformationPresets key:

<?php
return [
    // ...

    'transformationPresets' => [
        'graythumb' => [
            'thumbnail',
            'desaturate',
        ],
        // ...
    ],

    // ...
];

where the keys are the names of the transformations as specified in the URL, and the values are arrays containing other transformation names (as used in the eventListeners part of the configuration). You can also specify hard coded parameters for the presets if some of the transformations in the chain supports parameters:

<?php
return [
    // ...

    'transformationPresets' => [
        'fixedGraythumb' => [
            'thumbnail' => [
                'width' => 50,
                'height' => 50,
            ],
            'desaturate',
        ],
        // ...
    ],

    // ...
];

By doing this the thumbnail part of the fixedGraythumb preset will ignore the width and height query parameters, if present. By only specifying for instance 'width' => 50 in the configuration the height of the thumbnail can be adjusted via the query parameter, but the width is fixed.

Note

The URLs will stay the same if you change the transformation chain in a preset. Keep this in mind if you use for instance Varnish or some other HTTP accelerator in front of your web server(s).

Custom resources and routes - resources and routes

Warning

Custom resources and routes is an experimental and advanced way of extending Imbo, and requires extensive knowledge of how Imbo works internally. This feature can potentially be removed in future releases, so only use this for testing purposes.

If you need to create a custom route you can attach a route and a custom resource class using the configuration. Two keys exists for this purpose: resources and routes:

<?php
return [
    // ...

    'resources' => [
        'users' => new ImboUsers();

        // or

        'users' => function() {
            return new ImboUsers();
        },

        // or

        'users' => 'ImboUsers',
    ],

    'routes' => [
        'users' => '#^/users(\.(?<extension>json))?$#',
    ],

    // ...
];

In the above example we are creating a route for Imbo using a regular expression, called users. The route itself will match the following three requests:

  • /users

  • /users.json

When a request is made against any of these endpoints Imbo will try to access a resource that is specified with the same key (users). The value specified for this entry in the resources array can be:

  1. a string representing the name of the resource class

  2. an instance of a resource class

  3. an anonymous function that, when executed, returns an instance of a resource class

The resource class must implement the Imbo\Resource\ResourceInterface interface to be able to response to a request.

Below is an example implementation of the ImboUsers resource used in the above configuration:

<?php
use Imbo\Resource\ResourceInterface,
    Imbo\EventManager\EventInterface,
    Imbo\Model\ArrayModel;

class ImboUsers implements ResourceInterface {
    public function getAllowedMethods() {
        return ['GET'];
    }

    public static function getSubscribedEvents() {
        return [
            'users.get' => 'get',
        ];
    }

    public function get(EventInterface $event) {
        $model = new ArrayModel();
        $model->setData(['users' => ['someuser', 'someotheruser']]);
        $event->getResponse()->setModel($model);
    }
}

This resource informs Imbo that it supports HTTP GET, and specifies a callback for the users.get event. The name of the event is the name specified for the resource in the configuration above, along with the HTTP method, separated with a dot.

In the get() method we are simply creating a list model for Imbo’s response formatter, and we are supplying a list of users to the model. When formatted as JSON the response looks like this:

{
  "users": [
    "someuser",
    "someotheruser"
  ]
}

Feel free to experiment with this feature. If you end up creating a resource that you think should be a part of Imbo, send a pull request on GitHub.

Redirect the index route - indexRedirect

The index resource (Index resource - /) simply lists some URLs related to the Imbo project. If you would rather the index resource redirect the client to some specific URL, set the indexRedirect configuration option to that URL:

<?php
return [
    // ...

    'indexRedirect' => 'https://github.com/imbo',

    // ...
];

Input loaders - inputLoaders

The inputLoaders configuration element is an associative array of input loaders. The values in the array must be strings representing a FQCN of an input loader, or an instance of an input loader. In both cases the class specified must implement the Imbo\Image\InputLoader\InputLoaderInterface interface.

The default configuration includes a “basic” input loader, that supports the following image types:

  • image/png

  • image/jpeg

  • image/gif

  • image/tiff

To add more input loaders, simply specify them in the configuration file:

<?php
return [
    // ...

    'inputLoaders' => [
        'custom-loader' => My\Custom\Loader::class,
        'another-custom-loader' => new My\Other\Custom\Loader(),
    ],

    // ...
];

The keys in the array are not used for anything in Imbo, but enables you to override default settings. The basic input loader uses the basic key as seen in the default configuration file.

Output converters - outputConverters

The outputConverters configuration element is an associative array of output converters. The values in the array must be strings representing a FQCN of an output converter, or an instance of an output converter. In both cases the class specified must implement the Imbo\Image\OutputConverter\OutputConverterInterface interface.

The default configuration includes a “basic” output converter, that supports the following image types:

  • image/png

  • image/jpeg

  • image/gif

To add more output converters, simply specify them in the configuration file:

<?php
return [
    // ...

    'outputConverters' => [
        'custom-converter' => My\Custom\Converter::class,
        'another-custom-converter' => new My\Other\Custom\Converter(),
    ],

    // ...
];

The keys in the array are not used for anything in Imbo, but enables you to override default settings. The basic output converter uses the basic key as seen in the default configuration file.