Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** Base class for all Converters** phpDocumentor :: automatic documentation generator** PHP versions 4 and 5** Copyright (c) 2001-2006 Gregory Beaver** LICENSE:** This library is free software; you can redistribute it* and/or modify it under the terms of the GNU Lesser General* Public License as published by the Free Software Foundation;* either version 2.1 of the License, or (at your option) any* later version.** This library is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with this library; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA** @package Converters* @author Greg Beaver <cellog@php.net>* @copyright 2001-2006 Gregory Beaver* @license http://www.opensource.org/licenses/lgpl-license.php LGPL* @version CVS: $Id: Converter.inc 287891 2009-08-30 08:08:00Z ashnazg $* @filesource* @link http://www.phpdoc.org* @link http://pear.php.net/PhpDocumentor* @see parserDocBlock, parserInclude, parserPage, parserClass* @see parserDefine, parserFunction, parserMethod, parserVar* @since 1.0rc1*//*** Smarty template files*/include_once("phpDocumentor/Smarty-2.6.0/libs/Smarty.class.php");/*** Base class for all output converters.** The Converter marks the final stage in phpDocumentor. phpDocumentor works* in this order:** <pre>Parsing => Intermediate Parsing organization => Conversion to output</pre>** A Converter takes output from the {@link phpDocumentor_IntermediateParser} and* converts it to output. With version 1.2, phpDocumentor includes a variety* of output converters:* <ul>* <li>{@link HTMLframesConverter}</li>* <li>{@link HTMLSmartyConverter}</li>* <li>{@link PDFdefaultConverter}</li>* <li>{@link CHMdefaultConverter}</li>* <li>{@link CSVdia2codeConverter}</li>* <li>{@link XMLDocBookConverter}</li>* </ul>* {@internal* The converter takes output directly from {@link phpDocumentor_IntermediateParser}* and using {@link walk()} or {@link walk_everything} (depending on the value of* {@link $sort_absolutely_everything}) it "walks" over an array of phpDocumentor elements.}}** @package Converters* @abstract* @author Greg Beaver <cellog@php.net>* @since 1.0rc1* @version $Id: Converter.inc 287891 2009-08-30 08:08:00Z ashnazg $*/class Converter{/*** This converter knows about the new root tree processing* In order to fix PEAR Bug #6389* @var boolean*/var $processSpecialRoots = false;/*** output format of this converter** in Child converters, this will match the first part of the -o command-line* as in -o HTML:frames:default "HTML"* @tutorial phpDocumentor.howto.pkg#using.command-line.output* @var string*/var $outputformat = 'Generic';/*** package name currently being converted* @var string*/var $package = 'default';/*** subpackage name currently being converted* @var string*/var $subpackage = '';/*** set to a classname if currently parsing a class, false if not* @var string|false*/var $class = false;/**#@+* @access private*//*** the workhorse of linking.** This array is an array of link objects of format:* [package][subpackage][eltype][elname] = descendant of {@link abstractLink}* eltype can be page|function|define|class|method|var* if eltype is method or var, the array format is:* [package][subpackage][eltype][class][elname]* @var array* @see functionLink, pageLink, classLink, defineLink, methodLink, varLink, globalLink*/var $links = array();/*** the workhorse of linking, with allowance for support of multiple* elements in different files.** This array is an array of link objects of format:* [package][subpackage][eltype][file][elname] = descendant of {@link abstractLink}* eltype can be function|define|class|method|var* if eltype is method or var, the array format is:* [package][subpackage][eltype][file][class][elname]* @var array* @see functionLink, pageLink, classLink, defineLink, methodLink, varLink, globalLink*/var $linkswithfile = array();/**#@-*//*** set to value of -po commandline* @tutorial phpDocumentor.howto.pkg#using.command-line.packageoutput* @var mixed*/var $package_output;/*** name of current page being converted* @var string*/var $page;/*** path of current page being converted* @var string*/var $path;/*** template for the procedural page currently being processed* @var Smarty*/var $page_data;/*** template for the class currently being processed* @var Smarty*/var $class_data;/*** current procedural page being processed* @var parserPage*/var $curpage;/*** alphabetical index of all elements sorted by package, subpackage, page,* and class.* @var array Format: array(package => array(subpackage => array('page'|'class' => array(path|classname => array(element, element,...)))))* @uses $sort_absolutely_everything if true, then $package_elements is used,* otherwise, the {@link ParserData::$classelements} and* {@link ParserData::$pageelements} variables are used*/var $package_elements = array();/*** alphabetical index of all elements** @var array Format: array(first letter of element name => array({@link parserElement} or {@link parserPage},...))* @see formatIndex(), HTMLframesConverter::formatIndex()*/var $elements = array();/*** alphabetized index of procedural pages by package** @see $leftindex* @var array Format: array(package => array(subpackage => array({@link pageLink} 1,{@link pageLink} 2,...)*/var $page_elements = array();/*** alphabetized index of defines by package** @see $leftindex* @var array Format: array(package => array(subpackage => array({@link defineLink} 1,{@link defineLink} 2,...)*/var $define_elements = array();/*** alphabetized index of classes by package** @see $leftindex* @var array Format: array(package => array(subpackage => array({@link classLink} 1,{@link classLink} 2,...)*/var $class_elements = array();/*** alphabetized index of global variables by package** @see $leftindex* @var array Format: array(package => array(subpackage => array({@link globalLink} 1,{@link globalLink} 2,...)*/var $global_elements = array();/*** alphabetized index of functions by package** @see $leftindex* @var array Format: array(package => array(subpackage => array({@link functionLink} 1,{@link functionLink} 2,...)*/var $function_elements = array();/*** alphabetical index of all elements, indexed by package/subpackage** @var array Format: array(first letter of element name => array({@link parserElement} or {@link parserPage},...))* @see formatPkgIndex(), HTMLframesConverter::formatPkgIndex()*/var $pkg_elements = array();/*** alphabetical index of all elements on a page by package/subpackage** The page itself has a link under ###main* @var array Format: array(package => array(subpackage => array(path => array({@link abstractLink} descendant 1, ...)))* @see formatLeftIndex()*/var $page_contents = array();/*** This determines whether the {@link $page_contents} array should be sorted by element type as well as alphabetically by name* @see sortPageContentsByElementType()* @var boolean*/var $sort_page_contents_by_type = false;/*** This is used if the content must be passed in the order it should be read, i.e. by package, procedural then classes** This fixes bug 637921, and is used by {@link PDFdefaultConverter}*/var $sort_absolutely_everything = false;/*** alphabetical index of all methods and vars in a class by package/subpackage** The class itself has a link under ###main* @var array* Format:<pre>* array(package =>* array(subpackage =>* array(path =>* array(class =>* array({@link abstractLink} descendant 1, ...* )* )* )* )</pre>* @see formatLeftIndex()*/var $class_contents = array();/*** controls processing of elements marked private with @access private** defaults to false. Set with command-line --parseprivate or -pp* @var bool*/var $parseprivate;/*** controls display of progress information while parsing.** defaults to false. Set to true for cron jobs or other situations where no visual output is necessary* @var bool*/var $quietmode;/*** directory that output is sent to. -t command-line sets this.* @tutorial phpDocumentor.howto.pkg#using.command-line.target*/var $targetDir = '';/*** Directory that the template is in, relative to phpDocumentor root directory* @var string*/var $templateDir = '';/*** Directory that the smarty templates are in* @var string*/var $smarty_dir = '';/*** Name of the template, from last part of -o* @tutorial phpDocumentor.howto.pkg#using.command-line.output* @var string*/var $templateName = '';/*** full path of the current file being converted*/var $curfile;/*** All class information, organized by path, and by package* @var Classes*/var $classes;/*** Flag used to help converters determine whether to do special source highlighting* @var boolean*/var $highlightingSource = false;/*** Hierarchy of packages** Every package that contains classes may have parent or child classes* in other packages. In other words, this code is legal:** <code>* /*** * @package one* * /* class one {}** /*** * @package two* * /* class two extends one {}* </code>** In this case, package one is a parent of package two* @var array* @see phpDocumentor_IntermediateParser::$package_parents*/var $package_parents;/*** Packages associated with categories** Used by the XML:DocBook/peardoc2 converter, and available to others, to* group many packages into categories* @see phpDocumentor_IntermediateParser::$packagecategories* @var array*/var $packagecategories;/*** All packages encountered in parsing* @var array* @see phpDocumentor_IntermediateParser::$all_packages*/var $all_packages;/*** A list of files that have had source code generated* @var array*/var $sourcePaths = array();/*** Controls which of the one-element-only indexes are generated.** Generation of these indexes for large packages is time-consuming. This is an optimization feature. An* example of how to use this is in {@link HTMLframesConverter::$leftindex}, and in {@link HTMLframesConverter::formatLeftIndex()}.* These indexes are intended for use as navigational aids through documentation, but can be used for anything by converters.* @see $class_elements, $page_elements, $function_elements, $define_elements, $global_elements* @see formatLeftIndex()* @var array*/var $leftindex = array('classes' => true, 'pages' => true, 'functions' => true, 'defines' => true, 'globals' => true);/** @access private */var $killclass = false;/*** @var string* @see phpDocumentor_IntermediateParser::$title*/var $title = 'Generated Documentation';/*** Options for each template, parsed from the options.ini file in the template base directory* @tutorial phpDocumentor/tutorials.pkg#conversion.ppage* @var array*/var $template_options;/*** Tutorials and Extended Documentation parsed from a tutorials/package[/subpackage] directory* @tutorial tutorials.pkg* @access private*/var $tutorials = array();/*** tree-format structure of tutorials and their child tutorials, if any* @var array* @access private*/var $tutorial_tree = false;/*** list of tutorials that have already been processed. Used by @link _setupTutorialTree()* @var array* @access private*/var $processed_tutorials;/*** List of all @todo tags and a link to the element with the @todo** Format: array(package => array(link to element, array(todo {@link parserTag},...)),...)* @tutorial tags.todo.pkg* @var array*/var $todoList = array();/*** Directory where compiled templates go - will be deleted on exit** @var string* @access private*/var $_compiledDir = array();/*** Initialize Converter data structures* @param array {@link $all_packages} value* @param array {@link $package_parents} value* @param Classes {@link $classes} value* @param ProceduralPages {@link $proceduralpages} value* @param array {@link $package_output} value* @param boolean {@link $parseprivate} value* @param boolean {@link $quietmode} value* @param string {@link $targetDir} value* @param string {@link $templateDir} value* @param string (@link $title} value*/function Converter(&$allp, &$packp, &$classes, &$procpages, $po, $pp, $qm, $targetDir, $template, $title){$this->all_packages = $allp;$this->package_parents = $packp;$this->package = $GLOBALS['phpDocumentor_DefaultPackageName'];$this->proceduralpages = &$procpages;$this->package_output = $po;if (is_array($po)){$a = $po[0];$this->all_packages = array_flip($po);$this->all_packages[$a] = 1;}$this->parseprivate = $pp;$this->quietmode = $qm;$this->classes = &$classes;$this->roots = $classes->getRoots($this->processSpecialRoots);$this->title = $title;$this->setTemplateDir($template);$this->setTargetdir($targetDir);}/*** Called by IntermediateParser after creation* @access private*/function setTutorials($tutorials){$this->tutorials = $tutorials;}/*** @param pkg|cls|proc the tutorial type to search for* @param tutorial name* @param string package name* @param string subpackage name, if any* @return false|parserTutorial if the tutorial exists, return it*/function hasTutorial($type, $name, $package, $subpackage = ''){if (isset($this->tutorials[$package][$subpackage][$type][$name . '.' . $type]))return $this->tutorials[$package][$subpackage][$type][$name . '.' . $type];return false;}/*** Called by {@link walk()} while converting, when the last class element* has been parsed.** A Converter can use this method in any way it pleases. HTMLframesConverter* uses it to complete the template for the class and to output its* documentation* @see HTMLframesConverter::endClass()* @abstract*/function endClass(){}/*** Called by {@link walk()} while converting, when the last procedural page* element has been parsed.** A Converter can use this method in any way it pleases. HTMLframesConverter* uses it to complete the template for the procedural page and to output its* documentation* @see HTMLframesConverter::endClass()* @abstract*/function endPage(){}/*** Called by {@link walk()} while converting.** This method is intended to be the place that {@link $pkg_elements} is* formatted for output.* @see HTMLframesConverter::formatPkgIndex()* @abstract*/function formatPkgIndex(){}/*** Called by {@link walk()} while converting.** This method is intended to be the place that {@link $elements} is* formatted for output.* @see HTMLframesConverter::formatIndex()* @abstract*/function formatIndex(){}/*** Called by {@link walk()} while converting.** This method is intended to be the place that any of* {@link $class_elements, $function_elements, $page_elements},* {@link $define_elements}, and {@link $global_elements} is formatted for* output, depending on the value of {@link $leftindex}* @see HTMLframesConverter::formatLeftIndex()* @abstract*/function formatLeftIndex(){}/*** Called by {@link parserSourceInlineTag::stringConvert()} to allow* converters to format the source code the way they'd like.** default returns it unchanged (html with xhtml tags)* @param string output from highlight_string() - use this function to* reformat the returned data for Converter-specific output* @return string* @deprecated in favor of tokenizer-based highlighting. This will be* removed for 2.0*/function unmangle($sourcecode){return $sourcecode;}/*** Initialize highlight caching*/function startHighlight(){$this->_highlightCache = array(false, false);$this->_appendHighlight = '';}function getHighlightState(){return $this->_highlightCache;}function _setHighlightCache($type, $token){$test = ($this->_highlightCache[0] === $type && $this->_highlightCache[1] == $token);if (!$test) {$this->_appendHighlight = $this->flushHighlightCache();} else {$this->_appendHighlight = '';}$this->_highlightCache = array($type, $token);return $test;}/*** Return the close text for the current token* @return string*/function flushHighlightCache(){$hc = $this->_highlightCache;$this->_highlightCache = array(false, false);if ($hc[0]) {if (!isset($this->template_options[$hc[0]]['/'.$hc[1]])) {return '';}return $this->template_options[$hc[0]]['/'.$hc[1]];}return '';}/*** Used to allow converters to format the source code the way they'd like.** default returns it unchanged. Mainly used by the {@link HighlightParser}* {@internal* The method takes information from options.ini, the template options* file, specifically the [highlightSourceTokens] and [highlightSource]* sections, and uses them to enclose tokens.** {@source}}}* @param integer token value from {@link PHP_MANUAL#tokenizer tokenizer constants}* @param string contents of token* @param boolean whether the contents are preformatted or need modification* @return string*/function highlightSource($token, $word, $preformatted = false){if ($token !== false){if (!$preformatted) $word = $this->postProcess($word);if (isset($this->template_options['highlightSourceTokens'][token_name($token)])){if ($this->_setHighlightCache('highlightSourceTokens', token_name($token))) {return $word;}$e = $this->_appendHighlight;return $e . $this->template_options['highlightSourceTokens'][token_name($token)] . $word;} else{$this->_setHighlightCache(false, false);$e = $this->_appendHighlight;return $e . $word;}} else{if (isset($this->template_options['highlightSource'][$word])){$newword = ($preformatted ? $word : $this->postProcess($word));if ($this->_setHighlightCache('highlightSource', $word)) {return $newword;}$e = $this->_appendHighlight;return $e . $this->template_options['highlightSource'][$word] . $newword;} else{$this->_setHighlightCache(false, false);$e = $this->_appendHighlight;return $e . ($preformatted ? $word : $this->postProcess($word));}}}/*** Used to allow converters to format the source code of DocBlocks the way* they'd like.** default returns it unchanged. Mainly used by the {@link HighlightParser}* {@internal* The method takes information from options.ini, the template options* file, specifically the [highlightDocBlockSourceTokens] section, and uses* it to enclose tokens.** {@source}}}* @param string name of docblock token type* @param string contents of token* @param boolean whether the contents are preformatted or need modification* @return string*/function highlightDocBlockSource($token, $word, $preformatted = false){if (empty($word)) {$this->_setHighlightCache(false, false);$e = $this->_appendHighlight;return $e . $word;}if (isset($this->template_options['highlightDocBlockSourceTokens'][$token])){if (!$preformatted) $word = $this->postProcess($word);if ($this->_setHighlightCache('highlightDocBlockSourceTokens', $token)) {return $word;}$e = $this->_appendHighlight;return $e . $this->template_options['highlightDocBlockSourceTokens'][$token] . $word;} else {$this->_setHighlightCache(false, false);$e = $this->_appendHighlight;return $e . ($preformatted ? $word : $this->postProcess($word));}}/*** Used to allow converters to format the source code of Tutorial XML the way* they'd like.** default returns it unchanged. Mainly used by the {@link HighlightParser}* {@internal* The method takes information from options.ini, the template options* file, specifically the [highlightDocBlockSourceTokens] section, and uses* it to enclose tokens.** {@source}}}* @param string name of docblock token type* @param string contents of token* @param boolean whether the contents are preformatted or need modification* @return string*/function highlightTutorialSource($token, $word, $preformatted = false){if (empty($word)) {$this->_setHighlightCache(false, false);$e = $this->_appendHighlight;return $e . $word;}if (isset($this->template_options['highlightTutorialSourceTokens'][$token])){if (!$preformatted) $word = $this->postProcess($word);if ($this->_setHighlightCache('highlightTutorialSourceTokens', $token)) {return $word;}$e = $this->_appendHighlight;return $e . $this->template_options['highlightTutorialSourceTokens'][$token] . $word;} else {$this->_setHighlightCache(false, false);$e = $this->_appendHighlight;return $e . ($preformatted ? $word : $this->postProcess($word));}}/*** Called by {@link parserReturnTag::Convert()} to allow converters to* change type names to desired formatting** Used by {@link XMLDocBookConverter::type_adjust()} to change true and* false to the peardoc2 values* @param string* @return string*/function type_adjust($typename){return $typename;}/*** Used to convert the {@}example} inline tag in a docblock.** By default, this just wraps ProgramExample* @see XMLDocBookpeardoc2Converter::exampleProgramExample* @param string* @param boolean true if this is to highlight a tutorial <programlisting>* @return string*/function exampleProgramExample($example, $tutorial = false, $inlinesourceparse = null/*false*/,$class = null/*false*/, $linenum = null/*false*/, $filesourcepath = null/*false*/){return $this->ProgramExample($example, $tutorial, $inlinesourceparse, $class, $linenum, $filesourcepath);}/*** Used to convert the <<code>> tag in a docblock* @param string* @param boolean true if this is to highlight a tutorial <programlisting>* @return string*/function ProgramExample($example, $tutorial = false, $inlinesourceparse = null/*false*/,$class = null/*false*/, $linenum = null/*false*/, $filesourcepath = null/*false*/){$this->highlightingSource = true;if (tokenizer_ext){$e = $example;if (!is_array($example)){$obj = new phpDocumentorTWordParser;$obj->setup($example);$e = $obj->getFileSource();$bOpenTagFound = false;foreach ($e as $ke => $ee){foreach ($ee as $kee => $eee){if ((int) $e[$ke][$kee][0] == T_OPEN_TAG){$bOpenTagFound = true;}}}if (!$bOpenTagFound) {$example = "<?php\n".$example;$obj->setup($example);$e = $obj->getFileSource();unset($e[0]);$e = array_values($e);}unset($obj);}$saveclass = $this->class;$parser = new phpDocumentor_HighlightParser;if (!isset($inlinesourceparse)){$example = $parser->parse($e, $this, true); // force php mode} else{if (isset($filesourcepath)){$example = $parser->parse($e, $this, $inlinesourceparse, $class, $linenum, $filesourcepath);} elseif (isset($linenum)){$example = $parser->parse($e, $this, $inlinesourceparse, $class, $linenum);} elseif (isset($class)){$example = $parser->parse($e, $this, $inlinesourceparse, $class);} else{$example = $parser->parse($e, $this, $inlinesourceparse);}}$this->class = $saveclass;} else{$example = $this->postProcess($example);}$this->highlightingSource = false;if ($tutorial){return $example;}if (!isset($this->template_options['desctranslate'])) return $example;if (!isset($this->template_options['desctranslate']['code'])) return $example;$example = $this->template_options['desctranslate']['code'] . $example;if (!isset($this->template_options['desctranslate']['/code'])) return $example;return $example . $this->template_options['desctranslate']['/code'];}/*** @param string*/function TutorialExample($example){$this->highlightingSource = true;$parse = new phpDocumentor_TutorialHighlightParser;$x = $parse->parse($example, $this);$this->highlightingSource = false;return $x;}/*** Used to convert the contents of <<li>> in a docblock* @param string* @return string*/function ListItem($item){if (!isset($this->template_options['desctranslate'])) return $item;if (!isset($this->template_options['desctranslate']['li'])) return $item;$item = $this->template_options['desctranslate']['li'] . $item;if (!isset($this->template_options['desctranslate']['/li'])) return $item;return $item . $this->template_options['desctranslate']['/li'];}/*** Used to convert the contents of <<ol>> or <<ul>> in a docblock* @param string* @return string*/function EncloseList($list,$ordered){$listname = ($ordered ? 'ol' : 'ul');if (!isset($this->template_options['desctranslate'])) return $list;if (!isset($this->template_options['desctranslate'][$listname])) return $list;$list = $this->template_options['desctranslate'][$listname] . $list;if (!isset($this->template_options['desctranslate']['/'.$listname])) return $list;return $list . $this->template_options['desctranslate']['/'.$listname];}/*** Used to convert the contents of <<pre>> in a docblock* @param string* @return string*/function PreserveWhiteSpace($string){if (!isset($this->template_options['desctranslate'])) return $string;if (!isset($this->template_options['desctranslate']['pre'])) return $string;$string = $this->template_options['desctranslate']['pre'] . $string;if (!isset($this->template_options['desctranslate']['/pre'])) return $string;return $string . $this->template_options['desctranslate']['/pre'];}/*** Used to enclose a paragraph in a docblock* @param string* @return string*/function EncloseParagraph($para){if (!isset($this->template_options['desctranslate'])) return $para;if (!isset($this->template_options['desctranslate']['p'])) return $para;$para = $this->template_options['desctranslate']['p'] . $para;if (!isset($this->template_options['desctranslate']['/p'])) return $para;return $para . $this->template_options['desctranslate']['/p'];}/*** Used to convert the contents of <<b>> in a docblock* @param string* @return string*/function Bolden($para){if (!isset($this->template_options['desctranslate'])) return $para;if (!isset($this->template_options['desctranslate']['b'])) return $para;$para = $this->template_options['desctranslate']['b'] . $para;if (!isset($this->template_options['desctranslate']['/b'])) return $para;return $para . $this->template_options['desctranslate']['/b'];}/*** Used to convert the contents of <<i>> in a docblock* @param string* @return string*/function Italicize($para){if (!isset($this->template_options['desctranslate'])) return $para;if (!isset($this->template_options['desctranslate']['i'])) return $para;$para = $this->template_options['desctranslate']['i'] . $para;if (!isset($this->template_options['desctranslate']['/i'])) return $para;return $para . $this->template_options['desctranslate']['/i'];}/*** Used to convert the contents of <<var>> in a docblock* @param string* @return string*/function Varize($para){if (!isset($this->template_options['desctranslate'])) return $para;if (!isset($this->template_options['desctranslate']['var'])) return $para;$para = $this->template_options['desctranslate']['var'] . $para;if (!isset($this->template_options['desctranslate']['/var'])) return $para;return $para . $this->template_options['desctranslate']['/var'];}/*** Used to convert the contents of <<kbd>> in a docblock* @param string* @return string*/function Kbdize($para){if (!isset($this->template_options['desctranslate'])) return $para;if (!isset($this->template_options['desctranslate']['kbd'])) return $para;$para = $this->template_options['desctranslate']['kbd'] . $para;if (!isset($this->template_options['desctranslate']['/kbd'])) return $para;return $para . $this->template_options['desctranslate']['/kbd'];}/*** Used to convert the contents of <<samp>> in a docblock* @param string* @return string*/function Sampize($para){if (!isset($this->template_options['desctranslate'])) return $para;if (!isset($this->template_options['desctranslate']['samp'])) return $para;$para = $this->template_options['desctranslate']['samp'] . $para;if (!isset($this->template_options['desctranslate']['/samp'])) return $para;return $para . $this->template_options['desctranslate']['/samp'];}/*** Used to convert <<br>> in a docblock* @param string* @return string*/function Br($para){if (!isset($this->template_options['desctranslate'])) return $para;if (!isset($this->template_options['desctranslate']['br'])) return $para;$para = $this->template_options['desctranslate']['br'] . $para;return $para;}/*** This version does nothing** Perform necessary post-processing of string data. For example, the HTML* Converters should escape < and > to become < and >* @return string*/function postProcess($text){return $text;}/*** Creates a table of contents for a {@}toc} inline tag in a tutorial** This function should return a formatted table of contents. By default, it* does nothing, it is up to the converter to format the TOC* @abstract* @return string table of contents formatted for use in the current output format* @param array format: array(array('tagname' => section, 'link' => returnsee link, 'id' => anchor name, 'title' => from title tag),...)*/function formatTutorialTOC($toc){return '';}/*** Write out the formatted source code for a php file** This function provides the primary functionality for the* {@tutorial tags.filesource.pkg} tag.* @param string full path to the file* @param string fully highlighted/linked source code of the file* @abstract*/function writeSource($filepath, $source){debug($source);return;}/*** Write out the formatted source code for an example php file** This function provides the primary functionality for the* {@tutorial tags.example.pkg} tag.* @param string example title* @param string example filename (no path)* @param string fully highlighted/linked source code of the file* @abstract*/function writeExample($title, $path, $source){return;}/** Translate the path info into a unique file name for the highlighted* source code.* @param string $pathinfo* @return string*/function getFileSourceName($path){global $_phpDocumentor_options;$pathinfo = $this->proceduralpages->getPathInfo($path, $this);$pathinfo['source_loc'] = str_replace($_phpDocumentor_options['Program_Root'].'/','',$pathinfo['source_loc']);$pathinfo['source_loc'] = str_replace('/','_',$pathinfo['source_loc']);return "fsource_{$pathinfo['package']}_{$pathinfo['subpackage']}_{$pathinfo['source_loc']}";}/** Return the fixed path to the source-code file folder.* @param string $base Path is relative to this folder* @return string*/function getFileSourcePath($base){if (substr($base, strlen($base) - 1) != PATH_DELIMITER) {$base .= PATH_DELIMITER;}return $base . '__filesource';}/** Return the path to the current* @param string $pathinfo* @return string*/function getCurrentPageURL(){return '{$srcdir}' . PATH_DELIMITER . $this->page_dir;}/*** @return string an output-format dependent link to phpxref-style highlighted* source code* @abstract*/function getSourceLink($path){return '';}/*** @return string Link to the current page being parsed.* Should return {@link $curname} and a converter-specific extension.* @abstract*/function getCurrentPageLink(){}/*** Return a line of highlighted source code with formatted line number** If the $path is a full path, then an anchor to the line number will be* added as well* @param integer line number* @param string highlighted source code line* @param false|string full path to @filesource file this line is a part of,* if this is a single line from a complete file.* @return string formatted source code line with line number*/function sourceLine($linenumber, $line, $path = false){if ($path){return $this->getSourceAnchor($path, $linenumber) .$this->Br(sprintf('%-6u',$linenumber).str_replace("\n",'',$line));} else{return $this->Br(sprintf('%-6u',$linenumber).str_replace("\n",'',$line));}}/*** Determine whether an element's file has generated source code, used for* linking to line numbers of source.** Wrapper for {@link $sourcePaths} in this version** {@internal since file paths get stored with most/all slashes* set to forward slash '/', we need to doublecheck that* we're not given a backslashed path to search for...* if we are, it's likely that it was originally stored* with a forward slash. Further, I'm not convinced it's safe* to just check the {@link PHPDOCUMENTOR_WINDOWS} flag, so I'm checking* specifically for backslashes intead.}}** @param string full path to the source code file* @return boolean*/function hasSourceCode($path){return isset($this->sourcePaths[$path]);if (strpos($path, '\\') > -1) {$modifiedPath = str_replace('\\', '/', $path);return isset($this->sourcePaths[$modifiedPath]);} else {return isset($this->sourcePaths[$path]);}}/*** Mark a file as having had source code highlighted* @param string full path of source file*/function setSourcePaths($path){$this->sourcePaths[$path] = true;}/*** Used to translate an XML DocBook entity like ” from a tutorial by* reading the options.ini file for the template.* @param string entity name*/function TranslateEntity($name){if (!isset($this->template_options['ppage'])){if (!$this->template_options['preservedocbooktags'])return '';elsereturn '&'.$name.';';}if (isset($this->template_options['ppage']['&'.$name.';'])){return $this->template_options['ppage']['&'.$name.';'];} else{if (!$this->template_options['preservedocbooktags'])return '';elsereturn '&'.$name.';';}}/*** Used to translate an XML DocBook tag from a tutorial by reading the* options.ini file for the template.* @param string tag name* @param string any attributes Format: array(name => value)* @param string the tag contents, if any* @param string the tag contents, if any, unpost-processed* @return string*/function TranslateTag($name,$attr,$cdata,$unconvertedcdata){if (!isset($this->template_options['ppage'])){if (!$this->template_options['preservedocbooktags'])return $cdata;elsereturn '<'.$name.$this->AttrToString($name,$attr,true).'>'.$cdata.'</'.$name.'>'."\n";}// make sure this template transforms the tag into somethingif (isset($this->template_options['ppage'][$name])){// test for global attribute transforms like $attr$role = class, changing// all role="*" attributes to class="*" in html, for exampleforeach($attr as $att => $val){if (isset($this->template_options['$attr$'.$att])){$new = '';if (!isset($this->template_options['$attr$'.$att]['close'])){$new .= '<'.$this->template_options['$attr$'.$att]['open'];if (isset($this->template_options['$attr$'.$att]['cdata!'])){if (isset($this->template_options['$attr$'.$att]['separateall']))$new .= $this->template_options['$attr$'.$att]['separator'];else$new .= ' ';$new .= $this->template_options['$attr$'.$att]['$'.$att];$new .= $this->template_options['$attr$'.$att]['separator'];if ($this->template_options['$attr$'.$att]['quotevalues']) $val = '"'.$val.'"';$new .= $val.'>';} else{$new .= '>'.$val;}$new .= '</'.$this->template_options['$attr$'.$att]['open'].'>';} else{$new .= $this->template_options['$attr$'.$att]['open'] . $val . $this->template_options['$attr$'.$att]['close'];}unset($attr[$att]);$cdata = $new . $cdata;}}if (!isset($this->template_options['ppage']['/'.$name])){// if the close tag isn't specified, we put opening and closing tags around it, with translated attributesif (isset($this->template_options['ppage'][$name.'/']))$cdata = '<'.$this->template_options['ppage'][$name].$this->AttrToString($name,$attr).'/>' . $cdata;else$cdata = '<'.$this->template_options['ppage'][$name].$this->AttrToString($name,$attr).'>' . $cdata .'</'.$this->template_options['ppage'][$name].'>';} else{ // if close tag is specified, use the open and close as literalif ($name == 'programlisting' && isset($attr['role']) &&($attr['role'] == 'php' || $attr['role'] == 'tutorial' || $attr['role'] == 'html')){ // highlight PHP source// var_dump($unconvertedcdata, $cdata);exit;if ($attr['role'] == 'php') {$cdata = $this->ProgramExample($unconvertedcdata, true);} elseif ($attr['role'] == 'tutorial') {$cdata = $this->TutorialExample($unconvertedcdata);} elseif ($attr['role'] == 'html') {$cdata = $unconvertedcdata;}} else{// normal case below$cdata = $this->template_options['ppage'][$name].$this->AttrToString($name,$attr). $cdata .$this->template_options['ppage']['/'.$name];}}return $cdata;} else{if ($this->template_options['preservedocbooktags']){return '<'.$name.$this->AttrToString($name,$attr,true).'>' . $cdata .'</'.$name.'>'."\n";} else{return $cdata;}}}/*** Convert the attribute of a Tutorial docbook tag's attribute list* to a string based on the template options.ini* @param string tag name* @param attribute array* @param boolean if true, returns attrname="value"...* @return string*/function AttrToString($tag,$attr,$unmodified = false){$ret = '';if ($unmodified){$ret = ' ';foreach($attr as $n => $v){$ret .= $n.' = "'.$v.'"';}return $ret;}// no_attr tells us to ignore all attributesif (isset($this->template_options['no_attr'])) return $ret;// tagname! tells us to ignore all attributes for this tagif (isset($this->template_options['ppage'][$tag.'!'])) return $ret;if (count($attr)) $ret = ' ';// pass 1, check to see if any attributes add together$same = array();foreach($attr as $n => $v){if (isset($this->template_options['ppage'][$tag.'->'.$n])){$same[$this->template_options['ppage'][$tag.'->'.$n]][] = $n;}}foreach($attr as $n => $v){if (isset($this->template_options['ppage'][$tag.'->'.$n])){if (count($same[$this->template_options['ppage'][$tag.'->'.$n]]) == 1){ // only 1 attribute translated for this one// this is useful for equivalent value namesif (isset($this->template_options['ppage'][$tag.'->'.$n.'+'.$v])) $v = $this->template_options['ppage'][$tag.'->'.$n.'+'.$v];} else{ // more than 1 attribute combines to make the new attribute$teststrtemp = array();foreach($same[$this->template_options['ppage'][$tag.'->'.$n]] as $oldattr){$teststrtemp[] = $oldattr.'+'.$attr[$oldattr];}$teststrs = array();$num = count($same[$this->template_options['ppage'][$tag.'->'.$n]]);for($i=0;$i<$num;$i++){$started = false;$a = '';for($j=$i;!$started || $j != $i;$j = ($j + $i) % $num){if (!empty($a)) $a .= '|';$a .= $teststrtemp[$j];}$teststrs[$i] = $a;}$done = false;foreach($teststrs as $test){if ($done) break;if (isset($this->template_options['ppage'][$tag.'->'.$test])){$done = true;$v = $this->template_options['ppage'][$tag.'->'.$test];}}}$ret .= $this->template_options['ppage'][$tag.'->'.$n].' = "'.$v.'"';} else{if (!isset($this->template_options['ppage'][$tag.'!'.$n])){if (isset($this->template_options['ppage']['$attr$'.$n]))$ret .= $this->template_options['ppage']['$attr$'.$n].' = "'.$v.'"';else$ret .= $n.' = "'.$v.'"';}}}return $ret;}/*** Convert the title of a Tutorial docbook tag section* to a string based on the template options.ini* @param string tag name* @param array* @param string title text* @param string* @return string*/function ConvertTitle($tag,$attr,$title,$cdata){if (!isset($this->template_options[$tag.'_title'])) return array($attr,$cdata);if (isset($this->template_options[$tag.'_title']['tag_attr'])){$attr[$this->template_options[$tag.'_title']['tag_attr']] = urlencode($cdata);$cdata = '';} elseif(isset($this->template_options[$tag.'_title']['cdata_start'])){$cdata = $this->template_options[$tag.'_title']['open'] . $title .$this->template_options[$tag.'_title']['close'] . $cdata;} else $cdata = $title.$cdata;return array($attr,$cdata);}/*** Return a converter-specific id to distinguish tutorials and their* sections** Used by {@}id}* @return string*/function getTutorialId($package,$subpackage,$tutorial,$id){return $package.$subpackage.$tutorial.$id;}/*** Create the {@link $elements, $pkg_elements} and {@link $links} arrays* @access private* @todo version 2.0 - faulty package_output logic should be removed** in this version, if the parent file isn't in the package, all* the procedural elements are simply shunted to another package!*/function _createPkgElements(&$pages){if (empty($this->elements)){$this->elements = array();$this->pkg_elements = array();$this->links = array();phpDocumentor_out('Building indexes...');flush();foreach($pages as $j => $flub){$this->package = $pages[$j]->parent->package;$this->subpackage = $pages[$j]->parent->subpackage;$this->class = false;$this->curfile = $pages[$j]->parent->getFile();$this->curname = $this->getPageName($pages[$j]->parent);$this->curpath = $pages[$j]->parent->getPath();$use = true;if ($this->package_output){if (in_array($this->package,$this->package_output)){$this->addElement($pages[$j]->parent,$pages[$j]);} else{if (count($pages[$j]->classelements)){list(,$pages[$j]->parent->package) = each($this->package_output);reset($this->package_output);$pages[$j]->parent->subpackage = '';$this->addElement($pages[$j]->parent,$pages[$j]);} else{unset($pages[$j]);continue;}}} else{$this->addElement($pages[$j]->parent,$pages[$j]);}if ($use)for($i=0; $i<count($pages[$j]->elements); $i++){$pages[$j]->elements[$i]->docblock->package = $this->package;$pages[$j]->elements[$i]->docblock->subpackage = $this->subpackage;$this->proceduralpages->replaceElement($pages[$j]->elements[$i]);$this->addElement($pages[$j]->elements[$i]);}for($i=0; $i<count($pages[$j]->classelements); $i++){if ($this->class){if ($pages[$j]->classelements[$i]->type == 'class'){if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;$this->package = $pages[$j]->classelements[$i]->docblock->package;if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;$this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;$this->class = $pages[$j]->classelements[$i]->name;} else{if ($this->killclass) continue;// force all contained elements to have parent package/subpackage$pages[$j]->classelements[$i]->docblock->package = $this->package;$pages[$j]->classelements[$i]->docblock->subpackage = $this->subpackage;}}if ($pages[$j]->classelements[$i]->type == 'class'){if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;$this->package = $pages[$j]->classelements[$i]->docblock->package;if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;$this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;$this->class = $pages[$j]->classelements[$i]->name;}if (!$this->killclass) $this->addElement($pages[$j]->classelements[$i]);}}phpDocumentor_out("done\n");flush();}$this->sortIndexes();$this->sortTodos();if ($this->sort_page_contents_by_type) $this->sortPageContentsByElementType($pages);}/*** Process the {@link $tutorials} array** Using the tutorialname.ext.ini files, this method sets up tutorial* hierarchy. There is some minimal error checking to make sure that no* tutorial links to itself, even two levels deep as in tute->next->tute.** If all tests pass, it creates the hierarchy* @uses generateTutorialOrder()* @uses _setupTutorialTree()* @access private*/function _processTutorials(){$parents = $all = array();foreach($this->tutorials as $package => $els){if ($this->package_output){if (!in_array($package,$this->package_output)){unset($this->tutorials[$package]);continue;}}if (!isset($this->pkg_elements[$package])){unset($this->tutorials[$package]);continue;}foreach($els as $subpackage => $els2){foreach($els2 as $type => $tutorials){foreach($tutorials as $tutorial){if ($tutorial->ini){if (isset($tutorial->ini['Linked Tutorials'])){foreach($tutorial->ini['Linked Tutorials'] as $child){$sub = (empty($tutorial->subpackage) ? '' : $tutorial->subpackage . '/');$kid = $tutorial->package . '/' . $sub . $child . '.' . $tutorial->tutorial_type;// parent includes self as a linked tutorial?$kidlink = $this->getTutorialLink($kid,false,false,array($tutorial->package));if (is_object($kidlink) && $this->returnSee($kidlink) == $tutorial->getLink($this)){ // bad!addErrorDie(PDERROR_TUTORIAL_IS_OWN_CHILD,$tutorial->name,$tutorial->name.'.ini');}}$parents[] = $tutorial;}}$all[$package][$subpackage][$type][] = $tutorial;}}}}// loop error-checking, use this to eliminate possibility of accidentally linking to a parent as a child$testlinks = array();foreach($parents as $parent){$testlinks[$parent->name]['links'][] = $parent->getLink($this);$testlinks[$parent->name]['name'][$parent->getLink($this)] = $parent->name;}// generate the order of tutorials, and link them togetherforeach($parents as $parent){foreach($parent->ini['Linked Tutorials'] as $child){$sub = (empty($parent->subpackage) ? '' : $parent->subpackage . '/');$kid = $parent->package . '/' . $sub . $child . '.' . $parent->tutorial_type;// child tutorials must be in the same package AND subpackage// AND have the same extension as the parent, makes things clearer for both endsif (in_array($this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package))),$testlinks[$parent->name]['links']))addErrorDie(PDERROR_TUTORIAL_IS_OWN_GRANDPA,$testlinks[$parent->name][$this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package)))],$kid->name,$testlinks[$parent->name][$this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package)))],$kid->name.'.ini');if ($this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package))) == $kid){addWarning(PDERROR_CHILD_TUTORIAL_NOT_FOUND, $child . '.' . $parent->tutorial_type, $parent->name .'.ini',$parent->package, $parent->subpackage);}}}$new = $tree = $roots = array();// build a list of all 'root' tutorials (tutorials without parents).foreach($parents as $i => $parent){if (! $parent->isChildOf($parents)) {$roots[] = $parent;}}$parents = $roots;// add the parents and all child tutorials in order to the list of tutorials to processforeach($parents as $parent){$this->generateTutorialOrder($parent,$all,$new);}if (count($all)){// add the leftover tutorialsforeach($all as $package => $els){foreach($els as $subpackage => $els2){foreach($els2 as $type => $tutorials){foreach($tutorials as $tutorial){$new[$package][$subpackage][$type][] = $tutorial;}}}}}// remove the old, unprocessed tutorials, and set it up with the next code$this->tutorials = array();// reset integrity of the tutorial list$prev = false;uksort($new, 'tutorialcmp');// debug($this->vardump_tree($new));exit;foreach($new as $package => $els){foreach($els as $subpackage => $els2){foreach($els2 as $type => $tutorials){foreach($tutorials as $tutorial){if ($prev){$this->tutorials[$prevpackage][$prevsubpackage][$prevtype][$prevname]->setNext($tutorial,$this);$tutorial->setPrev($prev,$this);}$this->tutorials[$package][$subpackage][$type][$tutorial->name] = $tutorial;$prev = $tutorial->getLink($this,true);$prevpackage = $package;$prevsubpackage = $subpackage;$prevtype = $type;$prevname = $tutorial->name;}}}}$this->tutorial_tree = $this->_setupTutorialTree();return $new;}/*** called by {@link phpDocumentor_IntermediateParser::Convert()} to traverse* the array of pages and their elements, converting them to the output format** The walk() method should be flexible enough such that it never needs* modification. walk() sets up all of the indexes, and sorts everything in* logical alphabetical order. It then passes each element individually to* {@link Convert()}, which then passes to the Convert*() methods. A child* Converter need not override any of these unless special functionality must* be added. see {@tutorial Converters/template.vars.cls} for details.* {@internal* walk() first creates all of the indexes {@link $elements, $pkg_elements}* and the left indexes specified by {@link $leftindexes},* and then sorts them by calling {@link sortIndexes()}.** Next, it converts all README/CHANGELOG/INSTALL-style files, using* {@link Convert_RIC}.** After this, it* passes all package-level docs to Convert(). Then, it calls the index* sorting functions {@link formatPkgIndex(), formatIndex()} and* {@link formatLeftIndex()}.** Finally, it converts each procedural page in alphabetical order. This* stage passes elements from the physical file to Convert() in alphabetical* order. First, procedural page elements {@link parserDefine, parserInclude}* {@link parserGlobal}, and {@link parserFunction} are passed to Convert().** Then, class elements are passed in this order: {@link parserClass}, then* all of the {@link parserVar}s in the class and all of the* {@link parserMethod}s in the class. Classes are in alphabetical order,* and both vars and methods are in alphabetical order.** Finally, {@link ConvertErrorLog()} is called and the data walk is complete.}}* @param array Format: array(fullpath => {@link parserData} structure with full {@link parserData::$elements}* and {@link parserData::$class_elements}.* @param array Format: array({@link parserPackagePage} 1, {@link parserPackagePage} 2,...)* @uses Converter::_createPkgElements() sets up {@link $elements} and* {@link $pkg_elements} array, as well as {@link $links}*/function walk(&$pages,&$package_pages){if (empty($pages)){die("<b>ERROR</b>: nothing parsed");}$this->_createPkgElements($pages);if (count($this->ric)){phpDocumentor_out("Converting README/INSTALL/CHANGELOG contents...\n");flush();foreach($this->ric as $name => $contents){phpDocumentor_out("$name...");flush();$this->Convert_RIC($name,$contents);}phpDocumentor_out("\ndone\n");flush();}foreach($package_pages as $i => $perp){if ($this->package_output){if (!in_array($package_pages[$i]->package,$this->package_output)) continue;}phpDocumentor_out('Converting package page for package '.$package_pages[$i]->package.'... ');flush();$this->package = $package_pages[$i]->package;$this->subpackage = '';$this->class = false;$this->Convert($package_pages[$i]);phpDocumentor_out("done\n");flush();}phpDocumentor_out("Converting tutorials/extended docs\n");flush();// get tutorials into the order they will display, and set next/prev links$new = $this->_processTutorials();foreach($this->tutorials as $package => $els){foreach($els as $subpackage => $els2){foreach($els2 as $type => $tutorials){foreach($tutorials as $tutorial){switch ($type){case 'pkg' :$a = '';if ($tutorial->ini)$a .= 'Top-level ';if (!empty($tutorial->subpackage))$a .= 'Sub-';$ptext = "Converting ${a}Package-level tutorial ".$tutorial->name.'...';break;case 'cls' :$a = '';if ($tutorial->ini)$a .= 'Top-level ';$ptext = "Converting ${a}Class-level tutorial " . $tutorial->name ." and associating...";$link = Converter::getClassLink(str_replace('.cls','',$tutorial->name), $tutorial->package);if (is_object($link)){if ($this->sort_absolutely_everything){$addend = 'unsuccessful ';if (isset($this->package_elements[$tutorial->package][$tutorial->subpackage]['class'][$link->name])){$this->package_elements[$tutorial->package][$tutorial->subpackage]['class'][$link->name][0]->addTutorial($tutorial,$this);$addend = 'success ';}} else{$addend = 'unsuccessful ';if (!isset($this->classes->killclass[str_replace('.cls','',$tutorial->name)]) && !isset($this->classes->killclass[str_replace('.cls','',$tutorial->name)][$tutorial->path])){foreach($pages as $j => $inf){foreach($inf->classelements as $i => $class){if ($class->type == 'class' && $class->name == str_replace('.cls','',$tutorial->name) && $class->path == $link->path){$pages[$j]->classelements[$i]->addTutorial($tutorial,$this);$addend = 'success ';}}}}}$ptext .= $addend;} else $ptext .= "unsuccessful ";break;case 'proc' :$a = '';if ($tutorial->ini)$a .= 'Top-level ';$ptext = "Converting ${a}Procedural-level tutorial ".$tutorial->name." and associating...";$link = Converter::getPageLink(str_replace('.proc','',$tutorial->name), $tutorial->package);if (is_object($link)){$addend = 'unsuccessful ';if ($this->sort_absolutely_everything){if (isset($this->package_elements[$tutorial->package][$tutorial->subpackage]['page'][$link->path])){$this->package_elements[$tutorial->package][$tutorial->subpackage]['page'][$link->path][0]->addTutorial($tutorial,$this);$addend = "success ";}} else{foreach($pages as $j => $info){if ($j == $link->path){$pages[$j]->addTutorial($tutorial,$this);$addend = "success ";}}}$ptext .= $addend;} else $ptext .= "unsuccessful ";break;}phpDocumentor_out($ptext);flush();$this->package = $tutorial->package;$this->subpackage = $tutorial->subpackage;$this->Convert($tutorial);phpDocumentor_out("done\n");flush();}}}}phpDocumentor_out("Formatting Package Indexes...");flush();$this->formatPkgIndex();phpDocumentor_out("done\n");flush();phpDocumentor_out("Formatting Index...");flush();$this->formatIndex();phpDocumentor_out("done\n\n");flush();phpDocumentor_out("Formatting Left Quick Index...");flush();$this->formatLeftIndex();phpDocumentor_out("done\n\n");flush();if ($this->sort_absolutely_everything) return $this->walk_everything();foreach($pages as $j => $flub){phpDocumentor_out('Converting '.$pages[$j]->parent->getPath());flush();$this->package = $pages[$j]->parent->package;$this->subpackage = $pages[$j]->parent->subpackage;$this->class = false;$this->curfile = $pages[$j]->parent->getFile();$this->curname = $this->getPageName($pages[$j]->parent);$this->curpath = $pages[$j]->parent->getPath();$use = true;if ($this->package_output){if (in_array($this->package,$this->package_output)){$this->Convert($pages[$j]);} else{$use = false;}} else{$this->Convert($pages[$j]);}phpDocumentor_out(" Procedural Page Elements...");flush();if ($use)for($i=0; $i<count($pages[$j]->elements); $i++){$a = $pages[$j]->elements[$i]->docblock->getKeyword('access');if (is_object($a)) $a = $a->getString();if (!$this->parseprivate && ($a == 'private'))continue;// phpDocumentor_out(" ".$pages[$j]->elements[$i]->name."\n");$pages[$j]->elements[$i]->docblock->package = $this->package;$pages[$j]->elements[$i]->docblock->subpackage = $this->subpackage;$this->Convert($pages[$j]->elements[$i]);}phpDocumentor_out(" Classes...");$this->class = false;flush();for($i=0; $i<count($pages[$j]->classelements); $i++){if ($this->class){if ($pages[$j]->classelements[$i]->type == 'class'){if (!$this->killclass) $this->endClass();$this->killclass = false;if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;$this->package = $pages[$j]->classelements[$i]->docblock->package;if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;$this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;$this->class = $pages[$j]->classelements[$i]->name;} else{$a = $pages[$j]->classelements[$i]->docblock->getKeyword('access');if (is_object($a)) $a = $a->getString();if (!$this->parseprivate && ($a == 'private'))continue;if ($this->killclass) continue;// force all contained elements to have parent package/subpackage$pages[$j]->classelements[$i]->docblock->package = $this->package;$pages[$j]->classelements[$i]->docblock->subpackage = $this->subpackage;}}if ($pages[$j]->classelements[$i]->type == 'class'){$this->killclass = false;if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;$this->package = $pages[$j]->classelements[$i]->docblock->package;if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;$this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;$this->class = $pages[$j]->classelements[$i]->name;}if ($this->killclass) continue;// phpDocumentor_out(" ".$pages[$j]->classelements[$i]->name."\n");$this->Convert($pages[$j]->classelements[$i]);}if (count($pages[$j]->classelements) && !$this->killclass) $this->endClass();phpDocumentor_out(" done\n");flush();$this->endPage();}phpDocumentor_out("\nConverting @todo List...");flush();if (count($this->todoList)){$this->ConvertTodoList();}phpDocumentor_out("done\n");flush();phpDocumentor_out("\nConverting Error Log...");flush();$this->ConvertErrorLog();phpDocumentor_out("done\n");flush();}/*** Get a tree structure representing the hierarchy of tutorials** Returns an array in format:* <pre>* array('tutorial' => {@link parserTutorial},* 'kids' => array( // child tutorials* array('tutorial' => child {@link parserTutorial},* 'kids' => array(...)* )* )* )* </pre>* @param parserTutorial|array* @tutorial tutorials.pkg* @return array*/function getTutorialTree($tutorial){if (is_object($tutorial)){$path = $this->_tutorial_path($tutorial,$tutorial,$tutorial);if (isset($this->tutorial_tree[$path])) {$tutorial = $this->tutorial_tree[$path];} else {return false;}}$tree = array();if (isset($tutorial['tutorial'])){$tree['tutorial'] = $tutorial['tutorial'];if (isset($tutorial['child'])){foreach($tutorial['child'] as $a => $b){$btut = $b['tutorial'];$res = array('tutorial' => $this->tutorials[$btut->package][$btut->subpackage][$btut->tutorial_type][$btut->name]);if (isset($b['child'])){$tempres = Converter::getTutorialTree($b);$res['kids'] = $tempres['kids'];}$tree['kids'][] = $res;}}}return $tree;}/*** Remove tutorials one by one from $all, and transfer them into $new in the* order they should be parsed* @param parserTutorial* @param array* @param array* @access private*/function generateTutorialOrder($parent,&$all,&$new){// remove from the list of tutorials to processforeach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => $t){if ($t->name == $parent->name) {unset($all[$parent->package][$parent->subpackage][$parent->tutorial_type][$ind]);}}// add to the new ordered list of tutorials$x = &$new[$parent->package][$parent->subpackage][$parent->tutorial_type];if (!is_object($x[count($x) - 1]) || $x[count($x) - 1]->name != $parent->name){ // only add if the parent isn't also a child$new[$parent->package][$parent->subpackage][$parent->tutorial_type][] = $parent;// add a new branch to the tree}// process all child tutorials, and insert them in order// debug("processing parent ".$parent->name);if ($parent->ini){foreach($parent->ini['Linked Tutorials'] as $child){$sub = (empty($parent->subpackage) ? '' : $parent->subpackage . '/');$kid = $parent->package . '/' . $sub . $child . '.' . $parent->tutorial_type;$_klink = $this->getTutorialLink($kid,false,false,array($parent->package));if (is_object($_klink)) {$klink = $this->returnSee($_klink);} else {$klink = false;}// remove the child from the list of remaining tutorialsforeach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => $tute){if ($klink && $tute->getLink($this) == $klink){// set up parent, next and prev links$tute->setParent($parent, $this);// remove the child from the list of tutorials to processforeach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => $t){if ($t->name == $tute->name)unset($all[$parent->package][$parent->subpackage][$parent->tutorial_type][$ind]);}// add to the new ordered list of tutorials$new[$parent->package][$parent->subpackage][$parent->tutorial_type][] = $tute;if ($tute->ini){// add all the child's child tutorials to the list$this->generateTutorialOrder($tute,$all,$new);}}}}}return;}/** Returns the path to this tutorial as a string* @param parserTutorial $pkg* @param parserTutorial $subpkg* @param parserTutorial $namepkg* @return string */function _tutorial_path($pkg, $subpkg = 0, $namepkg = 0){if (!$subpkg) {$subpkg = $pkg;}if (!$namepkg) {$namepkg = $pkg;}$subpackagename = ($subpkg->subpackage ? '/' . $subpkg->subpackage : '');return $pkg->package . $subpackagename . '/' . $namepkg->name;}/*** Creates a tree structure of tutorials** Format:* <pre>* array('package/subpackage/tutorial1.ext' =>* array('tutorial' => {@link parserTutorial},* 'child' =>* array('package/subpackage/child1tutorial.ext' => ...,* 'package/subpackage/child2tutorial.ext' => ...,* ...* )* 'package/subpackage/tutorial2.ext' => ...,* ...* )* </pre>* @return array the tutorial tree* @access private*/function _setupTutorialTree($parent = false){if (! isset($this->processed_tutorials)) {$this->processed_tutorials = array();}$tree = array();if (!$parent){foreach($this->tutorials as $package => $s){foreach($s as $subpackage => $t){foreach($t as $type => $n){foreach($n as $name => $tutorial){if ($tutorial->parent) {continue;}$child_path = $this->_tutorial_path($tutorial,$tutorial,$tutorial);if (isset($this->processed_tutorials[$child_path])) {continue;}$this->processed_tutorials[$child_path] = $tutorial;//debug("parent ".$tutorial->name);$ret = $this->_setupTutorialTree($tutorial);if (!count($tree)) {$tree = $ret;} else {$tree = array_merge($tree,$ret);}}}}}return $tree;}$parent_path = $this->_tutorial_path($parent);$tree[$parent_path]['tutorial'] = $parent;// process all child tutorials, and insert them in orderif ($parent->ini){foreach($parent->ini['Linked Tutorials'] as $child){if (isset($this->tutorials[$parent->package][$parent->subpackage][$parent->tutorial_type][$child . '.' .$parent->tutorial_type])) {// remove the child from the list of remaining tutorials$tute = $this->tutorials[$parent->package][$parent->subpackage][$parent->tutorial_type][$child . '.' .$parent->tutorial_type];} else {$tute = false;}if (!$tute) {continue;}$child_path = $this->_tutorial_path($parent,$parent,$tute);if (isset($this->processed_tutorials[$child_path])) {continue;}$this->processed_tutorials[$child_path] = $tute;if ($tute->name != $child . '.' . $parent->tutorial_type) {continue;}//echo "Adding [$child_path] to [$parent_path]<br>";$tree[$parent_path]['child'][$this->_tutorial_path($parent,$parent,$tute)]['tutorial']= $tute;if (!$tute->ini) {continue;}// add all the child's child tutorials to the listif (!isset($tree[$parent_path]['child'])) {$tree[$parent_path]['child'] = $this->_setupTutorialTree($tute);} else {$tree[$parent_path]['child'] = array_merge($tree[$parent_path]['child'],$this->_setupTutorialTree($tute));}}}return $tree;}/*** Debugging function for dumping {@link $tutorial_tree}* @return string*/function vardump_tree($tree,$indent=''){if (phpDocumentor_get_class($tree) == 'parsertutorial') return $tree->name.' extends '.($tree->parent? $tree->parent->name : 'nothing');$a = '';foreach($tree as $ind => $stuff){$x = $this->vardump_tree($stuff,"$indent ");$a .= $indent.'['.$ind." => \n ".$indent.$x."]\n";}return substr($a,0,strlen($a) - 1);}/*** @access private*/function sort_package_elements($a,$b){if (($a->type == $b->type) && (isset($a->isConstructor) && $a->isConstructor)) return -1;if (($a->type == $b->type) && (isset($b->isConstructor) && $b->isConstructor)) return 1;if ($a->type == $b->type) return strnatcasecmp($a->name,$b->name);if ($a->type == 'class') return -1;if ($b->type == 'class') return 1;if ($a->type == 'const') return -1;if ($b->type == 'const') return 1;if ($a->type == 'var') return -1;if ($b->type == 'var') return 1;if ($a->type == 'page') return -1;if ($b->type == 'page') return 1;if ($a->type == 'include') return -1;if ($b->type == 'include') return 1;if ($a->type == 'define') return -1;if ($b->type == 'define') return 1;if ($a->type == 'global') return -1;if ($b->type == 'global') return 1;if ($a->type == 'function') return -1;if ($b->type == 'function') return 1;}/*** @access private*/function defpackagesort($a,$b){if ($a == $GLOBALS['phpDocumentor_DefaultPackageName']) return -1;if ($b == $GLOBALS['phpDocumentor_DefaultPackageName']) return 0;return strnatcasecmp($a,$b);}/*** @access private*/function Pc_sort($a,$b){return strnatcasecmp(key($a),key($b));}/*** walk over elements by package rather than page** This method is designed for converters like the PDF converter that need* everything passed in alphabetical order by package/subpackage and by* procedural and then class information* @see PDFdefaultConverter* @see walk()*/function walk_everything(){global $hooser;$hooser = false;uksort($this->package_elements,array($this,'defpackagesort'));foreach($this->package_elements as $package => $r){if ($this->package_output){if (!in_array($this->package,$this->package_output)){unset($this->package_elements[$package]);continue;}}uksort($this->package_elements[$package],'strnatcasecmp');}foreach($this->package_elements as $package => $r){foreach($this->package_elements[$package] as $subpackage => $r){if (isset($r['page'])){uksort($r['page'],'strnatcasecmp');foreach($r['page'] as $page => $oo){usort($this->package_elements[$package][$subpackage]['page'][$page],array($this,'sort_package_elements'));}}if (isset($r['class'])){uksort($r['class'],'strnatcasecmp');foreach($r['class'] as $page => $oo){usort($r['class'][$page],array($this,'sort_package_elements'));}}$this->package_elements[$package][$subpackage] = $r;}}foreach($this->package_elements as $package => $s){$notyet = false;foreach($s as $subpackage => $r){$this->package = $package;$this->subpackage = $subpackage;if (isset($r['page'])){$this->class = false;foreach($r['page'] as $page => $elements){if (is_array($elements)){foreach($elements as $element){if ($element->type == 'page'){phpDocumentor_out('Converting '.$element->parent->getPath());flush();$this->curfile = $element->parent->getFile();$this->curname = $this->getPageName($element->parent);$this->curpath = $element->parent->getPath();$notyet = true;} else{// force all contained elements to have parent package/subpackage$element->docblock->package = $this->package;$element->docblock->subpackage = $this->subpackage;$a = $element->docblock->getKeyword('access');if (is_object($a)) $a = $a->getString();if (!$this->parseprivate && ($a == 'private'))continue;}if ($notyet){phpDocumentor_out(" Procedural Page Elements...");flush();$notyet = false;}$this->Convert($element);}}$this->endPage();phpDocumentor_out("done\n");flush();}}$start_classes = true;if (isset($r['class'])){foreach($r['class'] as $class => $elements){foreach($elements as $element){if ($element->type == 'class'){if (!$start_classes){if (count($elements) && !$this->killclass) $this->endClass();phpDocumentor_out("done\n");flush();}$start_classes = false;$this->class = $element->getName();$this->killclass = false;if ($this->checkKillClass($element->getName(),$element->getPath())) continue;if (!$this->killclass){phpDocumentor_out('Converting '.$this->class."...");flush();$notyet = true;}} else{if ($notyet){phpDocumentor_out("Variables/methods/Class constants...\n");flush();$notyet = false;}$a = $element->docblock->getKeyword('access');if (is_object($a)) $a = $a->getString();if (!$this->parseprivate && ($a == 'private'))continue;if ($this->killclass) continue;// force all contained elements to have parent package/subpackage$element->docblock->package = $this->package;$element->docblock->subpackage = $this->subpackage;}if ($this->killclass) continue;$this->Convert($element);}}if (count($elements) && !$this->killclass) $this->endClass();phpDocumentor_out("done\n");flush();} // if isset($r['class'])} // foreach($s} // foreach($this->package_elements)phpDocumentor_out("\nConverting @todo List...");flush();if (count($this->todoList)){$this->ConvertTodoList();}phpDocumentor_out("done\n");flush();phpDocumentor_out("\nConverting Error Log...");flush();$this->ConvertErrorLog();phpDocumentor_out("done\n");flush();}/*** Convert the phpDocumentor parsing/conversion error log* @abstract*/function ConvertErrorLog(){}/*** Convert the list of all @todo tags* @abstract*/function ConvertTodoList(){}/*** Sorts the @todo list - do not override or modify this function* @access private* @uses _sortTodos passed to {@link usort()} to sort the todo list*/function sortTodos(){phpDocumentor_out("\nSorting @todo list...");flush();foreach($this->todoList as $package => $r) {usort($this->todoList[$package], array('Converter', '_sortTodoPackage'));foreach ($r as $a => $sub) {if (is_array($this->todoList[$package][$a][1])) {usort($this->todoList[$package][$a][1],array('Converter', '_sortTodos'));}}}phpDocumentor_out("done\n");}/** @access private */function _sortTodoPackage($a, $b){return strnatcasecmp($a[0]->name, $b[0]->name);}/** @access private */function _sortTodos($a, $b){if (!is_object($a)) {var_dump($a);}return strnatcasecmp($a->getString(), $b->getString());}/*** Sorts all indexes - do not override or modify this function* @uses $leftindex based on the value of leftindex, sorts link arrays* @uses $class_elements sorts with {@link compareLink}* @uses $page_elements sorts with {@link compareLink}* @uses $define_elements sorts with {@link compareLink}* @uses $global_elements sorts with {@link compareLink}* @uses $function_elements sorts with {@link compareLink}* @uses $elements sorts with {@link elementCmp}* @uses $pkg_elements sorts with {@link elementCmp} after sorting by* package/subpackage alphabetically* @access private*/function sortIndexes(){phpDocumentor_out("\nSorting Indexes...");flush();uksort($this->elements,'strnatcasecmp');if ($this->leftindex['classes']){foreach($this->class_elements as $package => $o1){foreach($o1 as $subpackage => $links){usort($this->class_elements[$package][$subpackage],array($this,'compareLink'));}}}if ($this->leftindex['pages']){foreach($this->page_elements as $package => $o1){uksort($this->page_elements[$package],'strnatcasecmp');foreach($o1 as $subpackage => $links){usort($this->page_elements[$package][$subpackage],array($this,'compareLink'));}}}if ($this->leftindex['defines']){foreach($this->define_elements as $package => $o1){uksort($this->define_elements[$package],'strnatcasecmp');foreach($o1 as $subpackage => $links){usort($this->define_elements[$package][$subpackage],array($this,'compareLink'));}}}if ($this->leftindex['globals']){foreach($this->global_elements as $package => $o1){uksort($this->global_elements[$package],'strnatcasecmp');foreach($o1 as $subpackage => $links){usort($this->global_elements[$package][$subpackage],array($this,'compareLink'));}}}if ($this->leftindex['functions']){foreach($this->function_elements as $package => $o1){uksort($this->function_elements[$package],'strnatcasecmp');foreach($o1 as $subpackage => $links){usort($this->function_elements[$package][$subpackage],array($this,'compareLink'));}}}foreach($this->elements as $letter => $nothuing){uasort($this->elements[$letter],array($this,"elementCmp"));}foreach($this->pkg_elements as $package => $els){uksort($this->pkg_elements[$package],'strnatcasecmp');foreach($this->pkg_elements[$package] as $subpackage => $els){if (empty($els)) continue;uksort($this->pkg_elements[$package][$subpackage],'strnatcasecmp');foreach($els as $letter => $yuh){usort($this->pkg_elements[$package][$subpackage][$letter],array($this,"elementCmp"));}}}phpDocumentor_out("done\n");flush();}/*** sorts {@link $page_contents} by element type as well as alphabetically* @see $sort_page_contents_by_element_type*/function sortPageContentsByElementType(&$pages){foreach($this->page_contents as $package => $els){foreach($this->page_contents[$package] as $subpackage => $els){if (empty($els)) continue;foreach($this->page_contents[$package][$subpackage] as $path => $stuff){if (!count($pages[$path]->elements)) continue;usort($pages[$path]->elements,array($this,'eltypecmp'));usort($this->page_contents[$package][$subpackage][$path],array($this,'eltypecmp'));if (isset($this->page_contents[$package][$subpackage][$path][0]))$this->page_contents[$package][$subpackage][$path]['###main'] = $this->page_contents[$package][$subpackage][$path][0];unset($this->page_contents[$package][$subpackage][$path][0]);}}}}/*** @access private* @see Converter::sortIndexes()*/function compareLink($a, $b){return strnatcasecmp($a->name,$b->name);}/*** @access private* @see Converter::sortPageContentsByElementType()*/function eltypecmp($a, $b){if ($a->type == 'page') return -1;if ($b->type == 'page') return 1;return strnatcasecmp($a->type.$a->name,$b->type.$b->name);}/*** does a nat case sort on the specified second level value of the array** @param mixed $a* @param mixed $b* @return int* @access private*/function elementCmp ($a, $b){return strnatcasecmp($a->getName(), $b->getName());}/*** Used to stop conversion of @ignored or private @access classes* @uses $killclass sets killclass based on the value of {@link Classes::$killclass}* and {@link $package_output}* @access private*/function checkKillClass($class, $path){$this->killclass = false;if (isset($this->classes->killclass[$class]) && isset($this->classes->killclass[$class][$path])) $this->killclass = true;if ($this->package_output){$a = $this->classes->getClass($class, $path);if (!in_array($a->docblock->package,$this->package_output)) $this->killclass = true;}if (PHPDOCUMENTOR_DEBUG && $this->killclass) debug("$class $path killed");return $this->killclass;}/*** @param abstractLink descendant of abstractLink* @param array|parserTag list of @todos|@todo tag* @access private*/function addTodoLink($link, $todos){$this->todoList[$link->package][] = array($link, $todos);}/*** Adds all elements to the {@link $elements, $pkg_elements, $links},* {@link $linkswithfile} and left indexes - Do not modify or override* @access private* @param parserBase any documentable element descendant of parserBase* except parserTutorial* @param false|parserPage only used to add a {@link parserPage} if the* $element passed is a parserPage* @staticvar string path of current page, used for {@link $page_contents} setup*/function addElement(&$element,$pageel=false){static $curpath = '';if ($this->package_output){if (!in_array($this->package, $this->package_output)) return;}if ($pageel && phpDocumentor_get_class($pageel) == 'parserdata'){if (isset($pageel->docblock) && phpDocumentor_get_class($pageel->docblock) == 'parserdocblock'){$a = $pageel->docblock->getKeyword('todo');if ($a){$this->addTodoLink($this->addLink($element),$a);}}}if (isset($element->docblock)){$a = $element->docblock->getKeyword('access');if (is_object($a)) $a = $a->getString();if (!$this->parseprivate && ($a == 'private'))return;$a = $element->docblock->getKeyword('todo');if ($a){if ($element->type != 'include') {$this->addTodoLink($this->addLink($element),$a);} else {addWarning(PDERROR_NOTODO_INCLUDE, $element->getLineNumber(),$element->getPath());}}}$startPositionOfElementName = 0; // which character of the element name actually starts its textual nameswitch($element->type){case 'page' :if ($this->sort_absolutely_everything){$this->package_elements[$element->package][$element->subpackage]['page'][$element->getPath()][] = $pageel;}$link = $this->addLink($element);$curpath = $element->getPath();if ($this->leftindex['pages'])$this->page_elements[$element->package][$element->subpackage][] = $link;$this->page_contents[$element->package][$element->subpackage][$curpath]['###main'] = $link;break;case 'class' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;}$link = $this->addLink($element);if ($this->leftindex['classes'])$this->class_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;$this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class]['###main'] = $link;break;case 'include' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;}$link = $this->addLink($element);break;case 'define' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;}$link = $this->addLink($element);if ($this->leftindex['defines'])$this->define_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;$this->page_contents[$element->docblock->package][$element->docblock->subpackage][$curpath][] = $link;break;case 'global' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;}$link = $this->addLink($element);$startPositionOfElementName = 1; // lose the leading "$" characterif ($this->leftindex['globals'])$this->global_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;$this->page_contents[$element->docblock->package][$element->docblock->subpackage][$curpath][] = $link;break;case 'var' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;}$link = $this->addLink($element);$startPositionOfElementName = 1; // lose the leading "$" character$this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class][] = $link;break;case 'const' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;}$link = $this->addLink($element);$this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class][] = $link;break;case 'method' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;}$link = $this->addLink($element);$this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class][] = $link;break;case 'function' :if ($this->sort_absolutely_everything){$this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;}$link = $this->addLink($element);if ($this->leftindex['functions'])$this->function_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;$this->page_contents[$element->docblock->package][$element->docblock->subpackage][$curpath][] = $link;break;default :break;}if ($element->getType() != 'include'){if ($element->getType() == 'var' || $element->getType() == 'method'|| $element->getType() == 'const'){$this->links[$this->package][$this->subpackage][$element->getType()][$element->class][$element->getName()] = $link;$this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->class][$element->getName()] = $link;} else{if ($element->type == 'page'){$this->links[$this->package][$this->subpackage][$element->getType()][$element->getFile()] = $link;$this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->getFile()] = $link;} else{$this->links[$this->package][$this->subpackage][$element->getType()][$element->getName()] = $link;$this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->getName()] = $link;}}}if ($element->type == 'page'){$this->elements[substr(strtolower($element->getFile()),$startPositionOfElementName,1)][] = $element;$this->pkg_elements[$this->package][$this->subpackage][substr(strtolower($element->getFile()),$startPositionOfElementName,1)][] = $element;} else{$this->elements[substr(strtolower($element->getName()),$startPositionOfElementName,1)][] = $element;$this->pkg_elements[$this->package][$this->subpackage][substr(strtolower($element->getName()),$startPositionOfElementName,1)][] = $element;}}/*** returns an abstract link to element. Do not modify or override** This method should only be called in process of Conversion, unless* $element is a parserPage, or $page is set to true, and $element is* not a parserPage* @return abstractLink abstractLink descendant* @access private* @param parserElement element to add a new link (descended from* {@link abstractLink})to the {@link $links} array* @param string classname for elements that are class-based (this may be* deprecated in the future, as the classname* should be contained within the element. if $element is a* page, this parameter is a package name* @param string subpackage name for page elements*/function addLink(&$element,$page = false){if ($page){// create a fake parserPage to extract the fileAlias for this link$fakepage = new parserPage;$fakepage->setPath($element->getPath());$fakepage->setFile(basename($element->getPath()));$this->curname = $this->getPageName($fakepage);}switch($element->type){case 'function':$x = new functionLink;$x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);return $x;break;case 'define':$x = new defineLink;$x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);return $x;break;case 'global':$x = new globalLink;$x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);return $x;break;case 'class':$x = new classLink;$x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);return $x;break;case 'method':$x = new methodLink;$x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);return $x;break;case 'var':$x = new varLink;$x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);return $x;break;case 'const':$x = new constLink;$x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);return $x;break;case 'page':$x = new pageLink;$x->addLink($element->getPath(),$this->getPageName($element),$element->file,$element->package, $element->subpackage, $element->category);return $x;break;}}/*** Return a tree of all classes that extend this class** The data structure returned is designed for a non-recursive algorithm,* and is somewhat complex.* In most cases, the array returned is:** <pre>* array('#root' =>* array('link' => {@link classLink} to $class,* 'parent' => false,* 'children' => array(array('class' => 'childclass1',* 'package' => 'child1package'),* array('class' => 'childclass2',* 'package' => 'child2package'),...* )* ),* 'child1package#childclass1' =>* array('link' => {@link classLink} to childclass1,* 'parent' => '#root',* 'children' => array(array('class' => 'kidclass',* 'package' => 'kidpackage'),...* )* ),* 'kidpackage#kidclass' =>* array('link' => {@link classLink} to kidclass,* 'parent' => 'child1package#childclass1',* 'children' => array() // no children* ),* ....* )*</pre>** To describe this format using language, every class in the tree has an* entry in the first level of the array. The index for all child* classes that extend the root class is childpackage#childclassname.* Each entry in the array has 3 elements: link, parent, and children.* <ul>* <li>link - a {@link classLink} to the current class</li>* <li>parent - a {@link classLink} to the class's parent, or false (except for one special case described below)</li>* <li>children - an array of arrays, each entry has a 'class' and 'package' index to the child class,* used to find the entry in the big array</li>* </ul>** special cases are when the #root class has a parent in another package,* or when the #root class extends a class not found* by phpDocumentor. In the first case, parent will be a* classLink to the parent class. In the second, parent will be the* extends clause, as in:* <code>* class X extends Y* {* ...* }* </code>* in this case, the #root entry will be array('link' => classLink to X, 'parent' => 'Y', children => array(...))** The fastest way to design a method to process the array returned* is to copy HTMLframesConverter::getRootTree() into* your converter and to modify the html to whatever output format you are going to use* @see HTMLframesConverter::getRootTree()* @param string class name* @param string* @param string* @return array Format: see docs*/function getSortedClassTreeFromClass($class,$package,$subpackage){$my_tree = array();$root = $this->classes->getClassByPackage($class,$package);if (!$root) return false;$class_children = $this->classes->getDefiniteChildren($class,$root->curfile);if (!$class_children){// special case: parent class is found, but is not part of this package, class has no childrenif (is_array($root->parent)){$x = $root->getParent($this);if ($x->docblock->package != $package){$v = Converter::getClassLink($root->getName(),$package,$root->getPath());return array('#root' => array('link' => $v,'parent' => Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath()), 'children' => array()));}} else{ // class has normal situation, no childrenif (is_string($root->getParent($this)))return array('#root' => array('link' => Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => $root->getExtends(),'children' => array()));elsereturn array('#root' => array('link' => Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => false, 'children' => array()));}}// special case: parent class is found, but is not part of this package, class has childrenif (is_array($root->parent)){$x = $root->getParent($this);if ($x->docblock->package != $package){$v = Converter::getClassLink($root->getName(),$package,$root->getPath());$my_tree = array('#root' => array('link' => $v, 'parent' => Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath()), 'children' => array()));} else{}} else$my_tree = array('#root' => array('link' => Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => false, 'children' => array()));// location of tree walker$cur = '#root';$lastcur = array(array(false,0));$childpos = 0;if (isset($class_children)){do{if (!$class_children){list($cur, $childpos) = array_pop($lastcur);if (isset($my_tree[$cur]['children'][$childpos + 1])){array_push($lastcur, array($cur, $childpos + 1));$par = $cur;$cur = $my_tree[$cur]['children'][$childpos + 1];$x = $this->classes->getClassByPackage($cur['class'],$cur['package']);$childpos = 0;$cur = $cur['package'] . '#' . $cur['class'];$my_tree[$cur]['link'] = Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath());$my_tree[$cur]['parent'] = $par;$my_tree[$cur]['children'] = array();$class_children = $this->classes->getDefiniteChildren($x->getName(), $x->curfile);continue;} else{$class_children = false;continue;}}foreach($class_children as $chileclass => $chilefile){$ch = $this->classes->getClass($chileclass,$chilefile);$my_tree[$cur]['children'][] = array('class' => $ch->getName(), 'package' => $ch->docblock->package);}usort($my_tree[$cur]['children'],'rootcmp');if (isset($my_tree[$cur]['children'][$childpos])){array_push($lastcur, array($cur, $childpos));$par = $cur;$cur = $my_tree[$cur]['children'][$childpos];$x = $this->classes->getClassByPackage($cur['class'],$cur['package']);$cur = $cur['package'] . '#' . $cur['class'];$my_tree[$cur]['link'] = Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath());$my_tree[$cur]['parent'] = $par;$my_tree[$cur]['children'] = array();$childpos = 0;$class_children = $this->classes->getDefiniteChildren($x->getName(), $x->curfile);} else{list($cur, $childpos) = array_pop($lastcur);}} while ($cur);}return $my_tree;}/*** do not override* @return bool true if a link to this class exists in package $package and subpackage $subpackage* @param string $expr class name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedClass($expr,$package,$subpackage,$file=false){if ($file)return isset($this->linkswithfile[$package][$subpackage]['class'][$file][$expr]);return isset($this->links[$package][$subpackage]['class'][$expr]);}/*** do not override* @return bool true if a link to this function exists in package $package and subpackage $subpackage* @param string $expr function name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedFunction($expr,$package,$subpackage,$file=false){if ($file)return isset($this->linkswithfile[$package][$subpackage]['function'][$file][$expr]);return isset($this->links[$package][$subpackage]['function'][$expr]);}/*** do not override* @return bool true if a link to this define exists in package $package and subpackage $subpackage* @param string $expr define name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedDefine($expr,$package,$subpackage,$file=false){if ($file)return isset($this->linkswithfile[$package][$subpackage]['define'][$file][$expr]);return isset($this->links[$package][$subpackage]['define'][$expr]);}/*** do not override* @return bool true if a link to this define exists in package $package and subpackage $subpackage* @param string $expr define name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedGlobal($expr,$package,$subpackage,$file=false){if ($file)return isset($this->linkswithfile[$package][$subpackage]['global'][$file][$expr]);return isset($this->links[$package][$subpackage]['global'][$expr]);}/*** do not override* @return bool true if a link to this procedural page exists in package $package and subpackage $subpackage* @param string $expr procedural page name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedPage($expr,$package,$subpackage,$path=false){if ($path)return isset($this->linkswithfile[$package][$subpackage]['page'][$path][$expr]);return isset($this->links[$package][$subpackage]['page'][$expr]);}/*** do not override* @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class* @param string $expr method name* @param string $class class name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedMethod($expr,$package,$subpackage,$class,$file=false){if ($file)return isset($this->linkswithfile[$package][$subpackage]['method'][$file][$class][$expr]);return isset($this->links[$package][$subpackage]['method'][$class][$expr]);}/*** do not override* @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class* @param string $expr var name* @param string $class class name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedVar($expr,$package,$subpackage,$class,$file=false){if ($file)return isset($this->linkswithfile[$package][$subpackage]['var'][$file][$class][$expr]);return isset($this->links[$package][$subpackage]['var'][$class][$expr]);}/*** do not override* @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class* @param string $expr constant name* @param string $class class name* @param string $package package to search in* @param string $subpackage subpackage to search in* @access private*/function isLinkedConst($expr,$package,$subpackage,$class,$file=false){if ($file)return isset($this->linkswithfile[$package][$subpackage]['const'][$file][$class][$expr]);return isset($this->links[$package][$subpackage]['const'][$class][$expr]);}/*** return false or a {@link classLink} to $expr* @param string $expr class name* @param string $package package name* @return mixed returns a {@link classLink} or false if the element is not found in package $package* @see classLink*/function getClassLink($expr,$package,$file=false, $text = false){if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedClass($expr,$package,$subpackage,$file)){if ($file){return $this->linkswithfile[$package][$subpackage]['class'][$file][$expr];}return $this->links[$package][$subpackage]['class'][$expr];}}return false;}/*** return false or a {@link functionLink} to $expr* @param string $expr function name* @param string $package package name* @return mixed returns a {@link functionLink} or false if the element is not found in package $package* @see functionLink*/function getFunctionLink($expr,$package,$file=false, $text = false){if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedFunction($expr,$package,$subpackage,$file)){if ($file){return $this->linkswithfile[$package][$subpackage]['function'][$file][$expr];}return $this->links[$package][$subpackage]['function'][$expr];}}return false;}/*** return false or a {@link defineLink} to $expr* @param string $expr constant name* @param string $package package name* @return mixed returns a {@link defineLink} or false if the element is not found in package $package* @see defineLink*/function getDefineLink($expr,$package,$file=false, $text = false){if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedDefine($expr,$package,$subpackage,$file)){if ($file){return $this->linkswithfile[$package][$subpackage]['define'][$file][$expr];}return $this->links[$package][$subpackage]['define'][$expr];}}return false;}/*** return false or a {@link globalLink} to $expr* @param string $expr global variable name (with leading $)* @param string $package package name* @return mixed returns a {@link defineLink} or false if the element is not found in package $package* @see defineLink*/function getGlobalLink($expr,$package,$file=false, $text = false){if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedGlobal($expr,$package,$subpackage,$file)){if ($file){return $this->linkswithfile[$package][$subpackage]['global'][$file][$expr];}return $this->links[$package][$subpackage]['global'][$expr];}}return false;}/*** return false or a {@link pageLink} to $expr* @param string $expr procedural page name* @param string $package package name* @return mixed returns a {@link pageLink} or false if the element is not found in package $package* @see pageLink*/function getPageLink($expr,$package,$path = false, $text = false, $packages = false){if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedPage($expr,$package,$subpackage,$path)){if ($path){return $this->linkswithfile[$package][$subpackage]['page'][$path][$expr];}return $this->links[$package][$subpackage]['page'][$expr];}}return false;}/*** return false or a {@link methodLink} to $expr in $class* @param string $expr method name* @param string $class class name* @param string $package package name* @return mixed returns a {@link methodLink} or false if the element is not found in package $package, class $class* @see methodLink*/function getMethodLink($expr,$class,$package,$file=false, $text = false){$expr = trim($expr);$class = trim($class);if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedMethod($expr,$package,$subpackage,$class,$file)){if ($file){return $this->linkswithfile[$package][$subpackage]['method'][$file][$class][$expr];}return $this->links[$package][$subpackage]['method'][$class][$expr];}}return false;}/*** return false or a {@link varLink} to $expr in $class* @param string $expr var name* @param string $class class name* @param string $package package name* @return mixed returns a {@link varLink} or false if the element is not found in package $package, class $class* @see varLink*/function getVarLink($expr,$class,$package,$file=false, $text = false){$expr = trim($expr);$class = trim($class);if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedVar($expr,$package,$subpackage,$class,$file)){if ($file){return $this->linkswithfile[$package][$subpackage]['var'][$file][$class][$expr];}return $this->links[$package][$subpackage]['var'][$class][$expr];}}return false;}/*** return false or a {@link constLink} to $expr in $class* @param string $expr constant name* @param string $class class name* @param string $package package name* @return mixed returns a {@link varLink} or false if the element is not found in package $package, class $class* @see constLink*/function getConstLink($expr,$class,$package,$file=false, $text = false){$expr = trim($expr);$class = trim($class);if (!isset($this->links[$package])) return false;foreach($this->links[$package] as $subpackage => $notused){if ($this->isLinkedConst($expr,$package,$subpackage,$class,$file)){if ($file){return $this->linkswithfile[$package][$subpackage]['const'][$file][$class][$expr];}return $this->links[$package][$subpackage]['const'][$class][$expr];}}return false;}/*** The meat of the @tutorial tag and inline {@}tutorial} tag** Take a string and return an abstract link to the tutorial it represents.* Since tutorial naming literally works like the underlying filesystem, the* way to reference the tutorial is similar. Tutorials are located in a* subdirectory of any directory parsed, which is named 'tutorials/' (we* try to make things simple when we can :). They are further organized by* package and subpackage as:** tutorials/package/subpackage** and the files are named *.cls, *.pkg, or *.proc, and so a link to a tutorial* named file.cls can be referenced (depending on context) as any of:** <code>* * @tutorial package/subpackage/file.cls* * @tutorial package/file.cls* * @tutorial file.cls* </code>** The first case will only be needed if file.cls exists in both the current* package, in anotherpackage/file.cls and in anotherpackage/subpackage/file.cls* and you wish to reference the one in anotherpackage/subpackage.* The second case is only needed if you wish to reference file.cls in another* package and it is unique in that package. the third will link to the first* file.cls it finds using this search method:** <ol>* <li>current package/subpackage</li>* <li>all other subpackages of current package</li>* <li>parent package, if this package has classes that extend classes in* another package</li>* <li>all other packages</li>* </ol>* @return tutorialLink|string returns either a link, or the original text, if not found* @param string the original expression* @param string package to look in first* @param string subpackage to look in first* @param array array of package names to search in if not found in parent packages.* This is used to limit the search, phpDocumentor automatically searches* all packages* @since 1.2*/function getTutorialLink($expr, $package = false, $subpackage = false, $packages = false){// is $expr a comma-delimited list?if (strpos($expr,',')){$a = explode(',',$expr);$b = array();for($i=0;$i<count($a);$i++){// if so return each component with a link$b[] = Converter::getTutorialLink(trim($a[$i]));}return $b;}$subsection = '';if (strpos($expr,'#')){$a = explode('#',$expr);$org = $expr;$expr = $a[0];$subsection = $a[1];}if (strpos($expr,'/')){$a = explode('/',$expr);if (count($a) == 3){return Converter::getTutorialLink($a[2],$a[0],$a[1],array());}if (count($a) == 2){return Converter::getTutorialLink($a[1],$a[0],false,array());}}if (!$package) $package = $this->package;if (!$subpackage) $subpackage = $this->subpackage;if (!isset($this->all_packages[$package])) return $expr;elseif (isset($packages[$package])) unset($packages[$package]);$ext = pathinfo($expr, PATHINFO_EXTENSION);if (isset($this->tutorials[$package][$subpackage][$ext][$expr])){$a = $this->tutorials[$package][$subpackage][$ext][$expr];$link = new tutorialLink;$link->addLink($subsection,$a->path,$a->name,$a->package,$a->subpackage,$a->getTitle($this,$subsection));return $link;}do{if (!is_array($packages)){$packages = $this->all_packages;if (isset($packages[$package])) unset($packages[$package]);}if (isset($this->tutorials[$package])){if (isset($this->tutorials[$package][$subpackage][$ext][$expr])){$a = $this->tutorials[$package][$subpackage][$ext][$expr];$link = new tutorialLink;$link->addLink($subsection,$a->path,$a->name,$a->package,$a->subpackage,$a->getTitle($this));return $link;} else{foreach($this->tutorials[$package] as $subpackage => $stuff){if (isset($stuff[$ext][$expr])){$a = $stuff[$ext][$expr];$link = new tutorialLink;$link->addLink($subsection,$a->path,$a->name,$a->package,$a->subpackage,$a->getTitle($this));return $link;}}}}// try other packages// look in parent package first, if foundif (isset($this->package_parents[$package])){$p1 = $package;$package = $this->package_parents[$package];} else{// no parent package, so start with the first one that's leftlist($package,) = @each($packages);}if ($package){if (isset($packages[$package])) unset($packages[$package]);}} while (count($packages) || $package);addWarning(PDERROR_TUTORIAL_NOT_FOUND,$expr);return $expr;}/*** The meat of the @see tag and inline {@}link} tag** $expr is a string with many allowable formats:* <ol>* <li>proceduralpagename.ext</li>* <li>constant_name</li>* <li>classname::function()</li>* <li>classname::constantname</li> (new 1.2.4)* <li>classname::$variablename</li>* <li>classname</li>* <li>object classname</li>* <li>function functionname()</li>* <li>global $globalvarname</li>* <li>packagename#expr where expr is any of the above</li>* </ol>** New in version 1.1, you can explicitly specify a package to link to that* is different from the current package. Use the # operator* to specify a new package, as in tests#bug-540368.php (which should appear* as a link like: "{@link tests#bug-540368.php}"). This* example links to the procedural page bug-540368.php in package* tests. Also, the "function" operator is now used to specifically* link to a function instead of a method in the current class.** <code>* class myclass* {* // from inside the class definition, use "function conflict()" to refer to procedural function "conflict()"* function conflict()* {* }* }** function conflict()* {* }* </code>** If classname:: is not present, and the see tag is in a documentation* block within a class, then the function uses the classname to* search for $expr as a function or variable within classname, or any of its parent classes.* given an $expr without '$', '::' or '()' getLink first searches for* classes, procedural pages, constants, global variables, and then searches for* methods and variables within the default class, and finally for any function** @param string $expr expression to search for a link* @param string $package package to start searching in* @param array $packages list of all packages to search in* @return mixed getLink returns a descendant of {@link abstractLink} if it finds a link, otherwise it returns a string* @see getPageLink(), getDefineLink(), getVarLink(), getFunctionLink(), getClassLink()* @see pageLink, functionLink, defineLink, classLink, methodLink, varLink*/function &getLink($expr, $package = false, $packages = false){// is $expr a comma-delimited list?if (strpos($expr,',')){$a = explode(',',$expr);$b = array();for($i=0;$i<count($a);$i++){// if so return each component with a link$b[] = Converter::getLink(trim($a[$i]));}return $b;}if (strpos($expr,'#')){$a = explode('#',$expr);if (count($a) == 2){ // can have exactly 1 package override, otherwise it's ignored// feature 564991, link to php manualif ($a[0] == 'PHP_MANUAL') {$s = 'http://www.php.net/'.$a[1];return $s;}$s = &Converter::getLink($a[1],$a[0],array());return $s;}}$a = &$this->_getLink($expr, $package, $packages);return $a;}/*** @access private*/function &_getLink($expr, $package = false, $packages = false){if (!$package) $package = $this->package;//if (!isset($this->all_packages[$package])) return $expr;elseif (isset($packages[$package])) unset($packages[$package]);$links = &$this->links;$class = $this->class;if (strpos($expr,'function ') === 0){ // asking for a function, not a methodif ($test = Converter::getFunctionLink(str_replace('function ','',str_replace('()','',$expr)), $package)) return $test;else return $expr;}if (strpos($expr,'global ') === 0){ // asking for a global variableif ($test = Converter::getGlobalLink(str_replace('global ','',$expr), $package)) return $test;else return $expr;}if (strpos($expr,'object ') === 0){ // asking for a classif ($test = Converter::getClassLink(str_replace('object ','',$expr), $package)) return $test;else return $expr;}if (strpos($expr,'constant ') === 0){ // asking for a classif ($test = Converter::getDefineLink(str_replace('constant ','',$expr), $package)) return $test;else return $expr;}// are we in a class?if ($class){// is $expr simply a word? see if it is the classif (trim($expr) == $class){if ($test = Converter::getClassLink(trim(str_replace('object ','',$expr)),$package)) return $test;}// if not, check to see if it is a method or variable of this class treeif (!strpos($expr,'::')){// if get is neither get() nor $get, assume get is a function, add () to make get()if (strpos($expr,'$') !== 0 && !strpos($expr,'()')) //$get = $get.'()';{if ($a = $this->getLinkMethod($expr,$class,$package)) return $a;if ($a = $this->getLinkConst($expr,$class,$package)) return $a;if ($a = $this->getLinkVar('$'.$expr,$class,$package)) return $a;}if (strpos($expr,'()')) if ($a = $this->getLinkMethod($expr,$class,$package)) return $a;if (is_numeric(strpos($expr,'$'))) if ($a = $this->getLinkVar($expr,$class,$package)) return $a;}}if ($test = Converter::getClassLink(trim(str_replace('object ','',$expr)),$package)) return $test;if ($test = Converter::getPageLink(trim($expr),$package)) return $test;if ($test = Converter::getDefineLink(trim($expr),$package)) return $test;if ($test = Converter::getGlobalLink(trim($expr),$package)) return $test;// if (strpos($expr,'.'))// package specifiedif (!is_array($packages)){$packages = $this->all_packages;}do{if (isset($packages[$package])) unset($packages[$package]);if ($test = Converter::getClassLink(str_replace('object ','',$expr),$package)) return $test;if ($test = Converter::getPageLink($expr,$package)) return $test;if ($test = Converter::getDefineLink($expr,$package)) return $test;if ($test = Converter::getGlobalLink($expr,$package)) return $test;// is $expr in class::method() or class::$variable format?if (strpos($expr,'function ') === 0){ // asking for a function, not a methodif ($test = Converter::getFunctionLink(str_replace('function','',str_replace('()','',$expr)), $package)) return $test;else return $expr;}$test = $this->_getDoubleColon($expr, $package, $packages, $class, $links);if (!is_string($test)) return $test;if (strpos($test, 'parent::') === 0) return $test;// $expr does not have ::if (is_numeric(@strpos('$',$expr))){// default to current class, whose name is contained in $this->render->parentif ($test = Converter::getVarLink($expr, $class, $package)) return $test;}// $expr is a function? (non-method)if (@strpos($expr,'()')){// otherwise, see if it is a methodif ($class){if ($test = Converter::getMethodLink(str_replace('()','',$expr), $class, $package)) return $test;}// extract the function name, use it to retrieve the file that the function is in// $page = $this->func_page[str_replace('function ','',str_replace('()','',$expr))];// return the linkif ($test = Converter::getFunctionLink(str_replace('function ','',str_replace('()','',$expr)), $package)) return $test;}// $expr is just a word. First, test to see if it is a function of the current packageif ($test = Converter::getFunctionLink(str_replace('function ','',str_replace('()','',$expr)), $package)) return $test;// try other packages// look in parent package first, if foundif (isset($this->package_parents[$package]) && in_array($this->package_parents[$package], $packages)){$p1 = $package;$package = $this->package_parents[$package];if ($package){if (isset($packages[$package])) unset($packages[$package]);}continue;}// no parent package, so start with the first one that's left$package = @array_shift(@array_keys($packages));if ($package && isset($packages[$package])){unset($packages[$package]);}} while (count($packages) || $package);$funcs = get_defined_functions();// feature 564991, link to php manualif (in_array(str_replace(array('(',')'),array('',''),$expr),$funcs['internal'])){$return = 'http://www.php.net/'.str_replace(array('(',')'),array('',''),$expr);return $return;}// no links foundreturn $expr;}/*** Split up getLink to make it easier to debug* @access private*/function _getDoubleColon(&$expr, &$package, &$packages, $class, $links){if (@strpos($expr,'::')){$class_method = explode('::',$expr);if ($class_method[0] == 'parent'){// can only have parent in the same package as the class! subtle bug$package = $this->package;$packages = array();$cl = $this->classes->getClassByPackage($class,$package);if (!$cl){ // this is possible if an example file has parent::method()return $expr;}$par = $cl->getParent($this);$phpparent = false;if (is_object($par)){$package = $par->docblock->package;$phpparent = $par->getName();} else{addWarning(PDERROR_CLASS_PARENT_NOT_FOUND,$class,$package,$class_method[1]);return $expr;}if ($phpparent) $class_method[0] = $phpparent;}if (strpos($class_method[1],'()')){// strip everything but the function name, return a linkif ($test = Converter::getMethodLink(str_replace('()','',$class_method[1]), $class_method[0], $package)) return $test;}if ($test = Converter::getVarLink($class_method[1], $class_method[0], $package)) return $test;if ($test = Converter::getConstLink($class_method[1], $class_method[0], $package)) return $test;}return $expr;}/*** cycle through parent classes to retrieve a link to a method* do not use or override, used by getLink* @access private*/function &getLinkMethod($expr, $class, $package){$links = &$this->links;do{// is $expr in class::method() or class::$variable format?if (@strpos($expr,'::')){$class_method = explode('::',$expr);if ($class_method[0] == 'parent'){$cl = $this->classes->getClassByPackage($class,$package);$par = $cl->getParent($this);$phpparent = false;if (is_object($par)){$package = $par->docblock->package;$phpparent = $par->getName();} else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);if ($phpparent) $class_method[0] = $phpparent;} else{$cl = $this->classes->getClassByPackage($class,$package);}if (strpos($class_method[1],'()')){// strip everything but the function name, return a linkif ($test = Converter::getMethodLink(str_replace('function ','',str_replace('()','',$class_method[1])), $class_method[0], $package)) return $test;}}if ($test = Converter::getMethodLink(str_replace('()','',$expr), $class, $package)) return $test;$cl = $this->classes->getClassByPackage($class,$package);if ($cl){$par = $cl->getParent($this);if (is_object($par)){$package = $par->docblock->package;$class = $par->getName();} else $class = $par;} else $class = false;} while ($class);// no links found$flag = false;return $flag;}/*** cycle through parent classes to retrieve a link to a var* do not use or override, used by getLink* @access private*/function &getLinkVar($expr, $class, $package){$links = &$this->links;do{// is $expr in class::method() or class::$variable format?if (@strpos($expr,'::')){$class_method = explode('::',$expr);if ($class_method[0] == 'parent'){$cl = $this->classes->getClassByPackage($class,$package);$phpparent = false;$par = $cl->getParent($this);if (is_object($par)){$package = $par->docblock->package;$phpparent = $par->getName();} else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);if ($phpparent) $class_method[0] = $phpparent;} else{$cl = $this->classes->getClassByPackage($class,$package);}if ($test = Converter::getVarLink($class_method[1], $class_method[0], $package)) return $test;if ($test = Converter::getVarLink('$'.$class_method[1], $class_method[0], $package)) return $test;}if ($test = Converter::getVarLink($expr, $class, $package)) return $test;if ($test = Converter::getVarLink('$'.$expr, $class, $package)) return $test;$cl = $this->classes->getClassByPackage($class,$package);if ($cl){$par = $cl->getParent($this);if (is_object($par)){$package = $par->docblock->package;$class = $par->getName();} else $class = $par;} else $class = false;} while ($class);// no links found$class = false;return $class;}/*** cycle through parent classes to retrieve a link to a class constant* do not use or override, used by getLink* @access private* @since 1.2.4*/function &getLinkConst($expr, $class, $package){$links = &$this->links;do{// is $expr in class::method() or class::$variable format?if (@strpos($expr,'::')){$class_method = explode('::',$expr);if ($class_method[0] == 'parent'){$cl = $this->classes->getClassByPackage($class,$package);$phpparent = false;$par = $cl->getParent($this);if (is_object($par)){$package = $par->docblock->package;$phpparent = $par->getName();} else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);if ($phpparent) $class_method[0] = $phpparent;} else{$cl = $this->classes->getClassByPackage($class,$package);}if ($test = Converter::getConstLink($class_method[1], $class_method[0], $package)) return $test;}if ($test = Converter::getConstLink($expr, $class, $package)) return $test;$cl = $this->classes->getClassByPackage($class,$package);if ($cl){$par = $cl->getParent($this);if (is_object($par)){$package = $par->docblock->package;$class = $par->getName();} else $class = $par;} else $class = false;} while ($class);// no links found$flag = false;return $flag;}/*** take URL $link and text $text and return a link in the format needed for the Converter* @param string URL* @param string text to display* @return string link to $link* @abstract*/function returnLink($link,$text){}/*** take {@link abstractLink} descendant and text $eltext and return a link* in the format needed for the Converter* @param abstractLink* @param string* @return string link to $element* @abstract*/function returnSee(&$link, $eltext = false){}/*** take {@link abstractLink} descendant and text $eltext and return a* unique ID in the format needed for the Converter* @param abstractLink* @return string unique identifier of $element* @abstract*/function getId(&$link){}/*** Convert README/INSTALL/CHANGELOG file contents to output format* @param README|INSTALL|CHANGELOG* @param string contents of the file* @abstract*/function Convert_RIC($name, $contents){}/*** Convert all elements to output format** This will call ConvertXxx where Xxx is {@link ucfirst}($element->type).* It is expected that a child converter defines a handler for every* element type, even if that handler does nothing. phpDocumentor will* terminate with an error if a handler doesn't exist.* {@internal* Since 1.2.0 beta 3, this function has been moved from child converters* to the parent, because it doesn't really make sense to put it in the* child converter, and we can add error handling.** {@source}}}* @throws {@link PDERROR_NO_CONVERT_HANDLER}* @param mixed {@link parserElement} descendant or {@link parserPackagePage} or {@link parserData}*/function Convert(&$element){$handler = 'convert'.ucfirst($element->type);if (method_exists($this,$handler)){$this->$handler($element);} else{addErrorDie(PDERROR_NO_CONVERTER_HANDLER,$element->type,$handler,phpDocumentor_get_class($this));}}/**#@+* Conversion Handlers** All of the convert* handlers set up template variables for the Smarty* template.{@internal In addition, the {@link newSmarty()} method is* called to retrieve the global Smarty template}}*//*** Default Tutorial Handler** Sets up the tutorial template, and its prev/next/parent links* {@internal* Retrieves the title using {@link parserTutorial::getTitle()} and uses the* {@link parserTutorial::prev, parserTutorial::next, parserTutorial::parent}* links to set up those links.}}* @param parserTutorial*/function &convertTutorial(&$element){$this->package = $element->package;$this->subpackage = $element->subpackage;$x = $element->Convert($this);$template = &$this->newSmarty();$template->assign('contents',$x);$template->assign('title',$element->getTitle($this));$template->assign('nav',$element->parent || $element->prev || $element->next);if ($element->parent){$template->assign('up',$this->getId($element->parent));$template->assign('uptitle',$element->parent->title);}if ($element->prev){$template->assign('prev',$this->getId($element->prev));$template->assign('prevtitle',$element->prev->title);}if ($element->next){$template->assign('next',$this->getId($element->next));$template->assign('nexttitle',$element->next->title);}return $template;}/*** Default Class Handler** Sets up the class template.* {@internal special methods* {@link generateChildClassList(), generateFormattedClassTree()},* {@link getFormattedConflicts, getFormattedInheritedMethods},* and {@link getFormattedInheritedVars} are called to complete vital* template setup.}}*/function convertClass(&$element){$this->class = $element->getName();$this->class_data = &$this->newSmarty();$this->class_data->assign("class_name",$element->getName());$this->class_data->assign("vars",array());$this->class_data->assign("methods",array());$this->class_data->assign("consts",array());$this->class_data->assign("is_interface", $element->isInterface());$this->class_data->assign("implements", $this->getFormattedImplements($element));$this->class_data->assign("package",$element->docblock->package);$this->class_data->assign("line_number",$element->getLineNumber());$this->class_data->assign("source_location",$element->getSourceLocation($this));$this->class_data->assign("page_link",$this->getCurrentPageLink());$docblock = $this->prepareDocBlock($element, false);$this->class_data->assign("sdesc",$docblock['sdesc']);$this->class_data->assign("desc",$docblock['desc']);$this->class_data->assign("access", $docblock['access']);$this->class_data->assign("abstract", $docblock['abstract']);$this->class_data->assign("tags",$docblock['tags']);$this->class_data->assign("api_tags",$docblock['api_tags']);$this->class_data->assign("info_tags",$docblock['info_tags']);$this->class_data->assign("utags",$docblock['utags']);$this->class_data->assign( "prop_tags", $docblock['property_tags'] );if ($this->hasSourceCode($element->getPath())) {$this->class_data->assign("class_slink",$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true));}else$this->class_data->assign("class_slink",false);$this->class_data->assign("children", $this->generateChildClassList($element));$this->class_data->assign("class_tree", $this->generateFormattedClassTree($element));$this->class_data->assign("conflicts", $this->getFormattedConflicts($element,"classes"));$inherited_methods = $this->getFormattedInheritedMethods($element);if (!empty($inherited_methods)){$this->class_data->assign("imethods",$inherited_methods);} else{$this->class_data->assign("imethods",false);}$inherited_vars = $this->getFormattedInheritedVars($element);if (!empty($inherited_vars)){$this->class_data->assign("ivars",$inherited_vars);} else{$this->class_data->assign("ivars",false);}$inherited_consts = $this->getFormattedInheritedConsts($element);if (!empty($inherited_consts)){$this->class_data->assign("iconsts",$inherited_consts);} else{$this->class_data->assign("iconsts",false);}}/*** Converts method for template output** This function must be called by a child converter with any extra* template variables needed in the parameter $addition* @param parserMethod*/function convertMethod(&$element, $additions = array()){$fname = $element->getName();$docblock = $this->prepareDocBlock($element);$returntype = 'void';if ($element->isConstructor) $returntype = $element->class;if ($element->docblock->return){$a = $element->docblock->return->Convert($this);$returntype = $element->docblock->return->converted_returnType;}$params = $param_i = array();if (count($element->docblock->params))foreach($element->docblock->params as $param => $val){$a = $val->Convert($this);$params[] = $param_i[$param] = array("var" => $param,"datatype" => $val->converted_returnType,"data" => $a);}if ($element->docblock->hasaccess) {$acc = $docblock['access'];} else {$acc = 'public';}if ($this->hasSourceCode($element->getPath()))$additions["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);$this->class_data->append('methods',array_merge(array('sdesc' => $docblock['sdesc'],'desc' => $docblock['desc'],'static' => $docblock['static'],'abstract' => $docblock['abstract'],'tags' => $docblock['tags'],'api_tags' => $docblock['api_tags'],'see_tags' => $docblock['see_tags'],'info_tags_sorted' => $docblock['info_tags_sorted'],'info_tags' => $docblock['info_tags'],'utags' => $docblock['utags'],'constructor' => $element->isConstructor,'access' => $acc,'function_name' => $fname,'function_return' => $returntype,'function_call' => $element->getFunctionCall(),'ifunction_call' => $element->getIntricateFunctionCall($this, $param_i),'descmethod' => $this->getFormattedDescMethods($element),'method_overrides' => $this->getFormattedOverrides($element),'method_implements' => $this->getFormattedMethodImplements($element),'line_number' => $element->getLineNumber(),'id' => $this->getId($element),'params' => $params),$additions));}/*** Converts class variables for template output.** This function must be called by a child converter with any extra* template variables needed in the parameter $addition* @param parserVar*/function convertVar(&$element, $additions = array()){$docblock = $this->prepareDocBlock($element);$b = 'mixed';if ($element->docblock->hasaccess)$acc = $element->docblock->tags['access'][0]->value;else$acc = 'public';if ($element->docblock->var){$b = $element->docblock->var->converted_returnType;}if ($this->hasSourceCode($element->getPath()))$additions["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);$this->class_data->append('vars',array_merge(array('sdesc' => $docblock['sdesc'],'desc' => $docblock['desc'],'static' => $docblock['static'],'abstract' => $docblock['abstract'],'utags' => $docblock['utags'],'tags' => $docblock['tags'],'api_tags' => $docblock['api_tags'],'info_tags' => $docblock['info_tags'],'var_name' => $element->getName(),'has_default' => strlen($element->getValue()),'var_default' => $this->postProcess($element->getValue()),'var_type' => $b,'access' => $acc,'line_number' => $element->getLineNumber(),'descvar' => $this->getFormattedDescVars($element),'var_overrides' => $this->getFormattedOverrides($element),'id' => $this->getId($element)),$additions));}/*** Converts class constants for template output.** This function must be called by a child converter with any extra* template variables needed in the parameter $addition* @param parserConst*/function convertConst(&$element, $additions = array()){$docblock = $this->prepareDocBlock($element);if ($element->docblock->hasaccess)$acc = $element->docblock->tags['access'][0]->value;else$acc = 'public';if ($this->hasSourceCode($element->getPath()))$additions["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);$this->class_data->append('consts',array_merge(array('sdesc' => $docblock['sdesc'],'desc' => $docblock['desc'],'access' => $docblock['access'],'abstract' => $docblock['abstract'],'utags' => $docblock['utags'],'tags' => $docblock['tags'],'api_tags' => $docblock['api_tags'],'info_tags' => $docblock['info_tags'],'const_name' => $element->getName(),'const_value' => $this->postProcess($element->getValue()),'access' => $acc,'line_number' => $element->getLineNumber(),'id' => $this->getId($element)),$additions));}/*** Default Page Handler** {@internal In addition to setting up the smarty template with {@link newSmarty()},* this class uses {@link getSourceLocation()} and {@link getClassesOnPage()}* to set template variables. Also used is {@link getPageName()}, to get* a Converter-specific name for the page.}}* @param parserPage*/function convertPage(&$element){$this->page_data = &$this->newSmarty(true);$this->page = $this->getPageName($element->parent);$this->path = $element->parent->getPath();$this->curpage = &$element->parent;$this->page_data->assign("source_location",$element->parent->getSourceLocation($this));$this->page_data->assign("functions",array());$this->page_data->assign("includes",array());$this->page_data->assign("defines",array());$this->page_data->assign("globals",array());$this->page_data->assign("classes",$this->getClassesOnPage($element));$this->page_data->assign("hasclasses",$element->hasClasses());$this->page_data->assign("hasinterfaces",$element->hasInterfaces());$this->page_data->assign("name", $element->parent->getFile());if ($t = $element->getTutorial()){$this->page_data->assign("tutorial",$this->returnSee($t));} else{$this->page_data->assign("tutorial",false);}if ($element->docblock){$docblock = $this->prepareDocBlock($element, false);$this->page_data->assign("sdesc",$docblock['sdesc']);$this->page_data->assign("desc",$docblock['desc']);$this->page_data->assign("tags",$docblock['tags']);$this->page_data->assign("api_tags",$docblock['api_tags']);$this->page_data->assign("info_tags",$docblock['info_tags']);$this->page_data->assign("utags",$docblock['utags']);}}/*** Converts global variables for template output** This function must be called by a child converter with any extra* template variables needed in the parameter $addition* {@internal* In addition to using {@link prepareDocBlock()}, this method also* uses utility functions {@link getGlobalValue(), getFormattedConflicts()}}}* @param parserGlobal* @uses postProcess() on global_value template value, makes it displayable* @param array any additional template variables should be in this array*/function convertGlobal(&$element, $addition = array()){$docblock = $this->prepareDocBlock($element);$value = $this->getGlobalValue($element->getValue());if ($this->hasSourceCode($element->getPath()))$addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);$this->page_data->append('globals',array_merge(array('sdesc' => $docblock['sdesc'],'desc' => $docblock['desc'],'tags' => $docblock['tags'],'api_tags' => $docblock['api_tags'],'info_tags' => $docblock['info_tags'],'utags' => $docblock['utags'],'global_name' => $element->getName(),'global_type' => $element->getDataType($this),'global_value' => $value,'line_number' => $element->getLineNumber(),'global_conflicts' => $this->getFormattedConflicts($element,"global variables"),'id' => $this->getId($element)),$addition));}/*** Converts defines for template output** This function must be called by a child converter with any extra* template variables needed in the parameter $addition* {@internal* In addition to using {@link prepareDocBlock()}, this method also* uses utility functions {@link getGlobalValue(), getFormattedConflicts()}}}* @param parserDefine* @uses postProcess() on define_value template value, makes it displayable* @param array any additional template variables should be in this array*/function convertDefine(&$element, $addition = array()){$docblock = $this->prepareDocBlock($element);if ($this->hasSourceCode($element->getPath()))$addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);$this->page_data->append('defines',array_merge(array('sdesc' => $docblock['sdesc'],'desc' => $docblock['desc'],'tags' => $docblock['tags'],'api_tags' => $docblock['api_tags'],'info_tags' => $docblock['info_tags'],'utags' => $docblock['utags'],'define_name' => $element->getName(),'line_number' => $element->getLineNumber(),'define_value' => $this->postProcess($element->getValue()),'define_conflicts' => $this->getFormattedConflicts($element,"defines"),'id' => $this->getId($element)),$addition));}/*** Converts includes for template output** This function must be called by a child converter with any extra* template variables needed in the parameter $addition* @see prepareDocBlock()* @param parserInclude*/function convertInclude(&$element, $addition = array()){$docblock = $this->prepareDocBlock($element);$per = $this->getIncludeValue($element->getValue(), $element->getPath());if ($this->hasSourceCode($element->getPath()))$addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);$this->page_data->append('includes',array_merge(array('sdesc' => $docblock['sdesc'],'desc' => $docblock['desc'],'tags' => $docblock['tags'],'api_tags' => $docblock['api_tags'],'info_tags' => $docblock['info_tags'],'utags' => $docblock['utags'],'include_name' => $element->getName(),'line_number' => $element->getLineNumber(),'include_value' => $per),$addition));}/*** Converts function for template output** This function must be called by a child converter with any extra* template variables needed in the parameter $addition* @see prepareDocBlock()* @param parserFunction*/function convertFunction(&$element, $addition = array()){$docblock = $this->prepareDocBlock($element);$fname = $element->getName();$params = $param_i = array();if (count($element->docblock->params))foreach($element->docblock->params as $param => $val){$a = $val->Convert($this);$params[] = $param_i[$param] = array("var" => $param,"datatype" => $val->converted_returnType,"data" => $a);}$returntype = 'void';if ($element->docblock->return){$a = $element->docblock->return->Convert($this);$returntype = $element->docblock->return->converted_returnType;}if ($this->hasSourceCode($element->getPath()))$addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);$this->page_data->append('functions',array_merge(array('sdesc' => $docblock['sdesc'],'desc' => $docblock['desc'],'tags' => $docblock['tags'],'api_tags' => $docblock['api_tags'],'info_tags' => $docblock['info_tags'],'utags' => $docblock['utags'],'function_name' => $fname,'function_return' => $returntype,'function_conflicts' => $this->getFormattedConflicts($element,"functions"),'ifunction_call' => $element->getIntricateFunctionCall($this, $param_i),'function_call' => $element->getFunctionCall(),'line_number' => $element->getLineNumber(),'id' => $this->getId($element),'params' => $params),$addition));}/**#@-*//*** convert the element's DocBlock for output** This function converts all tags and descriptions for output* @param mixed any descendant of {@link parserElement}, or {@link parserData}* @param array used to translate tagnames into other tags* @param boolean set to false for pages and classes, the only elements allowed to specify @package* @return array** Format:* <pre>* array('sdesc' => DocBlock summary* 'desc' => DocBlock detailed description* 'tags' => array('keyword' => tagname, 'data' => tag description)* known tags* 'api_tags' => array('keyword' => tagname, 'data' => tag description)* known api documentation tags* 'info_tags' => array('keyword' => tagname, 'data' => tag description)* known informational tags* [ 'utags' => array('keyword' => tagname, 'data' => tag description* unknown tags ]* [ 'vartype' => type from @var/@return tag ]* [ 'var_descrip' => description from @var/@return tag ]* )* </pre>*/function prepareDocBlock(&$element, $names = array(),$nopackage = true){$tagses = $element->docblock->listTags();$tags = $ret = $api_tags = $info_tags = array();$api_tags_arr = array("abstract", "access", "deprecated", "example", "filesource","global", "internal", "name", "return", "see","property", "property-read", "property-write", "method","staticvar", "usedby", "uses", "var");if (!$nopackage){$tags[] = array('keyword' => 'package','data' => $element->docblock->package);if (!empty($element->docblock->subpackage)) $tags[] = array('keyword' => 'subpackage','data' => $element->docblock->subpackage);}if ($element->docblock->var){$a = $element->docblock->var->Convert($this);$ret['vartype'] = $element->docblock->var->converted_returnType;if (!empty($a)){$tags[] = array('keyword' => 'var', 'data' => $a);$ret["var_descrip"] = $a;}}if ($element->docblock->return){$a = $element->docblock->return->Convert($this);$ret['vartype'] = $element->docblock->return->converted_returnType;if (!empty($a)){$tags[] = $api_tags[] = array('keyword' => 'return', 'data' => $a);$ret["var_descrip"] = $a;}}if ($element->docblock->funcglobals)foreach($element->docblock->funcglobals as $global => $val){if ($a = $this->getGlobalLink($global,$element->docblock->package)){$global = $a;}$b = Converter::getLink($val[0]);if (is_object($b) && phpDocumentor_get_class($b) == 'classlink'){$val[0] = $this->returnSee($b);}$tags[] = $api_tags[] = array('keyword' => 'global','data' => $val[0].' '.$global.': '.$val[1]->Convert($this));}if ($element->docblock->statics)foreach($element->docblock->statics as $static => $val){$a = $val->Convert($this);$tags[] = $api_tags[] = array('keyword' => 'staticvar','data' => $val->converted_returnType.' '.$static.': '.$a);}$property_tags = array();foreach ( $element->docblock->properties as $prop_name => $val ){$a = $val->Convert( $this );if ( !empty( $a ) ){$tags[] = $api_tags[] = array( 'keyword' => $val->keyword ,'data' => $val->converted_returnType . ' ' . $prop_name . ': ' . $a );$prop['prop_name'] = $prop_name;$prop['access'] = $val->keyword == 'property-read' ? 'read' :( $val->keyword == 'property-write' ? 'write' : 'read/write' );$prop['prop_type'] = $val->converted_returnType;$prop['sdesc'] = $a;$property_tags[ $prop_name ] = $prop;}}ksort( $property_tags, SORT_STRING );$property_tags = array_values( $property_tags );$info_tags_sorted = array();$ret['static'] = false;foreach($tagses as $tag){if (isset($names[$tag->keyword])) $tag->keyword = $names[$tag->keyword];if ($tag->keyword == 'static') {$ret['static'] = true;continue;}if ($tag->keyword)$tags[] = array("keyword" => $tag->keyword,"data" => $tag->Convert($this));if (in_array($tag->keyword, $api_tags_arr)) {$api_tags[] = array("keyword" => $tag->keyword,"data" => $tag->Convert($this));} else {$info_tags[] = array("keyword" => $tag->keyword,"data" => $tag->Convert($this));@list( $className, $desc ) = explode( " ", $tag->Convert($this), 2 );$info_tags_sorted[ $tag->keyword ][] = array( 'keyword' => $className, 'data' => $desc );}}$utags = array();foreach($element->docblock->unknown_tags as $keyword => $tag){foreach($tag as $t)$utags[] = array('keyword' => $keyword, 'data' => $t->Convert($this));}$ret['abstract'] = false;$ret['access'] = 'public';$see_tags = array();foreach($tags as $tag){if ($tag['keyword'] == 'access') {$ret['access'] = $tag['data'];}if ($tag['keyword'] == 'abstract') {$ret['abstract'] = true;}if ($tag['keyword'] == 'see' || $tag['keyword'] == 'uses' ||$tag['keyword'] == 'usedby') {$see_tags[] = $tag['data'];}}$ret['sdesc'] = $element->docblock->getSDesc($this);$ret['desc'] = $element->docblock->getDesc($this);$ret['tags'] = $tags;$ret['see_tags'] = $see_tags;$ret['info_tags_sorted'] = $info_tags_sorted;$ret['api_tags'] = $api_tags;$ret['info_tags'] = $info_tags;$ret['utags'] = $utags;$ret['property_tags'] = $property_tags;return $ret;}/*** gets a list of all classes declared on a procedural page represented by* $element, a {@link parserData} class* @param parserData &$element* @return array links to each classes documentation** Format:* <pre>* array('name' => class name,* 'sdesc' => summary of the class* 'link' => link to the class's documentation)* </pre>*/function getClassesOnPage(&$element){global $_phpDocumentor_setting;$a = $element->getClasses($this);$classes = array();foreach($a as $package => $clas){if (!empty($_phpDocumentor_setting['packageoutput'])){$packages = explode(',',$_phpDocumentor_setting['packageoutput']);if (!in_array($package, $packages)) continue;}for($i=0; $i<count($clas); $i++){if ($this->parseprivate || ! ($clas[$i]->docblock && $clas[$i]->docblock->hasaccess && $clas[$i]->docblock->tags['access'][0]->value == 'private')){$sdesc = '';$r = array();$sdesc = $clas[$i]->docblock->getSDesc($this);if ($clas[$i]->docblock->hasaccess)$r['access'] = $clas[$i]->docblock->tags['access'][0]->value;else$r['access'] = 'public';if (isset ($clas[$i]->docblock->tags['abstract']))$r['abstract'] = TRUE;else$r['abstract'] = FALSE;$r['name'] = $clas[$i]->getName();$r['sdesc'] = $sdesc;$r['link'] = $this->getClassLink($clas[$i]->getName(),$package,$clas[$i]->getPath());$classes[] = $r;}}}return $classes;}/*** returns an array containing the class inheritance tree from the root* object to the class.** This method must be overridden, or phpDocumentor will halt with a fatal* error* @return string Converter-specific class tree for an individual class* @param parserClass class variable* @abstract*/function generateFormattedClassTree($class){addErrorDie(PDERROR_CONVERTER_OVR_GFCT,phpDocumentor_get_class($this));}/*** returns an array containing the class inheritance tree from the root* object to the class.** This method must be overridden, or phpDocumentor will halt with a fatal* error* @return string Converter-specific class tree for an individual class* @param parserClass class variable* @abstract*/function getFormattedImplements($el){$ret = array();foreach ($el->getImplements() as $interface){$link = $this->getLink($interface);if ($link && is_object($link)) {$ret[] = $this->returnSee($link);} else {if (class_exists('ReflectionClass')) {if (interface_exists($interface)) {$inter = new ReflectionClass($interface);if ($inter->isInternal()) {$ret[] = $interface . ' (internal interface)';} else {$ret[] = $interface;}}} else {$ret[] = $interface;}}}return $ret;}/*** @param mixed {@link parserClass, parserFunction, parserDefine} or* {@link parserGlobal}* @param string type to display. either 'class','function','define'* or 'global variable'* @return array links to conflicting elements, or empty array* @uses parserClass::getConflicts()* @uses parserFunction::getConflicts()* @uses parserDefine::getConflicts()* @uses parserGlobal::getConflicts()*/function getFormattedConflicts(&$element,$type){$conflicts = $element->getConflicts($this);$r = array();if (!$conflicts) return false;foreach($conflicts as $package => $class){$r[] = $class->getLink($this,$class->docblock->package);}if (!empty($r)) $r = array('conflicttype' => $type, 'conflicts' => $r);return $r;}/*** Get a list of methods in child classes that override this method* @return array empty array or array(array('link'=>link to method,* 'sdesc'=>short description of the method),...)* @uses parserMethod::getOverridingMethods()* @param parserMethod*/function getFormattedDescMethods(&$element){$meths = $element->getOverridingMethods($this);$r = array();for($i=0; $i<count($meths); $i++){$ms = array();$ms['link'] = $meths[$i]->getLink($this);$ms['sdesc'] = $meths[$i]->docblock->getSDesc($this);$r[] = $ms;}return $r;}/*** Get a list of vars in child classes that override this var* @return array empty array or array('link'=>link to var,* 'sdesc'=>short description of the method* @uses parserVar::getOverridingVars()* @param parserVar*/function getFormattedDescVars(&$element){$vars = $element->getOverridingVars($this);$r = array();for($i=0; $i<count($vars); $i++){$vs = array();$vs['link'] = $vars[$i]->getLink($this);$vs['sdesc'] = $vars[$i]->docblock->getSDesc($this);$r[] = $vs;}return $r;}/*** Get the method this method overrides, if any* @return array|false array('link'=>link to overridden method,* 'sdesc'=>short description* @see parserMethod::getOverrides()* @param parserMethod*/function getFormattedOverrides(&$element){$ovr = $element->getOverrides($this);if (!$ovr) return false;$sdesc = $ovr->docblock->getSDesc($this);$name = method_exists($ovr, 'getFunctionCall') ? $ovr->getFunctionCall() : $ovr->getName();$link = ($link = $ovr->getLink($this)) ? $link : $ovr->getClass() . '::' . $name;return array('link' => $link,'sdesc' => $sdesc);}/*** Get the method this method(s) implemented from an interface, if any* @return array|false array('link'=>link to implemented method,* 'sdesc'=>short description* @uses parserMethod::getImplements()* @param parserMethod*/function getFormattedMethodImplements(&$element){$ovr = $element->getImplements($this);if (!$ovr) return false;$ret = array();foreach ($ovr as $impl) {$sdesc = $impl->docblock->getSDesc($this);$name = $impl->getName();$link = ($link = $impl->getLink($this)) ? $link : $impl->getClass() . '::' . $name;$ret[] = array('link' => $link,'sdesc' => $sdesc);}return $ret;}/*** returns a list of child classes** @param parserClass class variable* @uses parserClass::getChildClassList()*/function generateChildClassList($class){$kids = $class->getChildClassList($this);$list = array();if (count($kids)){for($i=0; $i<count($kids); $i++){$lt['link'] = $kids[$i]->getLink($this);$lt['sdesc'] = $kids[$i]->docblock->getSDesc($this);if ($kids[$i]->docblock->hasaccess)$lt['access'] = $kids[$i]->docblock->tags['access'][0]->value;else$lt['access'] = 'public';$lt['abstract'] = isset ($kids[$i]->docblock->tags['abstract'][0]);$list[] = $lt;}} else return false;return $list;}/*** Return template-enabled list of inherited variables** uses parserVar helper function getInheritedVars and generates a* template-enabled list using getClassLink()* @param parserVar $child class var* @see getClassLink(), parserVar::getInheritedVars()* @return array Format:* <pre>* array(* array('parent_class' => link to parent class's documentation,* 'ivars' =>* array(* array('name' => inherited variable name,* 'link' => link to inherited variable's documentation,* 'default' => default value of inherited variable,* 'sdesc' => summary of inherited variable),* ...),* ...)* </pre>*/function getFormattedInheritedVars($child){$package = $child->docblock->package;$subpackage = $child->docblock->subpackage;$ivars = $child->getInheritedVars($this);$results = array();if (!count($ivars)) return $results;foreach($ivars as $parent => $vars){$file = $vars['file'];$vars = $vars['vars'];$par = $this->classes->getClass($parent,$file);if ($par) {$package = $par->docblock->package;}usort($vars,array($this,"sortVar"));$result['parent_class'] = $this->getClassLink($parent, $package);if (!$result['parent_class']) {$result['parent_class'] = $parent . ' (Internal Class)';}foreach($vars as $var){$info = array();if ($var->docblock->hasaccess) {$info['access'] = $var->docblock->tags['access'][0]->value;} else {$info['access'] = 'public';}$info['abstract'] = isset ($var->docblock->tags['abstract'][0]);$info['name'] = $var->getName();$info['link'] = $var->getLink($this);if (!$info['link']) {$info['link'] = $info['name'];}$info['default'] = $this->postProcess($var->getValue());if ($var->docblock)$info['sdesc'] = $var->docblock->getSDesc($this);$result["ivars"][] = $info;}$results[] = $result;$result = array();}return $results;}/*** Return template-enabled list of inherited methods** uses parserMethod helper function getInheritedMethods and generates a* template-enabled list using getClassLink()* @param parserMethod $child class method* @see getClassLink(), parserMethod::getInheritedMethods()* @return array Format:* <pre>* array(* array('parent_class' => link to parent class's documentation,* 'ivars' =>* array(* array('name' => inherited variable name,* 'link' => link to inherited variable's documentation,* 'function_call' => {@link parserMethod::getIntricateFunctionCall()}* returned array,* 'sdesc' => summary of inherited variable),* ...),* ...)* </pre>*/function getFormattedInheritedMethods($child){$package = $child->docblock->package;$subpackage = $child->docblock->subpackage;$imethods = $child->getInheritedMethods($this);$results = array();if (!count($imethods)) return $results;foreach($imethods as $parent => $methods){$file = $methods['file'];$methods = $methods['methods'];$par = $this->classes->getClass($parent,$file);if ($par) {$package = $par->docblock->package;}usort($methods,array($this,"sortMethod"));$result['parent_class'] = $this->getClassLink($parent,$package);if (!$result['parent_class']) {$result['parent_class'] = $parent . ' (Internal Class)';}foreach($methods as $method){$info = array();if ($method->docblock->hasaccess) {$info['access'] = $method->docblock->tags['access'][0]->value;} else {$info['access'] = 'public';}$info['abstract'] = isset ($method->docblock->tags['abstract'][0]);if ($method->isConstructor) $info['constructor'] = 1;$returntype = 'void';if ($method->isConstructor) {$returntype = $method->getClass();}if ($method->docblock->return) {$a = $method->docblock->return->Convert($this);$returntype = $method->docblock->return->converted_returnType;}$info['function_return'] = $returntype;$info['static'] = isset ($method->docblock->tags['static'][0]);$info['link'] = $method->getLink($this);if (!$info['link']) {$info['link'] = $method->getFunctionCall();}$info['name'] = $method->getName();if ($method->docblock)$info['sdesc'] = $method->docblock->getSDesc($this);$params = array();if (count($method->docblock->params))foreach($method->docblock->params as $param => $val){$a = $val->Convert($this);$params[$param] = array("var" => $param,"datatype" => $val->converted_returnType,"data" => $a);}$info['function_call'] = $method->getIntricateFunctionCall($this,$params);$result["imethods"][] = $info;}$results[] = $result;$result = array();}return $results;}/*** Return template-enabled list of inherited class constants** uses parserConst helper function getInheritedConsts and generates a* template-enabled list using getClassLink()* @param parserConst $child class constant* @see getClassLink(), parserMethod::getInheritedConsts()* @return array Format:* <pre>* array(* array('parent_class' => link to parent class's documentation,* 'ivars' =>* array(* array('name' => inherited constant name,* 'link' => link to inherited constant's documentation,* 'value' => constant value,* 'sdesc' => summary of inherited constant),* ...),* ...)* </pre>*/function getFormattedInheritedConsts($child){$package = $child->docblock->package;$subpackage = $child->docblock->subpackage;$ivars = $child->getInheritedConsts($this);$results = array();if (!count($ivars)) return $results;foreach($ivars as $parent => $vars){$file = $vars['file'];$vars = $vars['consts'];$par = $this->classes->getClass($parent,$file);if ($par) {$package = $par->docblock->package;}usort($vars,array($this,"sortVar"));$result['parent_class'] = $this->getClassLink($parent,$package);if (!$result['parent_class']) {$result['parent_class'] = $parent . ' (Internal Class)';}foreach($vars as $var){$info = array();if ($var->docblock->hasaccess) {$info['access'] = $var->docblock->tags['access'][0]->value;} else {$info['access'] = 'public';}$info['name'] = $var->getName();$info['link'] = $var->getLink($this);if (!$info['link']) {$info['link'] = $info['name'] . ' = ' . $var->getValue();}$info['value'] = $this->postProcess($var->getValue());if ($var->docblock)$info['sdesc'] = $var->docblock->getSDesc($this);$result["iconsts"][] = $info;}$results[] = $result;$result = array();}return $results;}/*** Return a Smarty template object to operate with** This returns a Smarty template with pre-initialized variables for use.* If the method "SmartyInit()" exists, it is called.* @return Smarty*/function &newSmarty(){$templ = new Smarty;$templ->use_sub_dirs = false;$templ->template_dir = realpath($this->smarty_dir . PATH_DELIMITER . 'templates');$templatename = get_class($this) . $this->templateName;if (!file_exists($this->targetDir . DIRECTORY_SEPARATOR . md5($templatename))) {// we'll delete this on finishing conversion$this->_compiledDir[$this->targetDir . DIRECTORY_SEPARATOR . md5($templatename)] = 1;mkdir($this->targetDir . DIRECTORY_SEPARATOR . md5($templatename),0775);}$templ->compile_dir = realpath($this->targetDir . PATH_DELIMITER . md5($templatename));$templ->config_dir = realpath($this->smarty_dir . PATH_DELIMITER . 'configs');$templ->assign("date",date("r",time()));$templ->assign("maintitle",$this->title);$templ->assign("package",$this->package);$templ->assign("phpdocversion",PHPDOCUMENTOR_VER);$templ->assign("phpdocwebsite",PHPDOCUMENTOR_WEBSITE);$templ->assign("subpackage",$this->subpackage);if (method_exists($this,'SmartyInit')) return $this->SmartyInit($templ);return $templ;}/*** Finish up parsing/cleanup directories*/function cleanup(){foreach ($this->_compiledDir as $dir => $one) {$this->_rmdir($dir);}}/*** Completely remove a directory and its contents** @param string $directory*/function _rmdir($directory){$handle = @opendir($directory);if ($handle) {while (false !== ($file = readdir($handle))) {if ($file == '.' || $file == '..') {continue;}if (is_dir($directory . DIRECTORY_SEPARATOR . $file)) {$this->_rmdir($directory . DIRECTORY_SEPARATOR . $file);}@unlink($directory . DIRECTORY_SEPARATOR . $file);}closedir($handle);@rmdir($directory);}}/*** do all necessary output* @see Converter* @abstract*/function Output($title){phpDocumentor_out("WARNING: Generic Converter::Output was used, no output will be generated");}/*** Set the template directory with a different template base directory* @tutorial phpDocumentor.howto.pkg#using.command-line.templatebase* @param string template base directory* @param string template name*/function setTemplateBase($base, $dir){// remove trailing /'s from the base path, if any$base = str_replace('\\','/',$base);while ($base{strlen($base) - 1} == '/') $base = substr($base,0,strlen($base) - 1);$this->templateName = substr($dir,0,strlen($dir) - 1);$this->templateDir = $base . "/Converters/" . $this->outputformat . "/" . $this->name . "/templates/" . $dir;if (!is_dir($this->templateDir)){addErrorDie(PDERROR_TEMPLATEDIR_DOESNT_EXIST, $this->templateDir);}$this->smarty_dir = $this->templateDir;if (file_exists($this->templateDir . PATH_DELIMITER . 'options.ini')){// retrieve template options, allow array creation$this->template_options = phpDocumentor_parse_ini_file($this->templateDir . PATH_DELIMITER . 'options.ini',true);}}/*** sets the template directory based on the {@link $outputformat} and {@link $name}* Also sets {@link $templateName} to the $dir parameter* @param string subdirectory*/function setTemplateDir($dir){if ('/var/www/pear' != '@'.'DATA-DIR@') {$templateBase = str_replace('\\', '/', '/var/www/pear/PhpDocumentor/phpDocumentor');} else {$templateBase = str_replace('\\','/',$GLOBALS['_phpDocumentor_install_dir']) . '/phpDocumentor';}$this->setTemplateBase($templateBase, $dir);}/*** Get the absolute path to the converter's base directory* @return string*/function getConverterDir(){if ('/var/www/pear' != '@' . 'DATA-DIR@') {return str_replace('\\', '/', "/var/www/pear/PhpDocumentor/phpDocumentor/Converters/") . $this->outputformat . "/" . $this->name;} else {return str_replace('\\','/',$GLOBALS['_phpDocumentor_install_dir']) ."/phpDocumentor/Converters/" . $this->outputformat . "/" . $this->name;}}/*** Parse a global variable's default value for class initialization.** If a global variable's default value is "new class" as in:* <code>* $globalvar = new Parser* </code>* This method will document it not as "new Parser" but instead as* "new {@link Parser}". For examples, see {@link phpdoc.inc}.* Many global variables are classes, and phpDocumentor links to their* documentation* @return string default global variable value with link to class if* it's "new Class"* @param string default value of a global variable.*/function getGlobalValue($value){if (strpos($value,'new') === 0){preg_match('/new([^(]*)((?:.|\r|\n)*)/',$value,$newval);if (isset($newval[1])){$a = Converter::getLink(trim($newval[1]));if (!isset($newval[2])) $newval[2] = '';if ($a && phpDocumentor_get_class($a) == 'classlink') $value = 'new '.$this->returnSee($a) .$this->postProcess($newval[2]);}return $value;}return $this->postProcess($value);}/*** Parse an include's file to see if it is a file documented in this project** Although not very smart yet, this method will try to look for the* included file file.ext:** <code>* include ("file.ext");* </code>** If it finds it, it will return a link to the file's documentation. As of* 1.2.0rc1, phpDocumentor is smarty enough to find these cases:* <ul>* <li>absolute path to file</li>* <li>./file.ext or ../file.ext</li>* <li>relpath/to/file.ext if relpath is a subdirectory of the base parse* directory</li>* </ul>* For examples, see {@link Setup.inc.php} includes.* Every include auto-links to the documentation for the file that is included* @return string included file with link to docs for file, if found* @param string file included by include statement.* @param string path of file that has the include statement*/function getIncludeValue($value, $ipath){preg_match('/"([^"\']*\.[^"\']*)"/',$value,$match);if (!isset($match[1]))preg_match('/\'([^"\']*\.[^"\']*)\'/',$value,$match);if (isset($match[1])){$fancy_per = $this->proceduralpages->pathMatchesParsedFile($match[1],$ipath);if ($fancy_per){$link = $this->addLink($fancy_per);if (is_object($link) && phpDocumentor_get_class($link) == 'pagelink' &&isset($this->all_packages[$link->package])){$value = $this->returnSee($link,$value);}} else{$per = Converter::getLink($match[1]);if (is_object($per) && phpDocumentor_get_class($per) == 'pagelink')$value = $this->returnSee($per);}}return $value;}/*** Recursively creates all subdirectories that don't exist in the $dir path* @param string $dir*/function createParentDir($dir){if (empty($dir)) return;$tmp = explode(SMART_PATH_DELIMITER,$dir);array_pop($tmp);$parent = implode(SMART_PATH_DELIMITER,$tmp);if ($parent != '' && !file_exists($parent)){$test = @mkdir($parent,0775);if (!$test){$this->createParentDir($parent);$test = @mkdir($parent,0775);phpDocumentor_out("Creating Parent Directory $parent\n");} else{phpDocumentor_out("Creating Parent Directory $parent\n");}}}/*** Sets the output directory for generated documentation** As of 1.3.0RC6, this also sets the compiled templates directory inside* the target directory* @param string $dir the output directory*/function setTargetDir($dir){if (strlen($dir) > 0){$this->targetDir = $dir;// if directory does exist create it, this should have more error checking in the futureif (!file_exists($dir)){$tmp = str_replace(array("/","\\"),SMART_PATH_DELIMITER,$dir);if (substr($tmp,-1) == SMART_PATH_DELIMITER){$tmp = substr($tmp,0,(strlen($tmp)-1));}$this->createParentDir($tmp);phpDocumentor_out("Creating Directory $dir\n");mkdir($dir,0775);} elseif (!is_dir($dir)){echo "Output path: '$dir' is not a directory\n";die();}} else {echo "a target directory must be specified\n try phpdoc -h\n";die();}}/*** Writes a file to target dir* @param string* @param string* @param boolean true if the data is binary and not text*/function writeFile($file,$data,$binary = false){if (!file_exists($this->targetDir)){mkdir($this->targetDir,0775);}$string = '';if ($binary) $string = 'binary file ';phpDocumentor_out(" Writing $string".$this->targetDir . PATH_DELIMITER . $file . "\n");flush();$write = 'w';if ($binary) $write = 'wb';$fp = fopen($this->targetDir . PATH_DELIMITER . $file,$write);set_file_buffer( $fp, 0 );fwrite($fp,$data,strlen($data));fclose($fp);}/*** Copies a file from the template directory to the target directory* thanks to Robert Hoffmann for this fix* @param string*/function copyFile($file, $subdir = ''){if (!file_exists($this->targetDir)){mkdir($this->targetDir,0775);}copy($this->templateDir . $subdir . PATH_DELIMITER . $file, $this->targetDir . PATH_DELIMITER . $file);}/*** Return parserStringWithInlineTags::Convert() cache state* @see parserStringWithInlineTags::Convert()* @abstract*/function getState(){return true;}/*** Compare parserStringWithInlineTags::Convert() cache state to $state* @param mixed* @see parserStringWithInlineTags::Convert()* @abstract*/function checkState($state){return true;}}/*** @access private* @see Converter::getSortedClassTreeFromClass()*/function rootcmp($a, $b){return strnatcasecmp($a['class'],$b['class']);}/*** @access private* @global string used to make the first tutorials converted the default package tutorials*/function tutorialcmp($a, $b){global $phpDocumentor_DefaultPackageName;if ($a == $phpDocumentor_DefaultPackageName) return -1;if ($b == $phpDocumentor_DefaultPackageName) return 1;return strnatcasecmp($a, $b);}/*** smart htmlentities, doesn't entity the allowed tags list* Since version 1.1, this function uses htmlspecialchars instead of* htmlentities, for international support* This function has been replaced by functionality in {@link ParserDescCleanup.inc}* @param string $s* @return string browser-displayable page* @deprecated As of v1.2, No longer needed, as valid tags are parsed out of the source,* and everything else is {@link Converter::postProcess()} handled*/function adv_htmlentities($s){return;global $phpDocumentor___html,$_phpDocumentor_html_allowed;$result = htmlspecialchars($s);$entities = array_flip(get_html_translation_table(HTML_SPECIALCHARS));$result = strtr($result,$phpDocumentor___html);$matches = array();preg_match_all('/(<img.*>)/U',$result,$matches);for($i=0;$i<count($matches[1]);$i++){$result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);}preg_match_all('/(<font.*>)/U',$result,$matches);for($i=0;$i<count($matches[1]);$i++){$result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);}preg_match_all('/(<ol.*>)/U',$result,$matches);for($i=0;$i<count($matches[1]);$i++){$result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);}preg_match_all('/(<ul.*>)/U',$result,$matches);for($i=0;$i<count($matches[1]);$i++){$result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);}preg_match_all('/(<li.*>)/U',$result,$matches);for($i=0;$i<count($matches[1]);$i++){$result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);}preg_match_all('/(<a .*>)/U',$result,$matches);for($i=0;$i<count($matches[1]);$i++){$result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);}return $result;}/*** Used solely for setting up the @uses list* @package ignore* @ignore*/class __dummyConverter extends Converter{function setTemplateDir(){}function setTargetDir(){}function getPageName(&$element){if (phpDocumentor_get_class($element) == 'parserpage') return '_'.$element->getName();return '_'.$element->parent->getName();}}?>