-
Notifications
You must be signed in to change notification settings - Fork 41
Add chain mapper implementation #71
Changes from 2 commits
62a74d3
71120bd
d10bef1
9625fc5
fe810de
88fe97e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,8 +10,11 @@ | |
|
||
use Doctrine\Common\Persistence\ObjectManager; | ||
use Doctrine\Common\Persistence\ManagerRegistry; | ||
use Doctrine\Common\Persistence\Mapping\MappingException; | ||
use Midgard\CreatePHP\RdfChainableMapperInterface; | ||
use Midgard\CreatePHP\Entity\EntityInterface; | ||
use Midgard\CreatePHP\Entity\PropertyInterface; | ||
use Midgard\CreatePHP\Type\TypeInterface; | ||
|
||
/** | ||
* Base mapper for doctrine, removing the proxy class names in canonicalClassName | ||
|
@@ -20,7 +23,7 @@ | |
* | ||
* @package Midgard.CreatePHP | ||
*/ | ||
abstract class BaseDoctrineRdfMapper extends AbstractRdfMapper | ||
abstract class BaseDoctrineRdfMapper extends AbstractRdfMapper implements RdfChainableMapperInterface | ||
{ | ||
/** @var ObjectManager */ | ||
protected $om; | ||
|
@@ -58,9 +61,10 @@ public function store(EntityInterface $entity) | |
* | ||
* use getRealClass if className names a doctrine proxy class. | ||
*/ | ||
public function canonicalName($className) | ||
public function objectToName($object) | ||
{ | ||
$refl = new \ReflectionClass($className); | ||
$refl = new \ReflectionClass($object); | ||
$className = $refl->getName(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as we have the object now, we should not use reflection but instead simply do this (no need even for an "if")
(and lets add a use statement for Doctrine\Common\Util\ClassUtils) |
||
if (in_array('Doctrine\\Common\\Persistence\\Proxy', $refl->getInterfaceNames())) { | ||
$className = \Doctrine\Common\Util\ClassUtils::getRealClass($className); | ||
} | ||
|
@@ -94,4 +98,28 @@ public function setPropertyValue($object, PropertyInterface $property, $value) | |
|
||
return parent::setPropertyValue($object, $property, $value); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function supports($object) | ||
{ | ||
return $this->om->contains($object); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function supportsCreate(TypeInterface $type) | ||
{ | ||
$name = $this->getTypeMapKey($type); | ||
if (isset($this->typeMap[$name])) { | ||
try { | ||
$metadata = $this->om->getClassMetadata($this->typeMap[$name]); | ||
return is_object($metadata); | ||
} catch (MappingException $e) { } | ||
} | ||
|
||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
<?php | ||
|
||
namespace Midgard\CreatePHP\Mapper; | ||
|
||
|
||
use Midgard\CreatePHP\RdfChainableMapperInterface; | ||
use Midgard\CreatePHP\RdfMapperInterface; | ||
use Midgard\CreatePHP\Entity\PropertyInterface; | ||
use Midgard\CreatePHP\Entity\CollectionInterface; | ||
use Midgard\CreatePHP\Type\TypeInterface; | ||
use Midgard\CreatePHP\Entity\EntityInterface; | ||
|
||
use \RuntimeException; | ||
|
||
/** | ||
* Looks at all registered mappers to find one that can handle objects. | ||
* | ||
* @package Midgard.CreatePHP | ||
*/ | ||
class ChainRdfMapper implements RdfMapperInterface | ||
{ | ||
/** | ||
* All the registered mappers | ||
* | ||
* @var RdfMapperInterface[] | ||
*/ | ||
private $mappers = array(); | ||
|
||
/** | ||
* Mappers index by the spl_object_hash of objects created by CreatePHP | ||
* | ||
* @var RdfMapperInterface[] | ||
*/ | ||
private $createdObjects = array(); | ||
|
||
/** | ||
* Register a mapper with a key. The key will be prefixed to all subjects. | ||
* | ||
* @param RdfChainableMapperInterface $mapper | ||
* @param string $mapperKey | ||
*/ | ||
public function registerMapper(RdfChainableMapperInterface $mapper, $mapperKey) | ||
{ | ||
$this->mappers[$mapperKey] = $mapper; | ||
} | ||
|
||
/** | ||
* Get the mapper than can handle object. | ||
* | ||
* @param mixed $object | ||
* @return RdfChainableMapperInterface | ||
* @throws RuntimeException when no mapper can handle the object | ||
*/ | ||
protected function getMapperForObject($object) | ||
{ | ||
foreach ($this->mappers as $mapper) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we follow symfony codestyle, this |
||
if ($mapper->supports($object)) { | ||
return $mapper; | ||
} | ||
} | ||
|
||
$hash = spl_object_hash($object); | ||
if (isset($this->createdObjects[$hash])) { | ||
return $this->createdObjects[$hash]; | ||
} | ||
|
||
throw new RuntimeException("No mapper can create a subject for object."); | ||
} | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function setPropertyValue($object, PropertyInterface $property, $value) | ||
{ | ||
return $this->getMapperForObject($object)->setPropertyValue($object, $property, $value); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getPropertyValue($object, PropertyInterface $property) | ||
{ | ||
return $this->getMapperForObject($object)->getPropertyValue($object, $property); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isEditable($object) | ||
{ | ||
return $this->getMapperForObject($object)->isEditable($object); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getChildren($object, CollectionInterface $collection) | ||
{ | ||
return $this->getMapperForObject($object)->getChildren($object, $collection); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function objectToName($object) | ||
{ | ||
return $this->getMapperForObject($object)->objectToName($object); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function prepareObject(TypeInterface $controller, $parent = null) | ||
{ | ||
foreach ($this->mappers as $mapper) | ||
{ | ||
if ($mapper->supportsCreate($controller)) { | ||
$object = $mapper->prepareObject($controller, $parent); | ||
$this->createdObjects[spl_object_hash($object)] = $mapper; | ||
|
||
return $object; | ||
} | ||
} | ||
|
||
throw new RuntimeException("No mapper can create an object for type."); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function store(EntityInterface $entity) | ||
{ | ||
return $this->getMapperForObject($entity->getObject())->store($entity); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getBySubject($subject) | ||
{ | ||
list($mapperKey, $mapperSubject) = explode('|', $subject, 2); | ||
|
||
if (!isset($this->mappers[$mapperKey])) | ||
{ | ||
throw new RuntimeException("Invalid subject: $subject"); | ||
} | ||
|
||
$object = $this->mappers[$mapperKey]->getBySubject($mapperSubject); | ||
|
||
return $object; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function createSubject($object) | ||
{ | ||
foreach ($this->mappers as $mapperKey => $mapper) | ||
{ | ||
if ($mapper->supports($object)) { | ||
return $mapperKey . '|' . $mapper->createSubject($object); | ||
} | ||
} | ||
|
||
throw new RuntimeException("No mapper can create a subject for object."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets do |
||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function orderChildren(EntityInterface $entity, CollectionInterface $node, $expectedOrder) | ||
{ | ||
return $this->getMapperForObject($entity->getObject())->orderChildren($entity, $node, $expectedOrder); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
/** | ||
* @copyright CONTENT CONTROL GmbH, http://www.contentcontrol-berlin.de | ||
* @author CONTENT CONTROL GmbH, http://www.contentcontrol-berlin.de | ||
* @license Dual licensed under the MIT (MIT-LICENSE.txt) and LGPL (LGPL-LICENSE.txt) licenses. | ||
* @package Midgard.CreatePHP | ||
*/ | ||
|
||
namespace Midgard\CreatePHP; | ||
|
||
use Midgard\CreatePHP\Type\TypeInterface; | ||
|
||
/** | ||
* Map from CreatePHP to your domain objects | ||
* | ||
* You can have a mapper per type or a generic mapper that handles all types. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please update this description to explain what the chainable mapper is. the general description of what a mapper is can stay in RdfMapperInterface |
||
* | ||
* @package Midgard.CreatePHP | ||
*/ | ||
interface RdfChainableMapperInterface extends RdfMapperInterface | ||
{ | ||
/** | ||
* Get if the object can be handled by this mapper. | ||
* | ||
* @param mixed $object | ||
* | ||
* @return boolean | ||
*/ | ||
public function supports($object); | ||
|
||
/** | ||
* Get if this mapper can create this type. | ||
* | ||
* @param TypeInterface $type | ||
* | ||
* @return boolean | ||
*/ | ||
public function supportsCreate(TypeInterface $type); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for BC, lets just keep this method as it was but add the new objectToName method.
we can then eventually go for a version 2.0 of this library, but for now lets keep things working.