Installation

To install the Intent component, you will need to use Composer. Run the following command in your terminal:

composer require runopencode/intent

Intents have to be stored somewhere and this library does not impose which storage you should use. Therefore, depending on the storage of your choice, you will have to install additional dependencies as well.

For storing intents within a database table, using Doctrine Dbal:

composer require doctrine/dbal

If you want the storage table to be generated for you along with the rest of your schema, Doctrine ORM is required as well:

composer require doctrine/orm

For storing intents within a PSR-6 cache pool, any implementation will do, in example:

composer require symfony/cache

If you intend to use the provided console command for removing expired intents:

composer require symfony/console

Basic setup

In your project, you will need to initialize the storage of your choice. Storage which uses Doctrine Dbal expects a connection and, optionally, a name of the table within which intents are stored:

 1 <?php
 2
 3 declare(strict_types=1);
 4
 5 use Doctrine\DBAL\DriverManager;
 6 use RunOpenCode\Component\Intent\Storage\DbalStorage;
 7
 8 $connection = DriverManager::getConnection([
 9     'driver' => 'pdo_mysql',
10     // ...
11 ]);
12
13 $storage = new DbalStorage(
14     connection: $connection,
15     tableName: 'runopencode_intent' // Optional, this is the default value.
16 );

Do note that identifier of an intent is stored as ULID, so that type has to be registered within Doctrine as well, see Storages for details.

Storage which uses a PSR-6 cache pool expects the pool only:

1 <?php
2
3 declare(strict_types=1);
4
5 use RunOpenCode\Component\Intent\Storage\CacheStorage;
6 use Symfony\Component\Cache\Adapter\RedisAdapter;
7
8 $storage = new CacheStorage(RedisAdapter::createConnection('redis://localhost'));

See Storages for details about the provided storages and about implementing your own.

Using the interface

Concrete implementation of the storage should not be used as a dependency in your classes. Instead, use IntentStorageInterface, which will allow you to change the storage without changing the code which depends on it:

 1 <?php
 2
 3 declare(strict_types=1);
 4
 5 namespace App\Security;
 6
 7 use RunOpenCode\Component\Intent\Contract\IntentStorageInterface;
 8
 9 final readonly class PasswordResetService
10 {
11     public function __construct(private IntentStorageInterface $storage)
12     {
13         // noop.
14     }
15 }

Symfony integration

If you are using Symfony framework, you should use the runopencode/intent-bundle package which registers the storage of your choice as a service within your container and provides configuration options.

See the Intent Bundle documentation for more information about Symfony integration.