-
-
Notifications
You must be signed in to change notification settings - Fork 312
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
198 additions
and
13 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,8 +15,11 @@ public function process(ContainerBuilder $container) | |
{ | ||
$handlers = array(); | ||
$handlerServices = array(); | ||
foreach ($container->findTaggedServiceIds('jms_serializer.handler') as $id => $tags) { | ||
foreach ($tags as $attrs) { | ||
foreach ($this->findAndSortTaggedServices('jms_serializer.handler', $container) as $reference) { | ||
$id = (string)$reference; | ||
$definition = $container->getDefinition($id); | ||
foreach ($definition->getTags() as $serviceTags) { | ||
$attrs = $serviceTags[0]; | ||
if (!isset($attrs['type'], $attrs['format'])) { | ||
throw new \RuntimeException(sprintf('Each tag named "jms_serializer.handler" of service "%s" must have at least two attributes: "type" and "format".', $id)); | ||
} | ||
|
@@ -32,18 +35,20 @@ public function process(ContainerBuilder $container) | |
|
||
foreach ($directions as $direction) { | ||
$method = isset($attrs['method']) ? $attrs['method'] : HandlerRegistry::getDefaultMethod($direction, $attrs['type'], $attrs['format']); | ||
if (class_exists(ServiceLocatorTagPass::class) || $container->getDefinition($id)->isPublic()) { | ||
$handlerServices[$id] = new Reference($id); | ||
if (class_exists(ServiceLocatorTagPass::class) || $definition->isPublic()) { | ||
$handlerServices[$id] = $reference; | ||
$handlers[$direction][$attrs['type']][$attrs['format']] = array($id, $method); | ||
} else { | ||
$handlers[$direction][$attrs['type']][$attrs['format']] = array(new Reference($id), $method); | ||
$handlers[$direction][$attrs['type']][$attrs['format']] = array($reference, $method); | ||
} | ||
} | ||
} | ||
} | ||
|
||
foreach ($container->findTaggedServiceIds('jms_serializer.subscribing_handler') as $id => $tags) { | ||
$class = $container->getDefinition($id)->getClass(); | ||
foreach ($this->findAndSortTaggedServices('jms_serializer.subscribing_handler', $container) as $reference) { | ||
$id = (string)$reference; | ||
$definition = $container->getDefinition($id); | ||
$class = $definition->getClass(); | ||
$ref = new \ReflectionClass($class); | ||
if (!$ref->implementsInterface('JMS\Serializer\Handler\SubscribingHandlerInterface')) { | ||
throw new \RuntimeException(sprintf('The service "%s" must implement the SubscribingHandlerInterface.', $id)); | ||
|
@@ -61,22 +66,63 @@ public function process(ContainerBuilder $container) | |
|
||
foreach ($directions as $direction) { | ||
$method = isset($methodData['method']) ? $methodData['method'] : HandlerRegistry::getDefaultMethod($direction, $methodData['type'], $methodData['format']); | ||
if (class_exists(ServiceLocatorTagPass::class) || $container->getDefinition($id)->isPublic()) { | ||
$handlerServices[$id] = new Reference($id); | ||
if (class_exists(ServiceLocatorTagPass::class) || $definition->isPublic()) { | ||
$handlerServices[$id] = $reference; | ||
$handlers[$direction][$methodData['type']][$methodData['format']] = array($id, $method); | ||
} else { | ||
$handlers[$direction][$methodData['type']][$methodData['format']] = array(new Reference($id), $method); | ||
$handlers[$direction][$methodData['type']][$methodData['format']] = array($reference, $method); | ||
} | ||
} | ||
} | ||
} | ||
|
||
$container->findDefinition('jms_serializer.handler_registry') | ||
->addArgument($handlers); | ||
$container->findDefinition('jms_serializer.handler_registry')->addArgument($handlers); | ||
|
||
if (class_exists(ServiceLocatorTagPass::class)) { | ||
$serviceLocator = ServiceLocatorTagPass::register($container, $handlerServices); | ||
$container->findDefinition('jms_serializer.handler_registry')->replaceArgument(0, $serviceLocator); | ||
} | ||
} | ||
|
||
/** | ||
* Finds all services with the given tag name and order them by their priority. | ||
* | ||
* The order of additions must be respected for services having the same priority, | ||
* and knowing that the \SplPriorityQueue class does not respect the FIFO method, | ||
* we should not use that class. | ||
* | ||
* Original author is Iltar van der Berg <[email protected]> | ||
* | ||
* @see https://bugs.php.net/bug.php?id=53710 | ||
* @see https://bugs.php.net/bug.php?id=60926 | ||
* | ||
* @param string $tagName | ||
* @param ContainerBuilder $container | ||
* | ||
* @return Reference[] | ||
*/ | ||
private function findAndSortTaggedServices($tagName, ContainerBuilder $container) | ||
{ | ||
$services = array(); | ||
|
||
foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $attributes) { | ||
$definition = $container->getDefinition($serviceId); | ||
|
||
if (!isset($attributes[0]['priority'])) { | ||
$class = $definition->getClass(); | ||
$priority = strpos($class, 'JMS\Serializer') === 0 ? 100 : 0; | ||
} else { | ||
$priority = $attributes[0]['priority']; | ||
} | ||
|
||
$services[$priority][] = new Reference($serviceId); | ||
} | ||
|
||
if ($services) { | ||
krsort($services); | ||
$services = call_user_func_array('array_merge', $services); | ||
} | ||
|
||
return $services; | ||
} | ||
} |
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
21 changes: 21 additions & 0 deletions
21
Tests/DependencyInjection/Fixture/UserDefined/UserDefinedSubscribingHandler.php
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,21 @@ | ||
<?php | ||
namespace UserDefined\Foo; | ||
|
||
use JMS\Serializer\GraphNavigator; | ||
use JMS\Serializer\Handler\SubscribingHandlerInterface; | ||
|
||
class UserDefinedSubscribingHandler implements SubscribingHandlerInterface | ||
{ | ||
public static function getSubscribingMethods() | ||
{ | ||
return array( | ||
array( | ||
'direction' => GraphNavigator::DIRECTION_SERIALIZATION, | ||
'format' => 'json', | ||
'type' => 'DateTime', | ||
'method' => 'onDateTime', | ||
), | ||
); | ||
} | ||
} | ||
|
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