phpDocumentor
[ class tree: phpDocumentor ] [ index: phpDocumentor ] [ all elements ]

Source for file Io.inc

Documentation is available at Io.inc

  1. <?php
  2. /**
  3.  * File and input handling routines
  4.  * 
  5.  * This class parses command-line options, and works with files to
  6.  * generate lists of files to parse based on the ignore/include options
  7.  * 
  8.  * phpDocumentor :: automatic documentation generator
  9.  * 
  10.  * PHP versions 4 and 5
  11.  *
  12.  * Copyright (c) 2000-2006 Joshua Eichorn, Gregory Beaver
  13.  * 
  14.  * LICENSE:
  15.  * 
  16.  * This library is free software; you can redistribute it
  17.  * and/or modify it under the terms of the GNU Lesser General
  18.  * Public License as published by the Free Software Foundation;
  19.  * either version 2.1 of the License, or (at your option) any
  20.  * later version.
  21.  * 
  22.  * This library is distributed in the hope that it will be useful,
  23.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  25.  * Lesser General Public License for more details.
  26.  * 
  27.  * You should have received a copy of the GNU Lesser General Public
  28.  * License along with this library; if not, write to the Free Software
  29.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  30.  *
  31.  * @package    phpDocumentor
  32.  * @author     Joshua Eichorn <jeichorn@phpdoc.org>
  33.  * @author     Gregory Beaver <cellog@php.net>
  34.  * @copyright  2000-2006 Joshua Eichorn, Gregory Beaver
  35.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  36.  * @version    CVS: $Id: Io.inc,v 1.16 2007/04/19 20:20:57 ashnazg Exp $
  37.  * @filesource
  38.  * @link       http://www.phpdoc.org
  39.  * @link       http://pear.php.net/PhpDocumentor
  40.  * @since      0.1
  41.  */
  42. /**
  43.  * Class to handle file and user io opperations
  44.  *
  45.  * @author    Joshua Eichorn <jeichorn@phpdoc.org>
  46.  * @author     Gregory Beaver <cellog@php.net>
  47.  * @version    $Id: Io.inc,v 1.16 2007/04/19 20:20:57 ashnazg Exp $
  48.  * @package     phpDocumentor
  49.  */
  50. class Io 
  51. {
  52.     
  53.     /**
  54.      * Holds all the options that are avaible to the cmd line interface
  55.      * and to the different web interfaces
  56.      */
  57.     var $phpDocOptions;
  58.     /**
  59.      * Format: array(array(regexp-ready string to search for whole path,
  60.      * regexp-ready string to search for basename of ignore strings),...)
  61.      * @var false|array
  62.      */
  63.     var $ignore;
  64.     /**
  65.      * A specific array of values that boolean-based arguments can understand,
  66.      * aided by the {@link decideOnOrOff()} helper method.
  67.      * @var array 
  68.      */
  69.     var $valid_booleans = array
  70.     (
  71.         ''' ''on''On''ON''y''Y''yes''Yes''YES''true''True''TRUE''1'
  72.         'off''Off''OFF''n''N''no''No''NO''false''False''FALSE''0'
  73.     );
  74.     
  75.     /**
  76.      * creates an array $this->phpDocOptions and sets program options in it.
  77.      * Array is in the format of:
  78.      * <pre>
  79.      * [filename][tag][] = "f";
  80.      * [filename][tag][] = "-file";
  81.      * [filename][desc] "name of file to parse"
  82.      * </pre>
  83.      */
  84.     function Io()
  85.     {
  86.         $this->phpDocOptions['filename']['tag'= array"-f""--filename");
  87.         $this->phpDocOptions['filename']['desc'"name of file(s) to parse ',' file1,file2.  Can contain complete path and * ? wildcards";
  88.         $this->phpDocOptions['filename']['type'"path";
  89.  
  90.         $this->phpDocOptions['directory']['tag'= array"-d""--directory");
  91.         $this->phpDocOptions['directory']['desc'"name of a directory(s) to parse directory1,directory2";
  92.         $this->phpDocOptions['directory']['type'"path";
  93.  
  94.         $this->phpDocOptions['examplesdir']['tag'= array"-ed""--examplesdir");
  95.         $this->phpDocOptions['examplesdir']['desc'"full path of the directory to look for example files from @example tags";
  96.         $this->phpDocOptions['examplesdir']['type'"path";
  97.  
  98.         $this->phpDocOptions['templatebase']['tag'= array"-tb""--templatebase");
  99.         $this->phpDocOptions['templatebase']['desc'"base location of all templates for this parse.";
  100.         $this->phpDocOptions['templatebase']['type'"path";
  101.  
  102.         $this->phpDocOptions['target']['tag'= array("-t""--target");
  103.         $this->phpDocOptions['target']['desc'"path where to save the generated files";
  104.         $this->phpDocOptions['target']['type'"path";
  105.         
  106.         $this->phpDocOptions['ignore']['tag'= array("-i""--ignore");
  107.         $this->phpDocOptions['ignore']['desc'"file(s) that will be ignored, multiple separated by ','.  Wildcards * and ? are ok";
  108.         $this->phpDocOptions['ignore']['type'"path";
  109.  
  110.         $this->phpDocOptions['ignoresymlinks']['tag'= array("-is""--ignoresymlinks");
  111.         $this->phpDocOptions['ignoresymlinks']['desc'"ignore symlinks to other files or directories, default is off";
  112.         $this->phpDocOptions['ignoresymlinks']['type'"set";
  113.         $this->phpDocOptions['ignoresymlinks']['validvalues'$this->valid_booleans;
  114.  
  115.         $this->phpDocOptions['ignoretags']['tag'= array("-it""--ignore-tags");
  116.         $this->phpDocOptions['ignoretags']['desc'"tags to ignore for this parse.  @package, @subpackage, @access and @ignore may not be ignored.";
  117.         $this->phpDocOptions['ignoretags']['type'"value";
  118.  
  119.         $this->phpDocOptions['hidden']['tag'= array("-dh""--hidden");
  120.         $this->phpDocOptions['hidden']['desc'"set equal to on (-dh on) to descend into hidden directories (directories starting with '.'), default is off";
  121.         $this->phpDocOptions['hidden']['type'"set";
  122.         $this->phpDocOptions['hidden']['validvalues'$this->valid_booleans;
  123.  
  124.         $this->phpDocOptions['quiet']['tag'= array("-q""--quiet");
  125.         $this->phpDocOptions['quiet']['desc'"do not display parsing/conversion messages.  Useful for cron jobs on/off default off";
  126.         $this->phpDocOptions['quiet']['type'"set";
  127.         $this->phpDocOptions['quiet']['validvalues'$this->valid_booleans;
  128.  
  129.         $this->phpDocOptions['undocumentedelements']['tag'= array("-ue""--undocumentedelements");
  130.         $this->phpDocOptions['undocumentedelements']['desc'"Control whether or not warnings will be shown for undocumented elements. Useful for identifying classes and methods that haven't yet been documented on/off default off";
  131.         $this->phpDocOptions['undocumentedelements']['type'"set";
  132.         $this->phpDocOptions['undocumentedelements']['validvalues'$this->valid_booleans;
  133.  
  134.         $this->phpDocOptions['title']['tag'= array("-ti","--title");
  135.         $this->phpDocOptions['title']['desc'"title of generated documentation, default is 'Generated Documentation'";
  136.         $this->phpDocOptions['title']['type'"value";
  137.  
  138.         $this->phpDocOptions['help']['tag'= array("-h""--help");
  139.         $this->phpDocOptions['help']['desc'"    show this help message";
  140.  
  141.         $this->phpDocOptions['useconfig']['tag'= array("-c","--useconfig");
  142.         $this->phpDocOptions['useconfig']['desc'"Use a Config file in the users/ subdirectory for all command-line options";
  143.         $this->phpDocOptions['useconfig']['type'"value";
  144.  
  145.         $this->phpDocOptions['parseprivate']['tag'= array("-pp","--parseprivate");
  146.         $this->phpDocOptions['parseprivate']['desc'"parse @internal and elements marked private with @access.  Use on/off, default off";
  147.         $this->phpDocOptions['parseprivate']['type'"set";
  148.         $this->phpDocOptions['parseprivate']['validvalues'= array('on''off');
  149.  
  150.         $this->phpDocOptions['packageoutput']['tag'= array("-po","--packageoutput");
  151.         $this->phpDocOptions['packageoutput']['desc'"output documentation only for selected packages.  Use a comma-delimited list";
  152.         $this->phpDocOptions['packageoutput']['type'"value";
  153.  
  154.         $this->phpDocOptions['defaultpackagename']['tag'= array("-dn","--defaultpackagename");
  155.         $this->phpDocOptions['defaultpackagename']['desc'"name to use for the default package.  If not specified, uses 'default'";
  156.         $this->phpDocOptions['defaultpackagename']['type'"value";
  157.  
  158.         $this->phpDocOptions['defaultcategoryname']['tag'= array("-dc","--defaultcategoryname");
  159.         $this->phpDocOptions['defaultcategoryname']['desc'"name to use for the default category.  If not specified, uses 'default'";
  160.         $this->phpDocOptions['defaultcategoryname']['type'"value";
  161.  
  162.         $this->phpDocOptions['output']['tag'= array("-o","--output");
  163.         $this->phpDocOptions['output']['desc'"output information to use separated by ','.  Format: output:converter:templatedir like \"HTML:frames:phpedit\"";
  164.         $this->phpDocOptions['output']['type'"value";
  165.  
  166.         $this->phpDocOptions['converterparams']['tag'= array("-cp","--converterparams");
  167.         $this->phpDocOptions['converterparams']['desc'"dynamic parameters for a converter, separate values with commas";
  168.         $this->phpDocOptions['converterparams']['type'"value";
  169.  
  170.         $this->phpDocOptions['customtags']['tag'= array("-ct","--customtags");
  171.         $this->phpDocOptions['customtags']['desc'"custom tags, will be recognized and put in tags[] instead of unknowntags[]";
  172.         $this->phpDocOptions['customtags']['type'"value";
  173.  
  174.         $this->phpDocOptions['sourcecode']['tag'= array("-s","--sourcecode");
  175.         $this->phpDocOptions['sourcecode']['desc'"generate highlighted sourcecode for every parsed file (PHP 4.3.0+ only) on/off default off";
  176.         $this->phpDocOptions['sourcecode']['type'"set";
  177.         $this->phpDocOptions['sourcecode']['validvalues'= array('on''off');
  178.  
  179.         $this->phpDocOptions['javadocdesc']['tag'= array("-j","--javadocdesc");
  180.         $this->phpDocOptions['javadocdesc']['desc'"JavaDoc-compliant description parsing.  Use on/off, default off (more flexibility)";
  181.         $this->phpDocOptions['javadocdesc']['type'"set";
  182.         $this->phpDocOptions['javadocdesc']['validvalues'= array('on''off');
  183.  
  184.         $this->phpDocOptions['pear']['tag'= array("-p","--pear");
  185.         $this->phpDocOptions['pear']['desc'"Parse a PEAR-style repository (package is directory, _members are @access private) on/off default off";
  186.         $this->phpDocOptions['pear']['type'"set";
  187.         $this->phpDocOptions['pear']['validvalues'= array('on''off');
  188.  
  189.         $this->phpDocOptions['readmeinstallchangelog']['tag'= array("-ric","--readmeinstallchangelog");
  190.         $this->phpDocOptions['readmeinstallchangelog']['desc'"Specify custom filenames to parse like README, INSTALL or CHANGELOG files";
  191.         $this->phpDocOptions['readmeinstallchangelog']['type'"value";
  192.  
  193.         $this->phpDocOptions['general']['message'="You can have multiple directories and multiple files, as well as a combination of both options";
  194.     }
  195.  
  196.     
  197.     /**
  198.      * create the help message for display on the command-line
  199.      * @return string a string containing a help message
  200.      */
  201.     function displayHelpMsg()
  202.     {
  203.         unset($ret);
  204.         $ret "\n";
  205.         foreach($this->phpDocOptions as $data)
  206.         {
  207.             unset($tag);
  208.             $tag "";
  209.             if (isset($data['tag']))
  210.             {
  211.                 if (is_array($data['tag'])) {
  212.                     foreach($data['tag'as $param{
  213.                         $tag .= "$param    ";
  214.                     }
  215.                 }
  216.         $taglen = 34;
  217.         $outputwidth = 79;
  218.         $tagspace str_repeat(" ",$taglen);
  219.                 $tmp "  ".trim($tag).$tagspace;
  220.                 $tmp substr($tmp,0,$taglen);
  221.                 $d wordwrap(ltrim($data['desc']),($outputwidth-$taglen));
  222.         $dt explode("\n",$d);
  223.         $dt[0$tmp .$dt[0];
  224.         for($i=1;$i<count($dt);$i++)
  225.         {
  226.             $dt[$i$tagspace.$dt[$i];
  227.         }
  228.         $ret .= implode("\n",$dt)."\n\n";
  229.         
  230.             }
  231.         }
  232.         $ret .= "\n".wordwrap($data['message'],$outputwidth)."\n";
  233.         return $ret
  234.     }
  235.     
  236.     /**
  237.      * calls {@link file_exists()} for each value in include_path,
  238.      * then calls {@link is_readable()} when it finds the file
  239.      * @param string 
  240.      * @return boolean 
  241.      */
  242.     function isIncludeable($filename)
  243.     {
  244.         $test realpath($filename);
  245.         if ($test && is_readable($test)) {
  246.             return true; // for absolute paths
  247.         }
  248.         $ip get_include_path();
  249.         if (PHPDOCUMENTOR_WINDOWS)
  250.         {
  251.             $ip explode(';'$ip);
  252.         else {
  253.             $ip explode(':'$ip);
  254.         }
  255.         foreach($ip as $path)
  256.         {
  257.             if ($a realpath($path . DIRECTORY_SEPARATOR . $filename))
  258.             {
  259.                 if (is_readable($a))
  260.                 {
  261.                     return true;
  262.                 }
  263.             }
  264.         }
  265.         return false;
  266.     }
  267.  
  268.     /**
  269.      * Parses $_SERVER['argv'] and creates a setup array
  270.      * @return array a setup array
  271.      * @global array command-line arguments
  272.      */
  273.     function parseArgv()
  274.     {
  275.         global $argv;
  276.         // defaults for setting
  277.         $setting['hidden'"off";
  278.         $setting['ignoresymlinks''off';
  279.         $setting['template''templates' PATH_DELIMITER .'default' PATH_DELIMITER;
  280.  
  281.         $valnext "junk";
  282.         $data = array();
  283.         if(isset($argv&& is_array($argv))
  284.         {
  285.             foreach ($argv as $cmd)
  286.             {
  287.                 //if($cmd === 'phpdoc' || basename($cmd)==='phpdoc')
  288.                 //    continue;
  289.  
  290.                 if ($cmd == '--'{
  291.                     continue;
  292.                 }
  293.                 if ($cmd == '-h' || $cmd == '--help')
  294.                 {
  295.                     echo $this->displayHelpMsg();
  296.                     die();
  297.                 }
  298.                 if (isset($data['type']&& $data['type'== 'set'{
  299.                     if (!in_array(strtolower($cmd)$data['validvalues']true)) {
  300.                         addErrorDie(PDERROR_INVALID_VALUES$valnext$cmd,
  301.                             '(' implode(', '$data['validvalues']')');
  302.                     }
  303.                 }
  304.                 $setting[$valnext$cmd;
  305.                 foreach$this->phpDocOptions as $name => $data )
  306.                 {
  307.                     if (!empty($data['tag']))
  308.                     {
  309.                         if (in_array($cmd,$data['tag']))
  310.                         {
  311.                             $valnext $name;
  312.                             break;
  313.                         
  314.                         else
  315.                         {
  316.                             $valnext "junk";
  317.                         }
  318.                     }
  319.                 }
  320.                 if ($valnext == 'junk' && (strpos(trim($cmd),'-'=== 0))
  321.                 {
  322.                     addErrorDie(PDERROR_UNKNOWN_COMMANDLINE,$cmd);
  323.                 }
  324.             }
  325.         else
  326.         {
  327.             echo "Please use php-cli.exe in windows, or set register_argc_argv On";
  328.             die;
  329.         }
  330.         /* $setting will always have at least 3 elements
  331.         [hidden] => off
  332.         [ignoresymlinks] => 'off'
  333.         [template] => templates/default
  334.          */
  335.         if (count($setting< 4{
  336.             echo $this->displayhelpMsg();
  337.             die();
  338.         }
  339.         return $setting;
  340.     }
  341.  
  342.  
  343.     /**
  344.      * @return array list of files in a directory
  345.      * @param string $directory full path to the directory you want the list of
  346.      * @param bool whether to list files that begin with . like .bash_history
  347.      * @param bool whether to ignore symlinks
  348.      */
  349.     function dirList($orig_directory$hidden = false$ignore_symlinks = false)
  350.     {
  351.         $directory realpath($orig_directory);
  352.         $ret = false;
  353.         if (@is_dir($directory))
  354.         {
  355.             die("directory: '$directory'  not found\n");
  356.         }
  357.         $ret = array();
  358.         $d @dir($directory)// thanks to Jason E Sweat (jsweat@users.sourceforge.net) for fix
  359.         while($d && ($entry=$d->read()) !== false{
  360.             if (strcmp($entry,"."== 0 || strcmp($entry,".."== 0{
  361.                 continue;
  362.             }
  363.  
  364.             // skip hidden files, if we're supposed to
  365.             if (!$hidden)
  366.             {
  367.                 if (substr($entry,0,1== ".")
  368.                 {
  369.                     phpDocumentor_out("Hidden " $directory PATH_DELIMITER . $entry " Ignored\n");
  370.                     continue;
  371.                 }
  372.             }
  373.  
  374.             // skip symlink files, if we're supposed to
  375.             if ($ignore_symlinks)
  376.             {
  377.                 if (is_link($directory PATH_DELIMITER . $entry))
  378.                 {
  379.                     phpDocumentor_out("Symlink " $directory PATH_DELIMITER . $entry " Ignored\n");
  380.                     continue;
  381.                 }
  382.             }
  383.             
  384.             if (is_file($directory PATH_DELIMITER . $entry)) {
  385.                 $ret[$directory PATH_DELIMITER . $entry;
  386.             }
  387.             if (is_dir($directory PATH_DELIMITER . $entry)) {
  388.                 $tmp $this->dirList($directory PATH_DELIMITER . $entry$hidden$ignore_symlinks);
  389.                 if (is_array($tmp)) {
  390.                     foreach($tmp as $ent{
  391.                         $ret[$ent;
  392.                     }
  393.                 }
  394.             }
  395.         }
  396.         if ($d$d->close();
  397.         return $ret;
  398.     }
  399.  
  400.     /**
  401.      * Retrieve common directory (case-insensitive in windows)
  402.      *
  403.      * takes the list of files, and returns the subdirectory they share in common,
  404.      * so in this list:
  405.      *
  406.      * <code>
  407.      * array(
  408.      * "/dir1/dir2/subdir/dir3/filename.ext",
  409.      * "/dir1/dir2/subdir/dir4/filename.ext",
  410.      * "/dir1/dir2/mydir/dir5/filename.ext");
  411.      * </code>
  412.      *
  413.      * getBase will return "/dir1/dir2"
  414.      * @param array array of strings
  415.      */
  416.     function getBase($filelist)
  417.     {
  418.         $masterPath = false;
  419.         foreach($filelist as $path)
  420.         {
  421.             if (!$masterPath)
  422.             {
  423.                 $masterPath str_replace('\\','/',dirname($path));
  424.             else
  425.             {
  426.                 if (dirname($path!= $masterPath)
  427.                 {
  428.                     $mp split(PATH_DELIMITER,$masterPath);
  429.                     $np split(PATH_DELIMITER,str_replace('\\','/',dirname($path)));
  430.                     if (count($npcount($mp))
  431.                     {
  432.                         $masterPath join($npPATH_DELIMITER);
  433.                     else
  434.                     {
  435.                         $test = false;
  436.                         $found = false;
  437.                         for($i=0;$i count($mp&& $i count($np);$i++)
  438.                         {
  439.                             if (PHPDOCUMENTOR_WINDOWS)
  440.                             {
  441.                                 if (strtolower($mp[$i]!= strtolower($np[$i])) $found $i;
  442.                             else
  443.                             {
  444.                                 if ($mp[$i!= $np[$i]$found $i;
  445.                             }
  446.                         }
  447.                         if ($found !== false)
  448.                         {
  449.                             $mp array_slice($mp,0,$found);
  450.                             $masterPath join($mp,PATH_DELIMITER);
  451.                         }
  452.                     }
  453.                 }
  454.             }
  455.         }
  456.         return $masterPath;
  457.     }
  458.     
  459.     /**
  460.      * Retrieve tutorial subdirectories and their contents from the list of
  461.      * files to parse
  462.      * @param array array of paths (strings)
  463.      * @return array array(filelist - tutorials, tutorials)
  464.      */
  465.     function getTutorials($filelist)
  466.     {
  467.         $list $tutorials = array();
  468.         foreach($filelist as $file)
  469.         {
  470.             if (strpos($file,'tutorials/'!== false)
  471.             {
  472.                 $tutedir explode('/',substr($file,strpos($file,'tutorials/')));
  473.                 array_shift($tutedir);
  474.                 if (count($tutedir<= 3)
  475.                 {
  476.                     $res = array();
  477.                     // kludge - will need to fix for 2.0
  478.                     $res['category'$GLOBALS['phpDocumentor_DefaultCategoryName'];
  479.                     $res['package'array_shift($tutedir);
  480.                     $res['subpackage''';
  481.                     if (count($tutedir> 1)
  482.                     $res['subpackage'array_shift($tutedir);
  483.                     $f array_shift($tutedir);
  484.                     $res['tutename'$f;
  485.                     $f explode('.',$f);
  486.                     $res['tutetype'array_pop($f);
  487.                     if ($res['tutetype'== 'ini'continue;
  488.                     $res['path'$file;
  489.                     if (@file_exists($file '.ini'))
  490.                     {
  491.                         $res['ini'phpDocumentor_parse_ini_file($file '.ini'true);
  492.                     else
  493.                     {
  494.                         $res['ini'= false;
  495.                     }
  496.                     $tutorials[$res;
  497.                 }
  498.             else $list[$file;
  499.         }
  500.         return array($list,$tutorials);
  501.     }
  502.     
  503.     /**
  504.      * @param string base directory from {@link getBase()}
  505.      * @param array file list from {@link dirList()}
  506.      * @return array array(filelist - README/INSTALL/CHANGELOG,
  507.      *                      README/INSTALL/CHANGELOG)
  508.      */
  509.     function getReadmeInstallChangelog($base,$filelist)
  510.     {
  511.         $list $ric = array();
  512.         $names $GLOBALS['_phpDocumentor_RIC_files'];
  513.         foreach($filelist as $file)
  514.         {
  515.             if ((dirname($file== $base&& in_array(strtoupper(basename($file))$names))
  516.             // be sure to change $this->checkIgnore() if any other files are added here!!
  517.                 $ric[$file;
  518.             else
  519.             {
  520.                 $list[$file;
  521.             }
  522.         }
  523.         return array($list,$ric);
  524.     }
  525.  
  526.     /**
  527.      * @param string directory
  528.      * @param string base directory
  529.      * @param array array of ignored items
  530.      * @param boolean the "hidden" flag
  531.      * @param boolean the "ignoresymlinks" flag
  532.      * @uses dirList
  533.      * @uses checkIgnore
  534.      * @uses setup_dirs
  535.      */    
  536.     function getDirTree($dir$base_dir$ignore = array()$hidden = false$ignoresymlinks = false)
  537.     {
  538.         $allfiles $this->dirList($dir,$hidden,$ignoresymlinks);
  539.         $struc = array();
  540.         foreach($allfiles as $file)
  541.         {
  542.             if ($this->checkIgnore(basename($file),dirname(realpath($file)),$ignore,$ignoresymlinks)) continue;
  543.             $path substr(dirname($file),strlen(str_replace('\\','/',realpath($base_dir)))+1);
  544.             if (!$path$path '/';
  545.             $parts pathinfo($file);
  546.             if (!isset($parts['extension']))
  547.             {
  548.                 $parts['extension''';
  549.             }
  550.             $struc[$path][= array(
  551.                 'file' => $parts['basename'],
  552.                 'ext' => $parts['extension'],
  553.                 'path' => $file);
  554.         }
  555.         uksort($struc,'strnatcasecmp');
  556.         foreach($struc as $key => $ind)
  557.         {
  558.             usort($ind,'Ioinc_sortfiles');
  559.             $struc[$key$ind;
  560.             $save $key;
  561.             if ($key != '/')
  562.             {
  563.                 $key explode('/',$key);
  564.                 while (count($key))
  565.                 {
  566.                     array_pop($key);
  567.                     if (isset($struc[join('/',$key)]))
  568.                     {
  569.                         $struc[join('/',$key)][substr($save,strlen(join('/',$key)) + 1)$ind;
  570.                         unset($struc[$save]);
  571.                     }
  572.                 }
  573.             }
  574.         }
  575.         foreach($struc as $key => $ind)
  576.         {
  577.             if ($key != '/')
  578.             {
  579.                 if (count(explode('/',$key)) == 1)
  580.                 {
  581.                     $struc['/'][$key$struc[$key];
  582.                     unset($struc[$key]);
  583.                 }
  584.             }
  585.         }
  586.         $tempstruc $struc;
  587.         unset($tempstruc['/']);
  588.         $leftover_dirs array_keys($tempstruc);
  589.         $splitdirs = array();
  590.         foreach($leftover_dirs as $dir)
  591.         {
  592.             $splitdirs[explode('/',$dir);
  593.         }
  594.         $leftover_dirs = array();
  595.  
  596.         foreach($splitdirs as $dir)
  597.         {
  598.             $save join($dir,'/');
  599.             $struc['/'setup_dirs($struc['/']$dir$tempstruc[$save]);
  600.             unset($struc[$save]);
  601.         }
  602.         @uksort($struc['/'],'Ioinc_mystrucsort');
  603.         return $struc;
  604.     }
  605.     
  606.     /**
  607.      * Reads a file and returns it as a string
  608.      * Does basic error checking
  609.      *
  610.      * file extensions are set in {@link phpdoc.inc}
  611.      *
  612.      * @global array PHP File extensions, used to validate that $path is a PHP File
  613.      * @global array PHP File extensions in a CVS repository, used to validate that $path is a PHP File
  614.      * @param    string    $path 
  615.      */
  616.     function readPhpFile($path$quietMode = false)
  617.     {
  618.         global $_phpDocumentor_cvsphpfile_exts$_phpDocumentor_phpfile_exts;
  619.         // tiberiusblue addition
  620.         $cvsExt $_phpDocumentor_cvsphpfile_exts
  621.         $ext $_phpDocumentor_phpfile_exts;
  622.         if (file_exists($path))
  623.         {
  624.             if (is_file($path))
  625.             {
  626.                 // check extension
  627.                 $tmp explode(".",$path);
  628.                 // tiberiusblue addition
  629.                 $tmp2 $tmp;
  630.                 if (in_array(array_pop($tmp),$ext))
  631.                 {
  632.                     phpDocumentor_out(" -- Parsing file\n");
  633.                     flush();
  634.                     if (function_exists('file_get_contents')) {
  635.                         return file_get_contents($path);
  636.                     }
  637.                     $fp fopen($path,"r");
  638.                     $ret fread($fp,filesize($path));
  639.                     fclose($fp);
  640.                     return $ret;
  641.                 elseif (in_array(array_pop($tmp2),$cvsExt)) 
  642.                 
  643.                     phpDocumentor_out(" CVS file [EXPERIMENTAL]\n")
  644.                     flush();
  645.                     if (function_exists('file_get_contents')) {
  646.                         $ret file_get_contents($path);
  647.                     else {
  648.                         $fp fopen($path,"r")
  649.                         $ret fread($fp,filesize($path))
  650.                         fclose($fp)
  651.                     }
  652.                     $ret strstr($ret,"<?");
  653.                     $ret substr($ret,0,strpos($ret,"@\n"));
  654.                     $ret str_replace("@@","@",$ret)
  655.                     return $ret
  656.                 else
  657.                 {
  658.                     phpDocumentor_out(" -- File not parsed, not a php file\n");
  659.                     flush();
  660.                 }
  661.             else {
  662.                 phpDocumentor_out(" -- Unable to read file, not a file\n");
  663.                 flush();
  664.             }
  665.         else {
  666.             phpDocumentor_out(" -- Unable to read file, file does not exist\n");
  667.             flush();
  668.            }
  669.     }
  670.  
  671.     /**
  672.      * Tell whether to ignore a file or a directory
  673.      * allows * and ? wildcards
  674.      *
  675.      * @author Greg Beaver <cellog@php.net>
  676.      * @param    string  $file    just the file name of the file or directory,
  677.      *                           in the case of directories this is the last dir
  678.      * @param    string  $path    the path to consider (should be checked by
  679.      *                             realpath() before, and may be relative)
  680.      * @param    array   $ignore 
  681.      * @param    bool 
  682.      * @param    bool    Ignore symlinks?
  683.      * @return   bool    true if $path should be ignored, false if it should not
  684.      */
  685.     function checkIgnore($file,$path,$ignore,$ignore_no_ext = true,$ignoresymlinks = false)
  686.     {
  687.         global $_phpDocumentor_RIC_files;
  688.  
  689.         if ($ignoresymlinks && is_link($path PATH_DELIMITER . $file)) return false;
  690.         
  691.         if (!count($ignore)) return false;
  692.  
  693.         if (!isset($this->ignore))
  694.         {
  695.             $this->_setupIgnore($ignore);
  696.         }
  697.         if (!$this->ignore)
  698.         {
  699.             return false;
  700.         }
  701.  
  702.         if ($ignore_no_ext && 
  703.             !in_array(strtoupper($file)$_phpDocumentor_RIC_files))
  704.         {
  705.             if (!is_numeric(strpos($file,'.'))) return true;
  706.         }
  707.         if (is_array($this->ignore))
  708.         {
  709.             foreach($this->ignore as $match)
  710.             {
  711.                 // match is an array if the ignore parameter was a /path/to/pattern
  712.                 if (is_array($match))
  713.                 {
  714.                     // check to see if the path matches with a path delimiter appended
  715.                     preg_match('/^' strtoupper($match[0]).'$/'strtoupper($pathPATH_DELIMITER,$find);
  716.                     if (!count($find))
  717.                     {
  718.                         // check to see if it matches without an appended path delimiter
  719.                         preg_match('/^' strtoupper($match[0]).'$/'strtoupper($path)$find);
  720.                     }
  721.                     if (count($find))
  722.                     {
  723.                         // check to see if the file matches the file portion of the regex string
  724.                         preg_match('/^' strtoupper($match[1]).'$/'strtoupper($file)$find);
  725.                         if (count($find))
  726.                         {
  727.                             return true;
  728.                         }
  729.                     }
  730.                     // check to see if the full path matches the regex
  731.                     preg_match('/^' strtoupper($match[0]).'$/',
  732.                                strtoupper($path . DIRECTORY_SEPARATOR . $file)$find);
  733.                     if (count($find))
  734.                     {
  735.                         return true;
  736.                     }
  737.                 else
  738.                 {
  739.                     // ignore parameter was just a pattern with no path delimiters
  740.                     // check it against the path
  741.                     preg_match('/^' strtoupper($match).'$/'strtoupper($path)$find);
  742.                     if (count($find))
  743.                     {
  744.                         return true;
  745.                     }
  746.                     // check it against the file only
  747.                     preg_match('/^' strtoupper($match).'$/'strtoupper($file)$find);
  748.                     if (count($find))
  749.                     {
  750.                         return true;
  751.                     }
  752.                 }
  753.             }
  754.         }
  755.         return false;
  756.     }
  757.     
  758.     /**
  759.      * Construct the {@link $ignore} array
  760.      * @author Greg Beaver <cellog@php.net>
  761.      * @param array strings of files/paths/wildcards to ignore
  762.      * @access protected
  763.      */
  764.     function _setupIgnore($ignore)
  765.     {
  766.         $ig = array();
  767.         if is_array($ignore))
  768.         {
  769.             $this->ignore = false;
  770.             return;
  771.         }
  772.         for($i=0; $i<count($ignore);$i++)
  773.         {
  774.             if (empty($ignore[$i]))
  775.                 continue;
  776.  
  777.             $ignore[$istrtr($ignore[$i]'\\''/');
  778.             $ignore[$istr_replace('//','/',$ignore[$i]);
  779.  
  780.             if (!is_numeric(strpos($ignore[$i],PATH_DELIMITER)))
  781.             {
  782.                 $ig[$this->getRegExpableSearchString($ignore[$i]);
  783.             else
  784.             {
  785.                 if (basename($ignore[$i]PATH_DELIMITER == $ignore[$i])
  786.                 $ig[$this->getRegExpableSearchString($ignore[$i]);
  787.                 else
  788.                 $ig[= array($this->getRegExpableSearchString($ignore[$i]),$this->getRegExpableSearchString(basename($ignore[$i])));
  789.             }
  790.         }
  791.         if (count($ig)) $this->ignore = $ig;
  792.     }
  793.     
  794.     /**
  795.      * Converts $s into a string that can be used with preg_match
  796.      * @param string $s string with wildcards ? and *
  797.      * @author Greg Beaver <cellog@php.net>
  798.      * @return string converts * to .*, ? to ., etc.
  799.      */
  800.     function getRegExpableSearchString($s)
  801.     {
  802.         $y '\/';
  803.         if (DIRECTORY_SEPARATOR == '\\')
  804.         {
  805.             $y '\\\\';
  806.         }
  807.         $s str_replace('/'DIRECTORY_SEPARATOR$s);
  808.         $x strtr($sarray('?' => '.','*' => '.*','.' => '\\.','\\' => '\\\\','/' => '\\/',
  809.                                 '[' => '\\[',']' => '\\]','-' => '\\-'));
  810.         if (strpos($sDIRECTORY_SEPARATOR!== false &&
  811.             strrpos($sDIRECTORY_SEPARATOR=== strlen($s- 1)
  812.         {
  813.             $x = "(?:.*$y$x?.*|$x.*)";
  814.         }
  815.         return $x;
  816.     }
  817.     
  818.     /**
  819.      * Removes files from the $dir array that do not match the search string in
  820.      * $match
  821.      * @param array $dir array of filenames (full path)
  822.      * @param string $match search string with wildcards
  823.      * @author Greg Beaver <cellog@php.net>
  824.      * @return string|arraylisting of every file in a directory that matches
  825.      *                       the search string
  826.      */
  827.     function removeNonMatches($dir$match)
  828.     {
  829.         $match $this->getRegExpableSearchString($match);
  830.         $nodir = false;
  831.         if (!is_array($dir))
  832.         {
  833.             $dir = array($dir);
  834.             $nodir = true;
  835.         }
  836.         foreach($dir as $i => $file)
  837.         {
  838.             preg_match('/^'.$match.'$/',basename($file),$find);
  839.             if (!count($find)) unset($dir[$i]);
  840.         }
  841.         if ($nodirreturn $dir[0];
  842.         return $dir;
  843.     }
  844.     
  845.     /**
  846.      * Take a filename with wildcards and return all files that match the
  847.      * wildcards
  848.      * @param string $file a full path from the -f command-line parameter, with
  849.      *  potential * and ? wildcards.
  850.      * @return mixed if $file contains wildcards, returns an array of matching
  851.      *                files, otherwise returns false
  852.      * @author Greg Beaver <cellog@php.net>
  853.      * @uses dirList
  854.      * @uses removeNonMatches
  855.      */
  856.     function getAllFiles($file)
  857.     {
  858.         $path realpath(dirname($file));
  859.         $file basename($file);
  860.         // any wildcards?
  861.         if (is_numeric(strpos($file,'?')) || is_numeric(strpos($file,'*')))
  862.         {
  863.             $files $this->dirList($path);
  864.             $a $this->removeNonMatches($files,$file);
  865.             return $a;
  866.         }
  867.         return false;
  868.     }
  869. }
  870.  
  871. /**#@+
  872.  * Sorting functions for the file list
  873.  * @param string
  874.  * @param string
  875.  */
  876. function Ioinc_sortfiles($a$b)
  877. {
  878.     return strnatcasecmp($a['file'],$b['file']);
  879. }
  880.  
  881. function Ioinc_mystrucsort($a$b)
  882. {
  883.     if (is_numeric($a&& is_string($b)) return 1;
  884.     if (is_numeric($b&& is_string($a)) return -1;
  885.     if (is_numeric($a&& is_numeric($b))
  886.     {
  887.         if ($a $breturn 1;
  888.         if ($a $breturn -1;
  889.         if ($a == $breturn 0;
  890.     }
  891.     return strnatcasecmp($a,$b);
  892. }
  893. /**#@-*/
  894.  
  895. /**
  896.  * Recursively add all the subdirectories of $contents to $dir without erasing anything in
  897.  * $dir
  898.  * @param array 
  899.  * @param array 
  900.  * @return array processed $dir
  901.  */
  902. function set_dir($dir,$contents)
  903. {
  904.     while(list($one,$twoeach($contents))
  905.     {
  906.         if (isset($dir[$one]))
  907.         {
  908.             $dir[$oneset_dir($dir[$one],$contents[$one]);
  909.         else $dir[$one$two;
  910.     }
  911.     return $dir;
  912. }
  913.  
  914. /**
  915.  * Recursively move contents of $struc into associative array
  916.  *
  917.  * The contents of $struc have many indexes like 'dir/subdir/subdir2'.
  918.  * This function converts them to
  919.  * array('dir' => array('subdir' => array('subdir2')))
  920.  * @param array struc is array('dir' => array of files in dir,'dir/subdir' => array of files in dir/subdir,...)
  921.  * @param array array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2')
  922.  * @return array same as struc but with array('dir' => array(file1,file2,'subdir' => array(file1,...)))
  923.  */
  924. function setup_dirs($struc,$dir,$contents)
  925. {
  926.     if (!count($dir))
  927.     {
  928.         foreach($contents as $dir => $files)
  929.         {
  930.             if (is_string($dir))
  931.             {
  932.                 if (strpos($dir,'/'))
  933.                 {
  934.                     $test = true;
  935.                     $a $contents[$dir];
  936.                     unset($contents[$dir]);
  937.                     $b explode('/',$dir);
  938.                     $c array_shift($b);
  939.                     if (isset($contents[$c]))
  940.                     {
  941.                         $contents[$cset_dir($contents[$c],setup_dirs(array(),$b,$a));
  942.                     else $contents[$csetup_dirs(array(),$b,$a);
  943.                 }
  944.             }
  945.         }
  946.         return $contents;
  947.     }
  948.     $me array_shift($dir);
  949.     if (!isset($struc[$me])) $struc[$me= array();
  950.     $struc[$mesetup_dirs($struc[$me],$dir,$contents);
  951.     return $struc;
  952. }
  953.  
  954. if (!function_exists('get_include_path')) {
  955. function get_include_path()
  956. {
  957.     return ini_get('include_path');
  958. }
  959. }
  960. ?>

Documentation generated on Mon, 11 Mar 2019 15:08:14 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.