Skip to content

Commit

Permalink
Resource type is now dynamic when not specified. (#29)
Browse files Browse the repository at this point in the history
* Make type dynamic when it is not specified for a resource.
  • Loading branch information
koemeet authored Feb 2, 2017
1 parent d2326e6 commit 51995f6
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 35 deletions.
4 changes: 0 additions & 4 deletions Configuration/Metadata/Driver/AnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ public function loadMetadataForClass(\ReflectionClass $class)

foreach ($annotations as $annotation) {
if ($annotation instanceof Annotation\Resource) {
// auto transform type from class name
if (!$annotation->type) {
$annotation->type = StringUtil::dasherize($class->getShortName());
}
$classMetadata->setResource(new Resource($annotation->type, $annotation->showLinkSelf));
}
}
Expand Down
2 changes: 1 addition & 1 deletion Configuration/Metadata/Driver/YamlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ protected function parseResource(array $config, \ReflectionClass $class)
$resource = $config['resource'];

return new Resource(
isset($resource['type']) ? $resource['type'] : StringUtil::dasherize($class->getShortName()),
$resource['type'],
isset($resource['showLinkSelf']) ? $resource['showLinkSelf'] : null
);
}
Expand Down
15 changes: 10 additions & 5 deletions Configuration/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Mango\Bundle\JsonApiBundle\Configuration;

use Mango\Bundle\JsonApiBundle\Util\StringUtil;

/**
* @author Steffen Brem <[email protected]>
*/
Expand All @@ -32,10 +34,6 @@ class Resource
*/
public function __construct($type, $showLinkSelf = null)
{
if (null === $type) {
throw new \RuntimeException('A JSON-API resource must have a type defined and cannot be "null".');
}

$this->type = $type;

if (null !== $showLinkSelf) {
Expand All @@ -44,10 +42,17 @@ public function __construct($type, $showLinkSelf = null)
}

/**
* @param null|object $object
*
* @return string
*/
public function getType()
public function getType($object)
{
if (!$this->type) {
$reflectionClass = new \ReflectionClass($object);
return StringUtil::dasherize($reflectionClass->getShortName());
}

return $this->type;
}

Expand Down
48 changes: 24 additions & 24 deletions EventListener/Serializer/JsonEventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class JsonEventSubscriber implements EventSubscriberInterface
/**
* @var MetadataFactoryInterface
*/
protected $hateoasMetadataFactory;
protected $jsonApiMetadataFactory;

/**
* @var MetadataFactoryInterface
Expand All @@ -67,18 +67,18 @@ class JsonEventSubscriber implements EventSubscriberInterface
protected $baseUrl = '/api';

/**
* @param MetadataFactoryInterface $hateoasMetadataFactory
* @param MetadataFactoryInterface $jsonApiMetadataFactory
* @param MetadataFactoryInterface $jmsMetadataFactory
* @param PropertyNamingStrategyInterface $namingStrategy
* @param RequestStack $requestStack
*/
public function __construct(
MetadataFactoryInterface $hateoasMetadataFactory,
MetadataFactoryInterface $jsonApiMetadataFactory,
MetadataFactoryInterface $jmsMetadataFactory,
PropertyNamingStrategyInterface $namingStrategy,
RequestStack $requestStack
) {
$this->hateoasMetadataFactory = $hateoasMetadataFactory;
$this->jsonApiMetadataFactory = $jsonApiMetadataFactory;
$this->jmsMetadataFactory = $jmsMetadataFactory;
$this->namingStrategy = $namingStrategy;
$this->requestStack = $requestStack;
Expand All @@ -105,7 +105,7 @@ public function onPostSerialize(ObjectEvent $event)
$context = $event->getContext();

/** @var ClassMetadata $metadata */
$metadata = $this->hateoasMetadataFactory->getMetadataForClass(get_class($object));
$metadata = $this->jsonApiMetadataFactory->getMetadataForClass(get_class($object));

// if it has no json api metadata, skip it
if (null === $metadata) {
Expand All @@ -118,9 +118,12 @@ public function onPostSerialize(ObjectEvent $event)
$propertyAccessor = PropertyAccess::createPropertyAccessor();

if ($visitor instanceof JsonApiSerializationVisitor) {
$visitor->addData(self::EXTRA_DATA_KEY, $this->getRelationshipDataArray(
$metadata, $this->getId($metadata, $object)
));
$visitor->addData(
self::EXTRA_DATA_KEY,
$this->getRelationshipDataArray(
$metadata, $object
)
);

$relationships = array();

Expand Down Expand Up @@ -188,7 +191,7 @@ public function onPostSerialize(ObjectEvent $event)
if (true === $metadata->getResource()->getShowLinkSelf()) {
$visitor->addData('links', array(
'self' => $this->baseUrl.'/'.$metadata->getResource()
->getType().'/'.$this->getId($metadata, $object),
->getType($object).'/'.$this->getId($metadata, $object),
));
}

Expand All @@ -206,20 +209,19 @@ public function onPostSerialize(ObjectEvent $event)
protected function processRelationshipLinks($primaryObject, Relationship $relationship, $relationshipPayloadKey)
{
/** @var ClassMetadata $relationshipMetadata */
$primaryMetadata = $this->hateoasMetadataFactory->getMetadataForClass(get_class($primaryObject));
$primaryMetadata = $this->jsonApiMetadataFactory->getMetadataForClass(get_class($primaryObject));
$primaryId = $this->getId($primaryMetadata, $primaryObject);

$links = array();

// TODO: Improve this
if ($relationship->getShowLinkSelf()) {
$links['self'] = $this->baseUrl.'/'.$primaryMetadata->getResource()
->getType().'/'.$primaryId.'/relationships/'.$relationshipPayloadKey;
->getType($primaryObject).'/'.$primaryId.'/relationships/'.$relationshipPayloadKey;
}

if ($relationship->getShowLinkRelated()) {
$links['related'] = $this->baseUrl.'/'.$primaryMetadata->getResource()
->getType().'/'.$primaryId.'/'.$relationshipPayloadKey;
$links['related'] = $this->baseUrl.'/'.$primaryMetadata->getResource()->getType($primaryObject).'/'.$primaryId.'/'.$relationshipPayloadKey;
}

return $links;
Expand All @@ -243,7 +245,7 @@ protected function processRelationship($object, Relationship $relationship, Cont
}

/** @var ClassMetadata $relationshipMetadata */
$relationshipMetadata = $this->hateoasMetadataFactory->getMetadataForClass(get_class($object));
$relationshipMetadata = $this->jsonApiMetadataFactory->getMetadataForClass(get_class($object));

if (null === $relationshipMetadata) {
throw new \RuntimeException(sprintf(
Expand All @@ -252,13 +254,11 @@ protected function processRelationship($object, Relationship $relationship, Cont
));
}

$relationshipId = $this->getId($relationshipMetadata, $object);

// contains the relations type and id
$relationshipDataArray = $this->getRelationshipDataArray($relationshipMetadata, $relationshipId);
$relationshipDataArray = $this->getRelationshipDataArray($relationshipMetadata, $object);

// only include this relationship if it is needed
if ($relationship->isIncludedByDefault() && $this->canIncludeRelationship($relationshipMetadata, $relationshipId)) {
if ($relationship->isIncludedByDefault() && $this->canIncludeRelationship($relationshipMetadata, $object)) {
$includedRelationship = $relationshipDataArray; // copy data array so we do not override it with our reference
$this->includedRelationships[] =& $includedRelationship;
$includedRelationship = $context->accept($object); // override previous reference with the serialized data
Expand Down Expand Up @@ -328,11 +328,11 @@ protected function parseIncludeResources(array $resources, $index = 0)
*
* @return array
*/
protected function getRelationshipDataArray(ClassMetadata $classMetadata, $id)
protected function getRelationshipDataArray(ClassMetadata $classMetadata, $object)
{
return array(
'type' => $classMetadata->getResource()->getType(),
'id' => $id,
'type' => $classMetadata->getResource()->getType($object),
'id' => $this->getId($classMetadata, $object),
);
}

Expand Down Expand Up @@ -364,11 +364,11 @@ protected function isIteratable($data)
*
* @return bool
*/
protected function canIncludeRelationship(ClassMetadata $classMetadata, $id)
protected function canIncludeRelationship(ClassMetadata $classMetadata, $object)
{
foreach ($this->includedRelationships as $includedRelationship) {
if ($includedRelationship['type'] === $classMetadata->getResource()->getType()
&& $includedRelationship['id'] === $id
if ($includedRelationship['type'] === $classMetadata->getResource()->getType($object)
&& $includedRelationship['id'] === $this->getId($classMetadata, $object)
) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use Mango\Bundle\JsonApiBundle\Configuration\Annotation as JsonApi;
```
| Property | Default | Required | Content | Info |
| --- | --- | --- | --- | --- |
| type | ~ | No | string | If not present, it will use the dasherized classname as it's type |
| type | ~ | No | string | If left default, it will resolve its type dynamically based on the short class name. |
| showLinkSelf | true | No | boolean | Add `self` link to the resource |

### @Id (optional, it defaults to `id`)
Expand Down

0 comments on commit 51995f6

Please sign in to comment.