Я копался в коде jms и обнаружил, что setGroups использует GroupsExclusionStrategy, но есть и другие стратегии и ExclusionStrategyInterface. Поэтому я внедрил этот интерфейс в свой собственный
<?php
namespace AppBundle\Jms\Serializer;
use JMS\Serializer\Context;
use JMS\Serializer\Exclusion\ExclusionStrategyInterface;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\Metadata\PropertyMetadata;
/**
* Class IntersectGroupsExclusionStrategy
* @package AppBundle\Jms
*/
class IntersectGroupsExclusionStrategy implements ExclusionStrategyInterface
{
/**
* @var array
*/
private $groups;
/**
* IntersectGroupsExclusionStrategy constructor.
* @param array $groups
*/
public function __construct(array $groups)
{
$this->setGroups($groups);
}
/**
* {@inheritDoc}
*/
public function shouldSkipProperty(PropertyMetadata $property, Context $navigatorContext)
{
if (is_array($this->groups) && is_array($property->groups)) {
return !(!empty($this->groups) && array_intersect($this->groups, $property->groups) === $this->groups);
}
return false;
}
/**
* Whether the class should be skipped.
*
* @param ClassMetadata $metadata
*
* @return boolean
*/
public function shouldSkipClass(ClassMetadata $metadata, Context $context)
{
return false;
}
/**
* @param array $groups
* @return $this
*/
public function setGroups(array $groups)
{
$this->groups = $groups;
return $this;
}
}
При сериализации вместо использования setGroups
я использовал
$intersectExclusionStrategy = new IntersectGroupsExclusionStrategy($groups);
$serializationContext = SerializationContext::create();
$serializationContext->addExclusionStrategy($intersectExclusionStrategy);
Где $groups
содержит значения ['writable' ,'other']
.
Это сработало очень хорошо.
Я также создал тест для него, если кому-то нужно.
<?php
use AppBundle\Jms\Serializer\IntersectGroupsExclusionStrategy;
class IntersectGroupsExclusionStrategyTest extends PHPUnit_Framework_TestCase
{
public function testShouldSkipPropertyGroups()
{
$intersectExclusionStrategy = new IntersectGroupsExclusionStrategy(['group_a', 'group_b']);
$propertyMetaData = $this->getMock('JMS\Serializer\Metadata\PropertyMetadata', [], [], '', false);
$context = $this->getMock('JMS\Serializer\Context', [], [], '', false);
$propertyMetaData->groups = ['group_a', 'group_b', 'group_c'];
$this->assertNotTrue($intersectExclusionStrategy->shouldSkipProperty($propertyMetaData, $context));
$propertyMetaData->groups = ['group_a', 'group_b'];
$this->assertNotTrue($intersectExclusionStrategy->shouldSkipProperty($propertyMetaData, $context));
}
public function testShouldNotSkipPropertyGroups()
{
$intersectExclusionStrategy = new IntersectGroupsExclusionStrategy(['group_a', 'group_b']);
$propertyMetaData = $this->getMock('JMS\Serializer\Metadata\PropertyMetadata', [], [], '', false);
$context = $this->getMock('JMS\Serializer\Context', [], [], '', false);
$propertyMetaData->groups = ['group_a', 'group_c'];
$this->assertTrue($intersectExclusionStrategy->shouldSkipProperty($propertyMetaData, $context));
$propertyMetaData->groups = ['group_d', 'group_e'];
$this->assertTrue($intersectExclusionStrategy->shouldSkipProperty($propertyMetaData, $context));
$intersectExclusionStrategy = new IntersectGroupsExclusionStrategy([]);
$this->assertTrue($intersectExclusionStrategy->shouldSkipProperty($propertyMetaData, $context));
}
public function testShouldSkipClassReturnsFalse()
{
$intersectExclusionStrategy = new IntersectGroupsExclusionStrategy(['group_a', 'group_b']);
$classMetaData = $this->getMock('JMS\Serializer\Metadata\ClassMetadata', [], [], '', false);
$context = $this->getMock('JMS\Serializer\Context', [], [], '', false);
$this->assertFalse($intersectExclusionStrategy->shouldSkipClass($classMetaData, $context));
}
}
person
Robert
schedule
23.11.2016
writeble
, либо в группеother
, а пересечение — когда она должна быть в обеих группах. - person Robert   schedule 23.11.2016