Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PASS_THRU extraction #149

Merged
merged 2 commits into from
Apr 22, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/08. Mapping reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ Otherwise, this URI will returns a 404. By default, this is set to false for bet
works if `routable` is set to true.
* `extraction`: defines how an association is rendered by the resource renderer. This can take the values `NONE` (the
association is not rendered and completely removes from the payload), `EMBED` (the association is recursively extracted
using the bound hydrator in the associated resource metadata) and `ID` (only the identifier(s) is/are rendered). The
default value is `ID`.
using the bound hydrator in the associated resource metadata), `ID` (only the identifier(s) is/are rendered) and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear wording

`PASS_THRU` (for instance, if a User hydrator renders an association that has PASS_THRU, then the rendered
result will be used for the given association). The default value is `ID`.

### Navigation

Expand Down
2 changes: 1 addition & 1 deletion src/ZfrRest/Resource/Metadata/Annotation/Association.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ final class Association implements AnnotationInterface
/**
* @var string
*
* @Enum({"NONE", "EMBED", "ID"})
* @Enum({"NONE", "EMBED", "ID", "PASS_THRU"})
*/
public $extraction = ResourceMetadataInterface::ASSOCIATION_EXTRACTION_ID;

Expand Down
7 changes: 4 additions & 3 deletions src/ZfrRest/Resource/Metadata/ResourceMetadataInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ interface ResourceMetadataInterface
/**
* Extraction constants that define how extraction associations are rendered
*/
const ASSOCIATION_EXTRACTION_NONE = 'NONE';
const ASSOCIATION_EXTRACTION_EMBED = 'EMBED';
const ASSOCIATION_EXTRACTION_ID = 'ID';
const ASSOCIATION_EXTRACTION_NONE = 'NONE';
const ASSOCIATION_EXTRACTION_EMBED = 'EMBED';
const ASSOCIATION_EXTRACTION_ID = 'ID';
const ASSOCIATION_EXTRACTION_PASS_THRU = 'PASS_THRU';

/**
* Create a new resource from the metadata
Expand Down
5 changes: 5 additions & 0 deletions src/ZfrRest/View/Renderer/DefaultResourceRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ protected function renderAssociations(array $data, ResourceMetadataInterface $re
continue;
}

// If set to PASS_THRU, we let the parent hydrator do its own transform
if ($extractionStrategy === ResourceMetadataInterface::ASSOCIATION_EXTRACTION_PASS_THRU) {
continue;
}

// Otherwise, we render the association
$isCollectionValued = $classMetadata->isCollectionValuedAssociation($association);
$data[$association] = $this->renderAssociation(
Expand Down
43 changes: 43 additions & 0 deletions tests/ZfrRestTest/Asset/Hydrator/UserWithRoleHydrator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrRestTest\Asset\Hydrator;

use Zend\Stdlib\Exception;
use Zend\Stdlib\Hydrator\ClassMethods;

/**
* @author Michaël Gallego <mic.gallego@gmail.com>
* @licence MIT
*/
class UserWithRoleHydrator extends ClassMethods
{
public function extract($object)
{
$payload = parent::extract($object);
$roles = $object->getRoles();

$payload['roles'] = []; // Clear automatic extraction from ClassMethods

foreach ($roles as $role) {
$payload['roles'][] = $role->getName();
}

return $payload;
}
}
71 changes: 71 additions & 0 deletions tests/ZfrRestTest/Asset/Resource/Metadata/Annotation/Role.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrRestTest\Asset\Resource\Metadata\Annotation;

use Doctrine\ORM\Mapping as ORM;
use ZfrRest\Resource\Metadata\Annotation as REST;

/**
* @ORM\Entity
*/
class Role
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="string")
*/
protected $name;

/**
* @param int $id
*/
public function setId($id)
{
$this->id = (int) $id;
}

/**
* @return int
*/
public function getId()
{
return $this->id;
}

/**
* @param string $name
*/
public function setName($name)
{
$this->name = (string) $name;
}

/**
* @return string
*/
public function getName()
{
return $this->name;
}
}
106 changes: 106 additions & 0 deletions tests/ZfrRestTest/Asset/Resource/Metadata/Annotation/UserWithRoles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrRestTest\Asset\Resource\Metadata\Annotation;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use ZfrRest\Resource\Metadata\Annotation as REST;

/**
* @ORM\Entity
* @REST\Resource(hydrator="ZfrRestTest\Asset\Hydrator\UserWithRoleHydrator")
*/
class UserWithRoles
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $id;

/**
* @ORM\Column(type="string")
*/
protected $username;

/**
* @ORM\ManyToMany(targetEntity="Role")
* @REST\Association(extraction="PASS_THRU")
*/
protected $roles;

public function __construct()
{
$this->roles = new ArrayCollection();
}

/**
* @param (int) $id
*/
public function setId($id)
{
$this->id = (int) $id;
}

/**
* @return int
*/
public function getId()
{
return $this->id;
}

/**
* @param string $username
*/
public function setUsername($username)
{
$this->username = (string) $username;
}

/**
* @return string
*/
public function getUsername()
{
return $this->username;
}

/**
* @param Collection $roles
* @return void
*/
public function setRoles(Collection $roles)
{
$this->roles->clear();

foreach ($roles as $role) {
$this->roles->add($role);
}
}

/**
* @return ArrayCollection
*/
public function getRoles()
{
return $this->roles;
}
}
33 changes: 33 additions & 0 deletions tests/ZfrRestTest/View/Renderer/DefaultResourceRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

namespace ZfrRestTest\View\Renderer;

use Doctrine\Common\Collections\ArrayCollection;
use Zend\Paginator\Adapter\ArrayAdapter;
use Zend\Paginator\Paginator;
use Zend\Stdlib\Hydrator\HydratorPluginManager;
Expand All @@ -26,8 +27,10 @@
use ZfrRest\View\Model\ResourceModel;
use ZfrRest\View\Renderer\DefaultResourceRenderer;
use ZfrRestTest\Asset\Resource\Metadata\Annotation\Address;
use ZfrRestTest\Asset\Resource\Metadata\Annotation\Role;
use ZfrRestTest\Asset\Resource\Metadata\Annotation\Tweet;
use ZfrRestTest\Asset\Resource\Metadata\Annotation\User;
use ZfrRestTest\Asset\Resource\Metadata\Annotation\UserWithRoles;
use ZfrRestTest\Util\ServiceManagerFactory;

/**
Expand Down Expand Up @@ -422,4 +425,34 @@ public function testCanRenderCollectionResourceAsPaginator()

$this->assertEquals($expectedPayload, $payload);
}

public function testCanRenderResourceWithPassThruExtraction()
{
$role = new Role();
$role->setId(1);
$role->setName('member');

$user = new UserWithRoles();
$user->setId(2);
$user->setUsername('bakura');
$user->setRoles(new ArrayCollection([$role]));

$metadata = $this->resourceMetadataFactory->getMetadataForClass(
'ZfrRestTest\Asset\Resource\Metadata\Annotation\UserWithRoles'
);

// In this test, we enforce that association extraction is set to PASS_THRU
$metadata->propertyMetadata['associations']['roles']['extraction'] = 'PASS_THRU';

$resourceModel = new ResourceModel(new Resource($user, $metadata));
$payload = $this->resourceRenderer->render($resourceModel);

$expectedPayload = [
'id' => 2,
'username' => 'bakura',
'roles' => ['member']
];

$this->assertEquals($expectedPayload, $payload);
}
}