Store with Doctrine

In the previous example we showed how to store a process to file.
In this example we show how to store it to MySQL using Doctrine ORM library. Whenever the engine changes the state of a process or token it is persisted using DoctrineDAL (Data access layer).

Setup


mkdir ~/pvm-store-to-mysql
cd ~/pvm-store-to-mysql
composer req formapro/pvm:0.4.x-dev makasim/values:0.5.x-dev makasim/yadm:0.5.x-dev
composer req doctrine/orm:^2.6

# create such file with the code below
php store-to-mysql.php

Result

store-to-mysql.php

Connected to mysql://root:rootpass@mysql/pvm_demo
a_task
Found the process in DB

store-to-mysql.php


<?php
use Acme\StoreToDoctrine\OrmProcess;
use 
Acme\StoreToDoctrine\OrmToken;
use 
Doctrine\Common\Cache\ArrayCache;
use 
Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
use 
Doctrine\ORM\Configuration;
use 
Doctrine\ORM\EntityManager;
use 
Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
use 
Doctrine\ORM\Tools\SchemaTool;
use 
Formapro\Pvm\DefaultBehaviorRegistry;
use 
Formapro\Pvm\Doctrine\DoctrineDAL;
use 
Formapro\Pvm\ProcessEngine;
use 
Formapro\Pvm\Token;
use 
Formapro\Pvm\ProcessBuilder;

require_once 
__DIR__.'/vendor/autoload.php';
require_once 
__DIR__.'/OrmProcess.php';
require_once 
__DIR__.'/OrmToken.php';

$config = new Configuration();
$config->setAutoGenerateProxyClasses(true);
$config->setProxyDir(\sys_get_temp_dir());
$config->setProxyNamespace('Proxies');
$config->setQueryCacheImpl(new ArrayCache());
$config->setMetadataCacheImpl(new ArrayCache());

$driver = new MappingDriverChain();

$annotationDriver $config->newDefaultAnnotationDriver([__DIR__], false);
$driver->addDriver($annotationDriver'Acme\StoreToDoctrine');

$xmlDriver = new SimplifiedXmlDriver([
    
realpath(__DIR__.'/vendor/formapro/pvm/src/Doctrine/mapping') => 'Formapro\Pvm\Doctrine',
]);
$driver->addDriver($xmlDriver'Formapro\Pvm\Doctrine');

$config->setMetadataDriverImpl($driver);
$connection = ['url' => getenv('MYSQL_DSN')];

$em EntityManager::create($connection$config);
echo 
'Connected to '.getenv('MYSQL_DSN').PHP_EOL;

$schemaTool = new SchemaTool($em);
$schemaTool->updateSchema($em->getMetadataFactory()->getAllMetadata());

$doctrineDal = new DoctrineDAL($emOrmProcess::class, OrmToken::class);

$process = (new ProcessBuilder())
    ->
createNode('a_task''print_label')->end()
    ->
createStartTransition('a_task')->end()

    ->
getProcess()
;

$registry = new DefaultBehaviorRegistry([
    
'print_label' => function(Token $token) {
        echo 
$token->getTo()->getId().PHP_EOL;
    },
]);

$engine = new ProcessEngine($registry$doctrineDal);

$token $engine->createTokenFor($process->getStartTransition());
$engine->proceed($token);

if (
$em->find(OrmProcess::class, $process->getId())) {
    echo 
'Found the process in DB'.PHP_EOL;
} else {
    echo 
'the process was not found in DB'.PHP_EOL;
}

OrmProcess.php


<?php
namespace Acme\StoreToDoctrine;

use 
Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class OrmProcess extends \Formapro\Pvm\Doctrine\Process
{
}

OrmToken.php


<?php
namespace Acme\StoreToDoctrine;

use 
Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class OrmToken extends \Formapro\Pvm\Doctrine\Token
{

}
{
    "schema": "http:\/\/pvm.forma-pro.com\/schemas\/Process.json",
    "id": "482707f2-87bd-40ad-abd0-fd41b24e70b7",
    "nodes": {
        "a_task": {
            "schema": "http:\/\/pvm.forma-pro.com\/schemas\/Node.json",
            "id": "a_task",
            "behavior": "print_label"
        }
    },
    "transitions": {
        "92e24a5c-6c22-4883-a312-0fef56ff8ec6": {
            "id": "92e24a5c-6c22-4883-a312-0fef56ff8ec6",
            "weight": 1,
            "async": false,
            "active": true,
            "schema": "http:\/\/pvm.forma-pro.com\/schemas\/Transition.json",
            "to": "a_task"
        }
    },
    "inTransitions": {
        "a_task": [
            "92e24a5c-6c22-4883-a312-0fef56ff8ec6"
        ]
    }
}