321bbb5d14049f68bc7f09d6ce99fbc1eec5617d
[atutor.git] / mods / phpdoc2 / PhpDocumentor / phpDocumentor / ParserData.inc
1 <?php\r
2 /**\r
3  * Parser Data Structures\r
4  * \r
5  * phpDocumentor :: automatic documentation generator\r
6  * \r
7  * PHP versions 4 and 5\r
8  *\r
9  * Copyright (c) 2002-2006 Gregory Beaver\r
10  * \r
11  * LICENSE:\r
12  * \r
13  * This library is free software; you can redistribute it\r
14  * and/or modify it under the terms of the GNU Lesser General\r
15  * Public License as published by the Free Software Foundation;\r
16  * either version 2.1 of the License, or (at your option) any\r
17  * later version.\r
18  * \r
19  * This library is distributed in the hope that it will be useful,\r
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
22  * Lesser General Public License for more details.\r
23  * \r
24  * You should have received a copy of the GNU Lesser General Public\r
25  * License along with this library; if not, write to the Free Software\r
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
27  *\r
28  * @package    phpDocumentor\r
29  * @subpackage ParserData\r
30  * @author     Gregory Beaver <cellog@php.net>\r
31  * @copyright  2002-2006 Gregory Beaver\r
32  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL\r
33  * @version    CVS: $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $\r
34  * @link       http://www.phpdoc.org\r
35  * @link       http://pear.php.net/PhpDocumentor\r
36  * @since      1.0rc1\r
37  */\r
38 /**\r
39  * Contains information about a PHP file, used to group procedural elements\r
40  * together.\r
41  * @package phpDocumentor\r
42  * @subpackage ParserData\r
43  * @author Greg Beaver <cellog@php.net>\r
44  * @since 1.0rc1\r
45  * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $\r
46  */\r
47 class parserPage\r
48 {\r
49     /**\r
50      * Type is used by many functions to skip the hassle of if\r
51      * <code>phpDocumentor_get_class($blah) == 'parserBlah'</code>\r
52      * @var string\r
53      */\r
54     var $type = 'page';\r
55     /**\r
56      * not implemented in this version, will be used to link xml output pages\r
57      * @var string\r
58      */\r
59     var $id = '';\r
60     /**\r
61      * filename.ext (no path)\r
62      * @var string\r
63      */\r
64     var $file = '';\r
65     /**\r
66      * relative source location\r
67      * @var string\r
68      */\r
69     var $sourceLocation = '';\r
70     /**\r
71      * phpdoc-safe name (only letters, numbers and _)\r
72      * @var string\r
73      */\r
74     var $name = '';\r
75     /**\r
76      * original phpdoc-safe name (only letters, numbers and _)\r
77      * \r
78      * This fixes [ 1391432 ] Too many underscores in include links.\r
79      * @var string\r
80      */\r
81     var $origName = '';\r
82     /**\r
83      * @var string\r
84      */\r
85     var $category = 'default';\r
86     /**\r
87      * @var string\r
88      */\r
89     var $package = 'default';\r
90     /**\r
91      * @var string\r
92      */\r
93     var $subpackage = '';\r
94     /**\r
95      * @var string\r
96      */\r
97     var $parserVersion = PHPDOCUMENTOR_VER;\r
98     /**\r
99      * not implemented yet\r
100      * file modification date, will be used for makefiles\r
101      * @var string\r
102      */\r
103     var $modDate = '';\r
104     /**\r
105      * @var string full path this page represents\r
106      */\r
107     var $path = '';\r
108     /**\r
109      * Tokenized source code of the file\r
110      * @var array\r
111      */\r
112     var $source = array();\r
113     /**\r
114      * Used to limit output, contains contents of --packageoutput commandline.\r
115      * Does not increase parsing time.  Use --ignore for that\r
116      * @see phpDocumentor_IntermediateParser::$packageoutput, Converter::$package_output\r
117      * @var mixed either false or an array of packages\r
118      */\r
119     var $packageOutput = false;\r
120     \r
121     /**\r
122      * sets package to default package\r
123      * @global string default package name\r
124      */\r
125     function parserPage()\r
126     {\r
127         global $phpDocumentor_DefaultPackageName;\r
128         $this->package = $GLOBALS['phpDocumentor_DefaultPackageName'];\r
129     }\r
130     \r
131     /**\r
132      * @return string always "page"\r
133      */\r
134     function getType()\r
135     {\r
136         return 'page';\r
137     }\r
138     \r
139     /**\r
140      * Sets the source code of the file for highlighting.\r
141      *\r
142      * PHP 4.3.0+ passes an array of tokenizer tokens by line number.  PHP\r
143      * 4.2.3- passes a string to be passed to {@link highlight_string()}\r
144      * @param string|array\r
145      */\r
146     function setSource($source)\r
147     {\r
148         $this->source = $source;\r
149     }\r
150     \r
151     /**\r
152      * Sets the name to display in documentation (can be an alias set with @name)\r
153      * @param string $file\r
154      */\r
155     function setFile($file)\r
156     {\r
157         $this->file = $file;\r
158     }\r
159     \r
160     /**\r
161      * @return string filename.ext or @name alias\r
162      */\r
163     function getFile()\r
164     {\r
165         if (!isset($this->file)) return false;\r
166         return $this->file;\r
167     }\r
168     \r
169     /**\r
170      * @param string $path full path to file\r
171      */\r
172     function setPath($path)\r
173     {\r
174         // look for special windows case\r
175         if(SMART_PATH_DELIMITER === '\\')\r
176             $this->path = strtr($path,'/','\\');\r
177         else\r
178             $this->path = $path;\r
179     }\r
180     \r
181     /**\r
182      * @return string fully delimited path (OS-dependent format)\r
183      */\r
184     function getPath()\r
185     {\r
186         if (!isset($this->path)) return false;\r
187         return $this->path;\r
188     }\r
189     \r
190     /**\r
191      * @param array $packages array of packages to display in documentation (package1,package2,...)\r
192      * @see phpDocumentor_IntermediateParser::$packageoutput\r
193      */\r
194     function setPackageOutput($packages)\r
195     {\r
196         $this->packageOutput = $packages;\r
197     }\r
198     \r
199     /**\r
200      * @return array array of packages (package1,package2,...)\r
201      * @see phpDocumentor_IntermediateParser::$packageoutput\r
202      */\r
203     function getPackageOutput()\r
204     {\r
205         return $this->packageOutput;\r
206     }\r
207     \r
208     /**\r
209      * @param string $name phpdoc-safe name (only _, numbers and letters) set by Parser::parse()\r
210      * @see Parser::parse()\r
211      */\r
212     function setName($name)\r
213     {\r
214         $this->origName = $name;\r
215         $this->name = $name;\r
216     }\r
217     \r
218     /**\r
219      * @return string phpdoc-safe name (only _, numbers and letters)\r
220      */\r
221     function getName()\r
222     {\r
223         if (!isset($this->name)) return false;\r
224         return $this->name;\r
225     }\r
226     \r
227     /**\r
228      * @param string $source path of this file relative to program root\r
229      */\r
230     function setSourceLocation($source)\r
231     {\r
232         $this->sourceLocation = $source;\r
233     }\r
234     \r
235     /**\r
236     * @param Converter\r
237     * @param boolean if this parameter is true, it will truncate the source location to the\r
238     * subdirectory of pear\r
239     * @return string path of this file relative to program root\r
240     * @todo determine if the str_replace in the 'pear/' ELSE branch should be removed \r
241     *       (see Documentation/tests/bug1574043.php).  It does NOT exist in the similar\r
242     *       function parserClass->getSourceLocation() in ParserElements.inc.\r
243     */\r
244     function getSourceLocation ($c,$pearize = false)\r
245     {\r
246         global $_phpDocumentor_options;\r
247         if (!isset($this->sourceLocation)) \r
248         {\r
249             $sl = false;   \r
250         }\r
251         else \r
252         {\r
253             $sl = $this->sourceLocation;\r
254             if ($pearize)\r
255             {\r
256                 if (strpos($sl,'pear/'))\r
257                 {\r
258                     $sl = substr($sl,strpos($sl,'pear/') + 5);\r
259                 } \r
260                 else\r
261                 {\r
262                     $sl = str_replace($_phpDocumentor_options['Program_Root'] . PATH_DELIMITER,'',$sl);\r
263                 }\r
264             }\r
265         }\r
266         return $sl;\r
267     }\r
268     /**\r
269      * Not implemented in this version\r
270      * @return boolean tell the parser whether to parse the file, otherwise\r
271      *                   this function will retrieve the parsed data from external file\r
272      */\r
273     function getParseData()\r
274     {\r
275         return true;\r
276     }\r
277 }\r
278 \r
279 /**\r
280  * Contains an in-memory representation of all documentable elements\r
281  * ({@link parserPage}, {@link parserFunction}, {@link parserDefine},\r
282  * {@link parserInclude}, {@link parserClass}, {@link parserMethod},\r
283  * {@link parserVar}) and their DocBlocks ({@link parserDocBlock}).\r
284  *\r
285  * This class works in coordination with {@link phpDocumentor_IntermediateParser}\r
286  * to take output from {@link Parser::handleEvent()} and create indexes, links,\r
287  * and other assorted things (all documented in phpDocumentor_IntermediateParser\r
288  * and {@link Converter})\r
289  * @package phpDocumentor\r
290  * @subpackage ParserData\r
291  * @author Greg Beaver <cellog@php.net>\r
292  * @since 1.0rc1\r
293  * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $\r
294  */\r
295 class parserData\r
296 {\r
297     /**\r
298      * {@link parserPage} element that is this parserData's parent, or false if\r
299      * not set.\r
300      * @var false|parserPage\r
301      */\r
302     var $parent = false;\r
303     /**\r
304      * array of parsed elements\r
305      * @var array\r
306      */\r
307     var $elements = array();\r
308     /**\r
309      * @var boolean\r
310      * @access private\r
311      */\r
312     var $_hasclasses = false;\r
313     /**\r
314      * @var boolean\r
315      * @access private\r
316      */\r
317     var $_hasinterfaces = false;\r
318     /**\r
319      * array of parsed elements with @access private\r
320      * @var array\r
321      */\r
322     var $privateelements = array();\r
323     /**\r
324      * array of parsed class elements\r
325      * @var array\r
326      */\r
327     var $classelements = array();\r
328     \r
329     /**\r
330      * @var parserTutorial|false\r
331      */\r
332     var $tutorial = false;\r
333     /**\r
334      * array of parsed class elements with @access private\r
335      * @var array\r
336      */\r
337     var $privateclasselements = array();\r
338     /**\r
339      * array of links descended from {@link abstractLink}\r
340      * @var array\r
341      * @see pageLink, defineLink, classLink, functionLink, methodLink, varLink\r
342      */\r
343     var $links = array();\r
344     /**\r
345      * used by {@link phpDocumentor_IntermediateParser::handleDocBlock()} to\r
346      * determine whether a docblock is a page-level docblock or not.  $clean is\r
347      * true as long as only 0 or 1 docblock has been parsed, and no element\r
348      * other than parserPage has been parsed\r
349      * @var boolean\r
350      */\r
351     var $clean = true;\r
352     /**\r
353      * DocBlock ({@link parserDocBlock}) for this page, or false if not set\r
354      * @var mixed\r
355      */\r
356     var $docblock = false;\r
357     /**\r
358      * Flag used to determine whether a page-level docblock is present\r
359      * @var boolean\r
360      * @access private\r
361      */\r
362     var $_explicitdocblock = false;\r
363     /**\r
364      * Type is used by many functions to skip the hassle of if\r
365      * <code>phpDocumentor_get_class($blah) == 'parserBlah'</code>\r
366      * always 'page', used in element indexing and conversion functions found in\r
367      * {@link Converter}\r
368      * @var string\r
369      */\r
370     var $type = 'page';\r
371     \r
372     /**\r
373      * @param parserElement add a parsed element to the {@link $elements} array,\r
374      *                      also sets {@link $clean} to false\r
375      */\r
376     function addElement(&$element)\r
377     {\r
378         $element->setPath($this->parent->path);\r
379         if ($element->getType() == 'class' || $element->getType() == 'method' || $element->getType() == 'var'\r
380             || $element->getType() == 'const')\r
381         {\r
382             if ($element->getType() == 'class') {\r
383                 if ($element->isInterface()) {\r
384                     $this->_hasinterfaces = true;\r
385                 } else {\r
386                     $this->_hasclasses = true;\r
387                 }\r
388             }\r
389             $this->classelements[] = $element;\r
390         } else\r
391         {\r
392             $this->elements[] = $element;\r
393         }\r
394         $this->clean = false;\r
395     }\r
396 \r
397     /**\r
398      * Does this package have interfaces?\r
399      *\r
400      * @return boolean\r
401      */\r
402     function hasInterfaces()\r
403     {\r
404         return $this->_hasinterfaces;\r
405     }\r
406 \r
407     /**\r
408      * Does this package have classes?\r
409      *\r
410      * @return boolean\r
411      */\r
412     function hasClasses()\r
413     {\r
414         return $this->_hasclasses;\r
415     }\r
416 \r
417     /**\r
418      * @param parserTutorial\r
419      * @param Converter\r
420      */\r
421     function addTutorial($t,&$c)\r
422     {\r
423         $this->tutorial = new tutorialLink;\r
424         $this->tutorial->addLink('',$t->path,$t->name,$t->package,$t->subpackage,$t->getTitle($c));\r
425     }\r
426     \r
427     /**\r
428      * If this file has a tutorial associated with it, returns a link to the\r
429      * tutorial.\r
430      * @return tutorialLink\r
431      */\r
432     function getTutorial()\r
433     {\r
434         return $this->tutorial;\r
435     }\r
436     \r
437     /**\r
438      * If the page-level DocBlock was present in the source, returns true\r
439      * @return boolean\r
440      */\r
441     function hasExplicitDocBlock()\r
442     {\r
443         return $this->_explicitdocblock;\r
444     }\r
445     \r
446     /**\r
447      * Tells this page that its DocBlock was not implicit\r
448      */\r
449     function explicitDocBlock()\r
450     {\r
451         $this->_explicitdocblock = true;\r
452     }\r
453     \r
454     /**\r
455      * @param parserElement element to add a new link (descended from\r
456      * {@link abstractLink})to the {@link $links} array\r
457      * @param string classname for elements that are class-based (this may be\r
458      *               deprecated in the future, as the classname should be\r
459      *               contained within the element.  if $element is a page, this\r
460      *               parameter is a package name\r
461      * @param string subpackage name for page elements\r
462      */\r
463     function addLink(&$element,$classorpackage = '', $subpackage = '')\r
464     {\r
465         switch($element->type)\r
466         {\r
467             case 'function':\r
468                 $x = new functionLink;\r
469                 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);\r
470                 return $x;\r
471             break;\r
472             case 'define':\r
473                 $x = new defineLink;\r
474                 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);\r
475                 return $x;\r
476             break;\r
477             case 'global':\r
478                 $x = new globalLink;\r
479                 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);\r
480                 return $x;\r
481             break;\r
482             case 'class':\r
483                 $x = new classLink;\r
484                 $x->addLink($this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);\r
485                 return $x;\r
486             break;\r
487             case 'method':\r
488                 $x = new methodLink;\r
489                 $x->addLink($classorpackage, $this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);\r
490                 return $x;\r
491             break;\r
492             case 'var':\r
493                 $x = new varLink;\r
494                 $x->addLink($classorpackage, $this->parent->path, $this->parent->name, $element->name, $element->docblock->package, $element->docblock->subpackage);\r
495                 return $x;\r
496             break;\r
497             case 'page':\r
498                 if (empty($classorpackage)) $classorpackage = $GLOBALS['phpDocumentor_DefaultPackageName'];\r
499                 $x = new pageLink;\r
500                 $x->addLink($element->path,$element->name,$element->file,$classorpackage, $subpackage);\r
501                 return $x;\r
502             break;\r
503         }\r
504     }\r
505     \r
506     function &getLink(&$c, $text = false)\r
507     {\r
508         $a = $c->getPageLink($this->parent->file, $this->docblock->package, $this->parent->path, $text);\r
509         return $a;\r
510     }\r
511     \r
512     /**\r
513      * returns a list of all classes declared in a file\r
514      * @param Converter &$c\r
515      * @return array Format: array(packagename => parserClass,packagename => parserClass,...)\r
516      */\r
517     function getClasses(&$c)\r
518     {\r
519         $r = $c->classes->getClassesInPath($this->parent->path);\r
520         $rr = array();\r
521         if ($r)\r
522         foreach($r as $class => $obj)\r
523         {\r
524             $rr[$obj->docblock->package][] = $obj;\r
525         }\r
526         return $rr;\r
527     }\r
528     \r
529     /**\r
530      * Get the output-safe filename (. changed to _)\r
531      * @return string\r
532      */\r
533     function getName()\r
534     {\r
535         if (isset($this->parent) && $this->parent)\r
536         return $this->parent->getName();\r
537     }\r
538     \r
539     /**\r
540      * @param parserPage parent element of this parsed data\r
541      */\r
542     function setParent(&$parent)\r
543     {\r
544         $this->parent = $parent;\r
545     }\r
546     \r
547     /**\r
548      * @return bool returns the value of {@link $clean}\r
549      */\r
550     function isClean()\r
551     {\r
552         return $this->clean;\r
553     }\r
554     \r
555     /**\r
556      * @param parserDocBlock\r
557      * @see parserDocBlock\r
558      */\r
559     function setDocBlock(&$docblock)\r
560     {\r
561         $this->docblock = $docblock;\r
562     }\r
563 }\r
564 \r
565 /**\r
566  * Base class for all elements\r
567  * @package phpDocumentor\r
568  * @subpackage ParserData\r
569  * @abstract\r
570  * @author Greg Beaver <cellog@php.net>\r
571  * @since 1.0rc1\r
572  * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $\r
573  */\r
574 class parserBase\r
575 {\r
576     /**\r
577      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'\r
578      * always base\r
579      * @var string\r
580      */\r
581     var $type = 'base';\r
582     /**\r
583      * set to different things by its descendants\r
584      * @abstract\r
585      * @var mixed\r
586      */\r
587     var $value = false;\r
588 \r
589     /**\r
590      * @return string returns value of {@link $type}\r
591      */\r
592     function getType()\r
593     {\r
594         return $this->type;\r
595     }\r
596     \r
597     /**\r
598      * @param mixed set the value of this element\r
599      */\r
600     function setValue($value)\r
601     {\r
602         $this->value = $value;\r
603     }\r
604     \r
605     /**\r
606      * @return mixed get the value of this element (element-dependent)\r
607      */\r
608     function getValue()\r
609     {\r
610         return $this->value;\r
611     }\r
612 }\r
613 \r
614 \r
615 /**\r
616  * Used to represent strings that contain inline tags, so that they can be properly parsed at link time\r
617  * @package phpDocumentor\r
618  * @subpackage ParserData\r
619  * @author Greg Beaver <cellog@php.net>\r
620  * @since 1.0rc1\r
621  * @version $Id: ParserData.inc,v 1.8 2007/04/24 21:27:43 ashnazg Exp $\r
622  */\r
623 class parserStringWithInlineTags extends parserBase\r
624 {\r
625     /**\r
626      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'\r
627      * always '_string'\r
628      * @var string\r
629      */\r
630     var $type = '_string';\r
631     /** @access private */\r
632     var $cache = false;\r
633     /**\r
634      * array of strings and {@link parserInlineTag}s\r
635      * Format:\r
636      * array(string1,string2,parserInlineTag1,string3,parserInlineTag2,...)\r
637      * @var array\r
638      */\r
639     var $value = array();\r
640 \r
641     /**\r
642      * equivalent to the . operator ($a = $b . $c)\r
643      * @param mixed either a string or a {@link parserInlineTag}\r
644      */\r
645     function add($stringOrInlineTag)\r
646     {\r
647         if (is_string($stringOrInlineTag))\r
648         {\r
649             if (!count($this->value))\r
650             {\r
651                 $this->value[] = $stringOrInlineTag;\r
652                 return;\r
653             }\r
654             if (is_string($this->value[count($this->value) - 1]))\r
655             {\r
656                 $this->value[count($this->value) - 1] .= $stringOrInlineTag;\r
657                 return;\r
658             } else\r
659             {\r
660                 $this->value[] = $stringOrInlineTag;\r
661                 return;\r
662             }\r
663         } else\r
664         {\r
665             if (is_a($stringOrInlineTag,'parserinlinetag') && phpDocumentor_setup::checkIgnoreTag($stringOrInlineTag->inlinetype, true)) return;\r
666             $this->value[] = $stringOrInlineTag;\r
667         }\r
668     }\r
669     \r
670     /**\r
671      * Determine whether the string contains any inline tags\r
672      * @tutorial inlinetags.pkg\r
673      * @return boolean\r
674      */\r
675     function hasInlineTag()\r
676     {\r
677         for($i=0;$i<count($this->value);$i++)\r
678         {\r
679             if (is_a($this->value[$i],'parserinlinetag')) return true;\r
680         }\r
681         return false;\r
682     }\r
683     \r
684     /**\r
685      * Pass source code to any {@}source} tags contained within the string\r
686      * for later conversion.\r
687      * @param string|array source code ready to be highlighted\r
688      */\r
689     function setSource($source)\r
690     {\r
691         for($i=0;$i<count($this->value);$i++)\r
692         {\r
693             if (phpDocumentor_get_class($this->value[$i]) == 'parsersourceinlinetag')\r
694             {\r
695                 $this->value[$i]->setSource($source);\r
696             }\r
697         }\r
698     }\r
699 \r
700     /**\r
701      * equivalent to trim(strlen($string))\r
702      * @return integer length of the string this object represents\r
703      */\r
704     function trimmedStrlen()\r
705     {\r
706         $a = 0;\r
707         for($i=0;$i<count($this->value);$i++)\r
708         {\r
709             if (is_string($this->value[$i]))\r
710             {\r
711                 if ($i == 0)\r
712                 {\r
713                     $a += strlen(ltrim($this->value[$i]));\r
714                 } elseif ($i == count($this->value[$i]) - 1)\r
715                 {\r
716                     $a += strlen(chop($this->value[$i]));\r
717                 }\r
718             } else\r
719             {\r
720                 $a += $this->value[$i]->Strlen();\r
721             }\r
722         }\r
723         return $a;\r
724     }\r
725     \r
726     /**\r
727      * return the string unconverted (all inline tags are taken out - this\r
728      * should only be used in pre-parsing to see if any other text\r
729      * is in the string)\r
730      * @uses parserInlineTag::getString() removes inline tag length, as it is\r
731      *       indeterminate until conversion.\r
732      * @return string trimmed value\r
733      */\r
734     function getString($trim = true)\r
735     {\r
736         $a = '';\r
737         for($i=0; $i<count($this->value); $i++)\r
738         {\r
739             if (is_string($this->value[$i]))\r
740             {\r
741                 $a .= $this->value[$i];\r
742             } else\r
743             {\r
744                 $a .= $this->value[$i]->getString();\r
745             }\r
746         }\r
747         if ($trim) $a = trim($a);\r
748         return $a;\r
749     }\r
750     \r
751     /**\r
752      * Use to convert the string to a real string with all inline tags parsed and linked\r
753      * @see Converter::returnSee()\r
754      * @param Converter\r
755      * @param boolean true if one needs to postprocess\r
756      * @param boolean false if the output should not be trimmed\r
757      */\r
758     function Convert(&$converter,$postprocess = true, $trim = true)\r
759     {\r
760         if ($this->cache)\r
761         {\r
762             if ($converter->name == $this->cache['name'] && $converter->outputformat == $this->cache['output'] && $converter->checkState($this->cache['state']) && $this->cache['postprocess'] === $postprocess) return $this->cache['contents'];\r
763             if ($converter->name != $this->cache['name']) {\r
764                 $this->cache = false;\r
765             }\r
766         }\r
767         if (is_string($this->value)) return $this->value;\r
768         $a = '';\r
769         for($i=0; $i<count($this->value); $i++)\r
770         {\r
771             if (is_string($this->value[$i]))\r
772             {\r
773                 if ($postprocess && !method_exists($converter,'postProcess')) var_dump('a',$converter);\r
774                 if ($postprocess) $a .= $converter->postProcess($this->value[$i]);\r
775                 else $a .= $this->value[$i];\r
776             } else\r
777             {\r
778                 $a .= $this->value[$i]->Convert($converter, $postprocess);\r
779             }\r
780         }\r
781         if ($trim) {\r
782             $a = trim($a);\r
783         }\r
784         $this->cache = array('name' => $converter->name,'output' => $converter->outputformat, 'contents' => $a, 'state' => $converter->getState(), 'postprocess' => $postprocess);\r
785         return $a;\r
786     }\r
787 }\r
788 \r
789 ?>