196 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
		
		
			
		
	
	
			196 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * This file is part of the Monolog package.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * (c) Jordi Boggiano <j.boggiano@seld.be>
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * For the full copyright and license information, please view the LICENSE
							 | 
						||
| 
								 | 
							
								 * file that was distributed with this source code.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Monolog\Handler;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use Monolog\Formatter\WildfireFormatter;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class FirePHPHandler extends AbstractProcessingHandler
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * WildFire JSON header message format
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * FirePHP structure for parsing messages & their presentation
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Must reference a "known" plugin, otherwise headers won't display in FirePHP
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Header prefix for Wildfire to recognize & parse headers
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    const HEADER_PREFIX = 'X-Wf';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Whether or not Wildfire vendor-specific headers have been generated & sent yet
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected static $initialized = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Shared static message index between potentially multiple handlers
							 | 
						||
| 
								 | 
							
								     * @var int
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected static $messageIndex = 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    protected static $sendHeaders = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Base header creation function used by init headers & record headers
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param  array  $meta    Wildfire Plugin, Protocol & Structure Indexes
							 | 
						||
| 
								 | 
							
								     * @param  string $message Log message
							 | 
						||
| 
								 | 
							
								     * @return array  Complete header string ready for the client as key and message as value
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function createHeader(array $meta, $message)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $header = sprintf('%s-%s', self::HEADER_PREFIX, join('-', $meta));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return array($header => $message);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Creates message header from record
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @see createHeader()
							 | 
						||
| 
								 | 
							
								     * @param  array  $record
							 | 
						||
| 
								 | 
							
								     * @return string
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function createRecordHeader(array $record)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Wildfire is extensible to support multiple protocols & plugins in a single request,
							 | 
						||
| 
								 | 
							
								        // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake.
							 | 
						||
| 
								 | 
							
								        return $this->createHeader(
							 | 
						||
| 
								 | 
							
								            array(1, 1, 1, self::$messageIndex++),
							 | 
						||
| 
								 | 
							
								            $record['formatted']
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * {@inheritDoc}
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function getDefaultFormatter()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return new WildfireFormatter();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Wildfire initialization headers to enable message parsing
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @see createHeader()
							 | 
						||
| 
								 | 
							
								     * @see sendHeader()
							 | 
						||
| 
								 | 
							
								     * @return array
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function getInitHeaders()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Initial payload consists of required headers for Wildfire
							 | 
						||
| 
								 | 
							
								        return array_merge(
							 | 
						||
| 
								 | 
							
								            $this->createHeader(array('Protocol', 1), self::PROTOCOL_URI),
							 | 
						||
| 
								 | 
							
								            $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI),
							 | 
						||
| 
								 | 
							
								            $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI)
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Send header string to the client
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param string $header
							 | 
						||
| 
								 | 
							
								     * @param string $content
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function sendHeader($header, $content)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!headers_sent() && self::$sendHeaders) {
							 | 
						||
| 
								 | 
							
								            header(sprintf('%s: %s', $header, $content));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Creates & sends header for a record, ensuring init headers have been sent prior
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @see sendHeader()
							 | 
						||
| 
								 | 
							
								     * @see sendInitHeaders()
							 | 
						||
| 
								 | 
							
								     * @param array $record
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function write(array $record)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!self::$sendHeaders) {
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // WildFire-specific headers must be sent prior to any messages
							 | 
						||
| 
								 | 
							
								        if (!self::$initialized) {
							 | 
						||
| 
								 | 
							
								            self::$initialized = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            self::$sendHeaders = $this->headersAccepted();
							 | 
						||
| 
								 | 
							
								            if (!self::$sendHeaders) {
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            foreach ($this->getInitHeaders() as $header => $content) {
							 | 
						||
| 
								 | 
							
								                $this->sendHeader($header, $content);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $header = $this->createRecordHeader($record);
							 | 
						||
| 
								 | 
							
								        if (trim(current($header)) !== '') {
							 | 
						||
| 
								 | 
							
								            $this->sendHeader(key($header), current($header));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Verifies if the headers are accepted by the current user agent
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return bool
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function headersAccepted()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) {
							 | 
						||
| 
								 | 
							
								            return true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return isset($_SERVER['HTTP_X_FIREPHP_VERSION']);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * BC getter for the sendHeaders property that has been made static
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function __get($property)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ('sendHeaders' !== $property) {
							 | 
						||
| 
								 | 
							
								            throw new \InvalidArgumentException('Undefined property '.$property);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return static::$sendHeaders;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * BC setter for the sendHeaders property that has been made static
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function __set($property, $value)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ('sendHeaders' !== $property) {
							 | 
						||
| 
								 | 
							
								            throw new \InvalidArgumentException('Undefined property '.$property);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static::$sendHeaders = $value;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |