diff --git a/Anonymize/AnonymizerCollection.php b/Anonymize/AnonymizerCollection.php index 9916277..a21db10 100644 --- a/Anonymize/AnonymizerCollection.php +++ b/Anonymize/AnonymizerCollection.php @@ -59,7 +59,7 @@ public function addAnonymizer($type, $anonymizer) public function getAnonymizer($type) { if (!array_key_exists($type, $this->anonymizers)) { - throw new LogicException(sprintf('Anonymizer %s is not registered.', $type)); + throw new LogicException(sprintf('Anonymizer "%s" is not registered.', $type)); } return $this->anonymizers[$type]; diff --git a/DependencyInjection/Compiler/AddAnonymizersCompilerPass.php b/DependencyInjection/Compiler/AddAnonymizersCompilerPass.php index 382c238..379fb9d 100644 --- a/DependencyInjection/Compiler/AddAnonymizersCompilerPass.php +++ b/DependencyInjection/Compiler/AddAnonymizersCompilerPass.php @@ -14,6 +14,7 @@ namespace Superbrave\GdprBundle\DependencyInjection\Compiler; use LogicException; +use Superbrave\GdprBundle\Anonymize\AnonymizerCollection; use Superbrave\GdprBundle\Anonymize\Type\AnonymizerInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -36,11 +37,11 @@ class AddAnonymizersCompilerPass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { - if ($container->hasDefinition('superbrave_gdpr.anonymizer_collection') === false) { + if ($container->hasDefinition(AnonymizerCollection::class) === false) { return; } - $anonymizerManagerDefinition = $container->getDefinition('superbrave_gdpr.anonymizer_collection'); + $anonymizerManagerDefinition = $container->getDefinition(AnonymizerCollection::class); $anonymizers = $container->findTaggedServiceIds('superbrave_gdpr.anonymizer'); foreach ($anonymizers as $anonymizer => $attributes) { diff --git a/DependencyInjection/SuperbraveGdprExtension.php b/DependencyInjection/SuperbraveGdprExtension.php index d370059..8cdd1f2 100644 --- a/DependencyInjection/SuperbraveGdprExtension.php +++ b/DependencyInjection/SuperbraveGdprExtension.php @@ -46,5 +46,6 @@ public function load(array $configs, ContainerBuilder $container) $loader->load('services.yml'); $loader->load('services.exporter.types.yml'); $loader->load('services.anonymizer.types.yml'); + $loader->load('legacy_aliases.yml'); } } diff --git a/Resources/config/legacy_aliases.yml b/Resources/config/legacy_aliases.yml new file mode 100644 index 0000000..11cd1aa --- /dev/null +++ b/Resources/config/legacy_aliases.yml @@ -0,0 +1,7 @@ +services: + superbrave_gdpr.annotation.reader: '@Superbrave\GdprBundle\Annotation\AnnotationReader' + superbrave_gdpr.exporter: '@Superbrave\GdprBundle\Export\Exporter' + superbrave_gdpr.anonymizer: '@Superbrave\GdprBundle\Anonymize\Anonymizer' + superbrave_gdpr.property_manipulator: '@Superbrave\GdprBundle\Manipulator\PropertyManipulator' + superbrave_gdpr.anonymizer_collection: '@Superbrave\GdprBundle\Anonymize\AnonymizerCollection' + superbrave_gdpr.property_anonymizer: '@Superbrave\GdprBundle\Anonymize\PropertyAnonymizer' diff --git a/Resources/config/services.anonymizer.types.yml b/Resources/config/services.anonymizer.types.yml index 9a3f213..2a5f8ef 100644 --- a/Resources/config/services.anonymizer.types.yml +++ b/Resources/config/services.anonymizer.types.yml @@ -5,7 +5,7 @@ services: superbrave_gdpr.fixed_anonymizer: class: Superbrave\GdprBundle\Anonymize\Type\FixedAnonymizer arguments: - - "@superbrave_gdpr.property_manipulator" + - '@Superbrave\GdprBundle\Manipulator\PropertyManipulator' tags: - { name: superbrave_gdpr.anonymizer, type: fixed } @@ -22,18 +22,18 @@ services: superbrave_gdpr.object_anonymizer: class: Superbrave\GdprBundle\Anonymize\Type\ObjectAnonymizer arguments: - - "@superbrave_gdpr.anonymizer" + - '@Superbrave\GdprBundle\Anonymize\Anonymizer' tags: - { name: superbrave_gdpr.anonymizer, type: object } superbrave_gdpr.collection_anonymizer: class: Superbrave\GdprBundle\Anonymize\Type\ArrayAnonymizer arguments: - - "@superbrave_gdpr.object_anonymizer" + - '@superbrave_gdpr.object_anonymizer' tags: - { name: superbrave_gdpr.anonymizer, type: collection } superbrave_gdpr.null_anonymizer: class: Superbrave\GdprBundle\Anonymize\Type\NullAnonymizer tags: - - { name: superbrave_gdpr.anonymizer, type: "null" } + - { name: superbrave_gdpr.anonymizer, type: 'null' } diff --git a/Resources/config/services.exporter.types.yml b/Resources/config/services.exporter.types.yml index ed00698..01cdbef 100644 --- a/Resources/config/services.exporter.types.yml +++ b/Resources/config/services.exporter.types.yml @@ -2,21 +2,30 @@ services: _defaults: public: false - superbrave_gdpr.exporter.serializer.normalizer.export_annotation: - class: Superbrave\GdprBundle\Serializer\Normalizer\AnnotationNormalizer + superbrave_gdpr.exporter.serializer.normalizer.iterable_normalizer: + class: Superbrave\GdprBundle\Serializer\Normalizer\IterableNormalizer + tags: + - { name: 'superbrave_gdpr.serializer.normalizer' } + + superbrave_gdpr.exporter.serializer.normalizer.datetime_normalizer: + class: Symfony\Component\Serializer\Normalizer\DateTimeNormalizer + tags: + - { name: 'superbrave_gdpr.serializer.normalizer' } + + Superbrave\GdprBundle\Serializer\Normalizer\AnnotationNormalizer: arguments: - - "@superbrave_gdpr.annotation.reader" - - "Superbrave\\GdprBundle\\Annotation\\Export" - - "@superbrave_gdpr.property_manipulator" + - '@Superbrave\GdprBundle\Annotation\AnnotationReader' + - 'Superbrave\GdprBundle\Annotation\Export' + - '@Superbrave\GdprBundle\Manipulator\PropertyManipulator' tags: - - { name: "superbrave_gdpr.serializer.normalizer" } + - { name: 'superbrave_gdpr.serializer.normalizer' } superbrave_gdpr.exporter.serializer.encoder.xml: class: Symfony\Component\Serializer\Encoder\XmlEncoder tags: - - { name: "superbrave_gdpr.serializer.encoder" } + - { name: 'superbrave_gdpr.serializer.encoder' } superbrave_gdpr.exporter.serializer.encoder.json: class: Symfony\Component\Serializer\Encoder\JsonEncoder tags: - - { name: "superbrave_gdpr.serializer.encoder" } + - { name: 'superbrave_gdpr.serializer.encoder' } diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 680fc15..d6d2693 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -2,43 +2,37 @@ services: _defaults: public: false - superbrave_gdpr.annotation.reader: - class: Superbrave\GdprBundle\Annotation\AnnotationReader + Superbrave\GdprBundle\Annotation\AnnotationReader: - superbrave_gdpr.exporter: - class: Superbrave\GdprBundle\Export\Exporter + Superbrave\GdprBundle\Export\Exporter: arguments: - - "@superbrave_gdpr.exporter.serializer" + - '@superbrave_gdpr.exporter.serializer' public: true - superbrave_gdpr.anonymizer: - class: Superbrave\GdprBundle\Anonymize\Anonymizer + Superbrave\GdprBundle\Anonymize\Anonymizer: arguments: - - "@superbrave_gdpr.annotation.reader" - - "@superbrave_gdpr.property_anonymizer" + - '@Superbrave\GdprBundle\Annotation\AnnotationReader' + - '@Superbrave\GdprBundle\Anonymize\PropertyAnonymizer' public: true superbrave_gdpr.exporter.serializer: class: Symfony\Component\Serializer\Serializer - factory: ["Superbrave\\GdprBundle\\DependencyInjection\\ObjectFactory", "createSerializer"] + factory: ['Superbrave\GdprBundle\DependencyInjection\ObjectFactory', 'createSerializer'] arguments: - - !tagged "superbrave_gdpr.serializer.normalizer" - - !tagged "superbrave_gdpr.serializer.encoder" + - !tagged 'superbrave_gdpr.serializer.normalizer' + - !tagged 'superbrave_gdpr.serializer.encoder' superbrave_gdpr.property_accessor: class: Symfony\Component\PropertyAccess\PropertyAccessor - superbrave_gdpr.property_manipulator: - class: Superbrave\GdprBundle\Manipulator\PropertyManipulator + Superbrave\GdprBundle\Manipulator\PropertyManipulator: arguments: - - "@superbrave_gdpr.property_accessor" + - '@superbrave_gdpr.property_accessor' - superbrave_gdpr.anonymizer_collection: - class: Superbrave\GdprBundle\Anonymize\AnonymizerCollection + Superbrave\GdprBundle\Anonymize\AnonymizerCollection: public: true - superbrave_gdpr.property_anonymizer: - class: Superbrave\GdprBundle\Anonymize\PropertyAnonymizer + Superbrave\GdprBundle\Anonymize\PropertyAnonymizer: arguments: - - "@superbrave_gdpr.property_manipulator" - - "@superbrave_gdpr.anonymizer_collection" + - '@Superbrave\GdprBundle\Manipulator\PropertyManipulator' + - '@Superbrave\GdprBundle\Anonymize\AnonymizerCollection' diff --git a/Serializer/Normalizer/AnnotationNormalizer.php b/Serializer/Normalizer/AnnotationNormalizer.php index 27c6cad..342ca80 100644 --- a/Serializer/Normalizer/AnnotationNormalizer.php +++ b/Serializer/Normalizer/AnnotationNormalizer.php @@ -17,15 +17,20 @@ use Superbrave\GdprBundle\Annotation\AnnotationReader; use Superbrave\GdprBundle\Manipulator\PropertyManipulator; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** * Normalizes object data based on the specified property annotation. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ -class AnnotationNormalizer implements NormalizerInterface +class AnnotationNormalizer implements NormalizerInterface, NormalizerAwareInterface { + use NormalizerAwareTrait; + /** * The AnnotationReader instance. * @@ -71,6 +76,8 @@ public function __construct( * @param string $format The format being (de-)serialized from or into * * @return bool + * + * @throws \ReflectionException */ public function supportsNormalization($data, $format = null) { @@ -94,6 +101,8 @@ public function supportsNormalization($data, $format = null) * @param array $context Context options for the normalizer * * @return array|string|int|float|bool + * + * @throws \ReflectionException */ public function normalize($object, $format = null, array $context = []) { @@ -109,7 +118,11 @@ public function normalize($object, $format = null, array $context = []) $propertyName = $propertyAnnotation->alias; } - $normalizedData[$propertyName] = $this->getMappedPropertyValue($propertyAnnotation, $propertyValue); + if (false === is_scalar($propertyValue)) { + $normalizedData[$propertyName] = $this->normalizer->normalize($propertyValue, $format, $context); + } else { + $normalizedData[$propertyName] = $this->getMappedPropertyValue($propertyAnnotation, $propertyValue); + } } return $normalizedData; @@ -125,10 +138,6 @@ public function normalize($object, $format = null, array $context = []) */ private function getMappedPropertyValue($annotation, $propertyValue) { - if (is_scalar($propertyValue) === false) { - return $propertyValue; - } - if (property_exists($annotation, 'valueMap') === false || isset($annotation->valueMap) === false) { return $propertyValue; } diff --git a/Serializer/Normalizer/IterableNormalizer.php b/Serializer/Normalizer/IterableNormalizer.php new file mode 100644 index 0000000..78fd262 --- /dev/null +++ b/Serializer/Normalizer/IterableNormalizer.php @@ -0,0 +1,54 @@ + + * @copyright 2018 SuperBrave + * @license https://github.com/superbrave/gdpr-bundle/blob/master/LICENSE MIT + * + * @see https://www.superbrave.nl/ + */ + +namespace Superbrave\GdprBundle\Serializer\Normalizer; + +use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; + +/** + * Normalizes data if it's iterable by calling the normalizer chain. + * + * @author Jelle van Oosterbosch + */ +class IterableNormalizer implements NormalizerInterface, NormalizerAwareInterface +{ + use NormalizerAwareTrait; + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null) + { + if (is_array($data) || $data instanceof \Traversable) { + return true; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function normalize($object, $format = null, array $context = []) + { + $normalizedData = []; + + foreach ($object as $value) { + $normalizedData[] = $this->normalizer->normalize($value, $format, $context); + } + + return $normalizedData; + } +} diff --git a/Tests/AnnotatedMock.php b/Tests/AnnotatedMock.php index ff64a62..e80b5af 100644 --- a/Tests/AnnotatedMock.php +++ b/Tests/AnnotatedMock.php @@ -20,6 +20,7 @@ * Class used to test the @see GDPR\AnnotationReader. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ class AnnotatedMock { @@ -60,6 +61,15 @@ class AnnotatedMock */ private $quux; + /** + * The quuz property. + * + * @GDPR\Export() + * + * @var \DateTime + */ + private $quuz; + /** * The property that is annotated with the Export annotation, but without getter method. * @@ -91,8 +101,10 @@ public function __construct(AnnotatedMock $annotatedMock = null) $elements = []; if ($annotatedMock instanceof AnnotatedMock) { $elements[] = $annotatedMock; + $elements[] = clone $annotatedMock; } + $this->quuz = new \DateTime('2016/01/01'); $this->quux = new ArrayCollection($elements); } @@ -136,6 +148,14 @@ public function getQuux() return $this->quux; } + /** + * @return \DateTime + */ + public function getQuuz() + { + return $this->quuz; + } + /** * Returns the value of the notAnnotatedProperty property. * diff --git a/Tests/Annotation/AnnotationReaderTest.php b/Tests/Annotation/AnnotationReaderTest.php index 81baa19..cdcb3bd 100644 --- a/Tests/Annotation/AnnotationReaderTest.php +++ b/Tests/Annotation/AnnotationReaderTest.php @@ -25,6 +25,7 @@ * AnnotationReaderTest. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ class AnnotationReaderTest extends TestCase { @@ -65,9 +66,9 @@ public function testGetPropertiesWithAnnotationExport(): void ); $this->assertIsArray($result); - $this->assertCount(5, $result); + $this->assertCount(6, $result); $this->assertSame( - ['foo', 'baz', 'qux', 'quux', 'annotatedPropertyWithoutMethod'], + ['foo', 'baz', 'qux', 'quux', 'quuz', 'annotatedPropertyWithoutMethod'], array_keys($result) ); $this->assertInstanceOf(Export::class, current($result)); @@ -109,11 +110,12 @@ public function testGetPropertiesWithAnnotationForExtendedClass(): void ); $this->assertIsArray($result); - $this->assertCount(6, $result); + $this->assertCount(7, $result); $this->assertSame( - ['extendedProperty', 'foo', 'baz', 'qux', 'quux', 'annotatedPropertyWithoutMethod'], + ['extendedProperty', 'foo', 'baz', 'qux', 'quux', 'quuz', 'annotatedPropertyWithoutMethod'], array_keys($result) ); + $this->assertInstanceOf(Export::class, current($result)); } } diff --git a/Tests/Resources/json/annotation_normalize_result.json b/Tests/Resources/json/annotation_normalize_result.json new file mode 100644 index 0000000..7b3713d --- /dev/null +++ b/Tests/Resources/json/annotation_normalize_result.json @@ -0,0 +1 @@ +{"foo":"bar","baz":1,"qux":[],"quuxs":[{"foo":"bar","baz":1,"qux":[],"quuxs":[],"quuz":"2016-01-01T00:00:00+00:00","annotatedPropertyWithoutMethod":"Yes"},{"foo":"bar","baz":1,"qux":[],"quuxs":[],"quuz":"2016-01-01T00:00:00+00:00","annotatedPropertyWithoutMethod":"Yes"}],"quuz":"2016-01-01T00:00:00+00:00","annotatedPropertyWithoutMethod":"Yes"} \ No newline at end of file diff --git a/Tests/Resources/json/iterable_normalize_result.json b/Tests/Resources/json/iterable_normalize_result.json new file mode 100644 index 0000000..4e73407 --- /dev/null +++ b/Tests/Resources/json/iterable_normalize_result.json @@ -0,0 +1 @@ +["bar",1,[["2020-01-01T00:00:00+00:00","2020-01-01T00:00:00+00:00"]]] \ No newline at end of file diff --git a/Tests/Resources/xml/annotation_normalizer_result.xml b/Tests/Resources/xml/annotation_normalizer_result.xml index 1114392..2db23dc 100644 --- a/Tests/Resources/xml/annotation_normalizer_result.xml +++ b/Tests/Resources/xml/annotation_normalizer_result.xml @@ -1,2 +1,2 @@ -bar1bar1YesYes +bar1bar12016-01-01T00:00:00+00:00Yesbar12016-01-01T00:00:00+00:00Yes2016-01-01T00:00:00+00:00Yes diff --git a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php index 7c47997..8aacd78 100644 --- a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php +++ b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php @@ -13,7 +13,6 @@ namespace Superbrave\GdprBundle\Tests\Serializer\Normalizer; -use Doctrine\Common\Collections\ArrayCollection; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use ReflectionClass; @@ -21,15 +20,19 @@ use Superbrave\GdprBundle\Annotation\Export; use Superbrave\GdprBundle\Manipulator\PropertyManipulator; use Superbrave\GdprBundle\Serializer\Normalizer\AnnotationNormalizer; +use Superbrave\GdprBundle\Serializer\Normalizer\IterableNormalizer; use Superbrave\GdprBundle\Tests\AnnotatedMock; use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Serializer; /** * AnnotationNormalizerTest. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ class AnnotationNormalizerTest extends TestCase { @@ -155,6 +158,12 @@ public function testNormalize(): void ); $normalizer = new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator); + $serializer = new Serializer([ + new DateTimeNormalizer(), + new IterableNormalizer(), + $normalizer, + ]); + $normalizer->setNormalizer($serializer); $annotatedMock = new AnnotatedMock(); @@ -163,7 +172,8 @@ public function testNormalize(): void 'foo' => 'bar', 'baz' => 1, 'qux' => [], - 'quuxs' => new ArrayCollection(), + 'quuxs' => [], + 'quuz' => '2016-01-01T00:00:00+00:00', 'annotatedPropertyWithoutMethod' => 'Yes', ], $normalizer->normalize($annotatedMock) @@ -171,24 +181,28 @@ public function testNormalize(): void } /** - * Tests if AnnotationNormalizer::normalize returns the expected normalized data + * Tests if @see AnnotationNormalizer::normalize returns the expected xml normalized data * for serialization through the Serializer. * * @return void */ - public function testNormalizeThroughSerializer(): void + public function testNormalizeThroughXmlSerializer(): void { $annotationReader = new AnnotationReader(); $propertyManipulator = new PropertyManipulator( PropertyAccess::createPropertyAccessor() ); - $normalizer = new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator); - $encoder = new XmlEncoder('mock'); + $normalizers = [ + new DateTimeNormalizer(), + new IterableNormalizer(), + new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator), + ]; + $encoders = [new XmlEncoder('mock')]; $serializer = new Serializer( - [$normalizer], - [$encoder] + $normalizers, + $encoders ); $data = new AnnotatedMock(new AnnotatedMock()); @@ -198,4 +212,37 @@ public function testNormalizeThroughSerializer(): void $serializer->serialize($data, 'xml') ); } + + /** + * Test if @see AnnotationNormalizer::normalize returns the expected json normalized data + * for serialization through the Serializer. + * + * @return void + */ + public function testNormalizeThroughJsonSerializer(): void + { + $annotationReader = new AnnotationReader(); + $propertyManipulator = new PropertyManipulator( + PropertyAccess::createPropertyAccessor() + ); + + $normalizers = [ + new DateTimeNormalizer(), + new IterableNormalizer(), + new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator), + ]; + $encoders = [new JsonEncoder()]; + + $serializer = new Serializer( + $normalizers, + $encoders + ); + + $data = new AnnotatedMock(new AnnotatedMock()); + + $this->assertStringEqualsFile( + __DIR__.'/../../Resources/json/annotation_normalize_result.json', + $serializer->serialize($data, 'json') + ); + } } diff --git a/Tests/Serializer/Normalizer/IterableNormalizerTest.php b/Tests/Serializer/Normalizer/IterableNormalizerTest.php new file mode 100644 index 0000000..7479d4d --- /dev/null +++ b/Tests/Serializer/Normalizer/IterableNormalizerTest.php @@ -0,0 +1,128 @@ + + * @copyright 2018 SuperBrave + * @license https://github.com/superbrave/gdpr-bundle/blob/master/LICENSE MIT + * + * @see https://www.superbrave.nl/ + */ + +namespace Superbrave\GdprBundle\Tests\Serializer\Normalizer; + +use Doctrine\Common\Collections\ArrayCollection; +use PHPUnit\Framework\TestCase; +use Superbrave\GdprBundle\Serializer\Normalizer\IterableNormalizer; +use Symfony\Component\Serializer\Encoder\JsonEncoder; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; +use Symfony\Component\Serializer\Serializer; + +/** + * AnnotationNormalizerTest. + * + * @author Jelle van Oosterbosch + */ +class IterableNormalizerTest extends TestCase +{ + /** + * @var IterableNormalizer + */ + private $normalizer; + + /** + * @var Serializer + */ + private $serializer; + + /** + * {@inheritdoc} + */ + public function setUp(): void + { + $this->normalizer = new IterableNormalizer(); + $this->serializer = new Serializer([ + new DateTimeNormalizer(), + $this->normalizer, + ], [ + new JsonEncoder(), + ]); + + $this->normalizer->setNormalizer($this->serializer); + } + + /** + * Tests if @see IterableNormalizer::supportsNormalization() returns false + * when the data is not iterable. + * + * @return void + */ + public function testSupportsNormalizationReturnsFalseWhenDataIsNotIterable() + { + $this->assertFalse($this->normalizer->supportsNormalization('no object')); + $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass())); + } + + /** + * Tests if @see IterableNormalizer::supportsNormalization() returns true + * when the data is iterable. + * + * @return void + */ + public function testSupportsNormalizationReturnsTrueWhenDataIsIterable() + { + $this->assertTrue($this->normalizer->supportsNormalization([])); + $this->assertTrue($this->normalizer->supportsNormalization(new ArrayCollection())); + } + + /** + * Tests if @see IterableNormalizer::$normalizer returns the expected array of a iterable object. + * + * @return void + * + * @throws \Exception + */ + public function testNormalize() + { + $collection = new ArrayCollection(); + $collection->add(new \DateTime('2020/01/01')); + $collection->add(new \DateTime('2020/01/01')); + + $this->assertEquals( + [ + '2020-01-01T00:00:00+00:00', + '2020-01-01T00:00:00+00:00', + ], + $this->normalizer->normalize($collection) + ); + } + + /** + * Test is @see IterableNormalizer::$normalizer returns the expected json normalized data + * for serialization through the Serializer. + * + * @return void + * + * @throws \Exception + */ + public function testNormalizeThroughJsonSerializer() + { + $data = [ + 'foo' => 'bar', + 'baz' => 1, + 'qux' => [ + new ArrayCollection([ + new \DateTime('2020/01/01'), + new \DateTime('2020/01/01'), + ]), + ], + ]; + + $this->assertStringEqualsFile( + __DIR__.'/../../Resources/json/iterable_normalize_result.json', + $this->serializer->serialize($data, 'json') + ); + } +} diff --git a/composer.json b/composer.json index 4b03219..6f1395d 100644 --- a/composer.json +++ b/composer.json @@ -1,38 +1,38 @@ { - "name": "superbrave/gdpr-bundle", - "type": "symfony-bundle", - "description": "A Symfony bundle for using entity annotations according to GDPR requirements and anonymizing/exporting data", - "keywords": [ - "annotations", - "GDPR", - "anonymizing", - "exporting" - ], - "license": "MIT License", - "require": { - "php": ">=7.2.0", - "doctrine/annotations": "^1.4", - "symfony/framework-bundle": "^4.0.0", - "symfony/options-resolver": "^4.0", - "symfony/property-access": "^4.0", - "symfony/serializer": "^4.0" - }, - "require-dev": { - "doctrine/collections": "^1.5", - "friendsofphp/php-cs-fixer": "^2.16", - "phpunit/phpunit": "^8.0", - "roave/security-advisories": "dev-master" - }, - "autoload": { - "psr-4": { - "Superbrave\\GdprBundle\\": "" - } - }, - "config": { - "bin-dir": "bin", - "platform": { - "php": "7.2.0" - }, - "sort-packages": true + "name": "superbrave/gdpr-bundle", + "type": "symfony-bundle", + "description": "A Symfony bundle for using entity annotations according to GDPR requirements and anonymizing/exporting data", + "keywords": [ + "annotations", + "GDPR", + "anonymizing", + "exporting" + ], + "licence": "MIT License", + "require": { + "php": ">=7.2.0", + "doctrine/annotations": "^1.4", + "symfony/framework-bundle": "^3.4 || ^4.0", + "symfony/options-resolver": "^3.4 || ^4.0", + "symfony/property-access": "^3.4 || ^4.0", + "symfony/serializer": "^3.4 || ^4.0" + }, + "require-dev": { + "doctrine/collections": "^1.5", + "friendsofphp/php-cs-fixer": "^2.16", + "phpunit/phpunit": "^8.0", + "roave/security-advisories": "dev-master" + }, + "autoload": { + "psr-4": { + "Superbrave\\GdprBundle\\": "" } + }, + "config": { + "bin-dir": "bin", + "platform": { + "php": "7.2.0" + }, + "sort-packages": true + } } diff --git a/composer.lock b/composer.lock index adfe10d..83fb7b6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "37c275e28487dd6f6a3d5572797f077b", + "content-hash": "00fa3001ae336b007abf848dc05e5792", "packages": [ { "name": "doctrine/annotations", @@ -1778,16 +1778,16 @@ }, { "name": "symfony/serializer", - "version": "v4.4.2", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e" + "reference": "76ecc214a93b763c29b924277e85f64326f9fbb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e", - "reference": "e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e", + "url": "https://api.github.com/repos/symfony/serializer/zipball/76ecc214a93b763c29b924277e85f64326f9fbb2", + "reference": "76ecc214a93b763c29b924277e85f64326f9fbb2", "shasum": "" }, "require": { @@ -1855,7 +1855,7 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "time": "2019-12-16T11:07:37+00:00" + "time": "2020-01-07T22:30:39+00:00" }, { "name": "symfony/service-contracts", @@ -2375,16 +2375,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.9.4", + "version": "1.9.5", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7" + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/579bb7356d91f9456ccd505f24ca8b667966a0a7", - "reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef", "shasum": "" }, "require": { @@ -2419,7 +2419,7 @@ "object", "object graph" ], - "time": "2019-12-15T19:12:40+00:00" + "time": "2020-01-17T21:11:47+00:00" }, { "name": "paragonie/random_compat", @@ -2673,41 +2673,38 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" + "reference": "a48807183a4b819072f26e347bbd0b5199a9d15f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/a48807183a4b819072f26e347bbd0b5199a9d15f", + "reference": "a48807183a4b819072f26e347bbd0b5199a9d15f", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" + "ext-filter": "^7.1", + "php": "^7.2", + "phpdocumentor/reflection-common": "^2.0", + "phpdocumentor/type-resolver": "^1.0", + "webmozart/assert": "^1" }, "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpdocumentor/type-resolver": "0.4.*", - "phpunit/phpunit": "^6.4" + "doctrine/instantiator": "^1", + "mockery/mockery": "^1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2718,10 +2715,14 @@ { "name": "Mike van Riel", "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-12-28T18:55:12+00:00" + "time": "2020-02-09T09:16:15+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -2772,24 +2773,24 @@ }, { "name": "phpspec/prophecy", - "version": "1.10.1", + "version": "v1.10.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc" + "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/cbe1df668b3fe136bcc909126a0f529a78d4cbbc", - "reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b4400efc9d206e83138e2bb97ed7f5b14b831cd9", + "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" }, "require-dev": { "phpspec/phpspec": "^2.5 || ^3.2", @@ -2831,7 +2832,7 @@ "spy", "stub" ], - "time": "2019-12-22T21:05:45+00:00" + "time": "2020-01-20T15:57:02+00:00" }, { "name": "phpunit/php-code-coverage", @@ -3087,16 +3088,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.5.1", + "version": "8.5.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7870c78da3c5e4883eaef36ae47853ebb3cb86f2" + "reference": "018b6ac3c8ab20916db85fa91bf6465acb64d1e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7870c78da3c5e4883eaef36ae47853ebb3cb86f2", - "reference": "7870c78da3c5e4883eaef36ae47853ebb3cb86f2", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/018b6ac3c8ab20916db85fa91bf6465acb64d1e0", + "reference": "018b6ac3c8ab20916db85fa91bf6465acb64d1e0", "shasum": "" }, "require": { @@ -3166,7 +3167,7 @@ "testing", "xunit" ], - "time": "2019-12-25T14:49:39+00:00" + "time": "2020-01-08T08:49:49+00:00" }, { "name": "roave/security-advisories", @@ -3174,12 +3175,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "666ba252853924887ac57dc9f66e6b6af78d5a76" + "reference": "0365bf26eddd4a8be9980d7dabf05ceb2aba2f02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/666ba252853924887ac57dc9f66e6b6af78d5a76", - "reference": "666ba252853924887ac57dc9f66e6b6af78d5a76", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0365bf26eddd4a8be9980d7dabf05ceb2aba2f02", + "reference": "0365bf26eddd4a8be9980d7dabf05ceb2aba2f02", "shasum": "" }, "conflict": { @@ -3191,11 +3192,14 @@ "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6", "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", "aws/aws-sdk-php": ">=3,<3.2.1", + "bagisto/bagisto": "<0.1.5", + "bolt/bolt": "<3.6.10", "brightlocal/phpwhois": "<=4.2.5", "bugsnag/bugsnag-laravel": ">=2,<2.0.2", "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.5.18|>=3.6,<3.6.15|>=3.7,<3.7.7", "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", "cartalyst/sentry": "<=2.1.6", + "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "codeigniter/framework": "<=3.0.6", "composer/composer": "<=1-alpha.11", "contao-components/mediaelement": ">=2.14.2,<2.21.1", @@ -3213,12 +3217,18 @@ "doctrine/mongodb-odm": ">=1,<1.0.2", "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1", + "dolibarr/dolibarr": "<=10.0.6", "dompdf/dompdf": ">=0.6,<0.6.2", "drupal/core": ">=7,<7.69|>=8,<8.7.11|>=8.8,<8.8.1", "drupal/drupal": ">=7,<7.69|>=8,<8.7.11|>=8.8,<8.8.1", "endroid/qr-code-bundle": "<3.4.2", + "enshrined/svg-sanitize": "<0.12", "erusev/parsedown": "<1.7.2", - "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.4", + "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1|>=5.4,<5.4.11.1|>=2017.12,<2017.12.0.1", + "ezsystems/ezplatform": ">=1.7,<1.7.9.1|>=1.13,<1.13.5.1|>=2.5,<2.5.4", + "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6", + "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2", + "ezsystems/ezplatform-user": ">=1,<1.0.1", "ezsystems/ezpublish-kernel": ">=5.3,<5.3.12.1|>=5.4,<5.4.13.1|>=6,<6.7.9.1|>=6.8,<6.13.5.1|>=7,<7.2.4.1|>=7.3,<7.3.2.1", "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.6|>=5.4,<5.4.12.3|>=2011,<2017.12.4.3|>=2018.6,<2018.6.1.4|>=2018.9,<2018.9.1.3", "ezsystems/repository-forms": ">=2.3,<2.3.2.1", @@ -3229,6 +3239,7 @@ "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", "fuel/core": "<1.8.1", + "getgrav/grav": "<1.7-beta.8", "gree/jose": "<=2.2", "gregwar/rst": "<1.0.3", "guzzlehttp/guzzle": ">=4-rc.2,<4.2.4|>=5,<5.3.1|>=6,<6.2.1", @@ -3246,12 +3257,15 @@ "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", "league/commonmark": "<0.18.3", + "librenms/librenms": "<1.53", + "magento/community-edition": ">=2,<2.2.10|>=2.3,<2.3.3", "magento/magento1ce": "<1.9.4.3", "magento/magento1ee": ">=1,<1.14.4.3", "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2-p.2", "monolog/monolog": ">=1.8,<1.12", "namshi/jose": "<2.2", "onelogin/php-saml": "<2.10.4", + "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5", "openid/php-openid": "<2.3", "oro/crm": ">=1.7,<1.7.4", "oro/platform": ">=1.7,<1.7.4", @@ -3260,32 +3274,45 @@ "paragonie/random_compat": "<2", "paypal/merchant-sdk-php": "<3.12", "pear/archive_tar": "<1.4.4", + "phpfastcache/phpfastcache": ">=5,<5.0.13", "phpmailer/phpmailer": ">=5,<5.2.27|>=6,<6.0.6", - "phpoffice/phpexcel": "<=1.8.1", - "phpoffice/phpspreadsheet": "<=1.5", + "phpmyadmin/phpmyadmin": "<4.9.2", + "phpoffice/phpexcel": "<1.8.2", + "phpoffice/phpspreadsheet": "<1.8", "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", + "pimcore/pimcore": "<6.3", + "prestashop/autoupgrade": ">=4,<4.10.1", + "prestashop/gamification": "<2.3.2", + "prestashop/ps_facetedsearch": "<3.4.1", + "privatebin/privatebin": "<1.2.2|>=1.3,<1.3.2", "propel/propel": ">=2-alpha.1,<=2-alpha.7", "propel/propel1": ">=1,<=1.7.1", "pusher/pusher-php-server": "<2.2.1", - "robrichards/xmlseclibs": ">=1,<3.0.4", + "robrichards/xmlseclibs": "<3.0.4", "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9", "scheb/two-factor-bundle": ">=0,<3.26|>=4,<4.11", "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", "shopware/shopware": "<5.3.7", - "silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11", + "silverstripe/admin": ">=1.0.3,<1.0.4|>=1.1,<1.1.1", + "silverstripe/assets": ">=1,<1.3.5", + "silverstripe/cms": "<4.3.6|>=4.4,<4.4.4", + "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", - "silverstripe/framework": ">=3,<3.6.7|>=3.7,<3.7.3|>=4,<4.4", + "silverstripe/framework": "<4.4.4", "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.1.2", "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4", + "silverstripe/subsites": ">=2,<2.1.1", + "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", "silverstripe/userforms": "<3", "simple-updates/phpwhois": "<=1", "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", - "simplesamlphp/simplesamlphp": "<1.17.8", + "simplesamlphp/simplesamlphp": "<1.18.4", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", + "simplito/elliptic-php": "<1.0.6", "slim/slim": "<2.6", "smarty/smarty": "<3.1.33", "socalnick/scn-social-auth": "<1.15.2", @@ -3297,8 +3324,10 @@ "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", "sylius/grid-bundle": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", - "sylius/resource-bundle": ">=1,<1.3.13|>=1.4,<1.4.6|>=1.5,<1.5.1|>=1.6,<1.6.3", - "sylius/sylius": ">=1,<1.3.12|>=1.4,<1.4.4", + "sylius/resource-bundle": "<1.3.13|>=1.4,<1.4.6|>=1.5,<1.5.1|>=1.6,<1.6.3", + "sylius/sylius": "<1.3.16|>=1.4,<1.4.12|>=1.5,<1.5.9|>=1.6,<1.6.5", + "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99", + "symbiote/silverstripe-versionedfiles": "<=2.0.3", "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", @@ -3338,8 +3367,11 @@ "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4", "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", "ua-parser/uap-php": "<3.8", + "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", + "verot/class.upload.php": "<1.0.3|>=2,<2.0.4", "wallabag/tcpdf": "<6.2.22", "willdurand/js-translation-bundle": "<2.1.1", + "yii2mod/yii2-cms": "<1.9.2", "yiisoft/yii": ">=1.1.14,<1.1.15", "yiisoft/yii2": "<2.0.15", "yiisoft/yii2-bootstrap": "<2.0.4", @@ -3348,6 +3380,7 @@ "yiisoft/yii2-gii": "<2.0.4", "yiisoft/yii2-jui": "<2.0.4", "yiisoft/yii2-redis": "<2.0.8", + "yourls/yourls": "<1.7.4", "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", @@ -3392,7 +3425,7 @@ } ], "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", - "time": "2020-01-28T17:25:41+00:00" + "time": "2020-02-10T16:13:40+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -4011,16 +4044,16 @@ }, { "name": "symfony/console", - "version": "v4.4.2", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "82437719dab1e6bdd28726af14cb345c2ec816d0" + "reference": "f512001679f37e6a042b51897ed24a2f05eba656" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/82437719dab1e6bdd28726af14cb345c2ec816d0", - "reference": "82437719dab1e6bdd28726af14cb345c2ec816d0", + "url": "https://api.github.com/repos/symfony/console/zipball/f512001679f37e6a042b51897ed24a2f05eba656", + "reference": "f512001679f37e6a042b51897ed24a2f05eba656", "shasum": "" }, "require": { @@ -4083,7 +4116,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2019-12-17T10:32:23+00:00" + "time": "2020-01-25T12:44:29+00:00" }, { "name": "symfony/polyfill-php70", @@ -4146,16 +4179,16 @@ }, { "name": "symfony/process", - "version": "v4.4.2", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "b84501ad50adb72a94fb460a5b5c91f693e99c9b" + "reference": "f5697ab4cb14a5deed7473819e63141bf5352c36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/b84501ad50adb72a94fb460a5b5c91f693e99c9b", - "reference": "b84501ad50adb72a94fb460a5b5c91f693e99c9b", + "url": "https://api.github.com/repos/symfony/process/zipball/f5697ab4cb14a5deed7473819e63141bf5352c36", + "reference": "f5697ab4cb14a5deed7473819e63141bf5352c36", "shasum": "" }, "require": { @@ -4191,20 +4224,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-12-06T10:06:46+00:00" + "time": "2020-01-09T09:50:08+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.4.2", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "5745b514fc56ae1907c6b8ed74f94f90f64694e9" + "reference": "abc08d7c48987829bac301347faa10f7e8bbf4fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5745b514fc56ae1907c6b8ed74f94f90f64694e9", - "reference": "5745b514fc56ae1907c6b8ed74f94f90f64694e9", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/abc08d7c48987829bac301347faa10f7e8bbf4fb", + "reference": "abc08d7c48987829bac301347faa10f7e8bbf4fb", "shasum": "" }, "require": { @@ -4241,7 +4274,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2019-11-05T16:11:08+00:00" + "time": "2020-01-04T13:00:46+00:00" }, { "name": "theseer/tokenizer",