|
0
|
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 |
} |