1<?php 2 3/* 4 * This file is part of the CsaGuzzleBundle package 5 * 6 * (c) Charles Sarrazin <charles@sarraz.in> 7 * (c) PrestaShop and Contributors 8 * 9 * For the full copyright and license information, please view the LICENSE 10 * file that was distributed with this source code 11 */ 12 13namespace Csa\Bundle\GuzzleBundle\DependencyInjection; 14 15use Csa\Bundle\GuzzleBundle\DependencyInjection\CompilerPass\SubscriberPass; 16use Symfony\Component\Config\FileLocator; 17use Symfony\Component\DependencyInjection\ContainerBuilder; 18use Symfony\Component\DependencyInjection\Definition; 19use Symfony\Component\DependencyInjection\DefinitionDecorator; 20use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; 21use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; 22use Symfony\Component\DependencyInjection\Reference; 23use Symfony\Component\ExpressionLanguage\Expression; 24use Symfony\Component\HttpKernel\DependencyInjection\Extension; 25 26/** 27 * Csa Guzzle Extension. 28 * 29 * @author Charles Sarrazin <charles@sarraz.in> 30 */ 31class CsaGuzzleExtension extends Extension 32{ 33 public function load(array $configs, ContainerBuilder $container) 34 { 35 $config = $this->processConfiguration(new Configuration(), $configs); 36 37 $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 38 39 $loader->load('subscribers.xml'); 40 $loader->load('collector.xml'); 41 $loader->load('twig.xml'); 42 $loader->load('factory.xml'); 43 $loader->load('services.xml'); 44 45 $descriptionFactory = $container->getDefinition('csa_guzzle.description_factory'); 46 47 $dataCollector = $container->getDefinition('csa_guzzle.data_collector.guzzle'); 48 $dataCollector->addArgument($config['profiler']['max_body_size']); 49 50 if (!$config['profiler']['enabled']) { 51 $container->removeDefinition('csa_guzzle.subscriber.debug'); 52 $container->removeDefinition('csa_guzzle.subscriber.stopwatch'); 53 $container->removeDefinition('csa_guzzle.data_collector.guzzle'); 54 $container->removeDefinition('csa_guzzle.twig.extension'); 55 } 56 57 $loggerDefinition = $container->getDefinition('csa_guzzle.subscriber.logger'); 58 59 if ($config['logger']['service']) { 60 $loggerDefinition->replaceArgument(0, new Reference($config['logger']['service'])); 61 } 62 63 if ($config['logger']['format']) { 64 $loggerDefinition->replaceArgument(1, $config['logger']['format']); 65 } 66 67 if (!$config['logger']['enabled']) { 68 $container->removeDefinition('csa_guzzle.subscriber.logger'); 69 } 70 71 $this->processCacheConfiguration($config['cache'], $container); 72 73 $definition = $container->getDefinition('csa_guzzle.client_factory'); 74 $definition->replaceArgument(0, $config['factory_class']); 75 76 $this->processClientsConfiguration($config, $container, $descriptionFactory); 77 } 78 79 private function processCacheConfiguration(array $config, ContainerBuilder $container) 80 { 81 if (!$config['enabled']) { 82 $container->removeDefinition('csa_guzzle.cache.adapter.doctrine'); 83 $container->removeDefinition('csa_guzzle.subscriber.cache'); 84 85 return; 86 } 87 88 $adapterId = $config['adapter']['service']; 89 90 if ('doctrine' === $config['adapter']['type']) { 91 $adapterId = 'csa_guzzle.cache.adapter.doctrine'; 92 93 $adapter = $container->getDefinition($adapterId); 94 $adapter->addArgument(new Reference($config['service'])); 95 } 96 97 $container->setAlias('csa_guzzle.default_cache_adapter', $adapterId); 98 } 99 100 private function processClientsConfiguration(array $config, ContainerBuilder $container, Definition $descriptionFactory) 101 { 102 foreach ($config['clients'] as $name => $options) { 103 $client = new Definition($options['class']); 104 105 if (isset($options['config'])) { 106 if (!is_array($options['config'])) { 107 throw new InvalidArgumentException(sprintf( 108 'Config for "csa_guzzle.client.%s" should be an array, but got %s', 109 $name, 110 gettype($options['config']) 111 )); 112 } 113 $client->addArgument($this->buildGuzzleConfig($options['config'])); 114 } 115 116 $subscribers = $this->findSubscriberIds($options['subscribers']); 117 118 $client->addTag( 119 SubscriberPass::CLIENT_TAG, 120 count($subscribers) ? ['subscribers' => implode(',', $subscribers)] : [] 121 ); 122 123 $clientServiceId = sprintf('csa_guzzle.client.%s', $name); 124 $container->setDefinition($clientServiceId, $client); 125 126 if (isset($options['description'])) { 127 $descriptionFactory->addMethodCall('addResource', [$name, $options['description']]); 128 129 $serviceDefinition = new DefinitionDecorator('csa_guzzle.service.abstract'); 130 $serviceDefinition->addArgument(new Reference($clientServiceId)); 131 $serviceDefinition->addArgument(new Expression(sprintf( 132 'service("csa_guzzle.description_factory").getDescription("%s")', 133 $name 134 ))); 135 $container->setDefinition(sprintf('csa_guzzle.service.%s', $name), $serviceDefinition); 136 } 137 138 if (isset($options['alias'])) { 139 $container->setAlias($options['alias'], $clientServiceId); 140 } 141 } 142 } 143 144 private function findSubscriberIds(array $explicitlyConfiguredIds) 145 { 146 return array_filter(array_keys($explicitlyConfiguredIds), function ($key) use ($explicitlyConfiguredIds) { 147 return isset($explicitlyConfiguredIds[$key]) && $explicitlyConfiguredIds[$key]; 148 }); 149 } 150 151 private function buildGuzzleConfig(array $config) 152 { 153 foreach (['message_factory', 'fsm', 'adapter', 'handler'] as $service) { 154 if (isset($config[$service])) { 155 $config[$service] = new Reference($config[$service]); 156 } 157 } 158 159 return $config; 160 } 161} 162