PageRenderTime 178ms CodeModel.GetById 15ms app.highlight 30ms RepoModel.GetById 125ms app.codeStats 0ms

/Wildfire/Plugin/FirePhp.php

https://bitbucket.org/bigstylee/zend-framework
PHP | 823 lines | 449 code | 127 blank | 247 comment | 93 complexity | 88d506a552f2ee65119f21bebe2d50b5 MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @category   Zend
 16 * @package    Zend_Wildfire
 17 * @subpackage Plugin
 18 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: FirePhp.php 24593 2012-01-05 20:35:02Z matthew $
 21 */
 22
 23/** Zend_Controller_Request_Abstract */
 24require_once('Zend/Controller/Request/Abstract.php');
 25
 26/** Zend_Controller_Response_Abstract */
 27require_once('Zend/Controller/Response/Abstract.php');
 28
 29/** Zend_Wildfire_Channel_HttpHeaders */
 30require_once 'Zend/Wildfire/Channel/HttpHeaders.php';
 31
 32/** Zend_Wildfire_Protocol_JsonStream */
 33require_once 'Zend/Wildfire/Protocol/JsonStream.php';
 34
 35/** Zend_Wildfire_Plugin_Interface */
 36require_once 'Zend/Wildfire/Plugin/Interface.php';
 37
 38/**
 39 * Primary class for communicating with the FirePHP Firefox Extension.
 40 *
 41 * @category   Zend
 42 * @package    Zend_Wildfire
 43 * @subpackage Plugin
 44 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 45 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 46 */
 47class Zend_Wildfire_Plugin_FirePhp implements Zend_Wildfire_Plugin_Interface
 48{
 49    /**
 50     * Plain log style.
 51     */
 52    const LOG = 'LOG';
 53
 54    /**
 55     * Information style.
 56     */
 57    const INFO = 'INFO';
 58
 59    /**
 60     * Warning style.
 61     */
 62    const WARN = 'WARN';
 63
 64    /**
 65     * Error style that increments Firebug's error counter.
 66     */
 67    const ERROR = 'ERROR';
 68
 69    /**
 70     * Trace style showing message and expandable full stack trace.
 71     */
 72    const TRACE = 'TRACE';
 73
 74    /**
 75     * Exception style showing message and expandable full stack trace.
 76     * Also increments Firebug's error counter.
 77     */
 78    const EXCEPTION = 'EXCEPTION';
 79
 80    /**
 81     * Table style showing summary line and expandable table
 82     */
 83    const TABLE = 'TABLE';
 84
 85    /**
 86     * Dump variable to Server panel in Firebug Request Inspector
 87     */
 88    const DUMP = 'DUMP';
 89
 90    /**
 91     * Start a group in the Firebug Console
 92     */
 93    const GROUP_START = 'GROUP_START';
 94
 95    /**
 96     * End a group in the Firebug Console
 97     */
 98    const GROUP_END = 'GROUP_END';
 99
100    /**
101     * The plugin URI for this plugin
102     */
103    const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/ZendFramework/FirePHP/1.6.2';
104
105    /**
106     * The protocol URI for this plugin
107     */
108    const PROTOCOL_URI = Zend_Wildfire_Protocol_JsonStream::PROTOCOL_URI;
109
110    /**
111     * The structure URI for the Dump structure
112     */
113    const STRUCTURE_URI_DUMP = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1';
114
115    /**
116     * The structure URI for the Firebug Console structure
117     */
118    const STRUCTURE_URI_FIREBUGCONSOLE = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1';
119
120    /**
121     * Singleton instance
122     * @var Zend_Wildfire_Plugin_FirePhp
123     */
124    protected static $_instance = null;
125
126    /**
127     * Flag indicating whether FirePHP should send messages to the user-agent.
128     * @var boolean
129     */
130    protected $_enabled = true;
131
132    /**
133     * The channel via which to send the encoded messages.
134     * @var Zend_Wildfire_Channel_Interface
135     */
136    protected $_channel = null;
137
138    /**
139     * Messages that are buffered to be sent when protocol flushes
140     * @var array
141     */
142    protected $_messages = array();
143
144    /**
145     * Options for the object
146     * @var array
147     */
148    protected $_options = array(
149        'traceOffset' => 1, /* The offset in the trace which identifies the source of the message */
150        'maxTraceDepth' => 99, /* Maximum depth for stack traces */
151        'maxObjectDepth' => 10, /* The maximum depth to traverse objects when encoding */
152        'maxArrayDepth' => 20, /* The maximum depth to traverse nested arrays when encoding */
153        'includeLineNumbers' => true /* Whether to include line and file info for each message */
154    );
155
156    /**
157     * Filters used to exclude object members when encoding
158     * @var array
159     */
160    protected $_objectFilters = array();
161
162    /**
163     * A stack of objects used during encoding to detect recursion
164     * @var array
165     */
166    protected $_objectStack = array();
167
168    /**
169     * Create singleton instance.
170     *
171     * @param string $class OPTIONAL Subclass of Zend_Wildfire_Plugin_FirePhp
172     * @return Zend_Wildfire_Plugin_FirePhp Returns the singleton Zend_Wildfire_Plugin_FirePhp instance
173     * @throws Zend_Wildfire_Exception
174     */
175    public static function init($class = null)
176    {
177        if (self::$_instance !== null) {
178            require_once 'Zend/Wildfire/Exception.php';
179            throw new Zend_Wildfire_Exception('Singleton instance of Zend_Wildfire_Plugin_FirePhp already exists!');
180        }
181        if ($class !== null) {
182            if (!is_string($class)) {
183                require_once 'Zend/Wildfire/Exception.php';
184                throw new Zend_Wildfire_Exception('Third argument is not a class string');
185            }
186
187            if (!class_exists($class)) {
188                require_once 'Zend/Loader.php';
189                Zend_Loader::loadClass($class);
190            }
191            self::$_instance = new $class();
192            if (!self::$_instance instanceof Zend_Wildfire_Plugin_FirePhp) {
193                self::$_instance = null;
194                require_once 'Zend/Wildfire/Exception.php';
195                throw new Zend_Wildfire_Exception('Invalid class to third argument. Must be subclass of Zend_Wildfire_Plugin_FirePhp.');
196            }
197        } else {
198            self::$_instance = new self();
199        }
200
201        return self::$_instance;
202    }
203
204    /**
205     * Constructor
206     * @return void
207     */
208    protected function __construct()
209    {
210        $this->_channel = Zend_Wildfire_Channel_HttpHeaders::getInstance();
211        $this->_channel->getProtocol(self::PROTOCOL_URI)->registerPlugin($this);
212    }
213
214    /**
215     * Get or create singleton instance
216     *
217     * @param bool $skipCreate True if an instance should not be created
218     * @return Zend_Wildfire_Plugin_FirePhp
219     */
220    public static function getInstance($skipCreate=false)
221    {
222        if (self::$_instance===null && $skipCreate!==true) {
223            return self::init();
224        }
225        return self::$_instance;
226    }
227
228    /**
229     * Destroys the singleton instance
230     *
231     * Primarily used for testing.
232     *
233     * @return void
234     */
235    public static function destroyInstance()
236    {
237        self::$_instance = null;
238    }
239
240    /**
241     * Enable or disable sending of messages to user-agent.
242     * If disabled all headers to be sent will be removed.
243     *
244     * @param boolean $enabled Set to TRUE to enable sending of messages.
245     * @return boolean The previous value.
246     */
247    public function setEnabled($enabled)
248    {
249        $previous = $this->_enabled;
250        $this->_enabled = $enabled;
251        if (!$this->_enabled) {
252            $this->_messages = array();
253            $this->_channel->getProtocol(self::PROTOCOL_URI)->clearMessages($this);
254        }
255        return $previous;
256    }
257
258    /**
259     * Determine if logging to user-agent is enabled.
260     *
261     * @return boolean Returns TRUE if logging is enabled.
262     */
263    public function getEnabled()
264    {
265        return $this->_enabled;
266    }
267
268    /**
269     * Set a single option
270     *
271     * @param  string $key The name of the option
272     * @param  mixed $value The value of the option
273     * @return mixed The previous value of the option
274     */
275    public function setOption($key, $value)
276    {
277      if (!array_key_exists($key,$this->_options)) {
278        throw new Zend_Wildfire_Exception('Option with name "'.$key.'" does not exist!');
279      }
280      $previous = $this->_options[$key];
281      $this->_options[$key] = $value;
282      return $previous;
283    }
284
285    /**
286     * Retrieve a single option
287     *
288     * @param  string $key The name of the option
289     * @return mixed The value of the option
290     */
291    public function getOption($key)
292    {
293      if (!array_key_exists($key,$this->_options)) {
294        throw new Zend_Wildfire_Exception('Option with name "'.$key.'" does not exist!');
295      }
296      return $this->_options[$key];
297    }
298
299    /**
300     * Retrieve all options
301     *
302     * @return array All options
303     */
304    public function getOptions()
305    {
306      return $this->_options;
307    }
308
309    /**
310     * Specify a filter to be used when encoding an object
311     *
312     * Filters are used to exclude object members.
313     *
314     * @param string $Class The class name of the object
315     * @param array $Filter An array of members to exclude
316     * @return void
317     */
318    public function setObjectFilter($class, $filter) {
319      $this->_objectFilters[$class] = $filter;
320    }
321
322    /**
323     * Starts a group in the Firebug Console
324     *
325     * @param string $title The title of the group
326     * @param array $options OPTIONAL Setting 'Collapsed' to true will initialize group collapsed instead of expanded
327     * @return TRUE if the group instruction was added to the response headers or buffered.
328     */
329    public static function group($title, $options=array())
330    {
331        return self::send(null, $title, self::GROUP_START, $options);
332    }
333
334    /**
335     * Ends a group in the Firebug Console
336     *
337     * @return TRUE if the group instruction was added to the response headers or buffered.
338     */
339    public static function groupEnd()
340    {
341        return self::send(null, null, self::GROUP_END);
342    }
343
344    /**
345     * Logs variables to the Firebug Console
346     * via HTTP response headers and the FirePHP Firefox Extension.
347     *
348     * @param  mixed  $var   The variable to log.
349     * @param  string  $label OPTIONAL Label to prepend to the log event.
350     * @param  string  $style  OPTIONAL Style of the log event.
351     * @param  array  $options OPTIONAL Options to change how messages are processed and sent
352     * @return boolean Returns TRUE if the variable was added to the response headers or buffered.
353     * @throws Zend_Wildfire_Exception
354     */
355    public static function send($var, $label=null, $style=null, $options=array())
356    {
357        $firephp = self::getInstance();
358
359        if (!$firephp->getEnabled()) {
360            return false;
361        }
362
363        if ($var instanceof Zend_Wildfire_Plugin_FirePhp_Message) {
364
365            if ($var->getBuffered()) {
366                if (!in_array($var, self::$_instance->_messages)) {
367                    self::$_instance->_messages[] = $var;
368                }
369                return true;
370            }
371
372            if ($var->getDestroy()) {
373                return false;
374            }
375
376            $style = $var->getStyle();
377            $label = $var->getLabel();
378            $options = $var->getOptions();
379            $var = $var->getMessage();
380        }
381
382        if (!self::$_instance->_channel->isReady()) {
383            return false;
384        }
385
386        foreach ($options as $name => $value) {
387            if ($value===null) {
388                unset($options[$name]);
389            }
390        }
391        $options = array_merge($firephp->getOptions(), $options);
392
393        $trace = null;
394
395        $skipFinalEncode = false;
396
397        $meta = array();
398        $meta['Type'] = $style;
399
400        if ($var instanceof Exception) {
401
402            $eTrace = $var->getTrace();
403            $eTrace = array_splice($eTrace, 0, $options['maxTraceDepth']);
404
405            $var = array('Class'=>get_class($var),
406                         'Message'=>$var->getMessage(),
407                         'File'=>$var->getFile(),
408                         'Line'=>$var->getLine(),
409                         'Type'=>'throw',
410                         'Trace'=>$firephp->_encodeTrace($eTrace));
411
412            $meta['Type'] = self::EXCEPTION;
413
414            $skipFinalEncode = true;
415
416        } else
417        if ($meta['Type']==self::TRACE) {
418
419            if (!$label && $var) {
420                $label = $var;
421                $var = null;
422            }
423
424            if (!$trace) {
425                $trace = $firephp->_getStackTrace(array_merge($options,
426                                                              array('maxTraceDepth'=>$options['maxTraceDepth']+1)));
427            }
428
429            $var = array('Class'=>$trace[0]['class'],
430                         'Type'=>$trace[0]['type'],
431                         'Function'=>$trace[0]['function'],
432                         'Message'=>$label,
433                         'File'=>isset($trace[0]['file'])?$trace[0]['file']:'',
434                         'Line'=>isset($trace[0]['line'])?$trace[0]['line']:'',
435                         'Args'=>isset($trace[0]['args'])?$firephp->_encodeObject($trace[0]['args']):'',
436                         'Trace'=>$firephp->_encodeTrace(array_splice($trace,1)));
437
438          $skipFinalEncode = true;
439
440        } else
441        if ($meta['Type']==self::TABLE) {
442
443          $var = $firephp->_encodeTable($var);
444
445          $skipFinalEncode = true;
446
447        } else {
448            if ($meta['Type']===null) {
449                $meta['Type'] = self::LOG;
450            }
451        }
452
453        if ($label!=null) {
454            $meta['Label'] = $label;
455        }
456
457        switch ($meta['Type']) {
458            case self::LOG:
459            case self::INFO:
460            case self::WARN:
461            case self::ERROR:
462            case self::EXCEPTION:
463            case self::TRACE:
464            case self::TABLE:
465            case self::DUMP:
466            case self::GROUP_START:
467            case self::GROUP_END:
468                break;
469            default:
470                require_once 'Zend/Wildfire/Exception.php';
471                throw new Zend_Wildfire_Exception('Log style "'.$meta['Type'].'" not recognized!');
472                break;
473        }
474
475        if ($meta['Type'] != self::DUMP && $options['includeLineNumbers']) {
476            if (!isset($meta['File']) || !isset($meta['Line'])) {
477
478                if (!$trace) {
479                    $trace = $firephp->_getStackTrace(array_merge($options,
480                                                                  array('maxTraceDepth'=>$options['maxTraceDepth']+1)));
481                }
482
483                $meta['File'] = isset($trace[0]['file'])?$trace[0]['file']:'';
484                $meta['Line'] = isset($trace[0]['line'])?$trace[0]['line']:'';
485
486            }
487        } else {
488            unset($meta['File']);
489            unset($meta['Line']);
490        }
491
492        if ($meta['Type'] == self::GROUP_START) {
493            if (isset($options['Collapsed'])) {
494                $meta['Collapsed'] = ($options['Collapsed'])?'true':'false';
495            }
496        }
497
498        if ($meta['Type'] == self::DUMP) {
499
500          return $firephp->_recordMessage(self::STRUCTURE_URI_DUMP,
501                                          array('key'=>$meta['Label'],
502                                                'data'=>$var),
503                                          $skipFinalEncode);
504
505        } else {
506
507          return $firephp->_recordMessage(self::STRUCTURE_URI_FIREBUGCONSOLE,
508                                          array('data'=>$var,
509                                                'meta'=>$meta),
510                                          $skipFinalEncode);
511        }
512    }
513
514    /**
515     * Gets a stack trace
516     *
517     * @param array $options Options to change how the stack trace is returned
518     * @return array The stack trace
519     */
520    protected function _getStackTrace($options)
521    {
522        $trace = debug_backtrace();
523
524        $trace = array_splice($trace, $options['traceOffset']);
525
526        if (!count($trace)) {
527            return $trace;
528        }
529
530        if (isset($options['fixZendLogOffsetIfApplicable']) && $options['fixZendLogOffsetIfApplicable']) {
531            if (count($trace) >=3 &&
532                isset($trace[0]['file']) && substr($trace[0]['file'], -7, 7)=='Log.php' &&
533                isset($trace[1]['function']) && $trace[1]['function']=='__call') {
534
535                $trace = array_splice($trace, 2);
536            }
537        }
538
539        return array_splice($trace, 0, $options['maxTraceDepth']);
540    }
541
542    /**
543     * Record a message with the given data in the given structure
544     *
545     * @param string $structure The structure to be used for the data
546     * @param array $data The data to be recorded
547     * @param boolean $skipEncode TRUE if variable encoding should be skipped
548     * @return boolean Returns TRUE if message was recorded
549     * @throws Zend_Wildfire_Exception
550     */
551    protected function _recordMessage($structure, $data, $skipEncode=false)
552    {
553        switch($structure) {
554
555            case self::STRUCTURE_URI_DUMP:
556
557                if (!isset($data['key'])) {
558                    require_once 'Zend/Wildfire/Exception.php';
559                    throw new Zend_Wildfire_Exception('You must supply a key.');
560                }
561                if (!array_key_exists('data',$data)) {
562                    require_once 'Zend/Wildfire/Exception.php';
563                    throw new Zend_Wildfire_Exception('You must supply data.');
564                }
565
566                $value = $data['data'];
567                if (!$skipEncode) {
568                  $value = $this->_encodeObject($data['data']);
569                }
570
571                return $this->_channel->getProtocol(self::PROTOCOL_URI)->
572                           recordMessage($this,
573                                         $structure,
574                                         array($data['key']=>$value));
575
576            case self::STRUCTURE_URI_FIREBUGCONSOLE:
577
578                if (!isset($data['meta']) ||
579                    !is_array($data['meta']) ||
580                    !array_key_exists('Type',$data['meta'])) {
581
582                    require_once 'Zend/Wildfire/Exception.php';
583                    throw new Zend_Wildfire_Exception('You must supply a "Type" in the meta information.');
584                }
585                if (!array_key_exists('data',$data)) {
586                    require_once 'Zend/Wildfire/Exception.php';
587                    throw new Zend_Wildfire_Exception('You must supply data.');
588                }
589
590                $value = $data['data'];
591                if (!$skipEncode) {
592                  $value = $this->_encodeObject($data['data']);
593                }
594
595                return $this->_channel->getProtocol(self::PROTOCOL_URI)->
596                           recordMessage($this,
597                                         $structure,
598                                         array($data['meta'],
599                                               $value));
600
601            default:
602                require_once 'Zend/Wildfire/Exception.php';
603                throw new Zend_Wildfire_Exception('Structure of name "'.$structure.'" is not recognized.');
604                break;
605        }
606        return false;
607    }
608
609    /**
610     * Encodes a table by encoding each row and column with _encodeObject()
611     *
612     * @param array $Table The table to be encoded
613     * @return array
614     */
615    protected function _encodeTable($table)
616    {
617      if (!$table) {
618          return $table;
619      }
620      for ($i=0 ; $i<count($table) ; $i++) {
621          if (is_array($table[$i])) {
622              for ($j=0 ; $j<count($table[$i]) ; $j++) {
623                  $table[$i][$j] = $this->_encodeObject($table[$i][$j]);
624              }
625          }
626        }
627      return $table;
628    }
629
630    /**
631     * Encodes a trace by encoding all "args" with _encodeObject()
632     *
633     * @param array $Trace The trace to be encoded
634     * @return array The encoded trace
635     */
636    protected function _encodeTrace($trace)
637    {
638      if (!$trace) {
639          return $trace;
640      }
641      for ($i=0 ; $i<sizeof($trace) ; $i++) {
642          if (isset($trace[$i]['args'])) {
643              $trace[$i]['args'] = $this->_encodeObject($trace[$i]['args']);
644          }
645      }
646      return $trace;
647    }
648
649    /**
650     * Encode an object by generating an array containing all object members.
651     *
652     * All private and protected members are included. Some meta info about
653     * the object class is added.
654     *
655     * @param mixed $object The object/array/value to be encoded
656     * @return array The encoded object
657     */
658    protected function _encodeObject($object, $objectDepth = 1, $arrayDepth = 1)
659    {
660        $return = array();
661
662        if (is_resource($object)) {
663
664            return '** '.(string)$object.' **';
665
666        } else
667        if (is_object($object)) {
668
669            if ($objectDepth > $this->_options['maxObjectDepth']) {
670              return '** Max Object Depth ('.$this->_options['maxObjectDepth'].') **';
671            }
672
673            foreach ($this->_objectStack as $refVal) {
674                if ($refVal === $object) {
675                    return '** Recursion ('.get_class($object).') **';
676                }
677            }
678            array_push($this->_objectStack, $object);
679
680            $return['__className'] = $class = get_class($object);
681
682            $reflectionClass = new ReflectionClass($class);
683            $properties = array();
684            foreach ( $reflectionClass->getProperties() as $property) {
685                $properties[$property->getName()] = $property;
686            }
687
688            $members = (array)$object;
689
690            foreach ($properties as $just_name => $property) {
691
692                $name = $raw_name = $just_name;
693
694                if ($property->isStatic()) {
695                    $name = 'static:'.$name;
696                }
697                if ($property->isPublic()) {
698                    $name = 'public:'.$name;
699                } else
700                if ($property->isPrivate()) {
701                    $name = 'private:'.$name;
702                    $raw_name = "\0".$class."\0".$raw_name;
703                } else
704                if ($property->isProtected()) {
705                    $name = 'protected:'.$name;
706                    $raw_name = "\0".'*'."\0".$raw_name;
707                }
708
709                if (!(isset($this->_objectFilters[$class])
710                      && is_array($this->_objectFilters[$class])
711                      && in_array($just_name,$this->_objectFilters[$class]))) {
712
713                    if (array_key_exists($raw_name,$members)
714                        && !$property->isStatic()) {
715
716                        $return[$name] = $this->_encodeObject($members[$raw_name], $objectDepth + 1, 1);
717
718                    } else {
719                        if (method_exists($property,'setAccessible')) {
720                            $property->setAccessible(true);
721                            $return[$name] = $this->_encodeObject($property->getValue($object), $objectDepth + 1, 1);
722                        } else
723                        if ($property->isPublic()) {
724                            $return[$name] = $this->_encodeObject($property->getValue($object), $objectDepth + 1, 1);
725                        } else {
726                            $return[$name] = '** Need PHP 5.3 to get value **';
727                        }
728                    }
729                } else {
730                  $return[$name] = '** Excluded by Filter **';
731                }
732            }
733
734            // Include all members that are not defined in the class
735            // but exist in the object
736            foreach($members as $just_name => $value) {
737
738                $name = $raw_name = $just_name;
739
740                if ($name{0} == "\0") {
741                    $parts = explode("\0", $name);
742                    $name = $parts[2];
743                }
744                if (!isset($properties[$name])) {
745                    $name = 'undeclared:'.$name;
746
747                    if (!(isset($this->objectFilters[$class])
748                          && is_array($this->objectFilters[$class])
749                          && in_array($just_name,$this->objectFilters[$class]))) {
750
751                      $return[$name] = $this->_encodeObject($value, $objectDepth + 1, 1);
752                    } else {
753                      $return[$name] = '** Excluded by Filter **';
754                    }
755                }
756            }
757
758            array_pop($this->_objectStack);
759
760        } elseif (is_array($object)) {
761
762            if ($arrayDepth > $this->_options['maxArrayDepth']) {
763              return '** Max Array Depth ('.$this->_options['maxArrayDepth'].') **';
764            }
765
766            foreach ($object as $key => $val) {
767
768              // Encoding the $GLOBALS PHP array causes an infinite loop
769              // if the recursion is not reset here as it contains
770              // a reference to itself. This is the only way I have come up
771              // with to stop infinite recursion in this case.
772              if ($key=='GLOBALS'
773                  && is_array($val)
774                  && array_key_exists('GLOBALS',$val)) {
775
776                  $val['GLOBALS'] = '** Recursion (GLOBALS) **';
777              }
778              $return[$key] = $this->_encodeObject($val, 1, $arrayDepth + 1);
779            }
780        } else {
781            return $object;
782        }
783        return $return;
784    }
785
786    /*
787     * Zend_Wildfire_Plugin_Interface
788     */
789
790    /**
791     * Get the unique indentifier for this plugin.
792     *
793     * @return string Returns the URI of the plugin.
794     */
795    public function getUri()
796    {
797        return self::PLUGIN_URI;
798    }
799
800    /**
801     * Flush any buffered data.
802     *
803     * @param string $protocolUri The URI of the protocol that should be flushed to
804     * @return void
805     */
806    public function flushMessages($protocolUri)
807    {
808        if (!$this->_messages || $protocolUri!=self::PROTOCOL_URI) {
809            return;
810        }
811
812        foreach( $this->_messages as $message ) {
813            if (!$message->getDestroy()) {
814                $this->send($message->getMessage(),
815                            $message->getLabel(),
816                            $message->getStyle(),
817                            $message->getOptions());
818            }
819        }
820
821        $this->_messages = array();
822    }
823}