* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ /** * sfWebDebug creates debug information for easy debugging in the browser. * * @package symfony * @subpackage debug * @author Fabien Potencier * @version SVN: $Id: sfWebDebug.class.php 32890 2011-08-05 07:44:44Z fabien $ */ class sfWebDebug { protected $dispatcher = null, $logger = null, $options = array(), $panels = array(); /** * Constructor. * * Available options: * * * image_root_path: The image root path * * request_parameters: The current request parameters * * @param sfEventDispatcher $dispatcher The event dispatcher * @param sfVarLogger $logger The logger * @param array $options An array of options */ public function __construct(sfEventDispatcher $dispatcher, sfVarLogger $logger, array $options = array()) { $this->dispatcher = $dispatcher; $this->logger = $logger; $this->options = $options; if (!isset($this->options['image_root_path'])) { $this->options['image_root_path'] = ''; } if (!isset($this->options['request_parameters'])) { $this->options['request_parameters'] = array(); } $this->configure(); $this->dispatcher->notify(new sfEvent($this, 'debug.web.load_panels')); } /** * Configures the web debug toolbar. */ public function configure() { $this->setPanel('symfony_version', new sfWebDebugPanelSymfonyVersion($this)); if (sfConfig::get('sf_debug') && sfConfig::get('sf_cache')) { $this->setPanel('cache', new sfWebDebugPanelCache($this)); } if (sfConfig::get('sf_logging_enabled')) { $this->setPanel('config', new sfWebDebugPanelConfig($this)); $this->setPanel('view', new sfWebDebugPanelView($this)); } $this->setPanel('logs', new sfWebDebugPanelLogs($this)); $this->setPanel('memory', new sfWebDebugPanelMemory($this)); if (sfConfig::get('sf_debug')) { $this->setPanel('time', new sfWebDebugPanelTimer($this)); } $this->setPanel('mailer', new sfWebDebugPanelMailer($this)); } /** * Gets the logger. * * @return sfVarLogger The logger instance */ public function getLogger() { return $this->logger; } /** * Gets the event dispatcher. * * @return sfEventDispatcher The event dispatcher */ public function getEventDispatcher() { return $this->dispatcher; } /** * Gets the registered panels. * * @return array The panels */ public function getPanels() { return $this->panels; } /** * Sets a panel by name. * * @param string $name The panel name * @param sfWebDebugPanel $panel The panel */ public function setPanel($name, sfWebDebugPanel $panel) { $this->panels[$name] = $panel; } /** * Removes a panel by name. * * @param string $name The panel name */ public function removePanel($name) { unset($this->panels[$name]); } /** * Gets an option value by name. * * @param string $name The option name * * @return mixed The option value */ public function getOption($name, $default = null) { return isset($this->options[$name]) ? $this->options[$name] : $default; } /** * Injects the web debug toolbar into a given HTML string. * * @param string $content The HTML content * * @return string The content with the web debug toolbar injected */ public function injectToolbar($content) { if (function_exists('mb_stripos')) { $posFunction = 'mb_stripos'; $posrFunction = 'mb_strripos'; $substrFunction = 'mb_substr'; } else { $posFunction = 'stripos'; $posrFunction = 'strripos'; $substrFunction = 'substr'; } if (false !== $pos = $posFunction($content, '')) { $styles = ''; $content = $substrFunction($content, 0, $pos).$styles.$substrFunction($content, $pos); } $debug = $this->asHtml(); if (false === $pos = $posrFunction($content, '')) { $content .= $debug; } else { $content = $substrFunction($content, 0, $pos).''.$debug.$substrFunction($content, $pos); } return $content; } /** * Returns the web debug toolbar as HTML. * * @return string The web debug toolbar HTML */ public function asHtml() { $current = isset($this->options['request_parameters']['sfWebDebugPanel']) ? $this->options['request_parameters']['sfWebDebugPanel'] : null; $titles = array(); $panels = array(); foreach ($this->panels as $name => $panel) { if ($title = $panel->getTitle()) { if (($content = $panel->getPanelContent()) || $panel->getTitleUrl()) { $id = sprintf('sfWebDebug%sDetails', $name); $titles[] = sprintf('%s', $panel->getStatus() ? ' class="sfWebDebug'.ucfirst($this->getPriority($panel->getStatus())).'"' : '', $panel->getPanelTitle(), $panel->getTitleUrl() ? $panel->getTitleUrl() : '#', $panel->getTitleUrl() ? '' : ' onclick="sfWebDebugShowDetailsFor(\''.$id.'\'); return false;"', $title ); $panels[] = sprintf('

%s

%s
', $id, $name == $current ? 'block' : 'none', $panel->getPanelTitle(), $content ); } else { $titles[] = sprintf('
  • %s
  • ', $title); } } } return '
    Debug toolbar
      '.implode("\n", $titles).'
    • Close
    '.implode("\n", $panels).'
    '; } /** * Converts a priority value to a string. * * @param integer $value The priority value * * @return string The priority as a string */ public function getPriority($value) { if ($value >= sfLogger::INFO) { return 'info'; } else if ($value >= sfLogger::WARNING) { return 'warning'; } else { return 'error'; } } /** * Gets the javascript code to inject in the head tag. * * @param string The javascript code */ public function getJavascript() { return << arrObjClass.length) continue; var c = 0; comparisonLoop: { var l = arrObjClass.length; for (var k = 0; k < l; k++) { var n = arrClass.length; for (var m = 0; m < n; m++) { if (arrClass[m] == arrObjClass[k]) c++; if (( delim == '|' && c == 1) || (delim == ' ' && c == arrClass.length)) { arr.push(objColl[i]); break comparisonLoop; } } } } } return arr; } function sfWebDebugToggleMenu() { var element = document.getElementById('sfWebDebugDetails'); var cacheElements = sfWebDebugGetElementsByClassName('sfWebDebugCache'); var mainCacheElements = sfWebDebugGetElementsByClassName('sfWebDebugActionCache'); var panelElements = sfWebDebugGetElementsByClassName('sfWebDebugTop'); if (element.style.display != 'none') { for (var i = 0; i < panelElements.length; ++i) { panelElements[i].style.display = 'none'; } // hide all cache information for (var i = 0; i < cacheElements.length; ++i) { cacheElements[i].style.display = 'none'; } for (var i = 0; i < mainCacheElements.length; ++i) { mainCacheElements[i].style.border = 'none'; } } else { for (var i = 0; i < cacheElements.length; ++i) { cacheElements[i].style.display = ''; } for (var i = 0; i < mainCacheElements.length; ++i) { mainCacheElements[i].style.border = '1px solid #f00'; } } sfWebDebugToggle('sfWebDebugDetails'); sfWebDebugToggle('sfWebDebugShowMenu'); sfWebDebugToggle('sfWebDebugHideMenu'); } function sfWebDebugShowDetailsFor(element) { if (typeof element == 'string') element = document.getElementById(element); var panelElements = sfWebDebugGetElementsByClassName('sfWebDebugTop'); for (var i = 0; i < panelElements.length; ++i) { if (panelElements[i] != element) { panelElements[i].style.display = 'none'; } } sfWebDebugToggle(element); } function sfWebDebugToggle(element) { if (typeof element == 'string') element = document.getElementById(element); if (element) element.style.display = element.style.display == 'none' ? '' : 'none'; } function sfWebDebugToggleMessages(klass) { var elements = sfWebDebugGetElementsByClassName(klass); var x = elements.length; for (var i = 0; i < x; ++i) { sfWebDebugToggle(elements[i]); } } function sfWebDebugToggleAllLogLines(show, klass) { var elements = sfWebDebugGetElementsByClassName(klass); var x = elements.length; for (var i = 0; i < x; ++i) { elements[i].style.display = show ? '' : 'none'; } } function sfWebDebugShowOnlyLogLines(type) { var types = new Array(); types[0] = 'info'; types[1] = 'warning'; types[2] = 'error'; for (klass in types) { var elements = sfWebDebugGetElementsByClassName('sfWebDebug' + types[klass].substring(0, 1).toUpperCase() + types[klass].substring(1, types[klass].length)); var x = elements.length; for (var i = 0; i < x; ++i) { if ('tr' == elements[i].tagName.toLowerCase()) { elements[i].style.display = (type == types[klass]) ? '' : 'none'; } } } } /* ]]> */ EOF; } /** * Gets the stylesheet code to inject in the head tag. * * @param string The stylesheet code */ public function getStylesheet() { return <<