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) 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: sfWebDebug.class.php 31254 2010-10-26 15:26:03Z fabien $
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: number;
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
}