|
1 <?php |
|
2 |
|
3 /* |
|
4 * This file is part of the Symfony package. |
|
5 * |
|
6 * (c) Fabien Potencier <fabien@symfony.com> |
|
7 * |
|
8 * For the full copyright and license information, please view the LICENSE |
|
9 * file that was distributed with this source code. |
|
10 */ |
|
11 |
|
12 namespace Symfony\Bundle\MonologBundle\DependencyInjection; |
|
13 |
|
14 use Symfony\Component\HttpKernel\DependencyInjection\Extension; |
|
15 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; |
|
16 use Symfony\Component\DependencyInjection\ContainerBuilder; |
|
17 use Symfony\Component\Config\FileLocator; |
|
18 use Symfony\Component\DependencyInjection\Definition; |
|
19 use Symfony\Component\DependencyInjection\Reference; |
|
20 use Symfony\Component\DependencyInjection\Parameter; |
|
21 |
|
22 /** |
|
23 * MonologExtension is an extension for the Monolog library. |
|
24 * |
|
25 * @author Jordi Boggiano <j.boggiano@seld.be> |
|
26 * @author Christophe Coevoet <stof@notk.org> |
|
27 */ |
|
28 class MonologExtension extends Extension |
|
29 { |
|
30 private $nestedHandlers = array(); |
|
31 |
|
32 /** |
|
33 * Loads the Monolog configuration. |
|
34 * |
|
35 * @param array $config An array of configuration settings |
|
36 * @param ContainerBuilder $container A ContainerBuilder instance |
|
37 */ |
|
38 public function load(array $configs, ContainerBuilder $container) |
|
39 { |
|
40 $configuration = new Configuration(); |
|
41 $config = $this->processConfiguration($configuration, $configs); |
|
42 |
|
43 if (isset($config['handlers'])) { |
|
44 $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
|
45 $loader->load('monolog.xml'); |
|
46 $container->setAlias('logger', 'monolog.logger'); |
|
47 |
|
48 $logger = $container->getDefinition('monolog.logger_prototype'); |
|
49 |
|
50 $handlers = array(); |
|
51 foreach ($config['handlers'] as $name => $handler) { |
|
52 $handlers[] = array('id' => $this->buildHandler($container, $name, $handler), 'priority' => $handler['priority'] ); |
|
53 } |
|
54 |
|
55 $handlers = array_reverse($handlers); |
|
56 uasort($handlers, function($a, $b) { |
|
57 if ($a['priority'] == $b['priority']) { |
|
58 return 0; |
|
59 } |
|
60 |
|
61 return $a['priority'] < $b['priority'] ? -1 : 1; |
|
62 }); |
|
63 foreach ($handlers as $handler) { |
|
64 if (!in_array($handler['id'], $this->nestedHandlers)) { |
|
65 $logger->addMethodCall('pushHandler', array(new Reference($handler['id']))); |
|
66 } |
|
67 } |
|
68 |
|
69 $this->addClassesToCompile(array( |
|
70 'Monolog\\Formatter\\FormatterInterface', |
|
71 'Monolog\\Formatter\\LineFormatter', |
|
72 'Monolog\\Handler\\HandlerInterface', |
|
73 'Monolog\\Handler\\AbstractHandler', |
|
74 'Monolog\\Handler\\AbstractProcessingHandler', |
|
75 'Monolog\\Handler\\StreamHandler', |
|
76 'Monolog\\Handler\\FingersCrossedHandler', |
|
77 'Monolog\\Logger', |
|
78 'Symfony\\Bridge\\Monolog\\Logger', |
|
79 'Symfony\\Bridge\\Monolog\\Handler\\DebugHandler', |
|
80 )); |
|
81 } |
|
82 } |
|
83 |
|
84 /** |
|
85 * Returns the base path for the XSD files. |
|
86 * |
|
87 * @return string The XSD base path |
|
88 */ |
|
89 public function getXsdValidationBasePath() |
|
90 { |
|
91 return __DIR__.'/../Resources/config/schema'; |
|
92 } |
|
93 |
|
94 public function getNamespace() |
|
95 { |
|
96 return 'http://symfony.com/schema/dic/monolog'; |
|
97 } |
|
98 |
|
99 private function buildHandler(ContainerBuilder $container, $name, array $handler) |
|
100 { |
|
101 $handlerId = $this->getHandlerId($name); |
|
102 $definition = new Definition(sprintf('%%monolog.handler.%s.class%%', $handler['type'])); |
|
103 $handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::'.strtoupper($handler['level'])); |
|
104 |
|
105 switch ($handler['type']) { |
|
106 case 'service': |
|
107 $container->setAlias($handlerId, $handler['id']); |
|
108 |
|
109 return $handlerId; |
|
110 |
|
111 case 'stream': |
|
112 $definition->setArguments(array( |
|
113 $handler['path'], |
|
114 $handler['level'], |
|
115 $handler['bubble'], |
|
116 )); |
|
117 break; |
|
118 |
|
119 case 'firephp': |
|
120 $definition->setArguments(array( |
|
121 $handler['level'], |
|
122 $handler['bubble'], |
|
123 )); |
|
124 $definition->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse')); |
|
125 break; |
|
126 |
|
127 case 'rotating_file': |
|
128 $definition->setArguments(array( |
|
129 $handler['path'], |
|
130 $handler['max_files'], |
|
131 $handler['level'], |
|
132 $handler['bubble'], |
|
133 )); |
|
134 break; |
|
135 |
|
136 case 'fingers_crossed': |
|
137 $handler['action_level'] = is_int($handler['action_level']) ? $handler['action_level'] : constant('Monolog\Logger::'.strtoupper($handler['action_level'])); |
|
138 $nestedHandlerId = $this->getHandlerId($handler['handler']); |
|
139 $this->nestedHandlers[] = $nestedHandlerId; |
|
140 |
|
141 $definition->setArguments(array( |
|
142 new Reference($nestedHandlerId), |
|
143 $handler['action_level'], |
|
144 $handler['buffer_size'], |
|
145 $handler['bubble'], |
|
146 $handler['stop_buffering'], |
|
147 )); |
|
148 break; |
|
149 |
|
150 case 'buffer': |
|
151 $nestedHandlerId = $this->getHandlerId($handler['handler']); |
|
152 $this->nestedHandlers[] = $nestedHandlerId; |
|
153 |
|
154 $definition->setArguments(array( |
|
155 new Reference($nestedHandlerId), |
|
156 $handler['buffer_size'], |
|
157 $handler['level'], |
|
158 $handler['bubble'], |
|
159 )); |
|
160 break; |
|
161 |
|
162 case 'group': |
|
163 $references = array(); |
|
164 foreach ($handler['members'] as $nestedHandler) { |
|
165 $nestedHandlerId = $this->getHandlerId($nestedHandler); |
|
166 $this->nestedHandlers[] = $nestedHandlerId; |
|
167 $references[] = new Reference($nestedHandlerId); |
|
168 } |
|
169 |
|
170 $definition->setArguments(array( |
|
171 $references, |
|
172 $handler['bubble'], |
|
173 )); |
|
174 break; |
|
175 |
|
176 case 'syslog': |
|
177 $definition->setArguments(array( |
|
178 $handler['ident'], |
|
179 $handler['facility'], |
|
180 $handler['level'], |
|
181 $handler['bubble'], |
|
182 )); |
|
183 break; |
|
184 |
|
185 case 'swift_mailer': |
|
186 if (isset($handler['email_prototype'])) { |
|
187 if (!empty($handler['email_prototype']['method'])) { |
|
188 $prototype = array(new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']); |
|
189 } else { |
|
190 $prototype = new Reference($handler['email_prototype']['id']); |
|
191 } |
|
192 } else { |
|
193 $message = new Definition('Swift_Message'); |
|
194 $message->setFactoryService('mailer'); |
|
195 $message->setFactoryMethod('createMessage'); |
|
196 $message->setPublic(false); |
|
197 $message->addMethodCall('setFrom', array($handler['from_email'])); |
|
198 $message->addMethodCall('setTo', array($handler['to_email'])); |
|
199 $message->addMethodCall('setSubject', array($handler['subject'])); |
|
200 $messageId = sprintf('%s.mail_prototype', $handlerId); |
|
201 $container->setDefinition($messageId, $message); |
|
202 $prototype = new Reference($messageId); |
|
203 } |
|
204 $definition->setArguments(array( |
|
205 new Reference('mailer'), |
|
206 $prototype, |
|
207 $handler['level'], |
|
208 $handler['bubble'], |
|
209 )); |
|
210 break; |
|
211 |
|
212 case 'native_mailer': |
|
213 $definition->setArguments(array( |
|
214 $handler['to_email'], |
|
215 $handler['subject'], |
|
216 $handler['from_email'], |
|
217 $handler['level'], |
|
218 $handler['bubble'], |
|
219 )); |
|
220 break; |
|
221 |
|
222 // Handlers using the constructor of AbstractHandler without adding their own arguments |
|
223 case 'test': |
|
224 case 'null': |
|
225 case 'debug': |
|
226 $definition->setArguments(array( |
|
227 $handler['level'], |
|
228 $handler['bubble'], |
|
229 )); |
|
230 break; |
|
231 |
|
232 default: |
|
233 throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"', $handler['type'], $name)); |
|
234 } |
|
235 |
|
236 if (!empty($handler['formatter'])) { |
|
237 $definition->addMethodCall('setFormatter', array(new Reference($handler['formatter']))); |
|
238 } |
|
239 $container->setDefinition($handlerId, $definition); |
|
240 |
|
241 return $handlerId; |
|
242 } |
|
243 |
|
244 private function getHandlerId($name) |
|
245 { |
|
246 return sprintf('monolog.handler.%s', $name); |
|
247 } |
|
248 } |