Code Coverage for /home/user/workspace/all/Pyrus/src/Pyrus/PackageFile/v2.php in Registry/Sqlite3/install/test.phpt

Coverage: 11%

Aggregate Code Coverage for all tests

       1           : <?php
       2           : /**
       3           :  * PEAR_PackageFile_v2, package.xml version 2.1
       4           :  *
       5           :  * PHP version 5
       6           :  *
       7           :  * @category  PEAR2
       8           :  * @package   PEAR2_Pyrus
       9           :  * @author    Greg Beaver <cellog@php.net>
      10           :  * @copyright 2008 The PEAR Group
      11           :  * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
      12           :  * @version   SVN: $Id$
      13           :  * @link      http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/
      14           :  */
      15           : 
      16           : /**
      17           :  * File representing a package.xml file version 2.1
      18           :  *
      19           :  * @category  PEAR2
      20           :  * @package   PEAR2_Pyrus
      21           :  * @author    Greg Beaver <cellog@php.net>
      22           :  * @copyright 2008 The PEAR Group
      23           :  * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
      24           :  * @link      http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/
      25           :  */
      26           : class PEAR2_Pyrus_PackageFile_v2
      27         1 : {
      28           :     public $rootAttributes = array(
      29           :                                  'version' => '2.1',
      30           :                                  'xmlns' => 'http://pear.php.net/dtd/package-2.1',
      31           :                                  'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
      32           :                                  'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
      33           :                                  'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
      34           :      http://pear.php.net/dtd/tasks-1.0.xsd
      35           :      http://pear.php.net/dtd/package-2.1
      36           :      http://pear.php.net/dtd/package-2.1.xsd',
      37           :                              );
      38           :     /**
      39           :      * Parsed package information
      40           :      *
      41           :      * For created-from-scratch packagefiles, set some basic information needed.
      42           :      * @var array
      43           :      * @access private
      44           :      */
      45           :     protected $packageInfo = array('attribs' => array(
      46           :         'version' => '2.1',
      47           :         'xmlns' => 'http://pear.php.net/dtd/package-2.1',
      48           :         'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
      49           :         'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
      50           :         'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
      51           :      http://pear.php.net/dtd/tasks-1.0.xsd
      52           :      http://pear.php.net/dtd/package-2.1
      53           :      http://pear.php.net/dtd/package-2.1.xsd',
      54           :     ),
      55           :         'version' => array(
      56           :             'release' => '0.1.0',
      57           :             'api' => '0.1.0',
      58           :         ),
      59           :         'stability' => array(
      60           :             'release' => 'devel',
      61           :             'api' => 'alpha',
      62           :         ),
      63           :         'license' => array('attribs' => array('uri' => 'http://www.opensource.org/licenses/bsd-license.php'),
      64           :             '_content' => 'New BSD License',
      65           :         ),
      66           :         'dependencies' => array(
      67           :             'required' => array(
      68           :                 'php' => array('min' => '5.2.0'),
      69           :                 'pearinstaller' => array('min' => '2.0.0a1'),
      70           :             ),
      71           :         ),
      72           :         'phprelease' => array(),
      73           :     );
      74           : 
      75           :     /**
      76           :      * Set if the XML has been validated against schema
      77           :      *
      78           :      * @var unknown_type
      79           :      */
      80           :     private $_schemaValidated = false;
      81           : 
      82           :     protected $filelist = array();
      83           :     protected $baseinstalldirs = array();
      84           :     private $_dirtree = array();
      85           : 
      86           :     /**
      87           :      * path to package.xml or false if this is an abstract parsed-from-string xml
      88           :      * @var string|false
      89           :      * @access private
      90           :      */
      91           :     protected $_packageFile = false;
      92           : 
      93           :     /**
      94           :      * path to archive containing this package file, or false if this is a package.xml
      95           :      * or abstract parsed-from-string xml
      96           :      * @var string|false
      97           :      * @access private
      98           :      */
      99           :     protected $_archiveFile = false;
     100           : 
     101           :     /**
     102           :      * Optional Dependency group requested for installation
     103           :      * @var string
     104           :      * @access private
     105           :      */
     106           :     var $_requestedGroup = false;
     107           : 
     108           :     /**
     109           :      * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible
     110           :      */
     111           :     var $_tasksNs;
     112           : 
     113           :     function setPackagefile($file, $archive = false)
     114           :     {
     115         1 :         $this->_packageFile = $file;
     116         1 :         $this->_archiveFile = $archive ? $archive : $file;
     117         1 :     }
     118           : 
     119           :     function getPackageFile()
     120           :     {
     121           :         return $this->_packageFile;
     122           :     }
     123           : 
     124           :     function getArchiveFile()
     125           :     {
     126           :         return $this->_archiveFile;
     127           :     }
     128           : 
     129           :     /**
     130           :      * Directly set the array that defines this packagefile
     131           :      *
     132           :      * WARNING: no validation.  This should only be performed by internal methods
     133           :      * inside Pyrus or by inputting an array saved from an existing PEAR_PackageFile_v2
     134           :      * @param array
     135           :      */
     136           :     function fromArray($pinfo)
     137           :     {
     138         1 :         $this->_schemaValidated = true;
     139         1 :         $this->packageInfo = $pinfo['package'];
     140         1 :     }
     141           : 
     142           :     function hasFile($file)
     143           :     {
     144           :         return isset($this->filelist[$file]);
     145           :     }
     146           : 
     147           :     function getFile($file)
     148           :     {
     149           :         return $this->filelist[$file];
     150           :     }
     151           : 
     152           :     function setFilelist(array $list)
     153           :     {
     154         1 :         $this->filelist = $list;
     155         1 :     }
     156           : 
     157           :     function setBaseInstallDirs(array $list)
     158           :     {
     159         1 :         $this->baseinstalldirs = $list;
     160         1 :     }
     161           : 
     162           :     /**
     163           :      * @param string full path to file
     164           :      * @param string attribute name
     165           :      * @param string attribute value
     166           :      * @return bool success of operation
     167           :      */
     168           :     function setFileAttribute($filename, $attr, $value)
     169           :     {
     170           :         if (!in_array($attr, array('role', 'name', 'baseinstalldir', 'install-as'), true)) {
     171           :             // check to see if this is a task
     172           :             if ($this->isValidTask($attr)) {
     173           :                 if (!isset($this->filelist[$filename][$attr])) {
     174           :                     $this->filelist[$filename][$attr] = $value;
     175           :                 } else {
     176           :                     if (!isset($this->filelist[$filename][$attr][0])) {
     177           :                         $this->filelist[$filename][$attr] = array($this->filelist[$filename][$attr]);
     178           :                     }
     179           :                     $this->filelist[$filename][$attr][] = $value;
     180           :                 }
     181           :                 return;
     182           :             }
     183           :             throw new PEAR2_Pyrus_PackageFile_Exception(
     184           :                 'Cannot set invalid attribute ' . $attr . ' for file ' . $filename);
     185           :         }
     186           :         if (!isset($this->filelist[$filename])) {
     187           :             throw new PEAR2_Pyrus_PackageFile_Exception(
     188           :                 'Cannot set attribute ' . $attr . ' for non-existent file ' . $filename);
     189           :         }
     190           :         if ($attr == 'name') {
     191           :             throw new PEAR2_Pyrus_PackageFile_Exception('Cannot change name of file ' .
     192           :                 $filename);
     193           :         }
     194           :         $this->filelist[$filename]['attribs'][$attr] = $value;
     195           :     }
     196           : 
     197           :     function isValidTask($name)
     198           :     {
     199           :         $tasksns = $this->getTasksNs();
     200           :         if (strlen($name) <= strlen($tasksns) + 1) {
     201           :             return false;
     202           :         }
     203           :         if (substr($name, 0, strlen($tasksns)) === $tasksns) {
     204           :             if ($name[strlen($tasksns)] == ':') {
     205           :                 return true;
     206           :             }
     207           :         }
     208           :         return false;
     209           :     }
     210           : 
     211           :     /**
     212           :      * Used by uninstallation to set directory locations to erase
     213           :      * @param string $path
     214           :      */
     215           :     function setDirtree($path)
     216           :     {
     217           :         $this->_dirtree[$path] = true;
     218           :     }
     219           : 
     220           :     function getDirtree()
     221           :     {
     222           :         return $this->_dirtree;
     223           :     }
     224           : 
     225           :     /**
     226           :      * Determines whether this package claims it is compatible with the version of
     227           :      * the package that has a recommended version dependency
     228           :      * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package
     229           :      * @return boolean
     230           :      */
     231           :     function isCompatible($pf)
     232           :     {
     233           :         if (!isset($this->packageInfo['compatible'])) {
     234           :             return false;
     235           :         }
     236           :         if (!isset($this->packageInfo['channel'])) {
     237           :             return false;
     238           :         }
     239           :         $me = $pf->version['release'];
     240           :         $compatible = $this->packageInfo['compatible'];
     241           :         if (!isset($compatible[0])) {
     242           :             $compatible = array($compatible);
     243           :         }
     244           :         $found = false;
     245           :         foreach ($compatible as $info) {
     246           :             if (strtolower($info['name']) == strtolower($pf->package)) {
     247           :                 if (strtolower($info['channel']) == strtolower($pf->channel)) {
     248           :                     $found = true;
     249           :                     break;
     250           :                 }
     251           :             }
     252           :         }
     253           :         if (!$found) {
     254           :             return false;
     255           :         }
     256           :         if (isset($info['exclude'])) {
     257           :             if (!isset($info['exclude'][0])) {
     258           :                 $info['exclude'] = array($info['exclude']);
     259           :             }
     260           :             foreach ($info['exclude'] as $exclude) {
     261           :                 if (version_compare($me, $exclude, '==')) {
     262           :                     return false;
     263           :                 }
     264           :             }
     265           :         }
     266           :         if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) {
     267           :             return true;
     268           :         }
     269           :         return false;
     270           :     }
     271           : 
     272           :     function isSubpackageOf(PEAR2_Pyrus_PackageFile_v2 $p)
     273           :     {
     274           :         return $p->isSubpackage($this);
     275           :     }
     276           : 
     277           :     /**
     278           :      * Determines whether the passed in package is a subpackage of this package.
     279           :      *
     280           :      * No version checking is done, only name verification.
     281           :      * @return bool
     282           :      */
     283           :     function isSubpackage(PEAR2_Pyrus_PackageFile_v2 $p)
     284           :     {
     285           :         $sub = array();
     286           :         if (isset($this->packageInfo['dependencies']['required']['subpackage'])) {
     287           :             $sub = $this->packageInfo['dependencies']['required']['subpackage'];
     288           :             if (!isset($sub[0])) {
     289           :                 $sub = array($sub);
     290           :             }
     291           :         }
     292           :         if (isset($this->packageInfo['dependencies']['optional']['subpackage'])) {
     293           :             $sub1 = $this->packageInfo['dependencies']['optional']['subpackage'];
     294           :             if (!isset($sub1[0])) {
     295           :                 $sub1 = array($sub1);
     296           :             }
     297           :             $sub = array_merge($sub, $sub1);
     298           :         }
     299           :         if (isset($this->packageInfo['dependencies']['group'])) {
     300           :             $group = $this->packageInfo['dependencies']['group'];
     301           :             if (!isset($group[0])) {
     302           :                 $group = array($group);
     303           :             }
     304           :             foreach ($group as $deps) {
     305           :                 if (isset($deps['subpackage'])) {
     306           :                     $sub2 = $deps['subpackage'];
     307           :                     if (!isset($sub2[0])) {
     308           :                         $sub2 = array($sub2);
     309           :                     }
     310           :                     $sub = array_merge($sub, $sub2);
     311           :                 }
     312           :             }
     313           :         }
     314           :         foreach ($sub as $dep) {
     315           :             if (strtolower($dep['name']) == strtolower($p->package)) {
     316           :                 if (isset($dep['channel'])) {
     317           :                     if (strtolower($dep['channel']) == strtolower($p->channel)) {
     318           :                         return true;
     319           :                     }
     320           :                 } else {
     321           :                     if ($dep['uri'] == $p->uri) {
     322           :                         return true;
     323           :                     }
     324           :                 }
     325           :             }
     326           :         }
     327           :         return false;
     328           :     }
     329           : 
     330           :     function dependsOn($package, $channel)
     331           :     {
     332           :         if (!($deps = $this->dependencies)) {
     333           :             return false;
     334           :         }
     335           :         foreach (array('package', 'subpackage') as $type) {
     336           :             foreach (array('required', 'optional') as $needed) {
     337           :                 if (isset($deps[$needed][$type])) {
     338           :                     if (!isset($deps[$needed][$type][0])) {
     339           :                         $deps[$needed][$type] = array($deps[$needed][$type]);
     340           :                     }
     341           :                     foreach ($deps[$needed][$type] as $dep) {
     342           :                         $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
     343           :                         if (strtolower($dep['name']) == strtolower($package) &&
     344           :                               $depchannel == $channel) {
     345           :                             return true;
     346           :                         }
     347           :                     }
     348           :                 }
     349           :             }
     350           :             if (isset($deps['group'])) {
     351           :                 if (!isset($deps['group'][0])) {
     352           :                     $dep['group'] = array($deps['group']);
     353           :                 }
     354           :                 foreach ($deps['group'] as $group) {
     355           :                     if (isset($group[$type])) {
     356           :                         if (!is_array($group[$type])) {
     357           :                             $group[$type] = array($group[$type]);
     358           :                         }
     359           :                         foreach ($group[$type] as $dep) {
     360           :                             $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
     361           :                             if (strtolower($dep['name']) == strtolower($package) &&
     362           :                                   $depchannel == $channel) {
     363           :                                 return true;
     364           :                             }
     365           :                         }
     366           :                     }
     367           :                 }
     368           :             }
     369           :         }
     370           :         return false;
     371           :     }
     372           : 
     373           :     /**
     374           :      * Get the contents of a dependency group
     375           :      * @param string
     376           :      * @return array|false
     377           :      */
     378           :     function getDependencyGroup($name)
     379           :     {
     380           :         $name = strtolower($name);
     381           :         if (!isset($this->packageInfo['dependencies']['group'])) {
     382           :             return false;
     383           :         }
     384           :         $groups = $this->packageInfo['dependencies']['group'];
     385           :         if (!isset($groups[0])) {
     386           :             $groups = array($groups);
     387           :         }
     388           :         foreach ($groups as $group) {
     389           :             if (strtolower($group['attribs']['name']) == $name) {
     390           :                 return $group;
     391           :             }
     392           :         }
     393           :         return false;
     394           :     }
     395           : 
     396           :     /**
     397           :      * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false
     398           :      */
     399           :     function getPackageType()
     400           :     {
     401         1 :         if (isset($this->packageInfo['phprelease'])) {
     402         1 :             return 'php';
     403           :         }
     404           :         if (isset($this->packageInfo['extsrcrelease'])) {
     405           :             return 'extsrc';
     406           :         }
     407           :         if (isset($this->packageInfo['extbinrelease'])) {
     408           :             return 'extbin';
     409           :         }
     410           :         if (isset($this->packageInfo['zendextsrcrelease'])) {
     411           :             return 'zendextsrc';
     412           :         }
     413           :         if (isset($this->packageInfo['zendextbinrelease'])) {
     414           :             return 'zendextbin';
     415           :         }
     416           :         if (isset($this->packageInfo['bundle'])) {
     417           :             return 'bundle';
     418           :         }
     419           :         return false;
     420           :     }
     421           : 
     422           :     function hasDeps()
     423           :     {
     424           :         return isset($this->packageInfo['dependencies']);
     425           :     }
     426           : 
     427           :     function getPackagexmlVersion()
     428           :     {
     429           :         if (isset($this->packageInfo['zendextsrcrelease'])) {
     430           :             return '2.1';
     431           :         }
     432           :         if (isset($this->packageInfo['zendextbinrelease'])) {
     433           :             return '2.1';
     434           :         }
     435           :         return '2.0';
     436           :     }
     437           : 
     438           :     /**
     439           :      * validate dependencies against the local registry, packages to be installed,
     440           :      * and environment (php version, OS, architecture, enabled extensions)
     441           :      *
     442           :      * @param array $toInstall an array of PEAR2_Pyrus_Package objects
     443           :      * @param PEAR2_MultiErrors $errs
     444           :      */
     445           :     function validateDependencies(array $toInstall, PEAR2_MultiErrors $errs)
     446           :     {
     447           :         $dep = new PEAR2_Pyrus_Dependency_Validator($this->packageInfo['name'],
     448           :             PEAR2_Pyrus_Validate::DOWNLOADING, $errs);
     449           :         $dep->validatePhpDependency($this->dependencies->required->php);
     450           :         $dep->validatePearinstallerDependency($this->dependencies->required->pearinstaller);
     451           :         foreach (array('required', 'optional') as $required) {
     452           :             foreach ($this->dependencies->$required->package as $d) {
     453           :                 $dep->validatePackageDependency($d, $required == 'required', $toInstall);
     454           :             }
     455           :             foreach ($this->dependencies->$required->subpackage as $d) {
     456           :                 $dep->validateSubpackageDependency($d, $required == 'required', $toInstall);
     457           :             }
     458           :             foreach ($this->dependencies->$required->extension as $d) {
     459           :                 $dep->validateExtensionDependency($d, $required == 'required');
     460           :             }
     461           :         }
     462           :         foreach ($this->dependencies->required->arch as $d) {
     463           :             $dep->validateArchDependency($d);
     464           :         }
     465           :         foreach ($this->dependencies->required->os as $d) {
     466           :             $dep->validateOsDependency($d);
     467           :         }
     468           :     }
     469           : 
     470           :     function validate($state = PEAR2_Pyrus_Validate::NORMAL)
     471           :     {
     472           :         if (!isset($this->packageInfo) || !is_array($this->packageInfo)) {
     473           :             return false;
     474           :         }
     475           :         $validator = new PEAR2_Pyrus_PackageFile_v2_Validator;
     476           :         return $validator->validate($this, $state);
     477           :     }
     478           : 
     479           :     function getTasksNs()
     480           :     {
     481           :         if (!isset($this->_tasksNs)) {
     482           :             if (isset($this->packageInfo['attribs'])) {
     483           :                 foreach ($this->packageInfo['attribs'] as $name => $value) {
     484           :                     if ($value == 'http://pear.php.net/dtd/tasks-1.0') {
     485           :                         $this->_tasksNs = str_replace('xmlns:', '', $name);
     486           :                         break;
     487           :                     }
     488           :                 }
     489           :             }
     490           :         }
     491           :         return $this->_tasksNs;
     492           :     }
     493           : 
     494           :     /**
     495           :      * Determine whether a task name is a valid task.  Custom tasks may be defined
     496           :      * using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task>
     497           :      *
     498           :      * Note that this method will auto-load the task class file and test for the existence
     499           :      * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class
     500           :      * PEAR_Task_mycustom_task
     501           :      * @param string
     502           :      * @return boolean
     503           :      */
     504           :     function getTask($task)
     505           :     {
     506           :         $this->getTasksNs();
     507           :         // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace
     508           :         $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task);
     509           :         $task = str_replace(' ', '/', ucwords($task));
     510           :         $test = str_replace('/', '_', $task);
     511           :         if (class_exists("PEAR2_Pyrus_Task_$test", true)) {
     512           :             return "PEAR2_Pyrus_Task_$test";
     513           :         }
     514           :         return false;
     515           :     }
     516           : 
     517           :     function getBaseInstallDir($file)
     518           :     {
     519         1 :         $file = dirname($file);
     520         1 :         while ($file !== '.' && $file != '/') {
     521         1 :             if (isset($this->baseinstalldirs[$file])) {
     522         1 :                 return $this->baseinstalldirs[$file];
     523           :             }
     524         1 :             $file = dirname($file);
     525         1 :         }
     526         1 :         if (isset($this->baseinstalldirs[''])) {
     527           :             return $this->baseinstalldirs[''];
     528           :         }
     529         1 :         return false;
     530           :     }
     531           : 
     532           :     function __get($var)
     533           :     {
     534           :         switch ($var) {
     535         1 :             case 'bundledpackage' :
     536           :                 if ($this->getPackageType() !== 'bundle') {
     537           :                     return false;
     538           :                 }
     539           :                 if (!isset($this->packageInfo['contents'])) {
     540           :                     $this->packageInfo['contents'] = array();
     541           :                 }
     542           :                 if (!isset($this->packageInfo['contents']['bundledpackage'])) {
     543           :                     $this->packageInfo['contents']['bundledpackage'] = array();
     544           :                 }
     545           :                 return new ArrayObject($this->packageInfo['contents']['bundledpackage'],
     546           :                     ArrayObject::ARRAY_AS_PROPS);
     547         1 :             case 'packagefile' :
     548           :                 return $this->_packageFile;
     549         1 :             case 'filepath' :
     550           :                 return dirname($this->_packageFile);
     551         1 :             case 'contents' :
     552           :                 // allows stuff like:
     553           :                 // foreach ($pf->contents as $file) {
     554           :                 //     echo $file->name;
     555           :                 //     $file->installed_as = 'hi';
     556           :                 // }
     557           :                 return new PEAR2_Pyrus_PackageFile_v2Iterator_File(
     558           :                         new PEAR2_Pyrus_PackageFile_v2Iterator_FileAttribsFilter(
     559           :                         new PEAR2_Pyrus_PackageFile_v2Iterator_FileContents(
     560           :                             $this->packageInfo['contents'], 'contents', $this)),
     561           :                             RecursiveIteratorIterator::LEAVES_ONLY);
     562         1 :             case 'installcontents' :
     563         1 :                 PEAR2_Pyrus_PackageFile_v2Iterator_FileInstallationFilter::setParent($this);
     564         1 :                 return new PEAR2_Pyrus_PackageFile_v2Iterator_FileInstallationFilter(
     565         1 :                         new ArrayIterator(
     566         1 :                             $this->filelist));
     567         1 :             case 'packagingcontents' :
     568           :                 PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator::setParent($this);
     569           :                 return new PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator(
     570           :                             $this->filelist);
     571         1 :             case 'installGroup' :
     572         1 :                 $rel = $this->getPackageType();
     573         1 :                 if ($rel != 'bundle') $rel .= 'release';
     574         1 :                 $ret = $this->packageInfo[$rel];
     575         1 :                 if (!isset($ret[0])) {
     576         1 :                     return array($ret);
     577           :                 }
     578           :                 return $ret;
     579         1 :             case 'channel' :
     580         1 :                 if (isset($this->packageInfo['uri'])) {
     581           :                     return '__uri';
     582           :                 }
     583         1 :                 break;
     584         1 :             case 'state' :
     585           :                 if (!isset($this->packageInfo['stability']) ||
     586           :                       !isset($this->packageInfo['stability']['release'])) {
     587           :                     return false;
     588           :                 }
     589           :                 return $this->packageInfo['stability']['release'];
     590         1 :             case 'api-version' :
     591           :                 if (!isset($this->packageInfo['version']) ||
     592           :                       !isset($this->packageInfo['version']['api'])) {
     593           :                     return false;
     594           :                 }
     595           :                 return $this->packageInfo['version']['api'];
     596         1 :             case 'release-version' :
     597           :                 if (!isset($this->packageInfo['version']) ||
     598           :                       !isset($this->packageInfo['version']['release'])) {
     599           :                     return false;
     600           :                 }
     601           :                 return $this->packageInfo['version']['release'];
     602         1 :             case 'api-state' :
     603           :                 if (!isset($this->packageInfo['stability']) ||
     604           :                       !isset($this->packageInfo['stability']['api'])) {
     605           :                     return false;
     606           :                 }
     607           :                 return $this->packageInfo['stability']['api'];
     608         1 :             case 'allmaintainers' :
     609         1 :                 $leads = (array) $this->tag('lead');
     610         1 :                 if ($leads && !isset($leads[0])) {
     611           :                     $leads = array($leads);
     612           :                 }
     613         1 :                 $developers = (array) $this->tag('developer');
     614         1 :                 if ($developers && !isset($developers[0])) {
     615           :                     $developers = array($developers);
     616           :                 }
     617         1 :                 $helpers = (array) $this->tag('helper');
     618         1 :                 if ($helpers && !isset($helpers[0])) {
     619           :                     $helpers = array($helpers);
     620           :                 }
     621         1 :                 $contributors = (array) $this->tag('contributor');
     622         1 :                 if ($contributors && !isset($contributors[0])) {
     623           :                     $contributors = array($contributors);
     624           :                 }
     625           :                 return array(
     626         1 :                     'lead' => $leads,
     627         1 :                     'developer' => $developers,
     628         1 :                     'helper' => $helpers,
     629           :                     'contributor' => $contributors
     630         1 :                 );
     631         1 :             case 'releases' :
     632           :                 $type = $this->getPackageType();
     633           :                 if ($type != 'bundle') {
     634           :                     $type .= 'release';
     635           :                 }
     636           :                 if ($type && isset($this->packageInfo[$type])) {
     637           :                     return $this->packageInfo[$type];
     638           :                 }
     639           :                 return false;
     640         1 :             case 'sourcepackage' :
     641           :                 if (isset($this->packageInfo['extbinrelease']) ||
     642           :                       isset($this->packageInfo['zendextbinrelease'])) {
     643           :                     return array('channel' => $this->packageInfo['srcchannel'],
     644           :                                  'package' => $this->packageInfo['srcpackage']);
     645           :                 }
     646           :                 return false;
     647         1 :             case 'license' :
     648         1 :                 if (!isset($this->packageInfo['license'])) {
     649           :                     $this->packageInfo['license'] = array();
     650           :                 }
     651         1 :                 return new PEAR2_Pyrus_PackageFile_v2_License($this->packageInfo['license']);
     652         1 :             case 'files' :
     653           :                 return new PEAR2_Pyrus_PackageFile_v2_Files($this->filelist);
     654         1 :             case 'maintainer' :
     655           :                 return new PEAR2_Pyrus_PackageFile_v2_Developer($this->packageInfo);
     656         1 :             case 'rawdeps' :
     657           :                 return isset($this->packageInfo['dependencies']) ?
     658           :                     $this->packageInfo['dependencies'] : false;
     659         1 :             case 'dependencies' :
     660         1 :                 if (!isset($this->packageInfo['dependencies'])) {
     661           :                     $this->packageInfo['dependencies'] = array();
     662           :                 }
     663         1 :                 return new PEAR2_Pyrus_PackageFile_v2_Dependencies(
     664         1 :                     $this->packageInfo['dependencies'],
     665         1 :                     $this->packageInfo['dependencies']);
     666         1 :             case 'release' :
     667           :                 $t = $this->getPackageType();
     668           :                 if (!$t) {
     669           :                     $this->type = 'php';
     670           :                     $t = 'phprelease';
     671           :                 } else {
     672           :                     if ($t != 'bundle') {
     673           :                         $t .= 'release';
     674           :                     }
     675           :                 }
     676           :                 if (!isset($this->packageInfo[$t]) || !is_array($this->packageInfo[$t])) {
     677           :                     $this->packageInfo[$t] = array();
     678           :                 }
     679           :                 return new PEAR2_Pyrus_PackageFile_v2_Release(
     680           :                     $this, $this->packageInfo[$t], $this->filelist);
     681         1 :             case 'compatible' :
     682           :                 return new PEAR2_Pyrus_PackageFile_v2_Compatible($this->packageInfo);
     683         1 :             case 'schemaOK' :
     684           :                 return $this->_schemaValidated;
     685           :         }
     686         1 :         return $this->tag($var);
     687           :     }
     688           : 
     689           :     function __set($var, $value)
     690           :     {
     691           :         if ($var === 'license') {
     692           :             if ($value instanceof PEAR2_Pyrus_PackageFile_v2_License) {
     693           :                 $this->packageInfo['license'] = $value->getArray();
     694           :                 $value->link($this->packageInfo['license']);
     695           :             } elseif (!is_array($value)) {
     696           :                 $licensemap =
     697           :                     array(
     698           :                         'php' => 'http://www.php.net/license',
     699           :                         'php license' => 'http://www.php.net/license',
     700           :                         'lgpl' => 'http://www.gnu.org/copyleft/lesser.html',
     701           :                         'bsd' => 'http://www.opensource.org/licenses/bsd-license.php',
     702           :                         'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php',
     703           :                         'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php',
     704           :                         'mit' => 'http://www.opensource.org/licenses/mit-license.php',
     705           :                         'gpl' => 'http://www.gnu.org/copyleft/gpl.html',
     706           :                         'apache' => 'http://www.opensource.org/licenses/apache2.0.php'
     707           :                     );
     708           :                 if (isset($licensemap[strtolower($value)])) {
     709           :                     $this->packageInfo['license'] = array(
     710           :                         'attribs' => array('uri' =>
     711           :                             $licensemap[strtolower($value)]),
     712           :                         '_content' => $value
     713           :                         );
     714           :                 } else {
     715           :                     // don't use bogus uri
     716           :                     $arr['license'] = $value;
     717           :                 }
     718           :             } else {
     719           :                 $this->packageInfo['license'] = $value;
     720           :             }
     721           :             return;
     722           :         }
     723           :         if ($var === 'type') {
     724           :             if (!is_string($value)) {
     725           :                 throw new PEAR2_Pyrus_PackageFile_Exception('package.xml type must be a ' .
     726           :                 'string, was a ' . gettype($value));
     727           :             }
     728           :             if ($value != 'bundle') {
     729           :                 $value .= 'release';
     730           :             }
     731           :             if (in_array($value, $a = array('phprelease', 'extsrcrelease', 'extbinrelease',
     732           :                   'zendextsrcrelease', 'zendextbinrelease', 'bundle'))) {
     733           :                 foreach ($a as $type) {
     734           :                     if ($value == $type) {
     735           :                         if (!isset($this->packageInfo[$type])) {
     736           :                             $this->packageInfo[$type] = array();
     737           :                         }
     738           :                         continue;
     739           :                     }
     740           :                     if (isset($this->packageInfo[$type])) {
     741           :                         unset($this->packageInfo[$type]);
     742           :                     }
     743           :                 }
     744           :             }
     745           :             return;
     746           :         }
     747           :         if ($var === 'dependencies' && $value === null) {
     748           :             $this->packageInfo['dependencies'] = array();
     749           :             return;
     750           :         }
     751           :         if ($var === 'rawdependencies' && is_array($value)) {
     752           :             $this->packageInfo['dependencies'] = $value;
     753           :             return;
     754           :         }
     755           :         if ($var === 'rawrelease' && is_array($value)) {
     756           :             $t = $this->getPackageType();
     757           :             if ($t != 'bundle') {
     758           :                 $t .= 'release';
     759           :             }
     760           :             $this->packageInfo[$t] = $value;
     761           :             return;
     762           :         }
     763           :         if ($var === 'rawcompatible' && is_array($value)) {
     764           :             $this->packageInfo['compatible'] = $value;
     765           :             return;
     766           :         }
     767           :         if ($var === 'rawstability' && is_string($value)) {
     768           :             $this->packageInfo['stability'] = array('release' => $value, 'api' => $value);
     769           :             return;
     770           :         }
     771           :         if ($var === 'packagerversion' && is_string($value)) {
     772           :             $this->packageInfo['attribs']['packagerversion'] = $value;
     773           :             return;
     774           :         }
     775           :         if ($var === 'release' && $value === null) {
     776           :             $type = $this->getPackageType();
     777           :             if ($type != 'bundle') {
     778           :                 $type .= 'release';
     779           :             }
     780           :             $this->packageInfo[$type] = array();
     781           :             return;
     782           :         }
     783           :         if ($value instanceof ArrayObject) {
     784           :             $value = $value->getArrayCopy();
     785           :         }
     786           :         if ($var === 'release' && $value === null) {
     787           :             $rel = $this->getPackageType();
     788           :             if ($rel) {
     789           :                 if (isset($this->packageInfo[$rel . 'release'])) {
     790           :                     $rel .= 'release';
     791           :                 }
     792           :                 $this->packageInfo[$rel] = array();
     793           :             }
     794           :         }
     795           :         if (in_array($var, array('attribs', 'lead',
     796           :                 'developer', 'contributor', 'helper', 'version',
     797           :                 'stability', 'license', 'contents', 'compatible',
     798           :                 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
     799           :                 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
     800           :                 'extbinrelease', 'bundle', 'changelog'), true)) {
     801           :             throw new PEAR2_Pyrus_PackageFile_Exception('Cannot set ' . $var . ' directly');
     802           :         }
     803           :         if (!in_array($var, array('name', 'channel', 'uri', 'extends', 'summary',
     804           :                 'description', 'date', 'time','notes'), true)) {
     805           :             return;
     806           :         }
     807           :         if ($var === 'uri') {
     808           :             if (isset($this->packageInfo['channel'])) {
     809           :                 unset($this->packageInfo['channel']);
     810           :             }
     811           :         }
     812           :         if ($var == 'api-version') {
     813           :             $this->packageInfo['version']['api'] = $value;
     814           :             return;
     815           :         }
     816           :         if ($var == 'release-version') {
     817           :             $this->packageInfo['version']['release'] = $value;
     818           :         }
     819           :         $this->packageInfo[$var] = $value;
     820         1 :     }
     821         1 : 
     822         1 :     /**
     823         1 :      * Return the contents of a tag
     824           :      * @param string $name
     825           :      */
     826         1 :     protected function tag($name)
     827         1 :     {
     828           :         if (!isset($this->packageInfo[$name]) && in_array($name, array('version',
     829         1 :                 'stability', 'license', 'compatible',
     830         1 :                 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
     831           :                 ), true)) {
     832         1 :             $this->packageInfo[$name] = array();
     833           :         }
     834           :         if (!isset($this->packageInfo[$name])) {
     835           :             return false;
     836           :         }
     837           :         if (is_array($this->packageInfo[$name])) {
     838           :             return new ArrayObject($this->packageInfo[$name], ArrayObject::ARRAY_AS_PROPS);
     839           :         }
     840           :         return $this->packageInfo[$name];
     841           :     }
     842           : 
     843           :     /**
     844           :      * Update the changelog based on the current information
     845           :      */
     846           :     function updateChangelog()
     847           :     {
     848           :         $license = $this->license;
     849           :         if ($license instanceof ArrayObject) {
     850           :             $license = $license->getArrayCopy();
     851           :         }
     852           :         $info = array(
     853           :             'version' => array(
     854           :                 'release' => $this->version['release'],
     855           :                 'api' => $this->version['api']
     856           :             ),
     857           :             'stability' => array(
     858           :                 'release' => $this->stability['release'],
     859           :                 'api' => $this->stability['api']
     860           :             ),
     861           :             'date' => $this->date,
     862           :             'license' => $license,
     863           :             'notes' => $this->notes,
     864           :         );
     865           : 
     866           :         if (!is_array($this->packageInfo['changelog'])) {
     867           :             $this->packageInfo['changelog'] = $info;
     868           :         } elseif (!isset($this->packageInfo['changelog'][0])) {
     869           :             $this->packageInfo['changelog'] = array($info, $this->packageInfo['changelog']);
     870           :         } else {
     871           :             array_unshift($this->packageInfo['changelog'], $info);
     872           :         }
     873           :     }
     874           : 
     875           :     function __toString()
     876           :     {
     877           :         $this->packageInfo['attribs'] = $this->rootAttributes;
     878           :         $this->packageInfo['date'] = date('Y-m-d');
     879           :         $this->packageInfo['time'] = date('H:i:s');
     880           :         $arr = $this->toArray();
     881           :         return (string) new PEAR2_Pyrus_XMLWriter($arr);
     882           :     }
     883           : 
     884           :     public static function sortInstallAs($a, $b)
     885           :     {
     886           :         return strnatcasecmp($a['attribs']['name'], $b['attribs']['name']);
     887           :     }
     888           : 
     889           :     function toArray($forpackaging = false)
     890           :     {
     891           :         $this->packageInfo['contents'] = array(
     892           :             'dir' => array(
     893           :                 'attribs' => array('name' => '/'),
     894           :                 'file' => array()
     895           :             ));
     896           :         uksort($this->filelist, 'strnatcasecmp');
     897           :         $a = array_reverse($this->filelist, 1);
     898           :         if ($forpackaging) {
     899           :             PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator::setParent($this);
     900           :             $a = new PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator($a);
     901           :         }
     902           :         $temp = array();
     903           :         foreach ($a as $name => $stuff) {
     904           :             if ($forpackaging) {
     905           :                 // map old to new name
     906           :                 $temp[$stuff['attribs']['name']] = $name;
     907           :             }
     908           :             // if we are packaging, $name is the new name
     909           :             $stuff['attribs']['name'] = $name;
     910           :             $this->packageInfo['contents']['dir']['file'][] = $stuff;
     911           :         }
     912           :         if (count($this->packageInfo['contents']['dir']['file']) == 1) {
     913           :             $this->packageInfo['contents']['dir']['file'] =
     914           :                 $this->packageInfo['contents']['dir']['file'][0];
     915           :         }
     916           :         $arr = array();
     917           :         foreach (array('attribs', 'name', 'channel', 'uri', 'extends', 'summary',
     918           :                 'description', 'lead',
     919           :                 'developer', 'contributor', 'helper', 'date', 'time', 'version',
     920           :                 'stability', 'license', 'notes', 'contents', 'compatible',
     921           :                 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
     922           :                 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
     923           :                 'extbinrelease', 'bundle', 'changelog') as $index)
     924           :         {
     925           :             if (!isset($this->packageInfo[$index])) {
     926           :                 continue;
     927           :             }
     928           :             $arr[$index] = $this->packageInfo[$index];
     929           :         }
     930           :         if ($forpackaging) {
     931           :             // process releases
     932           :             $reltag = $this->getPackageType();
     933           :             if ($reltag != 'bundle') {
     934           :                 $reltag .= 'release';
     935           :                 if (is_array($arr[$reltag])) {
     936           :                     if (!isset($arr[$reltag][0])) {
     937           :                         $arr[$reltag] = array($arr[$reltag]);
     938           :                     }
     939           :                     foreach ($arr[$reltag] as $i => $inf) {
     940           :                         if (!isset($inf['filelist'])) {
     941           :                             continue;
     942           :                         }
     943           :                         $inf = $inf['filelist'];
     944           :                         if (isset($inf['install'])) {
     945           :                             if (!isset($inf['install'][0])) {
     946           :                                 if (isset($temp[$inf['install']['attribs']['name']])) {
     947           :                                     $arr[$reltag][$i]['filelist']['install']['attribs']
     948           :                                                        ['name'] =
     949           :                                         $temp[$inf['install']['attribs']['name']];
     950           :                                 }
     951           :                             } else {
     952           :                                 foreach ($inf['install'] as $j => $morinf) {
     953           :                                     if (isset($temp[$morinf['attribs']['name']])) {
     954           :                                         $arr[$reltag][$i]['filelist']['install'][$j]
     955           :                                                            ['attribs']['name'] =
     956           :                                             $temp[$morinf['attribs']['name']];
     957           :                                     }
     958           :                                 }
     959           :                             }
     960           :                         }
     961           :                         if (isset($inf['ignore'])) {
     962           :                             if (!isset($inf['ignore'][0])) {
     963           :                                 if (isset($temp[$inf['ignore']['attribs']['name']])) {
     964           :                                     $arr[$reltag][$i]['filelist']['ignore']
     965           :                                                        ['attribs']['name'] =
     966           :                                         $temp[$inf['ignore']['attribs']['name']];
     967           :                                 }
     968           :                             } else {
     969           :                                 foreach ($inf['ignore'] as $j => $morinf) {
     970           :                                     if (isset($temp[$morinf['attribs']['name']])) {
     971           :                                         $arr[$reltag][$i]['filelist']['ignore'][$j]
     972           :                                                            ['attribs']['name'] =
     973           :                                             $temp[$morinf['attribs']['name']];
     974           :                                     }
     975           :                                 }
     976           :                             }
     977           :                         }
     978           :                     }
     979           :                     if (count($arr[$reltag]) == 1) {
     980           :                         $arr[$reltag] = $arr[$reltag][0];
     981           :                     }
     982           :                 }
     983           :             }
     984           :         }
     985           :         $reltag = $this->getPackageType();
     986           :         if ($reltag != 'bundle') {
     987           :             $reltag .= 'release';
     988           :             if (!is_array($arr[$reltag])) {
     989           :                 // do nothing
     990           :             } elseif (!isset($arr[$reltag][0])) {
     991           :                 if (isset($arr[$reltag]['install']) && isset($arr[$reltag]['install'][0])) {
     992           :                     usort($arr[$reltag]['install'], array('PEAR2_Pyrus_PackageFile_v2',
     993           :                         'sortInstallAs'));
     994           :                 }
     995           :                 if (isset($arr[$reltag]['ignore']) && isset($arr[$reltag]['ignore'][0])) {
     996           :                     usort($arr[$reltag]['ignore'], array('PEAR2_Pyrus_PackageFile_v2',
     997           :                         'sortInstallAs'));
     998           :                 }
     999           :             } else {
    1000           :                 foreach ($arr[$reltag] as $i => &$contents) {
    1001           :                     if (isset($contents['install']) && isset($contents['install'][0])) {
    1002           :                         usort($contents['install'], array('PEAR2_Pyrus_PackageFile_v2',
    1003           :                             'sortInstallAs'));
    1004           :                     }
    1005           :                     if (isset($contents['ignore']) && isset($contents['ignore'][0])) {
    1006           :                         usort($contents['ignore'], array('PEAR2_Pyrus_PackageFile_v2',
    1007           :                             'sortInstallAs'));
    1008           :                     }
    1009           :                 }
    1010           :             }
    1011           :         }
    1012           :         if (isset($this->packageInfo['dependencies'])) {
    1013           :             if (isset($this->packageInfo['dependencies']['required'])) {
    1014           :                 $arr['dependencies']['required'] = array();
    1015           :                 foreach (array('php', 'pearinstaller', 'package', 'subpackage',
    1016           :                             'extension', 'os', 'arch') as $index) {
    1017           :                     if (!isset($this->packageInfo['dependencies']['required'][$index])) {
    1018           :                         continue;
    1019           :                     }
    1020           :                     $arr['dependencies']['required'][$index] =
    1021           :                         $this->packageInfo['dependencies']['required'][$index];
    1022           :                 }
    1023           :             }
    1024           :             if (isset($this->packageInfo['dependencies']['optional'])) {
    1025           :                 $arr['dependencies']['optional'] = array();
    1026           :                 foreach (array('package', 'subpackage', 'extension') as $index) {
    1027           :                     if (!isset($this->packageInfo['dependencies']['optional'][$index])) {
    1028           :                         continue;
    1029           :                     }
    1030           :                     $arr['dependencies']['optional'][$index] =
    1031           :                         $this->packageInfo['dependencies']['optional'][$index];
    1032           :                 }
    1033           :             }
    1034           :             if (isset($this->packageInfo['dependencies']['group'])) {
    1035           :                 if (isset($this->packageInfo['dependencies']['group'][0])) {
    1036           :                     foreach ($this->packageInfo['dependencies']['group'] as $i => $g) {
    1037           :                         $arr['dependencies']['group'][$i] = array();
    1038           :                         foreach (array('attribs', 'package', 'subpackage', 'extension') as $index) {
    1039           :                             if (!isset($g[$index])) {
    1040           :                                 continue;
    1041           :                             }
    1042           :                             $arr['dependencies']['group'][$i][$index] = $g[$index];
    1043           :                         }
    1044           :                     }
    1045           :                 } else {
    1046           :                     $a = $this->packageInfo['dependencies']['group'];
    1047           :                     $arr['dependencies']['group'] = array();
    1048           :                     foreach (array('attribs', 'package', 'subpackage', 'extension') as $index) {
    1049           :                         if (!isset($a[$index])) {
    1050           :                             continue;
    1051           :                         }
    1052         1 :                         $arr['dependencies']['group'][$index] = $a[$index];
    1053           :                     }
    1054           :                 }
    1055           :             }
    1056           :         }
    1057           :         return array('package' => $arr);
    1058           :     }
    1059           : }