home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / PhpDocumentor / phpDocumentor / ParserElements.inc < prev    next >
Encoding:
Text File  |  2008-07-02  |  71.7 KB  |  2,288 lines

  1. <?php
  2. /**
  3.  * Parser Elements, all classes representing documentable elements
  4.  * 
  5.  * phpDocumentor :: automatic documentation generator
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * Copyright (c) 2002-2006 Gregory Beaver
  10.  * 
  11.  * LICENSE:
  12.  * 
  13.  * This library is free software; you can redistribute it
  14.  * and/or modify it under the terms of the GNU Lesser General
  15.  * Public License as published by the Free Software Foundation;
  16.  * either version 2.1 of the License, or (at your option) any
  17.  * later version.
  18.  * 
  19.  * This library is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22.  * Lesser General Public License for more details.
  23.  * 
  24.  * You should have received a copy of the GNU Lesser General Public
  25.  * License along with this library; if not, write to the Free Software
  26.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27.  *
  28.  * @package    phpDocumentor
  29.  * @subpackage ParserElements
  30.  * @author     Gregory Beaver <cellog@php.net>
  31.  * @copyright  2002-2006 Gregory Beaver
  32.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  33.  * @version    CVS: $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  34.  * @link       http://www.phpdoc.org
  35.  * @link       http://pear.php.net/PhpDocumentor
  36.  * @see        Parser, WordParser
  37.  * @since      1.1
  38.  */
  39.  
  40. /**
  41.  * all elements except {@link parserPackagePage} descend from this abstract class
  42.  * @abstract
  43.  * @package phpDocumentor
  44.  * @subpackage ParserElements
  45.  * @author Greg Beaver <cellog@php.net>
  46.  * @since 1.0rc1
  47.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  48.  */
  49. class parserElement extends parserBase
  50. {
  51.     /**
  52.      * @var mixed either false or a {@link parserDocBlock}
  53.      */
  54.     var $docblock = false;
  55.     /**
  56.      * name of this element, or include type if element is a {@link parserInclude}
  57.      */
  58.     var $name;
  59.     
  60.     /**
  61.      * @var mixed either false or an array of paths to files with conflicts
  62.      */
  63.     var $conflicts = false;
  64.     
  65.     /**
  66.      * location of this element (filename)
  67.      * @var string
  68.      */
  69.     var $file = '';
  70.     
  71.     /**
  72.      * full path location of this element (filename)
  73.      * @var string
  74.      */
  75.     var $path = '';
  76.     
  77.     /**
  78.      * line number on file where this element stops
  79.      * @since 1.2
  80.      * @var false|integer
  81.      */
  82.     var $endlinenumber = 0;
  83.     
  84.     /**
  85.      * Line number in the source on which this element appears
  86.      * @since 1.2
  87.      * @var false|integer
  88.      */
  89.     var $linenumber = false;
  90.     
  91.     /**
  92.      * @param parserDocBlock
  93.      */
  94.     function setDocBlock($docblock)
  95.     {
  96.         $this->docblock = $docblock;
  97.     }
  98.     
  99.     /**
  100.      * @param string
  101.      */
  102.     function setName($name)
  103.     {
  104.         $this->name = trim($name);
  105.     }
  106.     
  107.     /**
  108.      * Set starting line number
  109.      * @param integer
  110.      */
  111.     function setLineNumber($number)
  112.     {
  113.         $this->linenumber = $number;
  114.     }
  115.     
  116.     /**
  117.      * Sets the ending line number of elements
  118.      * @param integer
  119.      */
  120.     function setEndLineNumber($l)
  121.     {
  122.         $this->endlinenumber = $l;
  123.     }
  124.     
  125.     /**
  126.      * @return integer
  127.      */
  128.     function getLineNumber()
  129.     {
  130.         return $this->linenumber;
  131.     }
  132.     
  133.     /**
  134.      * @return integer
  135.      */
  136.     function getEndLineNumber()
  137.     {
  138.         return $this->endlinenumber;
  139.     }
  140.     
  141.     /** @return string package containing this element */
  142.     function getPackage()
  143.     {
  144.         if ($this->docblock)
  145.         {
  146.             return $this->docblock->package;
  147.         } else return $GLOBALS['phpDocumentor_DefaultPackageName'];
  148.     }
  149.     
  150.     /** @param string */
  151.     function setFile($file)
  152.     {
  153.         $this->file = $file;
  154.     }
  155.     
  156.     /** @param string */
  157.     function setPath($file)
  158.     {
  159.         // look for special windows case
  160.         if(SMART_PATH_DELIMITER === '\\')
  161.             $this->path = strtr($file,'/','\\');
  162.         else
  163.             $this->path = $file;
  164.     }
  165.     
  166.     /**
  167.      * @return string
  168.      */
  169.     function getName()
  170.     {
  171.         if (!isset($this->name)) return false;
  172.         return $this->name;
  173.     }
  174.     
  175.     /**
  176.      * @return string
  177.      */
  178.     function getFile()
  179.     {
  180.         if (!isset($this->file)) return false;
  181.         return $this->file;
  182.     }
  183.     
  184.     /**
  185.      * @return string
  186.      */
  187.     function getPath()
  188.     {
  189.         if (!isset($this->path)) return false;
  190.         return $this->path;
  191.     }
  192. }
  193.  
  194. /**
  195.  * @package phpDocumentor
  196.  * @subpackage ParserElements
  197.  * @author Greg Beaver <cellog@php.net>
  198.  * @since 1.0rc1
  199.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  200.  */
  201. class parserInclude extends parserElement
  202. {
  203.     /**
  204.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  205.      * @var string always 'include'
  206.      */
  207.     var $type = 'include';
  208. }
  209.  
  210. /**
  211.  * @package phpDocumentor
  212.  * @subpackage ParserElements
  213.  * @author Greg Beaver <cellog@php.net>
  214.  * @since 1.1
  215.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  216.  */
  217. class parserGlobal extends parserElement
  218. {
  219.     /**
  220.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  221.      * @var string always 'global'
  222.      */
  223.     var $type = 'global';
  224.     
  225.     /**
  226.      * Name of the global's data type
  227.      * @var string
  228.      */
  229.     var $datatype = 'mixed';
  230.  
  231.     /**
  232.      * quick way to link to this element
  233.      * @return mixed converter-specific link to this global variable
  234.      * @param Converter
  235.      * @param string text to display for the link or false for default text
  236.      */
  237.     function getLink(&$c, $text = false, $returnobj = false)
  238.     {
  239.         if ($returnobj)
  240.         {
  241.             return $c->getLink('global ' . $this->name, $this->docblock->package);
  242.         }
  243.         return $c->getGlobalLink($this->name, $this->docblock->package, $this->path, $text);
  244.     }
  245.  
  246.     /**
  247.      * Returns all global variables in other packages that have the same name as this global variable
  248.      * @return mixed false or an array Format: (package => {@link parserGlobal} of conflicting global variable)
  249.      * @param Converter
  250.      */
  251.     function getConflicts(&$c)
  252.     {
  253.         $a = $c->proceduralpages->getGlobalConflicts($this->name);
  254.         unset($a[$this->docblock->package]);
  255.         return $a;
  256.     }
  257.     
  258.     /**
  259.      * Sets the name of the global variable's type
  260.      * @param string
  261.      */
  262.     function setDataType($type)
  263.     {
  264.         $this->datatype = $type;
  265.     }
  266.     
  267.     /**
  268.      * Retrieve converter-specific representation of the data type
  269.      *
  270.      * If the data type is a documented class name, then this function will
  271.      * return a Converter-specific link to that class's documentation, so users
  272.      * can click/browse to the documentation directly from the global variable
  273.      * declaration
  274.      * @return string
  275.      * @param Converter
  276.      */
  277.     function getDataType(&$converter)
  278.     {
  279.         $converted_datatype = $this->datatype;
  280.         if (strpos($this->datatype,'|'))
  281.         {
  282.             $my_types = '';
  283.             $types = explode('|',$this->datatype);
  284.             foreach($types as $returntype)
  285.             {
  286.                 $a = $converter->getLink($returntype);
  287.                 if (is_object($a) && phpDocumentor_get_class($a) == 'classlink')
  288.                 {
  289.                     if (!empty($my_types)) $my_types .= '|';
  290.                     $my_types .= $converter->returnSee($a,$converter->type_adjust($returntype));
  291.                 } else
  292.                 {
  293.                     if (!empty($my_types)) $my_types .= '|';
  294.                     $my_types .= $converter->type_adjust($returntype);
  295.                 }
  296.             }
  297.             $converted_datatype = $my_types;
  298.         } else
  299.         {
  300.             $a = $converter->getLink($this->datatype);
  301.             if (is_object($a) && phpDocumentor_get_class($a) == 'classlink')
  302.             {
  303.                 $converted_datatype = $converter->returnSee($a,$converter->type_adjust($this->datatype));
  304.             } else
  305.             {
  306.                 $converted_dataype = $converter->type_adjust($this->datatype);
  307.             }
  308.         }
  309.         return $converted_datatype;
  310.     }
  311.  
  312. }
  313.  
  314. /**
  315.  * @package phpDocumentor
  316.  * @subpackage ParserElements
  317.  * @author Greg Beaver <cellog@php.net>
  318.  * @since 1.0rc1
  319.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  320.  */
  321. class parserFunction extends parserElement
  322. {
  323.     /**
  324.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  325.      * @var string always 'function'
  326.      */
  327.     var $type = 'function';
  328.     /**
  329.      * parameters parsed from function definition.
  330.      *
  331.      * param name may be null, in which case, updateParams() must be called from the Converter
  332.      * @var array Format: array(param name => default value parsed from function definition)
  333.      * @see updateParams()
  334.      */
  335.     var $params = false;
  336.     /**
  337.      * Function returns a reference to an element, instead of a value
  338.      *
  339.      * set to true if function is declared as:
  340.      * <code>
  341.      * function &func(...
  342.      * </code>
  343.      * @var boolean
  344.      */
  345.     var $returnsreference = false;
  346.     /**
  347.      * global declarations parsed from function definition
  348.      *
  349.      * @var array Format: array(globalname1, globalname2,....)
  350.      */
  351.     var $globals = false;
  352.     /**
  353.      * static variable declarations parsed from function definition
  354.      * @var array Format: array(array('name' => staticvar1,'val' => '' or default val of staticvar1),...)
  355.      */
  356.     var $statics = false;
  357.     
  358.     var $source = '';
  359.     
  360.     /**
  361.      * @param string
  362.      * @param string default value parsed from function definition
  363.      * @param boolean indicates whether this parameter has a default value
  364.      * @param null|string class type hint
  365.      */
  366.     function addParam($name, $value, $has_default = true, $typehint = null)
  367.     {
  368.         $this->params[$name] = array($value, $has_default);
  369.         if (isset($typehint))
  370.         {
  371.             $this->params[$name][2] = $typehint;
  372.         }
  373.     }
  374.     
  375.     /**
  376.      * Set the source code.  Always array in PHP 4.3.0+
  377.      * @param string|array
  378.      */
  379.     function addSource($source)
  380.     {
  381.         $this->source = $source;
  382.     }
  383.     
  384.     /**
  385.      * Determine whether the source code has been requested via {@}source}
  386.      * @return boolean
  387.      */
  388.     function hasSource()
  389.     {
  390.         if (is_array($this->source)) return true;
  391.         return strlen($this->source);
  392.     }
  393.     
  394.     /**
  395.      * @return string|array source code ready for highlighting
  396.      */
  397.     function getSource()
  398.     {
  399.         return $this->source;
  400.     }
  401.     
  402.     /**
  403.      * quick way to link to this element
  404.      * @return mixed converter-specific link to this function
  405.      * @param Converter
  406.      * @param string text to display for the link or false for default text
  407.      */
  408.     function getLink($c, $text = false, $returnobj = false)
  409.     {
  410.         if ($returnobj)
  411.         {
  412.             return $c->getLink('function ' . $this->name, $this->docblock->package);
  413.         }
  414.         return $c->getFunctionLink($this->name, $this->docblock->package, $this->path, $text);
  415.     }
  416.  
  417.     /**
  418.      * Returns all functions in other packages that have the same name as this function
  419.      * @return mixed false or an array Format: (package => {@link parserFunction} of conflicting functions)
  420.      * @param Converter
  421.      */
  422.     function getConflicts(&$c)
  423.     {
  424.         $a = $c->proceduralpages->getFuncConflicts($this->name);
  425.         unset($a[$this->docblock->package]);
  426.         return $a;
  427.     }
  428.     
  429.     /**
  430.      * Add all "global $var, $var2" declarations to this function
  431.      * @param array $globals Format: array(globalname1, globalname2,....)
  432.      */
  433.     function addGlobals($globals)
  434.     {
  435.         $this->globals = $globals;
  436.     }
  437.  
  438.     /**
  439.      * Add all "static $var, $var2 = 6" declarations to this function
  440.      * @param array Format: array(varname1, varname2,...)
  441.      * @param array Format: array(default val of var 1, default val of var 2,...) if var 1 has no default, array(default val of var 2,...)
  442.      */
  443.     function addStatics($static,$vals)
  444.     {
  445.         if (count($static))
  446.         {
  447.             $this->statics = array();
  448.             for($i=0;$i<count($static);$i++)
  449.             {
  450.                 if (isset($static[$i]))
  451.                 {
  452.                     $a = '';
  453.                     if (isset($vals[$i])) $a = $vals[$i];
  454.                     $this->statics[] = array('name' => $static[$i],'val' => $a);
  455.                 }
  456.             }
  457.         }
  458.     }
  459.  
  460.     /**
  461.      * @return string default value of param $name
  462.      * @param string
  463.      */
  464.     function getParam ($name)
  465.     {
  466.         if (!isset($this->params[$name])) return false;
  467.         $test = $this->params[$name];
  468.         if ($test[1])
  469.         {
  470.             return $this->params[$name];
  471.         } else
  472.         {
  473.             return false;
  474.         }
  475.     }
  476.  
  477.     /**
  478.      * @return array format: array(array(paramname, default value),...)
  479.      */
  480.     function listParams ()
  481.     {
  482.         if (isset($this->params))
  483.         {
  484.             $ret = array();
  485.             if ($this->params)
  486.             foreach($this->params as $key => $val)
  487.             {
  488.                 if ($val[1])
  489.                 {
  490.                     $arr = array($key,$val[0]);
  491.                     if (isset($val[2]))
  492.                     {
  493.                         $arr[2] = $val[2];
  494.                     }
  495.                     $ret[$key] = $arr;
  496.                 } else
  497.                 {
  498.                     $arr = array($key,false);
  499.                     if (isset($val[2]))
  500.                     {
  501.                         $arr[2] = $val[2];
  502.                     }
  503.                     $ret[$key] = $arr;
  504.                 }
  505.             }
  506.             return $ret;
  507.         } else {
  508.             return array();
  509.         }
  510.     }
  511.     
  512.     /**
  513.      * @return array format: array(array(index, globalname),...)
  514.      */
  515.     function listGlobals ()
  516.     {
  517.         if (isset($this->globals))
  518.         {
  519.             $ret = array();
  520.             if ($this->globals)
  521.             foreach($this->globals as $key => $val)
  522.             {
  523.                 $ret[] = array($key,$val);
  524.             }
  525.             return $ret;
  526.         } else {
  527.             return array();
  528.         }
  529.     }
  530.     
  531.     /**
  532.      * @return array format: array(array(static var name, static var default value),...)
  533.      */
  534.     function listStatics ()
  535.     {
  536.         if (isset($this->statics))
  537.         {
  538.             $ret = array();
  539.             if ($this->statics)
  540.             foreach($this->statics as $key => $val)
  541.             {
  542.                 $ret[] = array($val['name'],$val['val']);
  543.             }
  544.             return $ret;
  545.         } else {
  546.             return array();
  547.         }
  548.     }
  549.     
  550.     /**
  551.      * sets {@link $returnsreference} to true
  552.      */
  553.     function setReturnsReference()
  554.     {
  555.         $this->returnsreference = true;
  556.     }
  557.     
  558.     /**
  559.      * @return boolean returns value of {@link $returnsreference}
  560.      */
  561.     function getReturnsReference()
  562.     {
  563.         return $this->returnsreference;
  564.     }
  565.     
  566.     /**
  567.      * Get a human-friendly description of the function call
  568.      *
  569.      * takes declaration like:
  570.      * <code>
  571.      * /** @returns string ... {rest of docblock}
  572.      * function &func($param1, $param2 = 6,
  573.      *                $param3 = array('20',9 => "heroo"))
  574.      * {...}
  575.      * </code>
  576.      * and returns:
  577.      * string &func( $param1, [$param2 = 6], [$param3 = array('20',9 => "heroo")] )
  578.      * @return string stylized function declaration
  579.      */
  580.     function getFunctionCall()
  581.     {
  582.         $a = '';
  583.         if ($this->getReturnsReference()) $a = '&';
  584.         $function_call = $a.$this->getName() . " ( ";
  585.         $tmp = 0;
  586.         foreach($this->listParams() as $param)
  587.         {
  588.             if ($tmp == 0)
  589.             {
  590.                 $tmp = 1;
  591.             } else {
  592.                 $function_call .= ", ";
  593.             }
  594.             if ($param[1] !== false)
  595.             {
  596.                 $function_call .= "[$param[0] = $param[1]]";
  597.             } else {
  598.                 $function_call .= $param[0];
  599.             }
  600.             $update_params[] = $param[0];
  601.         }
  602.         $function_call .= " )";
  603.         return $function_call;
  604.     }
  605.     
  606.     /**
  607.      * Like getFunctionCall(), but has no English or pre-determined formatting.
  608.      *
  609.      * Much more flexible.
  610.      * @return array Format:
  611.      * <code>
  612.      * array('name' => function name,
  613.      *       'returnsref' => boolean if declared as "function &name()"
  614.      *       'params' => array('type' => data type of parameter,
  615.      *                         'description' => from @param tag,
  616.      *                         'name' => variable name,
  617.      *                         'default' => default value if any))
  618.      * </code>
  619.      * @see getFunctionCall()
  620.      */
  621.     function getIntricateFunctionCall($converter,$paramtags)
  622.     {
  623.         $a = array();
  624.         if ($this->getReturnsReference()) $a['returnsref'] = true;
  625.         $a['name'] = $converter->type_adjust($this->getName());
  626.         $c = $this->listParams();
  627.         foreach($c as $param)
  628.         {
  629.             $b = array();
  630.             $b['type'] = 'mixed';
  631.             if (isset($paramtags[$param[0]]))
  632.             {
  633.                 $b['type'] = $paramtags[$param[0]]['datatype'];
  634.                 $b['description'] = $paramtags[$param[0]]['data'];
  635.                 unset($paramtags[$param[0]]);
  636.             } elseif(isset($paramtags[substr($param[0],1)]))
  637.             {
  638.                 $b['type'] = $paramtags[substr($param[0],1)]['datatype'];
  639.                 $b['description'] = $paramtags[substr($param[0],1)]['data'];
  640.                 unset($paramtags[substr($param[0],1)]);
  641.             }
  642.             if (isset($param[2]))
  643.             {
  644.                 $link = $converter->getLink('object ' . $param[2]);
  645.                 if ($link) {
  646.                     $link = $converter->returnSee($link, $param[2], true);
  647.                     $b['type'] = $link;
  648.                 } else {
  649.                     $b['type'] = $param[2];
  650.                 }
  651.             }
  652.             $b['name'] = $param[0];
  653.             $b['default'] = $converter->postProcess($param[1]);
  654.             $b['hasdefault'] = ($param[1] !== false);
  655.             $a['params'][] = $b;
  656.         }
  657.         // @param tags that don't correspond to actual parameters (like extra function values)
  658.         if (count($paramtags))
  659.         {
  660.             foreach($paramtags as $param)
  661.             {
  662.                 $b = array();
  663.                 $b['type'] = $param['datatype'];
  664.                 $b['description'] = $param['data'];
  665.                 $b['name'] = $param['var'];
  666.                 $b['default'] = '';
  667.                 $b['hasdefault'] = false;
  668.                 $a['params'][] = $b;
  669.             }
  670.         }
  671.         return $a;
  672.     }
  673. }
  674.  
  675. /**
  676.  * @package phpDocumentor
  677.  * @subpackage ParserElements
  678.  * @author Greg Beaver <cellog@php.net>
  679.  * @since 1.0rc1
  680.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  681.  */
  682. class parserClass extends parserElement
  683. {
  684.     /**
  685.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  686.      * @var string always 'class'
  687.      */
  688.     var $type = 'class';
  689.     /** @var string
  690.      * @see parserPage::$sourceLocation */
  691.     var $sourceLocation = '';
  692.     /**
  693.      * @var mixed false or contents of extends clause in class declaration
  694.      */
  695.     var $extends = false;
  696.     /**
  697.      * @var array a list of interfaces this class implements
  698.      */
  699.     var $_implements = array();
  700.     /**
  701.      * @var array a list of interfaces this class implements
  702.      * @access private
  703.      */
  704.     var $_modifiers = false;
  705.     /**
  706.      * @var boolean determines whether a class is considered to be an interface
  707.      * @access private
  708.      */
  709.     var $_isInterface = false;
  710.     /**
  711.      * Format: array(file, parent) where parent class is found or false if no parent
  712.      * @var mixed
  713.      */
  714.     var $parent = false;
  715.     /**
  716.      * Used to determine whether a class should be ignored or not.  Helps maintain integrity of parsing
  717.      * @var boolean
  718.      * @see Classes::getParentClass()
  719.      */
  720.     var $ignore = false;
  721.  
  722.     /**
  723.      * @var string same as {@link parserElement::$path}
  724.      */
  725.     var $curfile = false;
  726.     /**
  727.      * @var tutorialLink|false either a link to the tutorial associated with this class, or false
  728.      */
  729.     var $tutorial = false;
  730.     
  731.     /**
  732.      * Get the PHP5+ modifiers for this class
  733.      * (abstract/final/static/private/protected/public)
  734.      * @return array|false
  735.      */
  736.     function getModifiers()
  737.     {
  738.         return $this->_modifiers;
  739.     }
  740.  
  741.     /**
  742.      * Set the PHP5+ modifiers for this class
  743.      * (abstract/final/static/private/protected/public)
  744.      * @param string $m
  745.      */
  746.     function setModifiers($m)
  747.     {
  748.         $this->_modifiers = $m;
  749.     }
  750.     
  751.     /**
  752.      * @param parserTutorial
  753.      * @param Converter
  754.      */
  755.     function addTutorial($t,&$c)
  756.     {
  757.         $this->tutorial = new tutorialLink;
  758.         $this->tutorial->addLink('',$t->path,$t->name,$t->package,$t->subpackage,$t->getTitle($c));
  759.     }
  760.     
  761.     /**
  762.      * Get the associated tutorial for this class, if any
  763.      * @tutorial tutorials.pkg
  764.      * @return parserTutorial
  765.      */
  766.     function getTutorial()
  767.     {
  768.         return $this->tutorial;
  769.     }
  770.     
  771.     /**
  772.      * Returns all classes in other packages that have the same name as this class
  773.      * @return mixed false or an array Format: (package => {@link parserClass} of conflicting classes)
  774.      * @param Converter
  775.      */
  776.     function getConflicts(&$c)
  777.     {
  778.         $a = $c->classes->getConflicts($this->name);
  779.         unset($a[$this->docblock->package]);
  780.         return $a;
  781.     }
  782.     
  783.     /**
  784.      * quick way to link to this element
  785.      * @return mixed converter-specific link to this class
  786.      * @param Converter
  787.      * @param string text to display for the link or false for default text
  788.      */
  789.     function getLink($c, $text = false, $returnobj = false)
  790.     {
  791.         if ($returnobj)
  792.         {
  793.             return $c->getLink('object ' . $this->name, $this->docblock->package);
  794.         }
  795.         return $c->getClassLink($this->name, $this->docblock->package, $this->curfile, $text);
  796.     }
  797.  
  798.     /**
  799.      * @param string parent class name
  800.      * @param string parent class file
  801.      * @param Classes {@link Classes} object currently calling setParent
  802.      * @see Classes::setClassParent()
  803.      */
  804.     
  805.     function setParent($p,$f, &$c)
  806.     {
  807.         $this->parent = array($f, $p);
  808.         $p = $c->getClass($p, $f);
  809.         // inherit package if no @package tag is in the docblock, fixes 591396
  810.         if (!$this->docblock->getExplicitPackage())
  811.         {
  812.             $this->docblock->package = $p->docblock->package;
  813.         }
  814.         if ($this->docblock->package == $p->docblock->package)
  815.         {
  816.             if ($this->docblock->subpackage == '')
  817.             $this->docblock->subpackage = $p->docblock->subpackage;
  818.         }
  819.         $author = $p->docblock->getKeyword('author');
  820.         $version = $p->docblock->getKeyword('version');
  821.         $copyright = $p->docblock->getKeyword('copyright');
  822.         // inherit tags
  823.         if (!$this->docblock->getKeyword('author'))
  824.         {
  825.             if ($author && !is_array($author)) $author = array($author);
  826.             if ($author) $this->docblock->tags['author'] = $author;
  827.         }
  828.         if (!$this->docblock->getKeyword('version'))
  829.         {
  830.             if ($version && !is_array($version)) $version = array($version);
  831.             if ($version) $this->docblock->tags['version'] = $version;
  832.         }
  833.         if (!$this->docblock->getKeyword('copyright'))
  834.         {
  835.             if ($copyright && !is_array($copyright)) $copyright = array($copyright);
  836.             if ($copyright) $this->docblock->tags['copyright'] = $copyright;
  837.         }
  838.         if (!$this->docblock->sdesc)
  839.         {
  840.             $this->docblock->setShortDesc($p->docblock);
  841.             $this->docblock->setDesc($p->docblock);
  842.         } else
  843.         {
  844.             if ($this->docblock->hasInheritDoc())
  845.             {
  846.                 $this->docblock->replaceInheritDoc($p->docblock);
  847.             }
  848.         }
  849.     }
  850.     
  851.     /**
  852.      * @param string $par parent class name (used by {@link Classes::setClassParent()} if parent class not found
  853.      */
  854.     function setParentNoClass($par)
  855.     {
  856.         $this->parent = $par;
  857.     }
  858.     
  859.     /**
  860.      * Use this method to set the type of class to be an interface
  861.      */
  862.     function setInterface()
  863.     {
  864.         $this->_isInterface = true;
  865.     }
  866.     
  867.     /**
  868.      * @return boolean true if this is an interface class
  869.      */
  870.     function isInterface()
  871.     {
  872.         return $this->_isInterface;
  873.     }
  874.     
  875.     /**
  876.      * Use this method to set access modifiers for a class
  877.      * @param array 
  878.      */
  879.     function setAccessModifiers($modifiers)
  880.     {
  881.         $this->_modifiers = $modifiers;
  882.     }
  883.     
  884.     /**
  885.      * retrieve object that represents the parent class
  886.      * @param Converter this function will not work before the Conversion stage of parsing
  887.      * @return mixed returns the {@link parserClass} representation of the parent class, or false if no parent class
  888.      */
  889.     function &getParent(&$c)
  890.     {
  891.         $a = false;
  892.         if (!$this->parent) return $a;
  893.         if (is_array($this->parent))
  894.         {
  895.             return $c->classes->getClass($this->parent[1],$this->parent[0]);
  896.         } else return $this->parent;
  897.     }
  898.     
  899.     /**
  900.      * @param Converter this function will not work before the Conversion stage of parsing
  901.      * @return array returns a simple array of method objects
  902.      */
  903.     function getMethods(&$c)
  904.     {
  905.         return $c->classes->getMethods($this->name,$this->curfile);
  906.     }
  907.     
  908.     /**
  909.      * @return mixed {@link parserMethod} or false if not found
  910.      * @param Converter this function will not work before the Conversion stage of parsing
  911.      * @param string method name in this class
  912.      * @param boolean determines whether to search inherited methods as well
  913.      */
  914.     function getMethod(&$c, $name, $inherited = false)
  915.     {
  916.         $ret = $c->classes->getMethod($this->name, $this->curfile, $name);
  917.         if ($ret) return $ret;
  918.         if ($inherited) {
  919.             $x = $this;
  920.             while ($x->parent && is_array($x->parent)) {
  921.                 $par = $x->getParent($c);
  922.                 $x = $par;
  923.                 if ($meth = $x->getMethod($c, $name)) return $meth;
  924.             }
  925.         }
  926.         return false;
  927.     }
  928.     
  929.     /**
  930.      * @return mixed {@link parserVar} or false if not found
  931.      * @param Converter this function will not work before the Conversion stage of parsing
  932.      * @param string var name in this class
  933.      */
  934.     function getVar(&$c, $name)
  935.     {
  936.         return $c->classes->getVar($this->name,$this->curfile,$name);
  937.     }
  938.     
  939.     /**
  940.      * @param Converter this function will not work before the Conversion stage of parsing
  941.      * @return array returns a simple array of method name strings
  942.      */
  943.     function getMethodNames(&$c)
  944.     {
  945.         if (!$c->classes->hasMethods($this->curfile, $this->name)) return array();
  946.         $arr = array();
  947.         $arr1 = $this->getMethods($c);
  948.         for($i=0; $i < count($arr1); $i++)
  949.         {
  950.             $arr[] = $arr1[$i]->name;
  951.         }
  952.         return $arr;
  953.     }
  954.     
  955.     /**
  956.      * @param Converter this function will not work before the Conversion stage of parsing
  957.      * @param string method name
  958.      * @param boolean determines whether to search inherited methods as well
  959.      * @return boolean whether this class has a method of name $name
  960.      */
  961.     function hasMethod(&$c, $name, $inherited = false)
  962.     {
  963.         $ret = $c->classes->hasMethod($this->name, $this->curfile, $name);
  964.         if ($ret) return $ret;
  965.         if ($inherited) {
  966.             $x = $this;
  967.             while ($x->parent && is_array($x->parent)) {
  968.                 $par = $x->getParent($c);
  969.                 $x = $par;
  970.                 if ($x->hasMethod($c, $name)) return true;
  971.             }
  972.         }
  973.         return false;
  974.     }
  975.     
  976.     /**
  977.      * @param Converter this function will not work before the Conversion stage of parsing
  978.      * @param string var name
  979.      * @return boolean whether this class has a var of name $name
  980.      */
  981.     function hasVar(&$c,$name)
  982.     {
  983.         return $c->classes->hasVar($this->name, $this->curfile, $name);
  984.     }
  985.     
  986.     /**
  987.      * @param Converter this function will not work before the Conversion stage of parsing
  988.      * @param string class constant name
  989.      * @return boolean whether this class has a constant of name $name
  990.      */
  991.     function hasConst(&$c,$name)
  992.     {
  993.         return $c->classes->hasConst($this->name, $this->curfile, $name);
  994.     }
  995.     
  996.     /**
  997.      * @param Converter this function will not work before the Conversion stage of parsing
  998.      * @return array returns a simple array of var objects
  999.      */
  1000.     function getVars(&$c)
  1001.     {
  1002.         return $c->classes->getVars($this->name,$this->curfile);
  1003.     }
  1004.     
  1005.     /**
  1006.      * @param Converter this function will not work before the Conversion stage of parsing
  1007.      * @return array returns a simple array of const objects
  1008.      */
  1009.     function getConsts(&$c)
  1010.     {
  1011.         return $c->classes->getConsts($this->name,$this->curfile);
  1012.     }
  1013.     
  1014.     /**
  1015.      * @param Converter this function will not work before the Conversion stage of parsing
  1016.      * @return array returns a simple array of var name strings
  1017.      */
  1018.     function getVarNames(&$c)
  1019.     {
  1020.         if (!$c->classes->hasVars($this->curfile, $this->name)) return array();
  1021.         $arr = array();
  1022.         $arr1 = $this->getVars($c);
  1023.         for($i=0; $i < count($arr1); $i++)
  1024.         {
  1025.             $arr[] = $arr1[$i]->name;
  1026.         }
  1027.         return $arr;
  1028.     }
  1029.     
  1030.     /**
  1031.      * @param Converter this function will not work before the Conversion stage of parsing
  1032.      * @return array returns a simple array of const name strings
  1033.      */
  1034.     function getConstNames(&$c)
  1035.     {
  1036.         if (!$c->classes->hasConsts($this->curfile, $this->name)) return array();
  1037.         $arr = array();
  1038.         $arr1 = $this->getConsts($c);
  1039.         for($i=0; $i < count($arr1); $i++)
  1040.         {
  1041.             $arr[] = $arr1[$i]->name;
  1042.         }
  1043.         return $arr;
  1044.     }
  1045.     
  1046.     /**
  1047.      * @param Converter this function will not work before the Conversion stage of parsing
  1048.      * @param boolean determines whether overriden methods should be included in the list of inherited methods
  1049.      * @return array returns an array of methods by parent classname array(name => array(method1,method2..),name2 => array(method1....))
  1050.      */
  1051.     function getInheritedMethods(&$c,$override = false)
  1052.     {
  1053.         $x = $oldx = $this;
  1054.         $methods = array();
  1055.         $arr = array();
  1056.         while ($x->parent && is_array($x->parent))
  1057.         {
  1058.             $methods = array_merge($methods,$x->getMethodNames($c));
  1059.             $par = $x->getParent($c);
  1060.             $parmethodnames = $par->getMethodNames($c);
  1061.             $parmethods = $par->getMethods($c);
  1062.             for($i=0; $i<count($parmethodnames); $i++)
  1063.             {
  1064.                 if ($override)
  1065.                 {
  1066.                     if (!in_array($parmethodnames[$i],$methods))
  1067.                     {
  1068.                         // fix for bug 587733
  1069.                         if ($parmethods[$i]->docblock && $parmethods[$i]->docblock->hasaccess && !$c->parseprivate && $parmethods[$i]->docblock->tags['access'][0]->value == 'private')
  1070.                         {
  1071.                             continue;
  1072.                         }
  1073.                         $methods[] = $parmethodnames[$i];
  1074.                         $arr[$par->getName()]['methods'][] = $parmethods[$i];
  1075.                         $arr[$par->getName()]['file'] = $par->curfile;
  1076.                     }
  1077.                 } else
  1078.                 {
  1079.                     // fix for bug 587733
  1080.                     if ($parmethods[$i]->docblock && $parmethods[$i]->docblock->hasaccess && !$c->parseprivate && $parmethods[$i]->docblock->tags['access'][0]->value == 'private')
  1081.                     {
  1082.                         continue;
  1083.                     }
  1084.                     $arr[$par->getName()]['methods'][] = $parmethods[$i];
  1085.                     $arr[$par->getName()]['file'] = $par->curfile;
  1086.                 }
  1087.             }
  1088.             $oldx = $x;
  1089.             $x = &$par;
  1090.         }
  1091.         if (is_a($oldx, 'parserClass') && is_a($oldx->getExtends(true), 'ReflectionClass')) {
  1092.             $extends = $oldx->getExtends(true);
  1093.             foreach ($extends->getMethods() as $method) {
  1094.                 $var = new parserMethod($oldx->getExtends());
  1095.                 if ($method->returnsReference()) {
  1096.                     $var->setReturnsReference();
  1097.                 }
  1098.                 $doc = new parserDocBlock;
  1099.                 foreach ($method->getParameters() as $param) {
  1100.                     $value = $param->isDefaultValueAvailable() ? var_export($param->getDefaultValue(), true) : null;
  1101.                     if ($param->isPassedByReference()) {
  1102.                         $var->addParam('&$' . $param->getName(), $value, $param->isOptional(),
  1103.                             $param->getClass());
  1104.                     } else {
  1105.                         $var->addParam('$' . $param->getName(), $value, $param->isOptional(),
  1106.                             $param->getClass());
  1107.                     }
  1108.                 }
  1109.                 $var->setName($method->getName());
  1110.                 $doc->addPackage('package', $oldx->getPackage());
  1111.                 $var->setDocBlock($doc);
  1112.                 $par = $method->getDeclaringClass();
  1113.                 $var->setLineNumber($par->getStartLine());
  1114.                 $modifiers = array();
  1115.                 if ($method->isPrivate()) {
  1116.                     $modifiers[] = 'private';
  1117.                 }
  1118.                 if ($method->isAbstract()) {
  1119.                     $modifiers[] = 'abstract';
  1120.                 }
  1121.                 if ($method->isFinal()) {
  1122.                     $modifiers[] = 'final';
  1123.                 }
  1124.                 if ($method->isProtected()) {
  1125.                     $modifiers[] = 'protected';
  1126.                 }
  1127.                 if ($method->isPublic()) {
  1128.                     $modifiers[] = 'public';
  1129.                 }
  1130.                 if ($method->isStatic()) {
  1131.                     $modifiers[] = 'static';
  1132.                 }
  1133.                 if ($method->isConstructor()) {
  1134.                     $var->setConstructor();
  1135.                 }
  1136.                 $var->setModifiers($modifiers);
  1137.                 $arr[$oldx->getExtends()]['methods'][] = $var;
  1138.                 $arr[$oldx->getExtends()]['file'] = '(internal)';
  1139.             }
  1140.         }
  1141.         return $arr;
  1142.     }
  1143.     
  1144.     /**
  1145.      * @param Converter this function will not work before the Conversion stage of parsing
  1146.      * @param boolean determines whether overriden vars should be included in the list of inherited vars
  1147.      * @return array returns an array of vars by parent classname array(name => array(var1,var1..),name2 => array(var1....))
  1148.      */
  1149.     function getInheritedVars(&$c,$override = true, $vars = false)
  1150.     {
  1151.         $x = $oldx = $this;
  1152.         $vars = array();
  1153.         $arr = array();
  1154.         while ($x->parent && is_array($x->parent))
  1155.         {
  1156.             $vars = array_merge($vars,$x->getVarNames($c));
  1157.             $par = $x->getParent($c);
  1158.             $parvarnames = $par->getVarNames($c);
  1159.             $parvars = $par->getVars($c);
  1160.             for($i=0; $i<count($parvarnames); $i++)
  1161.             {
  1162.                 if ($override)
  1163.                 {
  1164.                     if (!in_array($parvarnames[$i],$vars))
  1165.                     {
  1166.                         // fix for bug 587733
  1167.                         if ($parvars[$i]->docblock && $parvars[$i]->docblock->hasaccess && !$c->parseprivate && $parvars[$i]->docblock->tags['access'][0]->value == 'private')
  1168.                         {
  1169.                             continue;
  1170.                         }
  1171.                         $vars[] = $parvarnames[$i];
  1172.                         $arr[$par->getName()]['vars'][] = $parvars[$i];
  1173.                         $arr[$par->getName()]['file'] = $par->curfile;
  1174.                     }
  1175.                 } else
  1176.                 {
  1177.                     // fix for bug 587733
  1178.                     if ($parvars[$i]->docblock && $parvars[$i]->docblock->hasaccess && !$c->parseprivate && $parvars[$i]->docblock->tags['access'][0]->value == 'private')
  1179.                     {
  1180.                         continue;
  1181.                     }
  1182.                     $arr[$par->getName()]['vars'][] = $parvars[$i];
  1183.                     $arr[$par->getName()]['file'] = $par->curfile;
  1184.                 }
  1185.             }
  1186.             $oldx = $x;
  1187.             $x = &$par;
  1188.         }
  1189.         if (is_a($oldx, 'parserClass') && is_a($oldx->getExtends(true), 'ReflectionClass')) {
  1190.             $extends = $oldx->getExtends(true);
  1191.             foreach ($extends->getProperties() as $property) {
  1192.                 $var = new parserVar($oldx->getExtends());
  1193.                 $doc = new parserDocBlock;
  1194.                 $var->setName('$' . $property->getName());
  1195.                 $doc->addPackage('package', $oldx->getPackage());
  1196.                 $par = $property->getDeclaringClass();
  1197.                 $var->setLineNumber($par->getStartLine());
  1198.                 $modifiers = array();
  1199.                 if ($property->isPrivate()) {
  1200.                     $modifiers[] = 'private';
  1201.                     $doc->addAccess('private');
  1202.                 }
  1203.                 if ($property->isProtected()) {
  1204.                     $modifiers[] = 'protected';
  1205.                     $doc->addAccess('protected');
  1206.                 }
  1207.                 if ($property->isPublic()) {
  1208.                     $modifiers[] = 'public';
  1209.                     $doc->addAccess('public');
  1210.                 }
  1211.                 $var->setDocBlock($doc);
  1212.                 $var->setModifiers($modifiers);
  1213.                 $arr[$oldx->getExtends()]['vars'][] = $var;
  1214.                 $arr[$oldx->getExtends()]['file'] = '(internal)';
  1215.             }
  1216.         }
  1217.         return $arr;
  1218.     }
  1219.     
  1220.     /**
  1221.      * @param Converter this function will not work before the Conversion stage of parsing
  1222.      * @param boolean determines whether overriden vars should be included in the list of inherited vars
  1223.      * @return array returns an array of consts by parent classname array(name => array(const1,const2..),name2 => array(const1....))
  1224.      */
  1225.     function getInheritedConsts(&$c,$override = false, $consts = false)
  1226.     {
  1227.         $x = $oldx = $this;
  1228.         $consts = array();
  1229.         $arr = array();
  1230.         while ($x->parent && is_array($x->parent))
  1231.         {
  1232.             $consts = array_merge($consts,$x->getConstNames($c));
  1233.             $par = $x->getParent($c);
  1234.             $parvarnames = $par->getConstNames($c);
  1235.             $parvars = $par->getConsts($c);
  1236.             for($i=0; $i<count($parvarnames); $i++)
  1237.             {
  1238.                 if ($override)
  1239.                 {
  1240.                     if (!in_array($parvarnames[$i],$consts))
  1241.                     {
  1242.                         // fix for bug 587733
  1243.                         if ($parvars[$i]->docblock && $parvars[$i]->docblock->hasaccess && !$c->parseprivate && $parvars[$i]->docblock->tags['access'][0]->value == 'private')
  1244.                         {
  1245.                             continue;
  1246.                         }
  1247.                         $consts[] = $parvarnames[$i];
  1248.                         $arr[$par->getName()]['consts'][] = $parvars[$i];
  1249.                         $arr[$par->getName()]['file'] = $par->curfile;
  1250.                     }
  1251.                 } else
  1252.                 {
  1253.                     // fix for bug 587733
  1254.                     if ($parvars[$i]->docblock && $parvars[$i]->docblock->hasaccess && !$c->parseprivate && $parvars[$i]->docblock->tags['access'][0]->value == 'private')
  1255.                     {
  1256.                         continue;
  1257.                     }
  1258.                     $arr[$par->getName()]['consts'][] = $parvars[$i];
  1259.                     $arr[$par->getName()]['file'] = $par->curfile;
  1260.                 }
  1261.             }
  1262.             $oldx = $x;
  1263.             $x = &$par;
  1264.         }
  1265.         if (is_a($oldx, 'parserClass') && is_a($oldx->getExtends(true), 'ReflectionClass')) {
  1266.             $extends = $oldx->getExtends(true);
  1267.             if (!$extends->getConstants()) {
  1268.                 return $arr;
  1269.             }
  1270.             foreach ($extends->getConstants() as $property => $value) {
  1271.                 $var = new parserConst($oldx->getExtends());
  1272.                 $doc = new parserDocBlock;
  1273.                 $var->setName($property);
  1274.                 $var->setValue(var_export($value, true));
  1275.                 $doc->addPackage('package', $oldx->getPackage());
  1276.                 $var->setLineNumber($extends->getStartLine());
  1277.                 $var->setDocBlock($doc);
  1278.                 $arr[$oldx->getExtends()]['consts'][] = $var;
  1279.                 $arr[$oldx->getExtends()]['file'] = '(internal)';
  1280.             }
  1281.         }
  1282.         return $arr;
  1283.     }
  1284.     
  1285.     /**
  1286.      * @param Converter this function will not work before the Conversion stage of parsing
  1287.      * @return array Format: array(parentclassname => parserClass/false if no parent, parentclassname2 => ...)
  1288.      */
  1289.     function getParentClassTree(&$c)
  1290.     {
  1291.         $result = array();
  1292.         $result[$this->name] = $arr = $this->getParent($c);
  1293.         if (is_string($arr)) $result[$arr] = false;
  1294.         while ($arr && is_object($arr))
  1295.         {
  1296.             $result[$arr->name] = $arr->getParent($c);
  1297.             $arr = $arr->getParent($c);
  1298.             if (is_string($arr)) $result[$arr] = false;
  1299.         }
  1300.         return $result;
  1301.     }
  1302.     
  1303.     /**
  1304.      * returns a list of all child classes of this class
  1305.      * @param Converter this function will not work before the Conversion stage of parsing
  1306.      * @return array Format: array(parserClass child1,parserClass child2,...)
  1307.      */
  1308.     function getChildClassList(&$c)
  1309.     {
  1310.         $list = array();
  1311.         $kids = $c->classes->getDefiniteChildren($this->name,$this->curfile);
  1312.         if ($kids)
  1313.         {
  1314.             foreach($kids as $chile => $file)
  1315.             {
  1316.                 $list[] = $c->classes->getClass($chile,$file);
  1317.             }
  1318.         }
  1319.         return $list;
  1320.     }
  1321.     
  1322.     /**
  1323.      * @param string
  1324.      * @see $sourceLocation
  1325.      */
  1326.     function setSourceLocation($sl)
  1327.     {
  1328.         $this->sourceLocation = $sl;
  1329.     }
  1330.     
  1331.     /**
  1332.      * @param Converter
  1333.      * @param boolean
  1334.      * @return string
  1335.      * @see $sourceLocation
  1336.      */
  1337.     function getSourceLocation($c,$pearize = false)
  1338.     {
  1339.         global $_phpDocumentor_options;
  1340.         if (!isset($this->sourceLocation)) 
  1341.         {
  1342.             $sl = false;   
  1343.         }
  1344.         else 
  1345.         {
  1346.             $sl = $this->sourceLocation;
  1347.             if ($pearize)
  1348.             {
  1349.                 if (strpos($sl,'pear/'))
  1350.                 {
  1351.                     $sl = substr($sl,strpos($sl,'pear/') + 5);
  1352.                 }   
  1353.             }
  1354.         }        
  1355.         return $sl;
  1356.     }
  1357.     
  1358.     /**
  1359.      * @param string
  1360.      * @see $extends
  1361.      */
  1362.     function setExtends($extends)
  1363.     {
  1364.         $this->extends = $extends;
  1365.         if (!class_exists('ReflectionClass') || !class_exists($extends)) {
  1366.             return;
  1367.         }
  1368.         // this may throw an exception.  Hopefully it won't if the class exists
  1369.         $parent = new ReflectionClass($extends);
  1370.         if (!$parent->isInternal()) {
  1371.             return;
  1372.         }
  1373.         $this->extends = $parent;
  1374.     }
  1375.     
  1376.     /**
  1377.      * @param string
  1378.      */
  1379.     function addImplements($implements)
  1380.     {
  1381.         $this->_implements[] = $implements;
  1382.     }
  1383.     
  1384.     /**
  1385.      * @return array
  1386.      */
  1387.     function getImplements()
  1388.     {
  1389.         return $this->_implements;
  1390.     }
  1391.     
  1392.     /**
  1393.      * @return boolean
  1394.      * @see $extends
  1395.      */
  1396.     function getExtends($raw = false)
  1397.     {
  1398.         if (!isset($this->extends)) return false;
  1399.         if (!$raw) {
  1400.             if (is_a($this->extends, 'ReflectionClass')) {
  1401.                 return $this->extends->getName();
  1402.             }
  1403.         }
  1404.         return $this->extends;
  1405.     }
  1406. }
  1407.  
  1408. /**
  1409.  * @package phpDocumentor
  1410.  * @subpackage ParserElements
  1411.  * @author Greg Beaver <cellog@php.net>
  1412.  * @since 1.0rc1
  1413.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  1414.  */
  1415. class parserVar extends parserElement
  1416. {
  1417.     /**
  1418.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  1419.      * @var string always 'var'
  1420.      */
  1421.     var $type = 'var';
  1422.     /** @var string class that contains this var */
  1423.     var $class = '';
  1424.     /** @var array */
  1425.     var $_modifiers;
  1426.     
  1427.     /**
  1428.      * @param string
  1429.      */
  1430.     function parserVar($class)
  1431.     {
  1432.         $this->class = $class;
  1433.     }
  1434.     
  1435.     /**
  1436.      * Retrieve the class name
  1437.      * @return string Class name that this var belongs to
  1438.      */
  1439.     function getClass()
  1440.     {
  1441.         return $this->class;
  1442.     }
  1443.     
  1444.     /**
  1445.      * Return a list of access modifiers (static/private/etc.)
  1446.      * @return array
  1447.      */
  1448.     function getModifiers()
  1449.     {
  1450.         return $this->_modifiers;
  1451.     }
  1452.     
  1453.     /**
  1454.      * Return name of the class that contains this method
  1455.      * @return string
  1456.      */
  1457.     function setModifiers($m)
  1458.     {
  1459.         $this->_modifiers = $m;
  1460.     }
  1461.  
  1462.     /**
  1463.      * quick way to link to this element
  1464.      * @return mixed converter-specific link to this var
  1465.      * @param Converter $c
  1466.      * @param string $text text to display for the link or false for default text
  1467.      */
  1468.     function getLink($c, $text = false, $returnobj = false)
  1469.     {
  1470.         if ($returnobj)
  1471.         {
  1472.             return $c->getLink($this->class . '::' . $this->name, $this->docblock->package);
  1473.         }
  1474.         return $c->getVarLink($this->name, $this->class, $this->docblock->package, false, $text);
  1475.     }
  1476.  
  1477.     /**
  1478.      * @param Converter
  1479.      * @return mixed {@link parserVar} representing var this var overrides from the parent class, or false if none
  1480.      */
  1481.     function getOverrides(&$c)
  1482.     {
  1483.         $class = $c->classes->getClass($this->class,$this->path);
  1484.         $par = $class->getParent($c);
  1485.         
  1486.         if (!is_object($par)) {
  1487.             if (is_a($class->getExtends(true), 'ReflectionClass')) {
  1488.                 $pare = $class->getExtends(true);
  1489.                 if (method_exists($pare, 'hasProperty') &&
  1490.                       $pare->hasProperty(substr($this->name, 1))) {
  1491.                     $par = $pare;
  1492.                     $property = $par->getProperty(substr($this->name, 1));
  1493.                     $ret = new parserVar($par->getName());
  1494.                     $doc = new parserDocBlock;
  1495.                     $ret->setName('$' . $property->getName());
  1496.                     $doc->addPackage('package', $class->getPackage());
  1497.                     $ret->setLineNumber($par->getStartLine());
  1498.                     $modifiers = array();
  1499.                     if ($property->isPrivate()) {
  1500.                         if ($c->parseprivate) {
  1501.                             return false;
  1502.                         }
  1503.                         $modifiers[] = 'private';
  1504.                         $doc->addAccess('private');
  1505.                     }
  1506.                     if ($property->isProtected()) {
  1507.                         $modifiers[] = 'protected';
  1508.                         $doc->addAccess('protected');
  1509.                     }
  1510.                     if ($property->isPublic()) {
  1511.                         $modifiers[] = 'public';
  1512.                         $doc->addAccess('public');
  1513.                     }
  1514.                     $ret->setDocBlock($doc);
  1515.                     $ret->setModifiers($modifiers);
  1516.                     return $ret;
  1517.                 }
  1518.             }
  1519.         }
  1520.         while (is_object($par))
  1521.         {
  1522.             if ($par->hasVar($c,$this->name))
  1523.             {
  1524.                 $var = $par->getVar($c,$this->name);
  1525.                 if (!($var->docblock && $var->docblock->hasaccess &&
  1526.                       !$c->parseprivate && $var->docblock->tags['access'][0]->value == 'private')) {
  1527.                     return $var;
  1528.                 }
  1529.             }
  1530.             $par = $par->getParent($c);
  1531.         }
  1532.         
  1533.         return false;
  1534.     }
  1535.  
  1536.     /**
  1537.      * @param Converter
  1538.      * @return array an array of parserVars from ALL child classes that override this var
  1539.      */
  1540.     function getOverridingVars(&$c)
  1541.     {
  1542.         $class = $c->classes->getClass($this->class,$this->path);
  1543.  
  1544.                 return $this->getOverridingVarsForClass($c, $class);
  1545.     }
  1546.  
  1547.     /**
  1548.      * @param Converter
  1549.          * @param parserClass
  1550.      * @return array an array of parserVars from ALL child classes that override this var in the given class
  1551.      */
  1552.         function getOverridingVarsForClass(&$c, &$class)
  1553.         {
  1554.             $vars = array();
  1555.             if (!$class) return $meths;
  1556.             $kids = $class->getChildClassList($c);
  1557.             for($i=0; $i<count($kids); $i++)
  1558.             {
  1559.                     if ($kids[$i]->hasVar($c, $this->name))
  1560.                     {
  1561.                         $var = $kids[$i]->getVar($c,$this->name);
  1562.                         if (!($var->docblock && $var->docblock->hasaccess && !$c->parseprivate && $var->docblock->tags['access'][0]->value == 'private'))
  1563.                             $vars[] = $var;
  1564.                     }
  1565.  
  1566.                     $vars = array_merge($vars, $this->getOverridingVarsForClass($c, $kids[$i]));
  1567.             }
  1568.             return $vars;
  1569.         }
  1570. }
  1571.  
  1572. /**
  1573.  * @package phpDocumentor
  1574.  * @subpackage ParserElements
  1575.  * @author Greg Beaver <cellog@php.net>
  1576.  * @since 1.2.4
  1577.  */
  1578. class parserConst extends parserElement
  1579. {
  1580.     /**
  1581.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  1582.      * @var string always 'const'
  1583.      */
  1584.     var $type = 'const';
  1585.     /** @var string class that contains this var */
  1586.     var $class = '';
  1587.     
  1588.     /**
  1589.      * @param string
  1590.      */
  1591.     function parserConst($class)
  1592.     {
  1593.         $this->class = $class;
  1594.     }
  1595.     
  1596.     /**
  1597.      * Retrieve the class name
  1598.      * @return string Class name that this var belongs to
  1599.      */
  1600.     function getClass()
  1601.     {
  1602.         return $this->class;
  1603.     }
  1604.  
  1605.     /**
  1606.      * quick way to link to this element
  1607.      * @return mixed converter-specific link to this var
  1608.      * @param Converter $c
  1609.      * @param string $text text to display for the link or false for default text
  1610.      */
  1611.     function getLink($c, $text = false, $returnobj = false)
  1612.     {
  1613.         if ($returnobj)
  1614.         {
  1615.             return $c->getLink($this->class . '::'. $this->name, $this->docblock->package);
  1616.         }
  1617.         return $c->getConstLink($this->name, $this->class, $this->docblock->package, false, $text);
  1618.     }
  1619. }
  1620.  
  1621. /**
  1622.  * @package phpDocumentor
  1623.  * @subpackage ParserElements
  1624.  * @author Greg Beaver <cellog@php.net>
  1625.  * @since 1.0rc1
  1626.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  1627.  */
  1628. class parserMethod extends parserFunction
  1629. {
  1630.     /**
  1631.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  1632.      * @var string always 'method'
  1633.      */
  1634.     var $type = 'method';
  1635.     /** @var boolean whether this method is a constructor */
  1636.     var $isConstructor = false;
  1637.     /** @var boolean whether this method is a destructor by PEAR standards */
  1638.     var $isDestructor = false;
  1639.     /** @var string class that contains this method */
  1640.     var $class = '';
  1641.     var $_modifiers = array();
  1642.     
  1643.     /**
  1644.      * @param string
  1645.      */
  1646.     function parserMethod($class)
  1647.     {
  1648.         $this->class = $class;
  1649.     }
  1650.     
  1651.     /**
  1652.      * @param string
  1653.      * @param string default value parsed from function definition
  1654.      * @param boolean indicates whether this parameter has a default value
  1655.      * @param null|string class type hint
  1656.      */
  1657.     function addParam($name, $value, $has_default = true, $typehint = null)
  1658.     {
  1659.         $this->params[$name] = array($value, $has_default);
  1660.         if (isset($typehint))
  1661.         {
  1662.             $this->params[$name][2] = $typehint;
  1663.         }
  1664.     }
  1665.     
  1666.     /**
  1667.      * adds "constructor " to start of function call if {@link $isConstructor} is true
  1668.      * @return string
  1669.      * @see parent::getFunctionCall()
  1670.      */
  1671.     function getFunctionCall()
  1672.     {
  1673.         $a = parserFunction::getFunctionCall();
  1674.         if ($this->isConstructor) $a = "constructor $a";
  1675.         return $a;
  1676.     }
  1677.     
  1678.     function getIntricateFunctionCall($converter,$paramtags)
  1679.     {
  1680.         $a = parserFunction::getIntricateFunctionCall($converter,$paramtags);
  1681.         if ($this->isConstructor) $a['constructor'] = true;
  1682.         if ($this->isDestructor) $a['destructor'] = true;
  1683.         return $a;
  1684.     }
  1685.     
  1686.     /**
  1687.      * Return name of the class that contains this method
  1688.      * @return string
  1689.      */
  1690.     function getClass()
  1691.     {
  1692.         return $this->class;
  1693.     }
  1694.     
  1695.     /**
  1696.      * Return name of the class that contains this method
  1697.      * @return string
  1698.      */
  1699.     function getModifiers()
  1700.     {
  1701.         return $this->_modifiers;
  1702.     }
  1703.     
  1704.     /**
  1705.      * Return name of the class that contains this method
  1706.      * @return string
  1707.      */
  1708.     function setModifiers($m)
  1709.     {
  1710.         $this->_modifiers = $m;
  1711.     }
  1712.     
  1713.     /**
  1714.      * @param Converter
  1715.      * @return mixed {@link parserMethod} representing method this method
  1716.      * overrides from the parent class, or false if none
  1717.      */
  1718.     function getOverrides(&$c)
  1719.     {
  1720.         $class = $c->classes->getClass($this->class,$this->path);
  1721.         
  1722.         $par = $class->getParent($c);
  1723.         if (!is_object($par)) {
  1724.             if (is_a($class->getExtends(true), 'ReflectionClass')) {
  1725.                 $pare = $class->getExtends(true);
  1726.                 if (method_exists($pare, 'hasMethod') && $pare->hasMethod($this->name)) {
  1727.                     $par = $pare;
  1728.                     $method = $par->getMethod($this->name);
  1729.                     $var = new parserMethod($par->getName());
  1730.                     if ($method->returnsReference()) {
  1731.                         $var->setReturnsReference();
  1732.                     }
  1733.                     $doc = new parserDocBlock;
  1734.                     foreach ($method->getParameters() as $param) {
  1735.                         $value = ($param->isOptional() && !$method->isInternal()) ? var_export($param->getDefaultValue(), true) : null;
  1736.                         if ($param->isPassedByReference()) {
  1737.                             $var->addParam('&$' . $param->getName(), $value, $param->isOptional(),
  1738.                                 $param->getClass());
  1739.                         } else {
  1740.                             $var->addParam('$' . $param->getName(), $value, $param->isOptional(),
  1741.                                 $param->getClass());
  1742.                         }
  1743.                     }
  1744.                     $var->setName($method->getName());
  1745.                     $doc->addPackage('package', $this->getPackage());
  1746.                     $par = $method->getDeclaringClass();
  1747.                     $var->setLineNumber($par->getStartLine());
  1748.                     $modifiers = array();
  1749.                     if ($method->isPrivate()) {
  1750.                         $modifiers[] = 'private';
  1751.                         $doc->addAccess('private');
  1752.                     }
  1753.                     $blank = new parserStringWithInlineTags;
  1754.                     if ($method->isAbstract()) {
  1755.                         $modifiers[] = 'abstract';
  1756.                         $doc->addKeyword('abstract', $blank);
  1757.                     }
  1758.                     if ($method->isFinal()) {
  1759.                         $modifiers[] = 'final';
  1760.                         $doc->addKeyword('final', $blank);
  1761.                     }
  1762.                     if ($method->isProtected()) {
  1763.                         $modifiers[] = 'protected';
  1764.                         $doc->addAccess('protected');
  1765.                     }
  1766.                     if ($method->isPublic()) {
  1767.                         $modifiers[] = 'public';
  1768.                         $doc->addAccess('public');
  1769.                     }
  1770.                     if ($method->isStatic()) {
  1771.                         $modifiers[] = 'static';
  1772.                         $doc->addKeyword('static', $blank);
  1773.                     }
  1774.                     if ($method->isConstructor()) {
  1775.                         $var->setConstructor();
  1776.                     }
  1777.                     $var->setDocBlock($doc);
  1778.                     $var->setModifiers($modifiers);
  1779.                     return $var;
  1780.                 }
  1781.             }
  1782.         }
  1783.  
  1784.         while (is_object($par))
  1785.         {
  1786.             if ($par->hasMethod($c,$this->name))
  1787.             {
  1788.                 $meth = $par->getMethod($c,$this->name);
  1789.                 if (!($meth->docblock && $meth->docblock->hasaccess &&
  1790.                       !$c->parseprivate && $meth->docblock->tags['access'][0]->value == 'private')) {
  1791.                     return $meth;
  1792.                 }
  1793.             }
  1794.             
  1795.             $par = $par->getParent($c);
  1796.         }
  1797.         
  1798.         return false;
  1799.     }
  1800.     /**
  1801.      * @param Converter
  1802.      * @return mixed {@link parserMethod} representing method this method implements
  1803.      * from an interface, or false if none
  1804.      */
  1805.     function getImplements(&$c)
  1806.     {
  1807.         $class = $c->classes->getClass($this->class,$this->path);
  1808.         
  1809.         $implements = $class->getImplements();
  1810.         if (!count($implements)) {
  1811.             return false;
  1812.         }
  1813.         $ret = array();
  1814.         $haveAlready = array();
  1815.         foreach ($implements as $interface) {
  1816.             $interface_link = $c->getLink('object ' . $interface);
  1817.             if (is_a($interface_link, 'classlink')) {
  1818.                 $par = $c->classes->getClass($interface_link->name,
  1819.                     $interface_link->path);
  1820.                 if (is_object($par)) {
  1821.                     if ($par->hasMethod($c, $this->name, true))
  1822.                     {
  1823.                         $meth = $par->getMethod($c, $this->name);
  1824.                         if (!$meth) {
  1825.                             $meth = $par->getMethod($c, $this->name, true);
  1826.                         }
  1827.                         if (!($meth->docblock && $meth->docblock->hasaccess &&
  1828.                               !$c->parseprivate && $meth->docblock->tags['access'][0]->value == 'private')) {
  1829.                             if (isset($haveAlready[$meth->getClass()])) {
  1830.                                 // this ensures extended interfaces don't cause
  1831.                                 // 2 links to the same method
  1832.                                 if ($haveAlready[$meth->getClass()] == $this->name) {
  1833.                                     continue;
  1834.                                 }
  1835.                             }
  1836.                             $ret[] = $meth;
  1837.                             $haveAlready = array($meth->getClass() => $this->name);
  1838.                         }
  1839.                     }
  1840.                 }
  1841.                 continue;
  1842.             }
  1843.             if (class_exists('ReflectionClass')) {
  1844.                 if (interface_exists($interface)) {
  1845.                     $info = new ReflectionClass($interface);
  1846.                     if (method_exists($info, 'hasMethod') && $info->hasMethod($this->name)) {
  1847.                         $par = $info;
  1848.                         $method = $par->getMethod($this->name);
  1849.                         $var = new parserMethod($par->getName());
  1850.                         if ($method->returnsReference()) {
  1851.                             $var->setReturnsReference();
  1852.                         }
  1853.                         $doc = new parserDocBlock;
  1854.                         foreach ($method->getParameters() as $param) {
  1855.                             $value = $param->isOptional() ? var_export($param->getDefaultValue(), true) : null;
  1856.                             if ($param->isPassedByReference()) {
  1857.                                 $var->addParam('&$' . $param->getName(), $value, $param->isOptional(),
  1858.                                     $param->getClass());
  1859.                             } else {
  1860.                                 $var->addParam('$' . $param->getName(), $value, $param->isOptional(),
  1861.                                     $param->getClass());
  1862.                             }
  1863.                         }
  1864.                         $var->setName($method->getName());
  1865.                         $doc->addPackage('package', $this->getPackage());
  1866.                         $par = $method->getDeclaringClass();
  1867.                         $var->setLineNumber($par->getStartLine());
  1868.                         $modifiers = array();
  1869.                         if ($method->isPrivate()) {
  1870.                             $modifiers[] = 'private';
  1871.                             $doc->addAccess('private');
  1872.                         }
  1873.                         $blank = new parserStringWithInlineTags;
  1874.                         if ($method->isAbstract()) {
  1875.                             $modifiers[] = 'abstract';
  1876.                             $doc->addKeyword('abstract', $blank);
  1877.                         }
  1878.                         if ($method->isFinal()) {
  1879.                             $modifiers[] = 'final';
  1880.                             $doc->addKeyword('final', $blank);
  1881.                         }
  1882.                         if ($method->isProtected()) {
  1883.                             $modifiers[] = 'protected';
  1884.                             $doc->addAccess('protected');
  1885.                         }
  1886.                         if ($method->isPublic()) {
  1887.                             $modifiers[] = 'public';
  1888.                             $doc->addAccess('public');
  1889.                         }
  1890.                         if ($method->isStatic()) {
  1891.                             $modifiers[] = 'static';
  1892.                             $doc->addKeyword('static', $blank);
  1893.                         }
  1894.                         if ($method->isConstructor()) {
  1895.                             $var->setConstructor();
  1896.                         }
  1897.                         $var->setDocBlock($doc);
  1898.                         $var->setModifiers($modifiers);
  1899.                         $ret[] = $var;
  1900.                         continue;
  1901.                     }
  1902.                 }
  1903.             }
  1904.         }
  1905.         
  1906.         return $ret;
  1907.     }
  1908.     
  1909.     /**
  1910.      * quick way to link to this element
  1911.      * @return mixed converter-specific link to this method
  1912.      * @param Converter $c
  1913.      * @param string $text text to display for the link or false for default text
  1914.      */
  1915.     function getLink($c, $text = false, $returnobj = false)
  1916.     {
  1917.         if ($returnobj)
  1918.         {
  1919.             return $c->getLink($this->class . '::' . $this->name . '()', $this->docblock->package);
  1920.         }
  1921.         return $c->getMethodLink($this->name, $this->class, $this->docblock->package, false, $text);
  1922.     }
  1923.  
  1924.     /**
  1925.      * Use this method to tell the parser that this method is the class constructor
  1926.      */
  1927.     function setConstructor()
  1928.     {
  1929.         $this->isConstructor = true;
  1930.     }
  1931.     
  1932.     /**
  1933.      * Use this method to tell the parser that this method is the class constructor
  1934.      */
  1935.     function setDestructor()
  1936.     {
  1937.         $this->isDestructor = true;
  1938.     }
  1939.     
  1940.     /**
  1941.      * @param Converter
  1942.      * @return array an array of parserMethods from child classes that override this method
  1943.      */
  1944.     function getOverridingMethods(&$c)
  1945.     {
  1946.         $class = $c->classes->getClass($this->class,$this->path);
  1947.  
  1948.                 return $this->getOverridingMethodsForClass($c, $class);
  1949.     }
  1950.  
  1951.     /**
  1952.      * @param Converter
  1953.          * @param parserClass
  1954.      * @return array an array of parserMethods from ALL child classes that override this method in the given class
  1955.      */
  1956.         function getOverridingMethodsForClass(&$c, &$class)
  1957.         {
  1958.             $meths = array();
  1959.             if (!$class) return $meths;
  1960.             $kids = $class->getChildClassList($c);
  1961.             for($i=0; $i<count($kids); $i++)
  1962.             {
  1963.                     if ($kids[$i]->hasMethod($c, $this->name))
  1964.                     {
  1965.                         $meth = $kids[$i]->getMethod($c,$this->name);
  1966.                         if (!($meth->docblock && $meth->docblock->hasaccess && !$c->parseprivate && $meth->docblock->tags['access'][0]->value == 'private'))
  1967.                             $meths[] = $meth;
  1968.                     }
  1969.  
  1970.                     $meths = array_merge($meths, $this->getOverridingMethodsForClass($c, $kids[$i]));
  1971.             }
  1972.             return $meths;
  1973.         }
  1974. }
  1975.  
  1976. /**
  1977.  * @package phpDocumentor
  1978.  * @subpackage ParserElements
  1979.  * @author Greg Beaver <cellog@php.net>
  1980.  * @since 1.0rc1
  1981.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  1982.  */
  1983. class parserDefine extends parserElement
  1984. {
  1985.     /**
  1986.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  1987.      * @var string always 'define'
  1988.      */
  1989.     var $type = 'define';
  1990.  
  1991.     /**
  1992.      * quick way to link to this element
  1993.      * @return mixed converter-specific link to this define
  1994.      * @param Converter $c
  1995.      * @param string $text text to display for the link or false for default text
  1996.      */
  1997.     function getLink($c, $text = false, $returnobj = false)
  1998.     {
  1999.         if ($returnobj)
  2000.         {
  2001.             return $c->getLink('constant ' . $this->name, $this->docblock->package);
  2002.         }
  2003.         return $c->getDefineLink($this->name, $this->docblock->package, false, $text);
  2004.     }
  2005.  
  2006.     /**
  2007.      * Returns all defines in other packages that have the same name as this define
  2008.      * @return mixed false or an array Format: (package => {@link parserDefine} of conflicting defines)
  2009.      * @param Converter
  2010.      */
  2011.     function getConflicts(&$c)
  2012.     {
  2013.         $a = $c->proceduralpages->getDefineConflicts($this->name);
  2014.         unset($a[$this->docblock->package]);
  2015.         return $a;
  2016.     }
  2017.     
  2018. }
  2019.  
  2020. /**
  2021.  * @package phpDocumentor
  2022.  * @subpackage ParserElements
  2023.  * @author Greg Beaver <cellog@php.net>
  2024.  * @since 1.0rc1
  2025.  * @version $Id: ParserElements.inc,v 1.20 2007/12/19 02:16:49 ashnazg Exp $
  2026.  */
  2027. class parserPackagePage extends parserStringWithInlineTags
  2028. {
  2029.     /**
  2030.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  2031.      * @var string always 'packagepage'
  2032.      */
  2033.     var $type = 'packagepage';
  2034.     /** @var string */
  2035.     var $package = 'default';
  2036.     
  2037.     /**
  2038.      * @param string
  2039.      */
  2040.     function parserPackagePage($package)
  2041.     {
  2042.         $this->package = $package;
  2043.     }
  2044.     
  2045.     /**
  2046.      * @param Converter
  2047.      */
  2048.     function Convert(&$c)
  2049.     {
  2050.         return parent::Convert($c,false);
  2051.     }
  2052. }
  2053.  
  2054. /**
  2055.  * @package phpDocumentor
  2056.  * @subpackage ParserElements
  2057.  * @since 1.2
  2058.  */
  2059. class parserTutorial extends parserPackagePage
  2060. {
  2061.     /**
  2062.      * Type is used by many functions to skip the hassle of if phpDocumentor_get_class($blah) == 'parserBlah'
  2063.      * @var string always 'tutorial'
  2064.      */
  2065.     var $type = 'tutorial';
  2066.     /** @var string */
  2067.     var $package = 'default';
  2068.     /**
  2069.      * Either cls, pkg, or proc
  2070.      * @var string
  2071.      */
  2072.     var $tutorial_type;
  2073.     /**
  2074.      * The documentable element this tutorial is linked to
  2075.      *
  2076.      * Can be a parserData, parserClass, or nothing for package/subpackage docs
  2077.      */
  2078.     var $linked_element;
  2079.     /**
  2080.      * path to the tutorial page
  2081.      * @var string
  2082.      */
  2083.     var $path;
  2084.     /**
  2085.      * filename minus extension of this tutorial (used for @tutorial tag)
  2086.      * @var string
  2087.      */
  2088.     var $name;
  2089.     /** @var boolean */
  2090.     var $_xml = true;
  2091.     /**
  2092.      * output from tutorialname.ext.ini
  2093.      *
  2094.      * an array generated by {@link phpDocumentor_parse_ini_file()} containing
  2095.      * an index 'Linked Tutorials' with an array of tutorial names in the order
  2096.      * they should appear.  This is used to generate a linked list of tutorials like
  2097.      * {@tutorial phpDocumentor/tags.pkg}
  2098.      * @var array
  2099.      */
  2100.     var $ini = false;
  2101.     /**
  2102.      * link to the next tutorial in a document series, or false if none
  2103.      * @var tutorialLink
  2104.      */
  2105.     var $next = false;
  2106.     /**
  2107.      * link to the previous tutorial in a document series, or false if none
  2108.      * @var tutorialLink
  2109.      */
  2110.     var $prev = false;
  2111.     /**
  2112.      * link to the parent tutorial in a document series, or false if none
  2113.      *
  2114.      * This is used to generate an "Up" or "Home" link like the php manual.
  2115.      * The parent is defined as a tutorial that has a parenttutorialname.ext.ini
  2116.      * file and is not contained by any other tutorial's tutorialname.ext.ini
  2117.      * @var tutorialLink
  2118.      */
  2119.     var $parent = false;
  2120.     /**
  2121.      * links to the child tutorials, or false if none
  2122.      * @var array
  2123.      */
  2124.     var $children = false;
  2125.     
  2126.     /**
  2127.      * @param parserXMLDocBookTag top-level tag (<refentry> for 1.2.0)
  2128.      * @param information about the tutorial file.  Format:
  2129.      *
  2130.      * <pre>
  2131.      * array('tutename' => tutorial name,
  2132.      *       'path' => relative path of tutorial to tutorials/ directory
  2133.      *       'ini' => contents of the tutorial .ini file, if any)
  2134.      * </pre>
  2135.      */
  2136.     function parserTutorial($data, $info)
  2137.     {
  2138.         $this->value = $data;
  2139.         $this->package = $info['package'];
  2140.         $this->subpackage = $info['subpackage'];
  2141.         $this->tutorial_type = $info['tutetype'];
  2142.         $this->name = $info['tutename'];
  2143.         $this->path = $info['path'];
  2144.         $this->ini = $info['ini'];
  2145.     }
  2146.     
  2147.     /**
  2148.      * Retrieve the title of the tutorial, or of any subsection
  2149.      * @param Converter
  2150.      * @param string which subsection to retrieve the title from, if any
  2151.      * @uses parserXMLDocBookTag::getSubSection() retrieve the subsection to
  2152.      *       to get a title from
  2153.      */
  2154.     function getTitle(&$c,$subsection = '')
  2155.     {
  2156.         if (!empty($subsection))
  2157.         {
  2158.             $z = $this->value->getSubSection($c,$subsection);
  2159.             if (!$z)
  2160.             {
  2161.                 addWarning(PDERROR_TUTORIAL_SUBSECTION_NOT_FOUND,$this->name,$subsection);
  2162.                 return $subsection;
  2163.             }
  2164.             return $z->getTitle($c);
  2165.         }
  2166.         return $this->value->getTitle($c);
  2167.     }
  2168.     
  2169.     /**
  2170.      * @param Converter
  2171.      * @param boolean determines whether character data is postprocessed to be
  2172.      *                Converter-friendly or not.
  2173.      */
  2174.     function Convert(&$c, $postprocess = true)
  2175.     {
  2176.         return $this->value->Convert($c, $postprocess);
  2177.     }
  2178.     
  2179.     /**
  2180.      * @uses $parent creates a link to the documentation for the parent tutorial
  2181.      * @param parserTutorial
  2182.      * @param Converter
  2183.      */
  2184.     function setParent($parent,&$c)
  2185.     {
  2186.         $this->parent = new tutorialLink;
  2187.         $this->parent->addLink('', $parent->path, $parent->name, $parent->package, $parent->subpackage, $parent->getTitle($c));
  2188.     }
  2189.     
  2190.     /**
  2191.      * Determine if this parserTutorial object is a child of another
  2192.      * 
  2193.      * WARNING:  This method can enter an infinite loop when run on PHP v5.2.1...
  2194.      * see {@link http://bugs.php.net/bug.php?id=40608 PHP Bug #40608}
  2195.      * and {@link http://pear.php.net/bugs/bug.php?id=10289 PEAR Bug #10289}
  2196.      * @param array $parents array of parserTutorials that have child tutorials
  2197.      * @return boolean whether or not this tutorial is a child of the any of the parents
  2198.      */
  2199.     function isChildOf($parents)
  2200.     {
  2201.         // avoid infinite loop PHP bug #40608 in PHP v5.2.1, see PEAR #10289
  2202.         checkForBugCondition('5.2.1', '40608', '10289');
  2203.  
  2204.         foreach($parents as $i => $parent)
  2205.         {
  2206.             if ($parent->path == $this->path) continue;
  2207.             if ($parent->ini && ($parent->package == $this->package) && ($parent->subpackage == $this->subpackage) && ($parent->tutorial_type == $this->tutorial_type))
  2208.             {
  2209.                 foreach($parent->ini['Linked Tutorials'] as $child)
  2210.                 {
  2211.                     if ($child . '.' . $this->tutorial_type == $this->name) return true;
  2212.                 }
  2213.             }
  2214.         }
  2215.     }
  2216.     
  2217.     /**
  2218.      * Retrieve converter-specific link to the parent tutorial's documentation
  2219.      * @param Converter
  2220.      */
  2221.     function getParent(&$c)
  2222.     {
  2223.         if (!$this->parent) return false;
  2224.         return $c->returnSee($this->parent);
  2225.     }
  2226.     
  2227.     /**
  2228.      * @uses $next creates a link to the documentation for the next tutorial
  2229.      * @param parserTutorial
  2230.      * @param Converter
  2231.      */
  2232.     function setNext($next,&$c)
  2233.     {
  2234.         if (phpDocumentor_get_class($next) == 'tutoriallink') return $this->next = $next;
  2235.         $this->next = new tutorialLink;
  2236.         $this->next->addLink('', $next->path, $next->name, $next->package, $next->subpackage, $next->getTitle($c));
  2237.     }
  2238.     
  2239.     /**
  2240.      * Retrieve converter-specific link to the next tutorial's documentation
  2241.      * @param Converter
  2242.      */
  2243.     function getNext(&$c)
  2244.     {
  2245.         if (!$this->next) return false;
  2246.         return $c->returnSee($this->next);
  2247.     }
  2248.     
  2249.     /**
  2250.      * @uses $prev creates a link to the documentation for the previous tutorial
  2251.      * @param parserTutorial
  2252.      * @param Converter
  2253.      */
  2254.     function setPrev($prev,&$c)
  2255.     {
  2256.         if (phpDocumentor_get_class($prev) == 'tutoriallink') return $this->prev = $prev;
  2257.         $this->prev = new tutorialLink;
  2258.         $this->prev->addLink('', $prev->path, $prev->name, $prev->package, $prev->subpackage, $prev->getTitle($c));
  2259.     }
  2260.     
  2261.     /**
  2262.      * Retrieve converter-specific link to the previous tutorial's documentation
  2263.      * @param Converter
  2264.      */
  2265.     function getPrev(&$c)
  2266.     {
  2267.         if (!$this->prev) return false;
  2268.         return $c->returnSee($this->prev);
  2269.     }
  2270.     
  2271.     /**
  2272.      * Get a link to this tutorial, or to any subsection of this tutorial
  2273.      * @param Converter
  2274.      * @param boolean if true, returns a {@link tutorialLink} instead of a string
  2275.      * @param string section name to link to
  2276.      * @return string|tutorialLink
  2277.      */
  2278.     function getLink(&$c,$pure = false,$section = '')
  2279.     {
  2280.         $link = new tutorialLink;
  2281.         $link->addLink($section, $this->path, $this->name, $this->package, $this->subpackage, $this->getTitle($c), $this->category);
  2282.         if ($pure) return $link;
  2283.         return $c->returnSee($link);
  2284.     }
  2285. }
  2286.  
  2287. ?>
  2288.