Skip to content

Instantly share code, notes, and snippets.

@muteor
Created November 8, 2011 16:30
Show Gist options
  • Save muteor/1348264 to your computer and use it in GitHub Desktop.
Save muteor/1348264 to your computer and use it in GitHub Desktop.
Storefront Refactor
<?php
namespace Storefront\Domain\Command;
abstract class AbstractCommand implements Command
{
public function __get($name)
{
$property = $name;
if (property_exists($this, $property)) {
return $this->$property;
}
throw new \Exception("Property not found: $name");
}
}
<?php
/**
* @namespace
*/
namespace Storefront\ReadModel;
use Zend_Controller_Front as FrontController,
Zend_Json as Json;
abstract class AbstractReadModel implements ReadModel
{
/**
* @var Doctrine\ORM\Query
*/
protected $currentQuery;
/**
* Get the current query as an array
*
* @return array
*/
public function asArray()
{
return $this->currentQuery->getArrayResult();
}
/**
* Get the current query as Json
*
* @return string
*/
public function asJson()
{
return Json::encode($this->asArray());
}
/**
* Get the current query as a scalar
*
* @return array
*/
public function asScalar()
{
return $this->currentQuery->getScalarResult();
}
/**
* Get the current query as a single scalar
*
* @return string
*/
public function asSingleScalar()
{
return $this->currentQuery->getSingleScalarResult();
}
/**
* Create a new query using raw DQL
*
* @param string $dql
*/
public function rawDql($dql)
{
$this->currentQuery = $this->createQuery($dql);
}
/**
* Get the query builder
*
* @return Doctrine\ORM\QueryBuilder
*/
protected function getQueryBuilder()
{
return $this->getEntityManager()->createQueryBuilder();
}
/**
* Create a new query
*
* @param string $dql
* @return Doctrine\ORM\Query
*/
protected function createQuery($dql)
{
$this->currentQuery = $this->getEntityManager()->createQuery($dql);
}
/**
* Get the entity manager (Bisna)
*
* @return Doctrine\ORM\EntityManager
*/
protected function getEntityManager()
{
$fc = FrontController::getInstance();
return $fc->getParam('bootstrap')->getResource('doctrine')->getEntityManager();
}
}
<?php
namespace Storefront\Domain\Command\Catalog\Product;
use Storefront\Domain\Command\AbstractCommand;
class CreateProduct extends AbstractCommand
{
protected $name;
protected $category;
protected $price;
public function __construct($name, $category, $price)
{
$this->name = $name;
$this->category = $category;
$this->price = $price;
}
}
<?php
namespace Storefront\ReadModel;
use Storefront\ReadModel\AbstractReadModel;
class Product extends AbstractReadModel
{
public function getProductByCategory($category)
{
$this->createQuery("SELECT p FROM Storefront\Model\Product p WHERE p.category = ?1");
$this->currentQuery->setParameter(1, $category);
return $this;
}
}
// Usage
$readModel = new Product();
$readModel->getProductByCategory('test')->asArray();
<?php
namespace Storefront\Domain\Catalog;
use Storefront\Domain\Command,
Storefront\Domain\Command\Catalog\Product as ProductCommand;
class Product
{
protected $id;
protected $name;
protected $price;
protected $category;
public function __construct($name, $category, $price)
{
$command = new ProductCommand\CreateProduct($name, $category, $price);
$this->handle($command);
}
protected function onCreateProduct(ProductCommand\CreateProduct $command)
{
$this->name = $command->name;
$this->category = $command->category;
$this->price = $command->price;
}
protected function onUpdateName(ProductCommand\UpdateName $command)
{
$this->name = $command->name;
}
public function handle(Command\Command $command)
{
$class = get_class($command);
$parts = explode('\\', $class);
$handler = 'on' . ucfirst(end($parts));
if (!method_exists($this, $handler)) {
throw new Exception\HandlerNotFoundException("No handler found for $handler");
}
return $this->$handler($command);
}
}
<?php
namespace StorefrontTest\Model\Catalog;
use Mockery as m,
Storefront\Domain\Catalog\Product,
Storefront\Domain\Command\Catalog\Product as ProductCommand;
class ProductTest extends \PHPUnit_Framework_TestCase
{
public function testCanCreateANewProduct()
{
$product = new Product('A Hat', 'A Category', 2.99);
$this->assertEquals('A Hat', $this->readAttribute($product, 'name'));
$this->assertEquals('A Category', $this->readAttribute($product, 'category'));
$this->assertEquals(2.99, $this->readAttribute($product, 'price'));
}
public function testCanUpdateProductName()
{
$product = new Product('A Hat', 'A Category', 2.99);
$command = new ProductCommand\UpdateName('A Great Hat');
$product->handle($command);
$this->assertEquals('A Great Hat', $this->readAttribute($product, 'name'));
}
}
<?php
namespace Storefront\Domain\Command\Catalog\Product;
use Storefront\Domain\Command\AbstractCommand;
class UpdateName extends AbstractCommand
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment