romm / configuration-object
Transform any configuration plain array into a dynamic and configurable object structure, and pull apart configuration handling from the main logic of your script. Use provided services to add more functionality to your objects: cache, parents, persistence and much more.
Installs: 29 258
Dependents: 2
Suggesters: 0
Security: 0
Stars: 5
Watchers: 2
Forks: 4
Open Issues: 3
Type:typo3-cms-extension
Requires
- php: ^7.1
- typo3/cms-beuser: ^9.5
- typo3/cms-core: ^9.5
Requires (Dev)
- mikey179/vfsstream: ^1.6
- satooshi/php-coveralls: ^1.0
- typo3/testing-framework: ^4.0
Replaces
- configuration_object: 2.0.0
- typo3-ter/configuration-object: 2.0.0
README
Warning This package is no longer maintained. As a more stable alternative, you may use package
cuyz/valinor
.
ℹ️ Show more info
❗ This PHP library has been developed for TYPO3 CMS and is intended to TYPO3 extension developers.
➡️ You can find the whole documentation on the TYPO3 official website, or even download the 🔗PDF version.
Introduction
Configuration Object provides powerful tools for handling configuration trees, by converting any configuration plain array (which can come from sources like TypoScript, JSON, XML) into a much more flexible PHP object structure. Its principal goal is to pull apart the configuration handling from the main logic of an application, so the script can focus on using the already validated configuration during its whole process.
Problem
When a script uses a configuration tree to handle parts of an application, this tree is often analyzed step by step during the script execution; if a value contains a mistake, the script can be forced to stop, too early (the whole process did not run entirely) but also too late (some sensitive operations may already have run). Moreover, the deeper the configuration tree is, the harder it is to handle and prevent all the possible configuration mistakes.
When it comes to configuration which may be customized by any third-party user (which happens often in TYPO3 thanks to TypoScript), validation rules have to be well thought and strong to prevent the user from breaking your own API scripts because of a configuration mistake.
Solution
Use Configuration Object to export the handling of your configuration: let the whole creation and validation processes be managed outside of your application, and enjoy the many other features provided by the API (cache management, parents, persistence and more).
It is simple, fast and reliable.
Example
Imagine you have this configuration array:
$myCompany = [ 'name' => 'My Company', 'employees' => [ [ 'name' => 'John Doe', 'gender' => 'Male', 'email' => 'john.doe@my-company.com' ], [ 'name' => 'Jane Doe', 'gender' => 'Female', 'email' => 'jane.doe@my-company.com' ] ] ];
While this example is quite simple, it allows us to understand easily how this API works.
Below stands an example of how this configuration could look like using Configuration Object API.
You can see that two services are used:
-
Cache service
It will store the whole company object, and its sub-objects, in a cache entry after they have been created. This will improve performances for next times the object must be fetched.
-
Parents service
With this service, the class
Employee
is able to retrieve the data from its parent (the classCompany
). In this example, we use it to dynamically generate an email address for the employee, if none was assigned.
namespace MyVendor\MyExtensions\Company; use Romm\ConfigurationObject\ConfigurationObjectInterface; use Romm\ConfigurationObject\Traits\ConfigurationObject\DefaultConfigurationObjectTrait; use Romm\ConfigurationObject\Traits\ConfigurationObject\MagicMethodsTrait; use MyVendor\MyExtensions\Model\Company\Employee; class Company implements ConfigurationObjectInterface { use DefaultConfigurationObjectTrait; use MagicMethodsTrait; const CACHE_NAME = 'cache_company'; /** * @var string * @validate NotEmpty */ protected $name; /** * @var \ArrayObject<MyVendor\MyExtensions\Company\Employee> */ protected $employees; /** * @return ServiceFactory */ public static function getConfigurationObjectServices() { return ServiceFactory::getInstance() ->attach(ServiceInterface::SERVICE_CACHE) ->setOption(CacheService::OPTION_CACHE_NAME, self::CACHE_NAME) ->attach(ServiceInterface::SERVICE_PARENTS); } }
namespace MyVendor\MyExtensions\Company; use Romm\ConfigurationObject\Service\Items\Parents\ParentsTrait; use Romm\ConfigurationObject\Traits\ConfigurationObject\MagicMethodsTrait; class Employee { use ParentsTrait; use MagicMethodsTrait; /** * @var string * @validate NotEmpty */ protected $name; /** * @var string * @validate NotEmpty * @validate Romm.ConfigurationObject:HasValues(values=Male|Female) */ protected $gender; /** * @var string * @validate EmailAddress */ protected $email; /** * Returns the email of the employee. * * If the email was not registered, a default one is assigned to * him, based on its name and its company name. * * Example: `John Doe` of the company `My Company` will be assigned * the default email: `john.doe@my-company.com`. * * @return string */ public function getEmail() { if (null === $this->email && $this->hasParent(Company::class) ) { $sanitizedEmployeeName = SomeUtility::sanitizeStringForEmail($this->getName()); $company = $this->getParent(Company::class); $sanitizedCompanyName = SomeUtility::sanitizeStringForEmail($company->getName(), '-'); $this->email = vprintf( '%s@%s.com', [$sanitizedEmployeeName, $sanitizedCompanyName] ); } return $this->email; } }