Development

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

You must first sign up to be able to contribute.

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

Revision 32890, 15.9 kB (checked in by fabien, 3 years ago)

[1.4] fixed bad value of property 'list-style' in css of WebDebug? toolbar (closes #9891 - patch from tomi)

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