Menu

Creating Your first PHP annotation with Maslosoft Addendum

Configure Project Skip this part if You know how to do this

First of all, we need to install addendum, by using following command

composer require maslosoft/addendum

Then configure autoloading for our our project, by adding psr-4 autoloader configuration to composer.json:

{
"require": {
"maslosoft/addendum": "^5.0"
},
"autoload": {
"psr-4": {
"Maslosoft\\Guides\\Addendum\\": "src"
}
}
}

Now run composer install, to generate autoloading. Now we have set up base for our project. There still need to be added runtime folder with write permissions for user invoking php scripts - either command line user or web server user when used in browser. Addendum will try to create it.

Let's configure Addendum engine itself. We will create additional bootstrap.php with basic addendum setup - we add annotations namespace with EmbeDi dependency injection - and autoloader require instruction.

Recommended way is to define constant with namespace value in one of annotations, and then use that constant. Resulting bootstrap file:

<?php

use Maslosoft\Addendum\Addendum;
use Maslosoft\EmbeDi\Adapters\ArrayAdapter;
use Maslosoft\EmbeDi\EmbeDi;
use Maslosoft\Guides\Addendum\Annotations\KindAnnotation;

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

$config = [
'addendum' => [
// Addendum main class
'class' => Addendum::class,
// Check for modifications
'checkMTime' => true,
// Namespaces of our annotations
'namespaces' => [
KindAnnotation::Ns
]
]
];
EmbeDi::fly()->addAdapter(new ArrayAdapter($config));
254

Creating annotation class read from begining to learn about configuration

Having addendum configured, let's create annotation class. This will allow us to use @ notation on our project classes. As each annotation is in fact class, which has some simple logic to set up metadata container. This container will be used to obtain values configured by annotations. Please not that this values might be different than raw values on @ notations. As value returned by meta container is solely dependent on values set by annotation definition.

This way, we have opportunity to set initial logic in annotation, thus having already prepared and cached values returned by metadata container. To obtain access to container for currently process class, there getEntity is method in annotation. This returns container instance, which can be configured with any property required.

It is recommended to inherit from MetaAnnotation, as it's prepared to work with built-in metadata container:

<?php

namespace Maslosoft\Guides\Addendum\Annotations;

use Maslosoft\Addendum\Collections\MetaAnnotation;

class KindAnnotation extends MetaAnnotation
{

const Ns = __NAMESPACE__;

public $value = null;

public function init()
{
// Set annotation value to kind property
$this->getEntity()->kind = $this->value;
// We can also set any other properties
$this->getEntity()->hasKind = true;
}
}

As this is single value annotation, we defined $value property, which will have value of @Kind when placed on our model class:

<?php

namespace Maslosoft\Guides\Addendum\Models;

use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
use Maslosoft\Guides\Addendum\Interfaces\EquipmentTypes;

/**
* @Kind(EquipmentTypes::Playable)
* @see EquipmentTypes
* @author Piotr Maselkowski <pmaselkowski at gmail.com>
*/
class Instrument implements AnnotatedInterface
{

}

Above annotation value uses constant defined in EquipmentTypes interface. It is defined at class declaration, so it will be available on metadata of type. To check if it's working properly, try to get this value:

<?php

require 'bootstrap.php';

use Maslosoft\Addendum\Collections\Meta;
use Maslosoft\Guides\Addendum\Models\Instrument;

$meta = Meta::create(Instrument::class)->type();

echo $meta->kind . PHP_EOL;
echo $meta->hasKind . PHP_EOL;

This should display values defined by @Kind annotation class, in this case playable and hasKind. See this repository first annotation in Maslosoft Addendum example.