Development

/branches/1.3/lib/debug/sfWebDebug.class.php

You must first sign up to be able to contribute.

root/branches/1.3/lib/debug/sfWebDebug.class.php

Revision 15767, 13.5 kB (checked in by hartym, 4 years ago)

[1.2][1.3] fix #5953: sfWebDebugToolbar do not use anymore the generic «menu» classname, but sf_web_debug_menu instead, to avoid side effects with integrators work.

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 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  * sfWebDebug creates debug information for easy debugging in the browser.
13  *
14  * @package    symfony
15  * @subpackage debug
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 class sfWebDebug
20 {
21   protected
22     $dispatcher = null,
23     $logger     = null,
24     $options    = array(),
25     $panels     = array();
26
27   /**
28    * Constructor.
29    *
30    * Available options:
31    *
32    *  * image_root_path: The image root path
33    *
34    * @param sfEventDispatcher $dispatcher The event dispatcher
35    * @param sfVarLogger       $logger     The logger
36    * @param array             $options    An array of options
37    */
38   public function __construct(sfEventDispatcher $dispatcher, sfVarLogger $logger, array $options = array())
39   {
40     $this->dispatcher = $dispatcher;
41     $this->logger     = $logger;
42     $this->options    = $options;
43
44     if (!isset($this->options['image_root_path']))
45     {
46       $this->options['image_root_path'] = '';
47     }
48
49     $this->configure();
50
51     $this->dispatcher->notify(new sfEvent($this, 'debug.web.load_panels'));
52   }
53
54   /**
55    * Configures the web debug toolbar.
56    */
57   public function configure()
58   {
59     $this->setPanel('symfony_version', new sfWebDebugPanelSymfonyVersion($this));
60     if (sfConfig::get('sf_debug') && sfConfig::get('sf_cache'))
61     {
62       $this->setPanel('cache', new sfWebDebugPanelCache($this));
63     }
64     if (sfConfig::get('sf_logging_enabled'))
65     {
66       $this->setPanel('config', new sfWebDebugPanelConfig($this));
67     }
68     $this->setPanel('logs', new sfWebDebugPanelLogs($this));
69     $this->setPanel('memory', new sfWebDebugPanelMemory($this));
70     if (sfConfig::get('sf_debug'))
71     {
72       $this->setPanel('time', new sfWebDebugPanelTimer($this));
73     }
74   }
75
76   /**
77    * Gets the logger.
78    *
79    * @return sfVarLogger The logger instance
80    */
81   public function getLogger()
82   {
83     return $this->logger;
84   }
85
86   /**
87    * Gets the event dispatcher.
88    *
89    * @return sfEventDispatcher The event dispatcher
90    */
91   public function getEventDispatcher()
92   {
93     return $this->dispatcher;
94   }
95
96   /**
97    * Gets the registered panels.
98    *
99    * @return array The panels
100    */
101   public function getPanels()
102   {
103     return $this->panels;
104   }
105
106   /**
107    * Sets a panel by name.
108    *
109    * @param string          $name  The panel name
110    * @param sfWebDebugPanel $panel The panel
111    */
112   public function setPanel($name, sfWebDebugPanel $panel)
113   {
114     $this->panels[$name] = $panel;
115   }
116
117   /**
118    * Removes a panel by name.
119    *
120    * @param string          $name  The panel name
121    */
122   public function removePanel($name)
123   {
124     unset($this->panels[$name]);
125   }
126
127   /**
128    * Gets an option value by name.
129    *
130    * @param  string $name  The option name
131    *
132    * @return mixed  The option value
133    */
134   public function getOption($name, $default = null)
135   {
136     return isset($this->options[$name]) ? $this->options[$name] : $default;
137   }
138
139   /**
140    * Injects the web debug toolbar into a given HTML string.
141    *
142    * @param string  $content The HTML content
143    *
144    * @return string The content with the web debug toolbar injected
145    */
146   public function injectToolbar($content)
147   {
148     $content = str_ireplace('</head>', '<style type="text/css">'.str_replace("\n", ' ', $this->getStylesheet()).'</style></head>', $content);
149
150     $debug = $this->asHtml();
151     $count = 0;
152     $content = str_ireplace('</body>', '<script type="text/javascript">'.$this->getJavascript().'</script>'.$debug.'</body>', $content, $count);
153     if (!$count)
154     {
155       $content .= $debug;
156     }
157
158     return $content;
159   }
160
161   /**
162    * Returns the web debug toolbar as HTML.
163    *
164    * @return string The web debug toolbar HTML
165    */
166   public function asHtml()
167   {
168     $titles = array();
169     $panels = array();
170     foreach ($this->panels as $name => $panel)
171     {
172       if ($title = $panel->getTitle())
173       {
174         if (($content = $panel->getPanelContent()) || $panel->getTitleUrl())
175         {
176           $id = sprintf('sfWebDebug%sDetails', $name);
177           $titles[]  = sprintf('<li><a title="%s" href="%s"%s>%s</a></li>',
178             $panel->getPanelTitle(),
179             $panel->getTitleUrl() ? $panel->getTitleUrl() : '#',
180             $panel->getTitleUrl() ? '' : ' onclick="sfWebDebugShowDetailsFor(\''.$id.'\'); return false;"',
181             $title
182           );
183           $panels[] = sprintf('<div id="%s" class="sfWebDebugTop" style="display: none"><h1>%s</h1>%s</div>',
184             $id,
185             $panel->getPanelTitle(),
186             $content
187           );
188         }
189         else
190         {
191           $titles[] = sprintf('<li>%s</li>', $title);
192         }
193       }
194     }
195
196     return '
197       <div id="sfWebDebug">
198         <div id="sfWebDebugBar" class="sfWebDebug'.ucfirst($this->getPriority($this->logger->getHighestPriority())).'">
199           <a href="#" onclick="sfWebDebugToggleMenu(); return false;"><img src="'.$this->options['image_root_path'].'/sf.png" alt="Debug toolbar" /></a>
200
201           <ul id="sfWebDebugDetails" class="sf_web_debug_menu">
202             '.implode("\n", $titles).'
203             <li class="last">
204               <a href="#" onclick="document.getElementById(\'sfWebDebug\').style.display=\'none\'; return false;"><img src="'.$this->options['image_root_path'].'/close.png" alt="Close" /></a>
205             </li>
206           </ul>
207         </div>
208
209         '.implode("\n", $panels).'
210       </div>
211     ';
212   }
213
214   /**
215    * Converts a priority value to a string.
216    *
217    * @param integer $value The priority value
218    *
219    * @return string The priority as a string
220    */
221   public function getPriority($value)
222   {
223     if ($value >= sfLogger::INFO)
224     {
225       return 'info';
226     }
227     else if ($value >= sfLogger::WARNING)
228     {
229       return 'warning';
230     }
231     else
232     {
233       return 'error';
234     }
235   }
236
237   /**
238    * Gets the javascript code to inject in the head tag.
239    *
240    * @param string The javascript code
241    */
242   public function getJavascript()
243   {
244     return <<<EOF
245 /* <![CDATA[ */
246 function sfWebDebugGetElementsByClassName(strClass, strTag, objContElm)
247 {
248   // http://muffinresearch.co.uk/archives/2006/04/29/getelementsbyclassname-deluxe-edition/
249   strTag = strTag || "*";
250   objContElm = objContElm || document;
251   var objColl = (strTag == '*' && document.all) ? document.all : objContElm.getElementsByTagName(strTag);
252   var arr = new Array();
253   var delim = strClass.indexOf('|') != -1  ? '|' : ' ';
254   var arrClass = strClass.split(delim);
255   var j = objColl.length;
256   for (var i = 0; i < j; i++) {
257     if(objColl[i].className == undefined) continue;
258     var arrObjClass = objColl[i].className.split(' ');
259     if (delim == ' ' && arrClass.length > arrObjClass.length) continue;
260     var c = 0;
261     comparisonLoop:
262     {
263       var l = arrObjClass.length;
264       for (var k = 0; k < l; k++) {
265         var n = arrClass.length;
266         for (var m = 0; m < n; m++) {
267           if (arrClass[m] == arrObjClass[k]) c++;
268           if (( delim == '|' && c == 1) || (delim == ' ' && c == arrClass.length)) {
269             arr.push(objColl[i]);
270             break comparisonLoop;
271           }
272         }
273       }
274     }
275   }
276   return arr;
277 }
278
279 function sfWebDebugToggleMenu()
280 {
281   var element = document.getElementById('sfWebDebugDetails');
282
283   var cacheElements = sfWebDebugGetElementsByClassName('sfWebDebugCache');
284   var mainCacheElements = sfWebDebugGetElementsByClassName('sfWebDebugActionCache');
285   var panelElements = sfWebDebugGetElementsByClassName('sfWebDebugTop');
286
287   if (element.style.display != 'none')
288   {
289     for (var i = 0; i < panelElements.length; ++i)
290     {
291       panelElements[i].style.display = 'none';
292     }
293
294     // hide all cache information
295     for (var i = 0; i < cacheElements.length; ++i)
296     {
297       cacheElements[i].style.display = 'none';
298     }
299     for (var i = 0; i < mainCacheElements.length; ++i)
300     {
301       mainCacheElements[i].style.border = 'none';
302     }
303   }
304   else
305   {
306     for (var i = 0; i < cacheElements.length; ++i)
307     {
308       cacheElements[i].style.display = '';
309     }
310     for (var i = 0; i < mainCacheElements.length; ++i)
311     {
312       mainCacheElements[i].style.border = '1px solid #f00';
313     }
314   }
315
316   sfWebDebugToggle('sfWebDebugDetails');
317   sfWebDebugToggle('sfWebDebugShowMenu');
318   sfWebDebugToggle('sfWebDebugHideMenu');
319 }
320
321 function sfWebDebugShowDetailsFor(element)
322 {
323   if (typeof element == 'string')
324     element = document.getElementById(element);
325
326   var panelElements = sfWebDebugGetElementsByClassName('sfWebDebugTop');
327   for (var i = 0; i < panelElements.length; ++i)
328   {
329     if (panelElements[i] != element)
330     {
331       panelElements[i].style.display = 'none';
332     }
333   }
334
335   sfWebDebugToggle(element);
336 }
337
338 function sfWebDebugToggle(element)
339 {
340   if (typeof element == 'string')
341     element = document.getElementById(element);
342
343   if (element)
344     element.style.display = element.style.display == 'none' ? '' : 'none';
345 }
346
347 function sfWebDebugToggleMessages(klass)
348 {
349   var elements = sfWebDebugGetElementsByClassName(klass);
350
351   var x = elements.length;
352   for (var i = 0; i < x; ++i)
353   {
354     sfWebDebugToggle(elements[i]);
355   }
356 }
357
358 function sfWebDebugToggleAllLogLines(show, klass)
359 {
360   var elements = sfWebDebugGetElementsByClassName(klass);
361   var x = elements.length;
362   for (var i = 0; i < x; ++i)
363   {
364     elements[i].style.display = show ? '' : 'none';
365   }
366 }
367
368 function sfWebDebugShowOnlyLogLines(type)
369 {
370   var types = new Array();
371   types[0] = 'info';
372   types[1] = 'warning';
373   types[2] = 'error';
374   for (klass in types)
375   {
376     var elements = sfWebDebugGetElementsByClassName('sfWebDebug' + types[klass].substring(0, 1).toUpperCase() + types[klass].substring(1, types[klass].length));
377     var x = elements.length;
378     for (var i = 0; i < x; ++i)
379     {
380       if ('tr' == elements[i].tagName.toLowerCase())
381       {
382         elements[i].style.display = (type == types[klass]) ? '' : 'none';
383       }
384     }
385   }
386 }
387 /* ]]> */
388 EOF;
389   }
390
391   /**
392    * Gets the stylesheet code to inject in the head tag.
393    *
394    * @param string The stylesheet code
395    */
396   public function getStylesheet()
397   {
398     return <<<EOF
399 #sfWebDebug
400 {
401   padding: 0;
402   margin: 0;
403   font-family: Arial, sans-serif;
404   font-size: 12px;
405   color: #333;
406   text-align: left;
407   line-height: 12px;
408 }
409
410 #sfWebDebug a, #sfWebDebug a:hover
411 {
412   text-decoration: none;
413   border: none;
414   background-color: transparent;
415   color: #000;
416 }
417
418 #sfWebDebug img
419 {
420   border: 0;
421 }
422
423 #sfWebDebugBar
424 {
425   position: absolute;
426   margin: 0;
427   padding: 1px 0;
428   right: 0px;
429   top: 0px;
430   opacity: 0.80;
431   filter: alpha(opacity:80);
432   z-index: 10000;
433   white-space: nowrap;
434 }
435
436 #sfWebDebugBar[id]
437 {
438   position: fixed;
439 }
440
441 #sfWebDebugBar img
442 {
443   vertical-align: middle;
444 }
445
446 #sfWebDebugBar .sf_web_debug_menu
447 {
448   padding: 5px;
449   padding-left: 0;
450   display: inline;
451   margin: 0;
452 }
453
454 #sfWebDebugBar .sf_web_debug_menu li
455 {
456   display: inline;
457   list-style: none;
458   margin: 0;
459   padding: 0 6px;
460 }
461
462 #sfWebDebugBar .sf_web_debug_menu li.last
463 {
464   margin: 0;
465   padding: 0;
466   border: 0;
467 }
468
469 #sfWebDebugDatabaseDetails li
470 {
471   margin: 0;
472   margin-left: 30px;
473   padding: 5px 0;
474 }
475
476 #sfWebDebugShortMessages li
477 {
478   margin-bottom: 10px;
479   padding: 5px;
480   background-color: #ddd;
481 }
482
483 #sfWebDebugShortMessages li
484 {
485   list-style: none;
486 }
487
488 #sfWebDebugDetails
489 {
490   margin-right: 7px;
491 }
492
493 #sfWebDebug pre
494 {
495   line-height: 1.3;
496   margin-bottom: 10px;
497 }
498
499 #sfWebDebug h1
500 {
501   font-size: 16px;
502   font-weight: bold;
503   margin-bottom: 20px;
504   padding: 0;
505   border: 0px;
506   background-color: #eee;
507 }
508
509 #sfWebDebug h2
510 {
511   font-size: 14px;
512   font-weight: bold;
513   margin: 10px 0;
514   padding: 0;
515   border: 0px;
516   background: none;
517 }
518
519 #sfWebDebug .sfWebDebugTop
520 {
521   position: absolute;
522   left: 0px;
523   top: 0px;
524   width: 98%;
525   padding: 0 1%;
526   margin: 0;
527   z-index: 9999;
528   background-color: #efefef;
529   border-bottom: 1px solid #aaa;
530 }
531
532 #sfWebDebugLog
533 {
534   margin: 0;
535   padding: 3px;
536   font-size: 11px;
537 }
538
539 #sfWebDebugLogMenu li
540 {
541   display: inline;
542   list-style: none;
543   margin: 0;
544   padding: 0 5px;
545   border-right: 1px solid #aaa;
546 }
547
548 #sfWebDebugConfigSummary
549 {
550   display: inline;
551   padding: 5px;
552   background-color: #ddd;
553   border: 1px solid #aaa;
554   margin: 20px 0;
555 }
556
557 #sfWebDebugConfigSummary li
558 {
559   list-style: none;
560   display: inline;
561   margin: 0;
562   padding: 0 5px;
563 }
564
565 #sfWebDebugConfigSummary li.last
566 {
567   border: 0;
568 }
569
570 .sfWebDebugInfo, .sfWebDebugInfo td
571 {
572   background-color: #ddd;
573 }
574
575 .sfWebDebugWarning, .sfWebDebugWarning td
576 {
577   background-color: orange;
578 }
579
580 .sfWebDebugError, .sfWebDebugError td
581 {
582   background-color: #f99;
583 }
584
585 .sfWebDebugLogNumber
586 {
587   width: 1%;
588 }
589
590 .sfWebDebugLogType
591 {
592   width: 1%;
593   white-space: nowrap;
594   color: darkgreen;
595 }
596
597 .sfWebDebugLogInfo
598 {
599   color: blue;
600 }
601
602 .ison
603 {
604   color: #3f3;
605   margin-right: 5px;
606 }
607
608 .isoff
609 {
610   color: #f33;
611   margin-right: 5px;
612   text-decoration: line-through;
613 }
614
615 .sfWebDebugLogs
616 {
617   padding: 0;
618   margin: 0;
619   border: 1px solid #999;
620   font-family: Arial;
621   font-size: 11px;
622 }
623
624 .sfWebDebugLogs tr
625 {
626   padding: 0;
627   margin: 0;
628   border: 0;
629 }
630
631 .sfWebDebugLogs td
632 {
633   margin: 0;
634   border: 0;
635   padding: 1px 3px;
636   vertical-align: top;
637 }
638
639 .sfWebDebugLogs th
640 {
641   margin: 0;
642   border: 0;
643   padding: 3px 5px;
644   vertical-align: top;
645   background-color: #999;
646   color: #eee;
647   white-space: nowrap;
648 }
649
650 .sfWebDebugDebugInfo
651 {
652   margin-left: 10px;
653   padding-left: 5px;
654   border-left: 1px solid #aaa;
655 }
656
657 .sfWebDebugCache
658 {
659   padding: 0;
660   margin: 0;
661   font-family: Arial;
662   position: absolute;
663   overflow: hidden;
664   z-index: 995;
665   font-size: 9px;
666   padding: 2px;
667   filter:alpha(opacity=85);
668   -moz-opacity:0.85;
669   opacity: 0.85;
670 }
671
672 #sfWebDebugSymfonyVersion
673 {
674   margin-left: 0;
675   padding: 1px 4px;
676   background-color: #666;
677   color: #fff;
678 }
679 EOF;
680   }
681 }
682
Note: See TracBrowser for help on using the browser.