-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from detailnet/feature/jms-serializer
Creating JMSSerializer
- Loading branch information
Showing
25 changed files
with
753 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<?php | ||
|
||
return array( | ||
return [ | ||
'detail_normalization' => [], | ||
); | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,93 @@ | ||
<?php | ||
|
||
use Detail\Normalization; | ||
use Detail\Normalization\Factory; | ||
|
||
return [ | ||
'service_manager' => [ | ||
'abstract_factories' => [ | ||
], | ||
'aliases' => [ | ||
'jms_serializer.php_serialization_visitor' => | ||
Detail\Normalization\JMSSerializer\PhpSerializationVisitor::CLASS, | ||
'jms_serializer.php_deserialization_visitor' => | ||
Detail\Normalization\JMSSerializer\PhpDeserializationVisitor::CLASS, | ||
'jms_serializer.naming_strategy.identical' => JMS\Serializer\Naming\IdenticalPropertyNamingStrategy::CLASS, | ||
// 'jms_serializer.json_serialization_visitor' => JMS\Serializer\JsonSerializationVisitor::CLASS, | ||
// 'jms_serializer.json_deserialization_visitor' => JMS\Serializer\JsonDeserializationVisitor::CLASS, | ||
'jms_serializer.php_serialization_visitor' => Normalization\JMSSerializer\PhpSerializationVisitor::CLASS, | ||
'jms_serializer.php_deserialization_visitor' => Normalization\JMSSerializer\PhpDeserializationVisitor::CLASS, | ||
// 'jms_serializer.xml_serialization_visitor' => JMS\Serializer\XmlSerializationVisitor::CLASS, | ||
// 'jms_serializer.xml_deserialization_visitor' => JMS\Serializer\XmlDeserializationVisitor::CLASS, | ||
'jms_serializer.serializer' => JMS\Serializer\Serializer::CLASS, | ||
], | ||
'invokables' => [ | ||
Detail\Normalization\JMSSerializer\EventDispatcher\Subscriber\DoctrineProxySubscriber::CLASS => | ||
Detail\Normalization\JMSSerializer\EventDispatcher\Subscriber\DoctrineProxySubscriber::CLASS, | ||
Detail\Normalization\JMSSerializer\Handler\ArrayCollectionHandler::CLASS => | ||
Detail\Normalization\JMSSerializer\Handler\ArrayCollectionHandler::CLASS, | ||
Detail\Normalization\JMSSerializer\Handler\DateHandler::CLASS => | ||
Detail\Normalization\JMSSerializer\Handler\DateHandler::CLASS, | ||
Detail\Normalization\JMSSerializer\Handler\DateImmutableHandler::CLASS => | ||
Detail\Normalization\JMSSerializer\Handler\DateImmutableHandler::CLASS, | ||
|
||
// Add our own version of the default subscriber to support HalCollection types | ||
'jms_serializer.doctrine_proxy_subscriber' => | ||
Detail\Normalization\JMSSerializer\EventDispatcher\Subscriber\DoctrineProxySubscriber::CLASS, | ||
// JMSSerializer | ||
JMS\Serializer\Naming\IdenticalPropertyNamingStrategy::CLASS => | ||
JMS\Serializer\Naming\IdenticalPropertyNamingStrategy::CLASS, | ||
// Normalizer | ||
Normalization\JMSSerializer\EventDispatcher\Subscriber\DoctrineProxySubscriber::CLASS => | ||
Normalization\JMSSerializer\EventDispatcher\Subscriber\DoctrineProxySubscriber::CLASS, | ||
Normalization\JMSSerializer\Handler\ArrayCollectionHandler::CLASS => | ||
Normalization\JMSSerializer\Handler\ArrayCollectionHandler::CLASS, | ||
Normalization\JMSSerializer\Handler\DateHandler::CLASS => | ||
Normalization\JMSSerializer\Handler\DateHandler::CLASS, | ||
Normalization\JMSSerializer\Handler\UuidHandler::CLASS => | ||
Normalization\JMSSerializer\Handler\UuidHandler::CLASS, | ||
], | ||
'factories' => [ | ||
Detail\Normalization\JMSSerializer\PhpSerializationVisitor::CLASS => | ||
Detail\Normalization\Factory\JMSSerializer\PhpSerializationVisitorFactory::CLASS, | ||
Detail\Normalization\JMSSerializer\PhpDeserializationVisitor::CLASS => | ||
Detail\Normalization\Factory\JMSSerializer\PhpDeserializationVisitorFactory::CLASS, | ||
Detail\Normalization\Normalizer\JMSSerializerBasedNormalizer::CLASS => | ||
Detail\Normalization\Factory\Normalizer\JMSSerializerBasedNormalizerFactory::CLASS, | ||
Detail\Normalization\Options\ModuleOptions::CLASS => | ||
Detail\Normalization\Factory\Options\ModuleOptionsFactory::CLASS, | ||
// JMSSerializer | ||
Normalization\Options\JMSSerializerOptions::CLASS => Factory\Options\JMSSerializerOptionsFactory::CLASS, | ||
// JMS\Serializer\JsonSerializationVisitor::CLASS => | ||
// Factory\JMSSerializer\JsonSerializationVisitorFactory::CLASS, | ||
// JMS\Serializer\JsonDeserializationVisitor::CLASS => | ||
// Factory\JMSSerializer\JsonDeserializationVisitorFactory::CLASS, | ||
JMS\Serializer\Serializer::CLASS => Factory\JMSSerializer\SerializerFactory::CLASS, | ||
// JMS\Serializer\XmlSerializationVisitor::CLASS => | ||
// Factory\JMSSerializer\XmlSerializationVisitorFactory::CLASS, | ||
// JMS\Serializer\XmlDeserializationVisitor::CLASS => | ||
// Factory\JMSSerializer\XmlDeserializationVisitorFactory::CLASS, | ||
'jms_serializer.naming_strategy' => Factory\JMSSerializer\NamingStrategyFactory::CLASS, | ||
// Normalizer | ||
Normalization\JMSSerializer\PhpSerializationVisitor::CLASS => | ||
Factory\JMSSerializer\PhpSerializationVisitorFactory::CLASS, | ||
Normalization\JMSSerializer\PhpDeserializationVisitor::CLASS => | ||
Factory\JMSSerializer\PhpDeserializationVisitorFactory::CLASS, | ||
Normalization\Normalizer\JMSSerializerBasedNormalizer::CLASS => | ||
Factory\Normalizer\JMSSerializerBasedNormalizerFactory::CLASS, | ||
Normalization\Options\ModuleOptions::CLASS => Factory\Options\ModuleOptionsFactory::CLASS, | ||
], | ||
'initializers' => [ | ||
Detail\Normalization\Normalizer\NormalizerInitializer::CLASS, | ||
], | ||
'shared' => [ | ||
Normalization\Normalizer\NormalizerInitializer::CLASS, | ||
], | ||
], | ||
'controllers' => [ | ||
'initializers' => [ | ||
Detail\Normalization\Normalizer\NormalizerInitializer::CLASS, | ||
Normalization\Normalizer\NormalizerInitializer::CLASS, | ||
], | ||
], | ||
'jms_serializer' => [ | ||
'debug' => false, | ||
'naming_strategy' => 'identical', | ||
'visitors' => [ | ||
'serialization' => [ | ||
// 'json' => 'jms_serializer.json_serialization_visitor', | ||
'php' => 'jms_serializer.php_serialization_visitor', | ||
// 'xml' => 'jms_serializer.xml_serialization_visitor', | ||
], | ||
'deserialization' => [ | ||
// 'json' => 'jms_serializer.json_deserialization_visitor', | ||
'php' => 'jms_serializer.php_deserialization_visitor', | ||
// 'xml' => 'jms_serializer.xml_deserialization_visitor', | ||
], | ||
], | ||
'handlers' => [ | ||
'subscribers' => [ | ||
Detail\Normalization\JMSSerializer\Handler\ArrayCollectionHandler::CLASS, | ||
Detail\Normalization\JMSSerializer\Handler\DateHandler::CLASS, | ||
Detail\Normalization\JMSSerializer\Handler\DateImmutableHandler::CLASS, | ||
Detail\Normalization\JMSSerializer\Handler\UuidHandler::CLASS, | ||
/** @todo Add handlers for PhpCollection and StdClass */ | ||
Normalization\JMSSerializer\Handler\ArrayCollectionHandler::CLASS, | ||
Normalization\JMSSerializer\Handler\DateHandler::CLASS, | ||
Normalization\JMSSerializer\Handler\UuidHandler::CLASS, | ||
], | ||
], | ||
'eventdispatcher' => [ | ||
'subscribers' => [] | ||
], | ||
], | ||
'detail_normalization' => [ | ||
'normalizer' => Detail\Normalization\Normalizer\JMSSerializerBasedNormalizer::CLASS, | ||
'normalizer' => Normalization\Normalizer\JMSSerializerBasedNormalizer::CLASS, | ||
], | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
namespace Detail\Normalization\Factory\JMSSerializer; | ||
|
||
use Interop\Container\ContainerInterface; | ||
|
||
use Zend\ServiceManager\Factory\FactoryInterface; | ||
|
||
use JMS\Serializer\Naming\CacheNamingStrategy; | ||
use JMS\Serializer\Naming\PropertyNamingStrategyInterface; | ||
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy; | ||
|
||
use Detail\Normalization\Options\JMSSerializerOptions; | ||
|
||
class NamingStrategyFactory implements | ||
FactoryInterface | ||
{ | ||
/** | ||
* @param ContainerInterface $container | ||
* @param string $requestedName | ||
* @param array|null $options | ||
* @return PropertyNamingStrategyInterface | ||
*/ | ||
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) | ||
{ | ||
/** @var JMSSerializerOptions $serializerOptions */ | ||
$serializerOptions = $container->get(JMSSerializerOptions::CLASS); | ||
$strategyName = sprintf('jms_serializer.naming_strategy.%s', $serializerOptions->getNamingStrategy()); | ||
|
||
/** @var PropertyNamingStrategyInterface $strategy */ | ||
$propertyStrategy = $container->get($strategyName); | ||
$annotationStrategy = new SerializedNameAnnotationStrategy($propertyStrategy); | ||
|
||
/** @todo Make cache optional/configurable */ | ||
return new CacheNamingStrategy($annotationStrategy); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?php | ||
|
||
namespace Detail\Normalization\Factory\JMSSerializer; | ||
|
||
use Interop\Container\ContainerInterface; | ||
|
||
use Zend\ServiceManager\Factory\FactoryInterface; | ||
|
||
use JMS\Serializer\EventDispatcher\EventDispatcher; | ||
use JMS\Serializer\EventDispatcher\EventSubscriberInterface; | ||
use JMS\Serializer\Handler\HandlerRegistry; | ||
use JMS\Serializer\Handler\SubscribingHandlerInterface; | ||
use JMS\Serializer\Naming\PropertyNamingStrategyInterface; | ||
use JMS\Serializer\Serializer; | ||
use JMS\Serializer\SerializerBuilder; | ||
use JMS\Serializer\VisitorInterface; | ||
|
||
use Detail\Normalization\Options\JMSSerializerOptions; | ||
|
||
class SerializerFactory implements | ||
FactoryInterface | ||
{ | ||
/** | ||
* @param ContainerInterface $container | ||
* @param string $requestedName | ||
* @param array|null $options | ||
* @return Serializer | ||
*/ | ||
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) | ||
{ | ||
/** @var JMSSerializerOptions $serializerOptions */ | ||
$serializerOptions = $container->get(JMSSerializerOptions::CLASS); | ||
|
||
$serializer = SerializerBuilder::create(); | ||
$serializer->setDebug((bool) $serializerOptions->getDebug()); | ||
|
||
// When configuring our own handlers, the default handlers of JMS won't be added | ||
$serializer->configureHandlers( | ||
function (HandlerRegistry $handlers) use ($serializerOptions, $container) { | ||
foreach ($serializerOptions->getHandlers()->getSubscribers() as $subscriberClass) { | ||
/** @var SubscribingHandlerInterface $subscriber */ | ||
$subscriber = $container->get($subscriberClass); | ||
|
||
$handlers->registerSubscribingHandler($subscriber); | ||
} | ||
} | ||
); | ||
|
||
// When configuring our own listeners, the default listeners of JMS won't be added | ||
$serializer->configureListeners( | ||
function (EventDispatcher $events) use ($serializerOptions, $container) { | ||
foreach ($serializerOptions->getEventDispatcher()->getSubscribers() as $subscriberClass) { | ||
/** @var EventSubscriberInterface $subscriber */ | ||
$subscriber = $container->get($subscriberClass); | ||
|
||
$events->addSubscriber($subscriber); | ||
} | ||
} | ||
); | ||
|
||
// Need to set naming strategy before adding default visitors | ||
/** @var PropertyNamingStrategyInterface $namingStrategy */ | ||
$namingStrategy = $container->get('jms_serializer.naming_strategy'); | ||
|
||
$serializer->setPropertyNamingStrategy($namingStrategy); | ||
|
||
// Add default visitors (JSON, XML)... | ||
$serializer->addDefaultSerializationVisitors(); | ||
$serializer->addDefaultDeserializationVisitors(); | ||
|
||
// ..and our own visitors. | ||
foreach ($serializerOptions->getVisitors()->getSerialization() as $format => $visitorName) { | ||
/** @var VisitorInterface $visitor */ | ||
$visitor = $container->get($visitorName); | ||
|
||
$serializer->setSerializationVisitor($format, $visitor); | ||
} | ||
|
||
foreach ($serializerOptions->getVisitors()->getDeserialization() as $format => $visitorName) { | ||
/** @var VisitorInterface $visitor */ | ||
$visitor = $container->get($visitorName); | ||
|
||
$serializer->setDeserializationVisitor($format, $visitor); | ||
} | ||
|
||
foreach ($serializerOptions->getMetadata()->getDirectories() as $directory) { | ||
$serializer->addMetadataDir( | ||
rtrim($directory->getPath(), '\\/'), | ||
$directory->getNamespacePrefix() ? rtrim($directory->getNamespacePrefix(), '\\') : '' | ||
); | ||
} | ||
|
||
$cacheDir = $serializerOptions->getMetadata()->getFileCache()->getDir(); | ||
|
||
if ($cacheDir !== null) { | ||
$serializer->setCacheDir($cacheDir); | ||
} | ||
|
||
return $serializer->build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Detail\Normalization\Factory\Options; | ||
|
||
use Interop\Container\ContainerInterface; | ||
|
||
use Detail\Normalization\Options\JMSSerializerOptions; | ||
|
||
/** | ||
* @method JMSSerializerOptions __invoke(ContainerInterface $container, $requestedName, array $options = null) | ||
*/ | ||
class JMSSerializerOptionsFactory extends RootOptionsFactory | ||
{ | ||
const OPTION = 'jms_serializer'; | ||
|
||
protected function getOptionsClass(): string | ||
{ | ||
return JMSSerializerOptions::CLASS; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
namespace Detail\Normalization\Factory\Options; | ||
|
||
use Interop\Container\ContainerInterface; | ||
|
||
use Zend\ServiceManager\Exception\ServiceNotCreatedException; | ||
use Zend\ServiceManager\Factory\FactoryInterface; | ||
use Zend\Stdlib\AbstractOptions; | ||
|
||
abstract class RootOptionsFactory implements | ||
FactoryInterface | ||
{ | ||
const OPTION = null; | ||
|
||
/** | ||
* @param ContainerInterface $container | ||
* @param string $requestedName | ||
* @param array|null $options | ||
* @return AbstractOptions | ||
*/ | ||
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) | ||
{ | ||
$config = $container->get('Config'); | ||
|
||
if (!isset($config[static::OPTION])) { | ||
throw new ServiceNotCreatedException(sprintf('Missing config option "%s"', static::OPTION)); | ||
} | ||
|
||
$optionsClass = $this->getOptionsClass(); | ||
|
||
/** @todo Check if class exists */ | ||
|
||
return new $optionsClass($config[static::OPTION]); | ||
} | ||
|
||
abstract protected function getOptionsClass(): string; | ||
} |
Oops, something went wrong.