-
Notifications
You must be signed in to change notification settings - Fork 15
Customizations
As alluded to in the articles Library overview and Loader and name lookup, you can overwrite (and customize) any class in the library. This page explains how that works in detail and contains guides for commonly used customizations.
Any custom classes go in the directory and namespace FACTFinder\Custom
. There are basically two ways to customize the library.
Any class (apart from \FACTFinder\Loader
) in the library can be replaced with a custom implementation. Simply add a class of the same name to the Custom
directory/namespace (or rather its appropriate subdirectory/subnamespace) and inherit from the class you want to replace.
Important: The file name and path must correspond to the class name and namespace!
Example: Say you want to make changes to \FACTFinder\Core\Server\UrlBuilder
. Add a class \FACTFinder\Custom\Core\Server\UrlBuilder
in the file src/FACTFinder/Custom/Core/Server/UrlBuilder.php
inheriting from the above class. Now the loader will return instances of your class, whenever someone requests FF::getInstance('Core\Server\UrlBuilder')
.
However, this approach should be only necessary in rare cases. Most customization needs can be dealt with by the next section.
Several parts of the library have been designed with customization in mind. These all inherit from an Abstract...
class or implement some ...Interface
and are never instantiated within the library (but passed in as constructor arguments instead or used only externally).
In most cases, you can simply add your own implementation of the abstract class or interface, and put it in some directory/namespace under Custom
. In this case, you don't even need to conform to the namespace structure of the library, although that would certainly be cleaner.
The library provides the following abstract classes and interfaces:
Adapter\AbstractAdapter
Core\AbstractEncodingConverter
Core\ConfigurationInterface
Core\Server\AbstractDataProvider
Core\Server\RequestFactoryInterface
Util\CurlInterface
Util\LoggerInterface
The two classes in Core\Server
will usually be implemented together. As an example, if you want to handle your server communication via sockets instead of using cURL, you could create the files
src/FACTFinder/Custom/Core/Server/SocketDataProvider.php
src/FACTFinder/Custom/Core/Server/SocketRequestFactory.php
containing the classes
\FACTFinder\Custom\Core\Server\SocketDataProvider
extends \FACTFinder\Core\Server\AbstractDataProvider
\FACTFinder\Custom\Core\Server\SocketRequestFactory
implements \FACTFinder\Core\Server\RequestFactoryInterface
respectively. You can then create a new request factory using sockets with FF::getInstance('Core\Server\SocketRequestFactory')
. Note that there is no need to include Custom
in the class identifier passed to the loader.
To see how to implement each of the classes, refer to their required interfaces and look at the existing implementations.
A few common customization examples follow.
If you don't like adding log4php as a dependency to your project, or you already have your logging system in place, you can write your own logger. Add a file src/FACTFinder/Custom/Util/MyLogger.php
containing
<?php
namespace FACTFinder\Custom\Util;
class MyLogger implements LoggerInterface
{
/* your implementation here */
};
In particular, you need to implement the methods fatal
, error
, warn
, info
, debug
and trace
which all take a string parameter (the message to be logged). Semantically these correspond to increasingly fine-grained logging levels. How you determine the currently active logging level is up to you.
You also need to implement a static method getLogger
which also takes a string parameter, being the name of the logger. This name uses log4php's semantics and will be the fully-qualified class name of the class instantiating the logger. You can use this name to load a specific configuration for the given class or its namespace or just ignore the name and always returned the same logger or identical instances.
Chances are your shop already has some configuration system in place, which you'd like to use for the library as well: either you already have an XML- or JSON-configuration file and would just like to add a section for the library, or you load your configuration from a database (for instance, the Magento shop system does this).
In the case of an existing XML file you may be lucky enough to be able to use the XmlConfiguration
class provided in the library. The file's root element name is arbitrary, and the library configuration goes into a second-level element whose name can be specified. So if you can modify your configuration to look like either
<?xml ... ?>
<configuration>
<!-- your existing configuration here -->
<fflibrary>
<!-- additional library configuration here -->
</fflibrary>
</configuration>
or
<?xml ... ?>
<webconfig>
<!-- your existing configuration here -->
<fflibrary>
<!-- additional library configuration here -->
</fflibrary>
</webconfig>
you can go ahead and use the existing configuration class like
FF::getInstance('Core\XmlConfiguration',
$fileName,
'fflibrary');
If your XML configuration format doesn't permit putting the library's configuration in such a place or if you are using an entirely different configuration mechanism, you'll have to provide your own configuration implementation. This is very similar to writing your own logger.
Add a file src/FACTFinder/Custom/Core/MyConfiguration.php
containing
<?php
namespace FACTFinder\Custom\Core;
class MyConfiguration implements ConfigurationInterface
{
/* your implementation here */
};
This interface requires quite a lot of methods, so make sure you implement all of them (please refer to to the interface's source file for a complete list).