scratch – Blame information for rev 115

Subversion Repositories:
Rev:
Rev Author Line No. Line
115 office 1 <?php
2  
3 /*
4 * This file is part of the Monolog package.
5 *
6 * (c) Jordi Boggiano <j.boggiano@seld.be>
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 Monolog\Handler;
13  
14 use Monolog\Formatter\WildfireFormatter;
15  
16 /**
17 * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol.
18 *
19 * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
20 */
21 class FirePHPHandler extends AbstractProcessingHandler
22 {
23 /**
24 * WildFire JSON header message format
25 */
26 const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2';
27  
28 /**
29 * FirePHP structure for parsing messages & their presentation
30 */
31 const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1';
32  
33 /**
34 * Must reference a "known" plugin, otherwise headers won't display in FirePHP
35 */
36 const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3';
37  
38 /**
39 * Header prefix for Wildfire to recognize & parse headers
40 */
41 const HEADER_PREFIX = 'X-Wf';
42  
43 /**
44 * Whether or not Wildfire vendor-specific headers have been generated & sent yet
45 */
46 protected static $initialized = false;
47  
48 /**
49 * Shared static message index between potentially multiple handlers
50 * @var int
51 */
52 protected static $messageIndex = 1;
53  
54 protected static $sendHeaders = true;
55  
56 /**
57 * Base header creation function used by init headers & record headers
58 *
59 * @param array $meta Wildfire Plugin, Protocol & Structure Indexes
60 * @param string $message Log message
61 * @return array Complete header string ready for the client as key and message as value
62 */
63 protected function createHeader(array $meta, $message)
64 {
65 $header = sprintf('%s-%s', self::HEADER_PREFIX, join('-', $meta));
66  
67 return array($header => $message);
68 }
69  
70 /**
71 * Creates message header from record
72 *
73 * @see createHeader()
74 * @param array $record
75 * @return string
76 */
77 protected function createRecordHeader(array $record)
78 {
79 // Wildfire is extensible to support multiple protocols & plugins in a single request,
80 // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake.
81 return $this->createHeader(
82 array(1, 1, 1, self::$messageIndex++),
83 $record['formatted']
84 );
85 }
86  
87 /**
88 * {@inheritDoc}
89 */
90 protected function getDefaultFormatter()
91 {
92 return new WildfireFormatter();
93 }
94  
95 /**
96 * Wildfire initialization headers to enable message parsing
97 *
98 * @see createHeader()
99 * @see sendHeader()
100 * @return array
101 */
102 protected function getInitHeaders()
103 {
104 // Initial payload consists of required headers for Wildfire
105 return array_merge(
106 $this->createHeader(array('Protocol', 1), self::PROTOCOL_URI),
107 $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI),
108 $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI)
109 );
110 }
111  
112 /**
113 * Send header string to the client
114 *
115 * @param string $header
116 * @param string $content
117 */
118 protected function sendHeader($header, $content)
119 {
120 if (!headers_sent() && self::$sendHeaders) {
121 header(sprintf('%s: %s', $header, $content));
122 }
123 }
124  
125 /**
126 * Creates & sends header for a record, ensuring init headers have been sent prior
127 *
128 * @see sendHeader()
129 * @see sendInitHeaders()
130 * @param array $record
131 */
132 protected function write(array $record)
133 {
134 if (!self::$sendHeaders) {
135 return;
136 }
137  
138 // WildFire-specific headers must be sent prior to any messages
139 if (!self::$initialized) {
140 self::$initialized = true;
141  
142 self::$sendHeaders = $this->headersAccepted();
143 if (!self::$sendHeaders) {
144 return;
145 }
146  
147 foreach ($this->getInitHeaders() as $header => $content) {
148 $this->sendHeader($header, $content);
149 }
150 }
151  
152 $header = $this->createRecordHeader($record);
153 if (trim(current($header)) !== '') {
154 $this->sendHeader(key($header), current($header));
155 }
156 }
157  
158 /**
159 * Verifies if the headers are accepted by the current user agent
160 *
161 * @return Boolean
162 */
163 protected function headersAccepted()
164 {
165 if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) {
166 return true;
167 }
168  
169 return isset($_SERVER['HTTP_X_FIREPHP_VERSION']);
170 }
171  
172 /**
173 * BC getter for the sendHeaders property that has been made static
174 */
175 public function __get($property)
176 {
177 if ('sendHeaders' !== $property) {
178 throw new \InvalidArgumentException('Undefined property '.$property);
179 }
180  
181 return static::$sendHeaders;
182 }
183  
184 /**
185 * BC setter for the sendHeaders property that has been made static
186 */
187 public function __set($property, $value)
188 {
189 if ('sendHeaders' !== $property) {
190 throw new \InvalidArgumentException('Undefined property '.$property);
191 }
192  
193 static::$sendHeaders = $value;
194 }
195 }