Permalink
Browse files

Merge pull request #34 from dantleech/form

[WIP] Added PHPCRReferenceType
  • Loading branch information...
2 parents 7531758 + 479a634 commit 744d48938890c0fbc6092359f0d6e791ed87d3b6 @dbu dbu committed Feb 26, 2013
@@ -0,0 +1,55 @@
+<?php
+
+namespace Doctrine\Bundle\PHPCRBundle\Form\DataTransformer;
+
+use PHPCR\SessionInterface;
+use PHPCR\NodeInterface;
+use Symfony\Component\Form\DataTransformerInterface;
+use Symfony\Component\Form\Exception\UnexpectedTypeException;
+
+class PHPCRNodeToPathTransformer implements DataTransformerInterface
+{
+ protected $session;
+
+ public function __construct(SessionInterface $session)
+ {
+ $this->session = $session;
+ }
+
+ /**
+ * Transform a node into a path
+ *
+ * @param PHPCR\NodeInterface
+ * @throws UnexpectedTypeException if given value is not a PHPCR\NodeInterface
+ * @return string|null
+ */
+ public function transform($node)
+ {
+ if (null === $node) {
+ return null;
+ }
+
+ if (!$node instanceof NodeInterface) {
+ throw new UnexpectedTypeException($node, 'PHPCR\NodeInterface');
+ }
+ return $node->getPath();
+ }
+
+ /**
+ * Transform a path/uuid to its corresponding PHPCR node
+ *
+ * @param string $path/uuid
+ * @throws PHPCR\ItemNotFoundException if node not found
+ * @return PHPCR\NodeInterface|null
+ */
+ public function reverseTransform($id)
+ {
+ if (!$id) {
+ return null;
+ }
+
+ $node = $this->session->getNodeByIdentifier($id);
+
+ return $node;
+ }
+}
@@ -0,0 +1,30 @@
+<?php
+
+namespace Doctrine\Bundle\PHPCRBundle\Form\DataTransformer;
+
+use PHPCR\SessionInterface;
+use PHPCR\NodeInterface;
+use Symfony\Component\Form\DataTransformerInterface;
+use Symfony\Component\Form\Exception\UnexpectedTypeException;
+
+class PHPCRNodeToUuidTransformer extends PHPCRNodeToPathTransformer
+{
+ /**
+ * Transform a node into a path
+ *
+ * @param PHPCR\NodeInterface
+ * @throws UnexpectedTypeException if given value is not a PHPCR\NodeInterface
+ * @return string
+ */
+ public function transform($node)
+ {
+ if (null === $node) {
+ return null;
+ }
+
+ if (!$node instanceof NodeInterface) {
+ throw new UnexpectedTypeException($node, 'PHPCR\NodeInterface');
+ }
+ return $node->getIdentifier();
+ }
+}
@@ -0,0 +1,65 @@
+<?php
+
+namespace Doctrine\Bundle\PHPCRBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+use Doctrine\Bundle\PHPCRBundle\Form\DataTransformer\PHPCRNodeToPathTransformer;
+use Doctrine\Bundle\PHPCRBundle\Form\DataTransformer\PHPCRNodeToUuidTransformer;
+use PHPCR\SessionInterface;
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
+/**
+ * Form type for PHPCR Node references
+ *
+ * Can use either a UUID or a PATH transformer as specified by
+ * the "transfomer_type" option.
+ *
+ * @author Daniel Leech <daniel@dantleech.com>
+ */
+class PHPCRReferenceType extends AbstractType
+{
+ private $session;
+
+ public function __construct(SessionInterface $session)
+ {
+ $this->session = $session;
+ }
+
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ switch (strtolower($options['transformer_type'])) {
+ case 'uuid':
+ $transformer = new PHPCRNodeToUuidTransformer($this->session);
+ break;
+ case 'path':
+ $transformer = new PHPCRNodeToPathTransformer($this->session);
+ break;
+ default:
+ throw new InvalidConfigurationException(sprintf('
+ The option "transformer_type" must be either "uuid" or "path", "%s" given',
+ $options['transformer_type']
+ ));
+ }
+
+ $builder->addModelTransformer($transformer);
+ }
+
+ public function setDefaultOptions(OptionsResolverInterface $resolver)
+ {
+ $resolver->setDefaults(array(
+ 'transformer_type' => 'uuid',
+ ));
+ }
+
+ public function getParent()
+ {
+ return 'text';
+ }
+
+ public function getName()
+ {
+ return 'phpcr_reference';
+ }
+}
View
@@ -136,6 +136,16 @@ More information on the doctrine event system integration is in this [symfony co
The bundle provides a ``ValidPhpcrOdm`` constraint validator you can use to check if your document ``Id`` or ``Nodename`` and ``Parent`` fields are correct.
+# Form types
+
+The bundle will provide various form types for PHPCR and PHPCR-ODM specific cases.
+
+## PHPCRReferenceType
+
+Represent a PHPCR reference within a form. The input will be rendered as a text field
+containing either the PATH or the UUID as per the configuration. The form will resolve
+to a PHPCR node.
+
# Additional requirements for the doctrine:phpcr:fixtures:load command
To use the doctrine:phpcr:fixtures:load command, you additionally need the Doctrine
@@ -34,6 +34,12 @@
</call>
</service>
+ <service id="form.type.phpcr.reference" class="Doctrine\Bundle\PHPCRBundle\Form\Type\PHPCRReferenceType">
+ <tag name="form.type" alias="phpcr_reference"/>
+ <argument type="service" id="doctrine_phpcr.session"/>
+ </service>
+
+
</services>
</container>
@@ -0,0 +1,61 @@
+<?php
+
+namespace Doctrine\Bundle\PHPCRBundle\Tests\Form\DataTransformer;
+
+use Doctrine\Bundle\PHPCRBundle\Form\DataTransformer\PHPCRNodeToPathTransformer;
+use Jackalope\Node;
+
+class PHPCRNodeToPathTransformerTest extends \PHPUnit_Framework_Testcase
+{
+ public function setUp()
+ {
+ $this->session = $this->getMock('PHPCR\SessionInterface');
+ $this->transformer = new PHPCRNodeToPathTransformer($this->session);
+ $this->node = $this->getMockBuilder('Jackalope\Node')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ public function testTransform()
+ {
+ $this->node->expects($this->once())
+ ->method('getPath')
+ ->will($this->returnValue('/asd'));
+ $res = $this->transformer->transform($this->node);
+ $this->assertEquals('/asd', $res);
+ }
+
+ /**
+ * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
+ */
+ public function testTransformWrongType()
+ {
+ $res = $this->transformer->transform(new \stdClass);
+ }
+
+ public function testReverseTransform()
+ {
+ $this->session->expects($this->once())
+ ->method('getNodeByIdentifier')
+ ->with('/asd')
+ ->will($this->returnValue($this->node));
+
+ $res = $this->transformer->reverseTransform('/asd');
+ $this->assertSame($this->node, $res);
+ }
+
+ public function testReverseTransformEmpty()
+ {
+ $this->session->expects($this->never())
+ ->method('getNodeByIdentifier');
+ $res = $this->transformer->reverseTransform('');
+ $this->assertNull($res);
+
+ }
+
+ public function testReverseTransformNotFound()
+ {
+ // nothing to test, the PHPCR session will throw an
+ // ItemNotFoundException
+ }
+}
@@ -0,0 +1,24 @@
+<?php
+
+namespace Doctrine\Bundle\PHPCRBundle\Tests\Form\DataTransformer;
+
+use Doctrine\Bundle\PHPCRBundle\Form\DataTransformer\PHPCRNodeToUuidTransformer;
+use Jackalope\Node;
+
+class PHPCRNodeToUuidTransformerTest extends PHPCRNodeToPathTransformerTest
+{
+ public function setUp()
+ {
+ parent::setUp();
+ $this->transformer = new PHPCRNodeToUuidTransformer($this->session);
+ }
+
+ public function testTransform()
+ {
+ $this->node->expects($this->once())
+ ->method('getIdentifier')
+ ->will($this->returnValue('/asd'));
+ $res = $this->transformer->transform($this->node);
+ $this->assertEquals('/asd', $res);
+ }
+}
@@ -0,0 +1,55 @@
+<?php
+
+namespace Doctrine\Bundle\PHPCRBundle\Tests\Form\DataTransformer;
+
+use Doctrine\Bundle\PHPCRBundle\Form\DataTransformer\PHPCRNodeToPathTransformer;
+use Jackalope\Node;
+use Doctrine\Bundle\PHPCRBundle\Form\Type\PHPCRReferenceType;
+
+class PHPCRReferenceTypeTest extends \PHPUnit_Framework_Testcase
+{
+ public function setUp()
+ {
+ $this->session = $this->getMock('PHPCR\SessionInterface');
+
+ // hmm, phpunit won't mock a traversable interface so mocking the concrete class
+ $this->builder = $this->getMockBuilder('Symfony\Component\Form\FormBuilder')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->type = new PHPCRReferenceType($this->session);
+ }
+
+ public function provideTypes()
+ {
+ return array(
+ array('uuid', 'Doctrine\Bundle\PHPCRBundle\Form\DataTransformer\PHPCRNodeToUuidTransformer'),
+ array('path', 'Doctrine\Bundle\PHPCRBundle\Form\DataTransformer\PHPCRNodeToPathTransformer'),
+ );
+ }
+
+ /**
+ * @dataProvider provideTypes
+ */
+ public function testBuildForm($transformerType, $transformerFqn)
+ {
+ $type = null;
+ $this->builder->expects($this->once())
+ ->method('addModelTransformer')
+ ->will($this->returnCallback(function ($transformer) use (&$type) {
+ $type = get_class($transformer);
+ return null;
+ }));
+ $this->type->buildForm($this->builder, array('transformer_type' => $transformerType));
+
+ $this->assertEquals($transformerFqn, $type);
+ }
+
+ /**
+ * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ */
+ public function testInvalidType()
+ {
+ $this->type->buildForm($this->builder, array('transformer_type' => 'asdasd'));
+ }
+}
+

0 comments on commit 744d489

Please sign in to comment.