Customizing Clients
===================

Logger injection
----------------

As the ``Rackspace`` client extends the ``OpenStack`` client, they both support
passing ``$options`` as an array via the constructor's third parameter. The
options are passed as a config to the `Guzzle` client, but also allow to inject
your own logger.

Your logger should implement the ``Psr\Log\LoggerInterface`` `as defined in
PSR-3 <https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md>`_.
One example of a compatible logger is `Monolog <https://github.com/Seldaek/monolog>`_.
When the client does create a service, it will inject the logger if one is
available.

To inject a ``LoggerInterface`` compatible logger into a new client:

.. code-block:: php

  use Monolog\Logger;
  use OpenCloud\OpenStack;

  // create a log channel
  $logger = new Logger('name');

  $client = new OpenStack('http://identity.my-openstack.com/v2.0', array(
    'username' => 'foo',
    'password' => 'bar'
  ), array(
    'logger' => $logger,
  ));


Authentication
--------------

The client does not automatically authenticate against the API when it is
instantiated - it waits for an API call. When this happens, it checks
whether the current “token” has expired, and (re-)authenticates if
necessary.

You can force authentication, by calling:

.. code-block:: php

  $client->authenticate();

If the credentials are incorrect, a ``401`` error will be returned. If
credentials are correct, a ``200`` status is returned with your Service
Catalog.


Service Catalog
---------------

The Service Catalog is returned on successful authentication, and is
composed of all the different API services available to the current
tenant. All of this functionality is encapsulated in the ``Catalog``
object, which allows you greater control and interactivity.

.. code-block:: php

  /** @var OpenCloud\Common\Service\Catalog */
  $catalog = $client->getCatalog();

  // Return a list of OpenCloud\Common\Service\CatalogItem objects
  foreach ($catalog->getItems() as $catalogItem) {

      $name = $catalogItem->getName();
      $type = $catalogItem->getType();

      if ($name == 'cloudServersOpenStack' && $type == 'compute') {
          break;
      }

      // Array of OpenCloud\Common\Service\Endpoint objects
      $endpoints = $catalogItem->getEndpoints();
      foreach ($endpoints as $endpoint) {
          if ($endpoint->getRegion() == 'DFW') {
              echo $endpoint->getPublicUrl();
          }
      }
  }

As you can see, you have access to each Service’s name, type and list of
endpoints. Each endpoint provides access to the specific region, along
with its public and private endpoint URLs.


Default HTTP headers
--------------------

To set default HTTP headers:

.. code-block:: php

  $client->setDefaultOption('headers/X-Custom-Header', 'FooBar');


User agents
-----------

php-opencloud will send a default ``User-Agent`` header for every HTTP
request, unless a custom value is provided by the end-user. The default
header will be in this format:

  User-Agent: OpenCloud/xxx cURL/yyy PHP/zzz

where ``xxx`` is the current version of the SDK, ``yyy`` is the current
version of cURL, and ``zzz`` is the current PHP version. To override
this default, you must run:

.. code-block:: php

  $client->setUserAgent('MyCustomUserAgent');

which will result in:

  User-Agent: MyCustomUserAgent

If you want to set a *prefix* for the user agent, but retain the default
``User-Agent`` as a suffix, you must run:

.. code-block:: php

  $client->setUserAgent('MyPrefix', true);

which will result in:

  User-Agent: MyPrefix OpenCloud/xxx cURL/yyy PHP/zzz

where ``$client`` is an instance of ``OpenCloud\OpenStack`` or
``OpenCloud\Rackspace``.


Other functionality
-------------------

For a full list of functionality provided by Guzzle, please consult the
`official documentation`_.

.. _official documentation: http://docs.guzzlephp.org/en/latest/http-client/client.html
