diff --git a/Factory/ContentFactory.php b/Factory/ContentFactory.php index fcc6fee..60b6ef9 100644 --- a/Factory/ContentFactory.php +++ b/Factory/ContentFactory.php @@ -37,12 +37,19 @@ public function createRelationsContent(ClassMetadataInterface $classMetadata, $o { $relationsContent = new \SplObjectStorage(); + /** + * @var RelationMetadataInterface $relationMetadata + */ foreach ($classMetadata->getRelations() as $relationMetadata) { if (null === $relationMetadata->getContent()) { continue; } - $relationsContent->attach($relationMetadata, $this->getContent($relationMetadata, $object)); + if (!$this->parametersFactory->createExclude($object, $relationMetadata->getExcludeIf()) + && $content = $this->getContent($relationMetadata, $object) + ) { + $relationsContent->attach($relationMetadata, $content); + } } return $relationsContent->count() === 0 ? null : $relationsContent; diff --git a/Factory/LinkFactory.php b/Factory/LinkFactory.php index dc67ccb..1a201ea 100644 --- a/Factory/LinkFactory.php +++ b/Factory/LinkFactory.php @@ -4,9 +4,6 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\PropertyAccess\PropertyPath; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; - use FSC\HateoasBundle\Model\Link; use FSC\HateoasBundle\Metadata\MetadataFactoryInterface; use FSC\HateoasBundle\Metadata\ClassMetadataInterface; @@ -15,19 +12,16 @@ class LinkFactory extends AbstractLinkFactory implements LinkFactoryInterface { - protected $propertyAccessor; protected $metadataFactory; protected $parametersFactory; public function __construct(MetadataFactoryInterface $metadataFactory, ParametersFactoryInterface $parametersFactory, RelationUrlGenerator $relationUrlGenerator, - PropertyAccessorInterface $propertyAccessor, $forceAbsolute = true ) { parent::__construct($relationUrlGenerator, $forceAbsolute); - $this->propertyAccessor = $propertyAccessor; $this->metadataFactory = $metadataFactory; $this->parametersFactory = $parametersFactory; } @@ -38,7 +32,8 @@ public function createLinks($object) return; } - if (null === ($classMetadata = $this->metadataFactory->getMetadata($object))) { + $classMetadata = $this->metadataFactory->getMetadata($object); + if (null === $classMetadata) { return; } @@ -53,8 +48,8 @@ public function createLinksFromMetadata(ClassMetadataInterface $classMetadata, $ * @var RelationMetadataInterface $relationMetadata */ foreach ($classMetadata->getRelations() as $relationMetadata) { - if (!$this->shouldExcludeLink($relationMetadata, $object) && - $link = $this->createLinkFromMetadata($relationMetadata, $object) + if (!$this->parametersFactory->createExclude($object, $relationMetadata->getExcludeIf()) + && $link = $this->createLinkFromMetadata($relationMetadata, $object) ) { $links[] = $link; } @@ -63,25 +58,6 @@ public function createLinksFromMetadata(ClassMetadataInterface $classMetadata, $ return $links; } - protected function shouldExcludeLink(RelationMetadataInterface $relationMetadata, $object) - { - if (!$fields = $relationMetadata->getExcludeIf()) { - return false; - } - - foreach ($fields as $field => $valueToExclude) { - $field = trim($field, '.'); - $propertyPath = new PropertyPath($field); - $value = $this->propertyAccessor->getValue($object, $propertyPath); - - if ($valueToExclude === $value) { - return true; - } - } - - return false; - } - public function createLinkFromMetadata(RelationMetadataInterface $relationMetadata, $object) { if (null !== $relationMetadata->getUrl()) { diff --git a/Factory/ParametersFactory.php b/Factory/ParametersFactory.php index 5fd518a..f2663d7 100644 --- a/Factory/ParametersFactory.php +++ b/Factory/ParametersFactory.php @@ -26,7 +26,8 @@ public function createParameters($data, $parameters) $propertyAccessor = $this->propertyAccessor; array_walk($parameters, function (&$value, $key) use ($data, $self, $propertyAccessor) { if (is_string($value) && in_array(substr($value, 0, 1), array('.', '['))) { - $propertyPath = new PropertyPath(preg_replace('/^\./', '', $value)); + $value = ltrim($value, '.'); + $propertyPath = new PropertyPath($value); $value = $propertyAccessor->getValue($data, $propertyPath); } elseif ('@' === $value) { $value = $data; @@ -37,4 +38,28 @@ public function createParameters($data, $parameters) return $parameters; } + + /** + * {@inheritdoc} + */ + public function createExclude($object, $excludeIf) + { + if ( !$excludeIf ) { + return false; + } + + foreach ($excludeIf as $field => $valueToExclude) { + $field = ltrim($field, '.'); + $propertyPath = new PropertyPath($field); + + $value = $this->propertyAccessor->getValue($object, $propertyPath); + + if ($valueToExclude === $value) { + return true; + } + } + + return false; + } + } diff --git a/Factory/ParametersFactoryInterface.php b/Factory/ParametersFactoryInterface.php index f243537..8e8797e 100644 --- a/Factory/ParametersFactoryInterface.php +++ b/Factory/ParametersFactoryInterface.php @@ -4,5 +4,19 @@ interface ParametersFactoryInterface { + /** + * @param object $data + * @param array $parameters + * + * @return mixed + */ public function createParameters($data, $parameters); + + /** + * @param object $object + * @param array $excludeIf + * + * @return boolean + */ + public function createExclude($object, $excludeIf); } diff --git a/README.md b/README.md index f7d9210..d43879d 100644 --- a/README.md +++ b/README.md @@ -667,7 +667,7 @@ class User } ``` -## Conditionally excluding links +## Conditionally excluding links and embedded relations You can add conditions on relations that will determine whether the link should be excluded or not. For example: @@ -694,4 +694,19 @@ relations: parameters: { id: .parent.id } exclude_if: ".parent": ~ -``` \ No newline at end of file +``` + +It is also worked with embedded relations: + +```php +/** + * @Rest\Relation( + * "parent", + * embed = @Rest\Content( property = ".childs" ), + * excludeIf = { ".showChilds" = null } + * ) + */ +class Post +{ +} +``` diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 4f596c2..c37edfb 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -31,7 +31,6 @@ services: - @fsc_hateoas.metadata.factory - @fsc_hateoas.factory.parameters - @fsc_hateoas.routing.relation_url_generator - - @fsc_hateoas.property_accessor fsc_hateoas.factory.parameters: class: %fsc_hateoas.factory.parameters.class%