Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/*
4
 * This file is part of the symfony package.
5
 * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
 
11
/**
12
 * sfWebDebugLogger logs messages into the web debug toolbar.
13
 *
14
 * @package    symfony
15
 * @subpackage log
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfWebDebugLogger.class.php 30790 2010-08-31 13:23:50Z Kris.Wallsmith $
18
 */
19
class sfWebDebugLogger extends sfVarLogger
20
{
21
  protected
22
    $context       = null,
23
    $webDebugClass = null,
24
    $webDebug      = null;
25
 
26
  /**
27
   * Initializes this logger.
28
   *
29
   * Available options:
30
   *
31
   *  * web_debug_class: The web debug class (sfWebDebug by default)
32
   *
33
   * @param  sfEventDispatcher $dispatcher  A sfEventDispatcher instance
34
   * @param  array             $options     An array of options.
35
   *
36
   * @return Boolean           true, if initialization completes successfully, otherwise false.
37
   *
38
   * @see sfVarLogger
39
   */
40
  public function initialize(sfEventDispatcher $dispatcher, $options = array())
41
  {
42
    $this->context = sfContext::getInstance();
43
 
44
    $this->webDebugClass = isset($options['web_debug_class']) ? $options['web_debug_class'] : 'sfWebDebug';
45
 
46
    if (sfConfig::get('sf_web_debug'))
47
    {
48
      $dispatcher->connect('context.load_factories', array($this, 'listenForLoadFactories'));
49
      $dispatcher->connect('response.filter_content', array($this, 'filterResponseContent'));
50
    }
51
 
52
    $this->registerErrorHandler();
53
 
54
    return parent::initialize($dispatcher, $options);
55
  }
56
 
57
  /**
58
   * Registers logger with PHP error handler.
59
   */
60
  protected function registerErrorHandler()
61
  {
62
    set_error_handler(array($this,'handlePhpError'));
63
  }
64
 
65
  /**
66
   * PHP error handler send PHP errors to log.
67
   *
68
   * PHP user space error handler can not handle E_ERROR, E_PARSE,
69
   * E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING,
70
   * and most of E_STRICT.
71
   *
72
   * @param string $errno      The level of the error raised, as an integer.
73
   * @param string $errstr     The error message, as a string.
74
   * @param string $errfile    The filename that the error was raised in, as a string.
75
   * @param string $errline    The line number the error was raised at, as an integer.
76
   * @param array  $errcontext An array that points to the active symbol table at the point the error occurred.
77
   */
78
  public function handlePhpError($errno, $errstr, $errfile, $errline, $errcontext = array())
79
  {
80
    if (($errno & error_reporting()) == 0)
81
    {
82
      return false;
83
    }
84
 
85
    $message = sprintf(' %%s at %s on line %s (%s)', $errfile, $errline, str_replace('%', '%%', $errstr));
86
    switch ($errno)
87
    {
88
      case E_STRICT:
89
        $this->dispatcher->notify(new sfEvent($this, 'application.log', array('priority' => sfLogger::ERR, sprintf($message, 'Strict notice'))));
90
        break;
91
      case E_NOTICE:
92
        $this->dispatcher->notify(new sfEvent($this, 'application.log', array('priority' => sfLogger::NOTICE, sprintf($message, 'Notice'))));
93
        break;
94
      case E_WARNING:
95
        $this->dispatcher->notify(new sfEvent($this, 'application.log', array('priority' => sfLogger::WARNING, sprintf($message, 'Warning'))));
96
        break;
97
      case E_RECOVERABLE_ERROR:
98
        $this->dispatcher->notify(new sfEvent($this, 'application.log', array('priority' => sfLogger::ERR, sprintf($message, 'Error'))));
99
        break;
100
    }
101
 
102
    return false; // do not prevent default error handling
103
  }
104
 
105
  /**
106
   * Listens for the context.load_factories event.
107
   *
108
   * @param sfEvent $event
109
   */
110
  public function listenForLoadFactories(sfEvent $event)
111
  {
112
    $path = sprintf('%s/%s/images', $event->getSubject()->getRequest()->getRelativeUrlRoot(), sfConfig::get('sf_web_debug_web_dir'));
113
    $path = str_replace('//', '/', $path);
114
 
115
    $this->webDebug = new $this->webDebugClass($this->dispatcher, $this, array(
116
      'image_root_path'    => $path,
117
      'request_parameters' => $event->getSubject()->getRequest()->getParameterHolder()->getAll(),
118
    ));
119
  }
120
 
121
  /**
122
   * Listens to the response.filter_content event.
123
   *
124
   * @param  sfEvent $event   The sfEvent instance
125
   * @param  string  $content The response content
126
   *
127
   * @return string  The filtered response content
128
   */
129
  public function filterResponseContent(sfEvent $event, $content)
130
  {
131
    if (!sfConfig::get('sf_web_debug'))
132
    {
133
      return $content;
134
    }
135
 
136
    // log timers information
137
    $messages = array();
138
    foreach (sfTimerManager::getTimers() as $name => $timer)
139
    {
140
      $messages[] = sprintf('%s %.2f ms (%d)', $name, $timer->getElapsedTime() * 1000, $timer->getCalls());
141
    }
142
    $this->dispatcher->notify(new sfEvent($this, 'application.log', $messages));
143
 
144
    // don't add debug toolbar:
145
    // * for XHR requests
146
    // * if response status code is in the 3xx range
147
    // * if not rendering to the client
148
    // * if HTTP headers only
149
    $response = $event->getSubject();
150
    $request  = $this->context->getRequest();
151
    if (
152
      null === $this->webDebug
153
      ||
154
      !$this->context->has('request')
155
      ||
156
      !$this->context->has('response')
157
      ||
158
      !$this->context->has('controller')
159
      ||
160
      $request->isXmlHttpRequest()
161
      ||
162
      strpos($response->getContentType(), 'html') === false
163
      ||
164
      '3' == substr($response->getStatusCode(), 0, 1)
165
      ||
166
      $this->context->getController()->getRenderMode() != sfView::RENDER_CLIENT
167
      ||
168
      $response->isHeaderOnly()
169
    )
170
    {
171
      return $content;
172
    }
173
 
174
    return $this->webDebug->injectToolbar($content);
175
  }
176
}