Skip to content
This repository has been archived by the owner on Jul 22, 2022. It is now read-only.

Commit

Permalink
Add sonata.payment.generator.postgres service (#418)
Browse files Browse the repository at this point in the history
Update docs for sonata.payment.generator.postgres
  • Loading branch information
azlotnikov authored and OskarStark committed Mar 22, 2017
1 parent 0e25bdc commit 08ef8e1
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/reference/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ Follow these instructions:
selector: sonata.payment.selector.simple
# service which generate the correct order and invoice number
generator: sonata.payment.generator.mysql
generator: sonata.payment.generator.mysql # or sonata.payment.generator.postgres
transformers:
order: sonata.payment.transformer.order
Expand Down
105 changes: 105 additions & 0 deletions src/Component/Generator/PostgresReference.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\Component\Generator;

use Sonata\Component\Invoice\InvoiceInterface;
use Sonata\Component\Order\OrderInterface;
use Symfony\Bridge\Doctrine\RegistryInterface;

final class PostgresReference implements ReferenceInterface
{
/**
* @var RegistryInterface
*/
private $registry;

public function __construct(RegistryInterface $registry)
{
$this->registry = $registry;
}

/**
* {@inheritdoc}
*/
public function invoice(InvoiceInterface $invoice)
{
if (!$invoice->getId()) {
throw new \RuntimeException('The invoice is not persisted into the database');
}

$this->generateReference($invoice,
$this->registry->getManager()->getClassMetadata(get_class($invoice))->table['name']);
}

/**
* {@inheritdoc}
*/
public function order(OrderInterface $order)
{
if (!$order->getId()) {
throw new \RuntimeException('The order is not persisted into the database');
}

$this->generateReference($order,
$this->registry->getManager()->getClassMetadata(get_class($order))->table['name']);
}

/**
* @param mixed $object
* @param string $tableName
*
* @throws \Exception
*
* @return string
*/
protected function generateReference($object, $tableName)
{
$date = new \DateTime();

$sql = sprintf(
"SELECT count(id) as counter FROM %s WHERE created_at >= '%s' AND reference IS NOT NULL",
$tableName,
$date->format('Y-m-d')
);

$this->registry->getConnection()->exec(sprintf('BEGIN WORK'));

$this->registry->getConnection()->exec(sprintf('LOCK TABLE %s IN EXCLUSIVE MODE', $tableName));

try {
$statement = $this->registry->getConnection()->query($sql);
$row = $statement->fetch();

$reference = sprintf('%02d%02d%02d%06d',
$date->format('y'),
$date->format('n'),
$date->format('j'),
$row['counter'] + 1
);

$this->registry->getConnection()->update(
$tableName,
array('reference' => $reference),
array('id' => $object->getId())
);
$object->setReference($reference);
} catch (\Exception $e) {
$this->registry->getConnection()->exec(sprintf('ROLLBACK WORK'));

throw $e;
}

$this->registry->getConnection()->exec(sprintf('COMMIT WORK'));

return $reference;
}
}
4 changes: 4 additions & 0 deletions src/PaymentBundle/Resources/config/generator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sonata.payment.generator.mysql.class">Sonata\Component\Generator\MysqlReference</parameter>
<parameter key="sonata.payment.generator.postgres.class">Sonata\Component\Generator\PostgresReference</parameter>
</parameters>
<services>
<service id="sonata.payment.generator.mysql" class="%sonata.payment.generator.mysql.class%">
<argument type="service" id="doctrine"/>
</service>
<service id="sonata.payment.generator.postgres" class="%sonata.payment.generator.postgres.class%">
<argument type="service" id="doctrine"/>
</service>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Full Configuration Options
selector: sonata.payment.selector.simple
# service which generate the correct order and invoice number
generator: sonata.payment.generator.mysql
generator: sonata.payment.generator.mysql # or sonata.payment.generator.postgres
transformers:
order: sonata.payment.transformer.order
Expand Down
82 changes: 82 additions & 0 deletions tests/Component/Generator/PostgresReferenceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\Component\Tests\Generator;

use Doctrine\ORM\Mapping\ClassMetadata;
use Sonata\Component\Generator\PostgresReference;
use Sonata\Tests\Helpers\PHPUnit_Framework_TestCase;

/**
* @author Anton Zlotnikov <exp.razor@gmail.com>
*/
class PostgresReferenceTest extends PHPUnit_Framework_TestCase
{
public function testInvoice()
{
$invoice = new InvoiceMock();
$postgresReference = $this->generateNewObject();

$this->expectException('\RuntimeException', 'The invoice is not persisted into the database');
$postgresReference->invoice($invoice);

$invoice->setId(13);

try {
$this->assertNull($postgresReference->invoice($invoice));
} catch (\Exception $e) {
$this->fail('->invoice() should return a NULL value but should now throw an \Exception');
}
}

public function testOrder()
{
$order = new OrderMock();
$postgresReference = $this->generateNewObject();

$this->expectException('\RuntimeException', 'The order is not persisted into the database');
$postgresReference->order($order);

$order->setId(13);

try {
$this->assertNull($postgresReference->order($order));
} catch (\Exception $e) {
$this->fail('->order() should return a NULL value but should not throw an \Exception');
}
}

/**
* @return \Sonata\Component\Generator\PostgresReference
*/
private function generateNewObject()
{
$metadata = new ClassMetadata('entityName');
$metadata->table = array('name' => 'tableName');

$connection = $this->createMock('Doctrine\DBAL\Connection');

$em = $this->createMock('Doctrine\ORM\EntityManager');
$em->expects($this->any())
->method('getClassMetadata')
->will($this->returnValue($metadata));

$connection->expects($this->any())
->method('query')
->will($this->returnValue(new \PDOStatement()));

$registry = $this->createMock('Symfony\Bridge\Doctrine\RegistryInterface');
$registry->expects($this->any())->method('getManager')->will($this->returnValue($em));
$registry->expects($this->any())->method('getConnection')->will($this->returnValue($connection));

return new PostgresReference($registry);
}
}

0 comments on commit 08ef8e1

Please sign in to comment.