Source for file v2.php
Documentation is available at v2.php
* PEAR_PackageFile_v2, package.xml version 2.0
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: v2.php 313023 2011-07-06 19:17:11Z dufuz $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
require_once 'PEAR/ErrorStack.php';
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.9.4
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* Parsed package information
var $_packageInfo = array ();
* path to package .tgz or false if this is a local/extracted package.xml
* path to package .xml or false if this is an abstract parsed-from-string xml
* This is used by file analysis routines to log progress information
* This is set to the highest validation level that has been validated
* If the package.xml is invalid or unknown, this is set to 0. If
* normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If
* downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING
* or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation
* "caching" to occur, which is particularly important for package validation, so
* that PHP files are not validated twice
* True if the filelist has been validated
var $_filesValid = false;
* Optional Dependency group requested for installation
var $_requestedGroup = false;
* Namespace prefix used for tasks in this package.xml - use tasks: whenever possible
* Determines whether this packagefile was initialized only with partial package info
* If this package file was constructed via parsing REST, it will only contain
* @var PEAR_PackageFile_v2_Validator
* The constructor merely sets up the private error stack
* To make unit-testing easier
* @return PEAR_Downloader
* To make unit-testing easier
* @param array package name as returned from {@link PEAR_Registry::parsePackageName()}
* @param int PEAR_VALIDATE_* constant
* @return PEAR_Dependency2
require_once 'PEAR/Dependency2.php';
return isset ($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] :
* Installation of source package has failed, attempt to download and install the
* binary version of this package.
if (!is_array($installer->getInstallPackages ())) {
foreach ($installer->getInstallPackages () as $p) {
if ($p->isExtension ($this->_packageInfo['providesextension'])) {
if ($p->getPackageType () != 'extsrc' && $p->getPackageType () != 'zendextsrc') {
return $a; // the user probably downloaded it separately
if (isset ($this->_packageInfo[$releasetype]['binarypackage'])) {
$installer->log (0 , 'Attempting to download binary version of extension "' .
$this->_packageInfo['providesextension'] . '"');
$params = $this->_packageInfo[$releasetype]['binarypackage'];
if (!is_array($params) || !isset ($params[0 ])) {
$params = array ($params);
if (isset ($this->_packageInfo['channel'])) {
foreach ($params as $i => $param) {
$params[$i] = array ('channel' => $this->_packageInfo['channel'],
'package' => $param, 'version' => $this->getVersion());
$verbose = $dl->config ->get ('verbose');
$dl->config ->set ('verbose', -1 );
foreach ($params as $param) {
$ret = $dl->download (array ($param));
$dl->config ->set ('verbose', $verbose);
$pf = $ret[0 ]->getPackageFile ();
$err = $installer->install ($ret[0 ]);
$this->_packageInfo['#binarypackage'] = $ret[0 ]->getPackage ();
// "install" self, so all dependencies will work transparently
$installer->log (0 , 'Download and install of binary extension "' .
array ('channel' => $pf->getChannel (),
'package' => $pf->getPackage ()), true ) . '" successful');
$a = array ($ret[0 ], $err);
$installer->log (0 , 'Download and install of binary extension "' .
array ('channel' => $pf->getChannel (),
'package' => $pf->getPackage ()), true ) . '" failed');
* @return string|falseExtension name
array ('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
if (isset ($this->_packageInfo['providesextension'])) {
return $this->_packageInfo['providesextension'];
* @param string Extension name
array ('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
return $this->_packageInfo['providesextension'] == $extension;
* Tests whether every part of the package.xml 1.0 is represented in
* @param PEAR_PackageFile_v1
$this->_stack->getErrors (true );
$this->_differentPackage ($pf1->getPackage ());
$this->_differentVersion ($pf1->getVersion ());
$this->_differentSummary ($pf1->getSummary ());
$this->_differentDescription ($pf1->getDescription ());
if ($pf1->getState () != $this->getState()) {
$this->_differentState ($pf1->getState ());
$this->_differentNotes ($pf1->getNotes ());
$yourmaintainers = $pf1->getMaintainers ();
for ($i1 = 0; $i1 < count($yourmaintainers); $i1++ ) {
for ($i2 = 0; $i2 < count($mymaintainers); $i2++ ) {
if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) {
if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) {
$this->_differentRole ($mymaintainers[$i2]['handle'],
$yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']);
if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) {
$this->_differentEmail ($mymaintainers[$i2]['handle'],
$yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']);
if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) {
$this->_differentName ($mymaintainers[$i2]['handle'],
$yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']);
unset ($mymaintainers[$i2]);
unset ($yourmaintainers[$i1]);
$this->_unmatchedMaintainers ($mymaintainers, $yourmaintainers);
foreach ($pf1->getFilelist () as $file => $atts) {
if (!isset ($filelist[$file])) {
$this->_missingFile ($file);
function _differentPackage ($package)
$this->_stack->push (__FUNCTION__ , 'error', array ('package' => $package,
'package.xml 1.0 package "%package%" does not match "%self%"');
function _differentVersion ($version)
$this->_stack->push (__FUNCTION__ , 'error', array ('version' => $version,
'package.xml 1.0 version "%version%" does not match "%self%"');
function _differentState ($state)
$this->_stack->push (__FUNCTION__ , 'error', array ('state' => $state,
'package.xml 1.0 state "%state%" does not match "%self%"');
function _differentRole ($handle, $role, $selfrole)
$this->_stack->push (__FUNCTION__ , 'error', array ('handle' => $handle,
'role' => $role, 'self' => $selfrole),
'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"');
function _differentEmail ($handle, $email, $selfemail)
$this->_stack->push (__FUNCTION__ , 'error', array ('handle' => $handle,
'email' => $email, 'self' => $selfemail),
'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"');
function _differentName ($handle, $name, $selfname)
$this->_stack->push (__FUNCTION__ , 'error', array ('handle' => $handle,
'name' => $name, 'self' => $selfname),
'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"');
function _unmatchedMaintainers ($my, $yours)
$this->_stack->push (__FUNCTION__ , 'error', array ('handles' => $my),
'package.xml 2.0 has unmatched extra maintainers "%handles%"');
$this->_stack->push (__FUNCTION__ , 'error', array ('handles' => $yours),
'package.xml 1.0 has unmatched extra maintainers "%handles%"');
function _differentNotes ($notes)
$truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0 , 24 ) . '...';
$this->_stack->push (__FUNCTION__ , 'error', array ('notes' => $truncnotes,
'self' => $truncmynotes),
'package.xml 1.0 release notes "%notes%" do not match "%self%"');
function _differentSummary ($summary)
$truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0 , 24 ) . '...';
substr($this->getsummary (), 0 , 24 ) . '...';
$this->_stack->push (__FUNCTION__ , 'error', array ('summary' => $truncsummary,
'self' => $truncmysummary),
'package.xml 1.0 summary "%summary%" does not match "%self%"');
function _differentDescription ($description)
$truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0 , 24 ) . '...');
substr($this->getdescription (), 0 , 24 ) . '...');
$this->_stack->push (__FUNCTION__ , 'error', array ('description' => $truncdescription,
'self' => $truncmydescription),
'package.xml 1.0 description "%description%" does not match "%self%"');
function _missingFile ($file)
$this->_stack->push (__FUNCTION__ , 'error', array ('file' => $file),
'package.xml 1.0 file "%file%" is not present in <contents>');
* WARNING - do not use this function unless you know what you're doing
if (!isset ($this->_packageInfo['stability'])) {
$this->_packageInfo['stability'] = array ();
$this->_packageInfo['stability']['release'] = $state;
* WARNING - do not use this function unless you know what you're doing
$this->_packageInfo['compatible'] = $compatible;
* WARNING - do not use this function unless you know what you're doing
$this->_packageInfo['name'] = $package;
* WARNING - do not use this function unless you know what you're doing
$this->_packageInfo['channel'] = $channel;
$this->_requestedGroup = $group;
if (isset ($this->_requestedGroup)) {
return $this->_requestedGroup;
* For saving in the registry.
* Set the last version that was installed
$this->_packageInfo['_lastversion'] = $version;
if (isset ($this->_packageInfo['_lastversion'])) {
return $this->_packageInfo['_lastversion'];
* Determines whether this package.xml has post-install scripts or not
$contents = $contents['dir']['file'];
if (!is_array($contents) || !isset ($contents[0 ])) {
$contents = array ($contents);
foreach ($contents as $file) {
$atts = $file['attribs'];
$taskfiles[$atts['name']] = $file;
$this->_scripts = array ();
foreach ($taskfiles as $name => $tasks) {
if (!isset ($filelist[$name])) {
// ignored files will not be in the filelist
$atts = $filelist[$name];
foreach ($tasks as $tag => $raw) {
$ret[] = $filelist[$name]['installed_as'];
* Initialize post-install scripts for running
* This method can be used to detect post-install scripts, as the return value
* indicates whether any exist
$contents = $contents['dir']['file'];
if (!is_array($contents) || !isset ($contents[0 ])) {
$contents = array ($contents);
foreach ($contents as $file) {
$atts = $file['attribs'];
$taskfiles[$atts['name']] = $file;
$this->_scripts = array ();
foreach ($taskfiles as $name => $tasks) {
if (!isset ($filelist[$name])) {
// file was not installed due to installconditions
$atts = $filelist[$name];
foreach ($tasks as $tag => $raw) {
if (!$task->isScript ()) {
continue; // scripts are only handled after installation
$lastversion = isset ($this->_packageInfo['_lastversion']) ?
$this->_packageInfo['_lastversion'] : null;
$task->init ($raw, $atts, $lastversion);
$res = $task->startSession ($this, $atts['installed_as']);
continue; // skip this file
$this->_scripts[] = &$assign;
if (count($this->_scripts)) {
$ui->runPostinstallScripts ($this->_scripts, $this);
* Convert a recursive set of <dir> and <file> tags into a single <dir> tag with
if (isset ($this->_packageInfo['bundle'])) {
if (isset ($this->_packageInfo['contents']['dir']['dir'])) {
if (!isset ($filelist[1 ])) {
$filelist = $filelist[0 ];
$this->_packageInfo['contents']['dir']['file'] = $filelist;
unset ($this->_packageInfo['contents']['dir']['dir']);
// else already flattened but check for baseinstalldir propagation
if (isset ($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) {
if (isset ($this->_packageInfo['contents']['dir']['file'][0 ])) {
foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) {
if (isset ($file['attribs']['baseinstalldir'])) {
$this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir']
= $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
if (!isset ($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) {
$this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir']
= $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
* @param array the final flattened file list
* @param array the current directory being processed
* @param string|falseany recursively inherited baeinstalldir attribute
* @param string private recursion variable
if (isset ($dir['attribs']) && isset ($dir['attribs']['baseinstalldir'])) {
$baseinstall = $dir['attribs']['baseinstalldir'];
if (isset ($dir['dir'])) {
if (!isset ($dir['dir'][0 ])) {
$dir['dir'] = array ($dir['dir']);
foreach ($dir['dir'] as $subdir) {
if (!isset ($subdir['attribs']) || !isset ($subdir['attribs']['name'])) {
$name = $subdir['attribs']['name'];
$newpath = empty ($path) ? $name :
if (isset ($dir['file'])) {
if (!isset ($dir['file'][0 ])) {
$dir['file'] = array ($dir['file']);
foreach ($dir['file'] as $file) {
$attrs = $file['attribs'];
if ($baseinstall && !isset ($attrs['baseinstalldir'])) {
$attrs['baseinstalldir'] = $baseinstall;
$attrs['name'] = empty ($path) ? $name : $path . '/' . $name;
$attrs['name'] = preg_replace(array ('!\\\\+!', '!/+!'), array ('/', '/'),
$file['attribs'] = $attrs;
return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
* WARNING - do not use this function directly unless you know what you're doing
$this->_packageInfo['dependencies'] = $deps;
* WARNING - do not use this function directly unless you know what you're doing
$this->_packageInfo['compatible'] = $compat;
$this->_packageFile = $file;
$this->_archiveFile = $archive ? $archive : $file;
* Wrapper to {@link PEAR_ErrorStack::getErrors()}
* @param boolean determines whether to purge the error stack after retrieving
return $this->_stack->getErrors ($purge);
return $this->_packageFile;
return $this->_archiveFile;
* Directly set the array that defines this packagefile
* WARNING: no validation. This should only be performed by internal methods
* inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2
unset ($pinfo['xsdversion']);
// If the changelog isn't an array then it was passed in as an empty tag
if (isset ($pinfo['changelog']) && !is_array($pinfo['changelog'])) {
unset ($pinfo['changelog']);
$this->_incomplete = false;
$this->_packageInfo = $pinfo;
return $this->_incomplete;
$arr = $this->_packageInfo;
$arr['old']['release_date'] = $this->getDate();
$arr['old']['release_state'] = $this->getState();
$arr['old']['release_license'] = $this->getLicense();
$arr['old']['release_notes'] = $this->getNotes();
$arr['old']['release_deps'] = $this->getDeps();
$arr['xsdversion'] = '2.0';
$info = $this->_packageInfo;
if (isset ($info['_lastversion'])) {
unset ($info['_lastversion']);
if (isset ($info['#binarypackage'])) {
unset ($info['#binarypackage']);
return $arr['stability']['release'];
if ($field == 'api-version') {
return $arr['version']['api'];
if ($field == 'api-state') {
return $arr['stability']['api'];
if (isset ($arr['old'][$field])) {
return $arr['old'][$field];
if (isset ($arr[$field])) {
if (isset ($this->_packageInfo['name'])) {
return $this->_packageInfo['name'];
if (isset ($this->_packageInfo['uri'])) {
if (isset ($this->_packageInfo['channel'])) {
return strtolower($this->_packageInfo['channel']);
if (isset ($this->_packageInfo['uri'])) {
return $this->_packageInfo['uri'];
if (isset ($this->_packageInfo['extends'])) {
return $this->_packageInfo['extends'];
if (isset ($this->_packageInfo['summary'])) {
return $this->_packageInfo['summary'];
if (isset ($this->_packageInfo['description'])) {
return $this->_packageInfo['description'];
if (!isset ($this->_packageInfo['lead'])) {
$ret = array ('lead' => $this->_packageInfo['lead']);
(isset ($this->_packageInfo['developer'])) ?
$ret['developer'] = $this->_packageInfo['developer'] :null;
(isset ($this->_packageInfo['contributor'])) ?
$ret['contributor'] = $this->_packageInfo['contributor'] :null;
(isset ($this->_packageInfo['helper'])) ?
$ret['helper'] = $this->_packageInfo['helper'] :null;
$leads = isset ($this->_packageInfo['lead'][0 ]) ? $this->_packageInfo['lead'] :
array ($this->_packageInfo['lead']);
foreach ($leads as $lead) {
$s['handle'] = $s['user'];
if (isset ($this->_packageInfo['developer'])) {
$leads = isset ($this->_packageInfo['developer'][0 ]) ?
$this->_packageInfo['developer'] :
array ($this->_packageInfo['developer']);
foreach ($leads as $maintainer) {
$s['handle'] = $s['user'];
$s['role'] = 'developer';
if (isset ($this->_packageInfo['contributor'])) {
$leads = isset ($this->_packageInfo['contributor'][0 ]) ?
$this->_packageInfo['contributor'] :
array ($this->_packageInfo['contributor']);
foreach ($leads as $maintainer) {
$s['handle'] = $s['user'];
$s['role'] = 'contributor';
if (isset ($this->_packageInfo['helper'])) {
$leads = isset ($this->_packageInfo['helper'][0 ]) ?
$this->_packageInfo['helper'] :
array ($this->_packageInfo['helper']);
foreach ($leads as $maintainer) {
$s['handle'] = $s['user'];
if (isset ($this->_packageInfo['lead'])) {
return $this->_packageInfo['lead'];
if (isset ($this->_packageInfo['developer'])) {
return $this->_packageInfo['developer'];
if (isset ($this->_packageInfo['contributor'])) {
return $this->_packageInfo['contributor'];
if (isset ($this->_packageInfo['helper'])) {
return $this->_packageInfo['helper'];
if (!isset ($this->_packageInfo['date'])) {
// ensure that the extends tag is set up in the right location
$this->_packageInfo = $this->_insertBefore ($this->_packageInfo,
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
'zendextbinrelease', 'bundle', 'changelog'), array (), 'date');
$this->_packageInfo['date'] = $date;
if (!isset ($this->_packageInfo['time'])) {
// ensure that the time tag is set up in the right location
$this->_packageInfo = $this->_insertBefore ($this->_packageInfo,
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
'zendextbinrelease', 'bundle', 'changelog'), $time, 'time');
$this->_packageInfo['time'] = $time;
if (isset ($this->_packageInfo['date'])) {
return $this->_packageInfo['date'];
if (isset ($this->_packageInfo['time'])) {
return $this->_packageInfo['time'];
* @param package|apiversion category to return
if (isset ($this->_packageInfo['version'][$key])) {
return $this->_packageInfo['version'][$key];
if (isset ($this->_packageInfo['stability'])) {
return $this->_packageInfo['stability'];
if (isset ($this->_packageInfo['stability'][$key])) {
return $this->_packageInfo['stability'][$key];
if (isset ($this->_packageInfo['license'])) {
return $this->_packageInfo['license'];
if (is_array($this->_packageInfo['license'])) {
return $this->_packageInfo['license']['_content'];
return $this->_packageInfo['license'];
if (!isset ($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) {
return $this->_packageInfo['license']['attribs'];
if (isset ($this->_packageInfo['notes'])) {
return $this->_packageInfo['notes'];
* Return the <usesrole> tag contents, if any
if (isset ($this->_packageInfo['usesrole'])) {
return $this->_packageInfo['usesrole'];
* Return the <usestask> tag contents, if any
if (isset ($this->_packageInfo['usestask'])) {
return $this->_packageInfo['usestask'];
* This should only be used to retrieve filenames and install attributes
if (isset ($this->_packageInfo['filelist']) && !$preserve) {
return $this->_packageInfo['filelist'];
if (!isset ($contents['dir'])) {
if (!isset ($contents['dir']['file'][0 ])) {
$contents['dir']['file'] = array ($contents['dir']['file']);
foreach ($contents['dir']['file'] as $file) {
$name = $file['attribs']['name'];
$file = $file['attribs'];
$this->_packageInfo['filelist'] = $ret;
* Return configure options array, if any
if (isset ($releases[0 ])) {
$releases = $releases[0 ];
if (isset ($releases['configureoption'])) {
if (!isset ($releases['configureoption'][0 ])) {
$releases['configureoption'] = array ($releases['configureoption']);
for ($i = 0; $i < count($releases['configureoption']); $i++ ) {
$releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs'];
return $releases['configureoption'];
* This is only used at install-time, after all serialization
$this->_packageInfo['filelist'] = array ();
* Retrieve a list of files that should be installed on this computer
if (isset ($contents['dir']['attribs']['baseinstalldir'])) {
$base = $contents['dir']['attribs']['baseinstalldir'];
if (isset ($this->_packageInfo['bundle'])) {
'Exception: bundles should be handled in download code only');
if (!isset ($release[0 ])) {
if (!isset ($release['installconditions']) && !isset ($release['filelist'])) {
$release = array ($release);
foreach ($release as $instance) {
if (isset ($instance['installconditions'])) {
$installconditions = $instance['installconditions'];
foreach ($installconditions as $type => $conditions) {
if (!isset ($conditions[0 ])) {
$conditions = array ($conditions);
foreach ($conditions as $condition) {
$ret = $depchecker->{" validate{$type}Dependency" }($condition);
continue 3; // skip this release
// this is the release to use
if (isset ($instance['filelist'])) {
if (isset ($instance['filelist']['ignore'])) {
$ignore = isset ($instance['filelist']['ignore'][0 ]) ?
$instance['filelist']['ignore'] :
array ($instance['filelist']['ignore']);
foreach ($ignore as $ig) {
unset ($contents[$ig['attribs']['name']]);
// install files as this name
if (isset ($instance['filelist']['install'])) {
$installas = isset ($instance['filelist']['install'][0 ]) ?
$instance['filelist']['install'] :
array ($instance['filelist']['install']);
foreach ($installas as $as) {
$contents[$as['attribs']['name']]['attribs']['install-as'] =
foreach ($contents as $file => $attrs) {
$contents[$file] = $attrs['attribs'];
} else { // simple release - no installconditions or install-as
return $this->getFilelist ();
return PEAR::raiseError('No releases in package.xml matched the existing operating ' .
'system, extensions installed, or architecture, cannot install');
* This is only used at install-time, after all serialization
* @param string file name
* @param string installed path
return $this->_packageInfo ['filelist'][$file]['installed_as'] = $path;
unset ($this->_packageInfo ['filelist'][$file]['installed_as']);
if (isset ($this->_packageInfo ['filelist'][$file]['installed_as'])) {
return $this->_packageInfo ['filelist'][$file]['installed_as'];
* This is only used at install-time, after all serialization
if (isset ($this->_packageInfo ['filelist'][$file])) {
$this->_packageInfo ['filelist'][$file] =
array_merge($this->_packageInfo ['filelist'][$file], $atts['attribs']);
$this->_packageInfo ['filelist'][$file] = $atts['attribs'];
* Retrieve the contents tag
if (isset ($this->_packageInfo ['contents'])) {
return $this->_packageInfo ['contents'];
* @param string full path to file
* @param string attribute name
* @param string attribute value
* @param int risky but fast - use this to choose a file based on its position in the list
* of files. Index is zero-based like PHP arrays.
* @return bool success of operation
if (in_array($attr, array ('role', 'name', 'baseinstalldir'))) {
$this->_filesValid = false;
isset ($this->_packageInfo ['contents']['dir']['file'][$index]['attribs'])) {
$this->_packageInfo ['contents']['dir']['file'][$index]['attribs'][$attr] = $value;
if (!isset ($this->_packageInfo ['contents']['dir']['file'])) {
$files = $this->_packageInfo ['contents']['dir']['file'];
foreach ($files as $i => $file) {
if (isset ($file['attribs'])) {
if ($file['attribs']['name'] == $filename) {
$this->_packageInfo ['contents']['dir']['file'][$i]['attribs'][$attr] = $value;
$this->_packageInfo ['contents']['dir']['file']['attribs'][$attr] = $value;
if (!isset ($this->_packageInfo ['dirtree'])) {
$this->_packageInfo ['dirtree'] = array ();
$this->_packageInfo ['dirtree'][$path] = true;
if (isset ($this->_packageInfo ['dirtree']) && count($this->_packageInfo ['dirtree'])) {
return $this->_packageInfo ['dirtree'];
unset ($this->_packageInfo ['dirtree']);
* Determines whether this package claims it is compatible with the version of
* the package that has a recommended version dependency
* @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package
if (!isset ($this->_packageInfo ['compatible'])) {
if (!isset ($this->_packageInfo ['channel'])) {
$compatible = $this->_packageInfo ['compatible'];
if (!isset ($compatible[0 ])) {
$compatible = array ($compatible);
foreach ($compatible as $info) {
if (isset ($info['exclude'])) {
if (!isset ($info['exclude'][0 ])) {
$info['exclude'] = array ($info['exclude']);
foreach ($info['exclude'] as $exclude) {
if (isset ($this->_packageInfo ['compatible'])) {
return $this->_packageInfo ['compatible'];
if (isset ($this->_packageInfo ['dependencies'])) {
return $this->_packageInfo ['dependencies'];
* Determines whether the passed in package is a subpackage of this package.
* No version checking is done, only name verification.
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
if (isset ($this->_packageInfo ['dependencies']['required']['subpackage'])) {
$sub = $this->_packageInfo ['dependencies']['required']['subpackage'];
if (isset ($this->_packageInfo ['dependencies']['optional']['subpackage'])) {
$sub1 = $this->_packageInfo ['dependencies']['optional']['subpackage'];
if (isset ($this->_packageInfo ['dependencies']['group'])) {
$group = $this->_packageInfo ['dependencies']['group'];
foreach ($group as $deps) {
if (isset ($deps['subpackage'])) {
$sub2 = $deps['subpackage'];
if (isset ($dep['channel'])) {
if ($dep['uri'] == $p->getURI ()) {
foreach (array ('package', 'subpackage') as $type) {
foreach (array ('required', 'optional') as $needed) {
if (isset ($deps[$needed][$type])) {
if (!isset ($deps[$needed][$type][0 ])) {
$deps[$needed][$type] = array ($deps[$needed][$type]);
foreach ($deps[$needed][$type] as $dep) {
$depchannel = isset ($dep['channel']) ? $dep['channel'] : '__uri';
$depchannel == $channel) {
if (isset ($deps['group'])) {
if (!isset ($deps['group'][0 ])) {
$dep['group'] = array ($deps['group']);
foreach ($deps['group'] as $group) {
if (isset ($group[$type])) {
$group[$type] = array ($group[$type]);
foreach ($group[$type] as $dep) {
$depchannel = isset ($dep['channel']) ? $dep['channel'] : '__uri';
$depchannel == $channel) {
* Get the contents of a dependency group
if (!isset ($this->_packageInfo ['dependencies']['group'])) {
$groups = $this->_packageInfo ['dependencies']['group'];
if (!isset ($groups[0 ])) {
$groups = array ($groups);
foreach ($groups as $group) {
if (strtolower($group['attribs']['name']) == $name) {
* Retrieve a partial package.xml 1.0 representation of dependencies
* a very limited representation of dependencies is returned by this method.
* The <exclude> tag for excluding certain versions of a dependency is
* completely ignored. In addition, dependency groups are ignored, with the
* assumption that all dependencies in dependency groups are also listed in
* the optional group that work with all dependency groups
* @param boolean return package.xml 2.0 <dependencies> tag
function getDeps($raw = false , $nopearinstaller = false )
if (isset ($this->_packageInfo ['dependencies'])) {
return $this->_packageInfo ['dependencies'];
'pearinstaller' => 'pkg',
foreach (array ('required', 'optional') as $type) {
$optional = ($type == 'optional') ? 'yes' : 'no';
if (!isset ($this->_packageInfo ['dependencies'][$type])
|| empty ($this->_packageInfo ['dependencies'][$type])) {
foreach ($this->_packageInfo ['dependencies'][$type] as $dtype => $deps) {
if ($dtype == 'pearinstaller' && $nopearinstaller) {
foreach ($deps as $dep) {
if (!isset ($map[$dtype])) {
// no support for arch type
if ($dtype == 'pearinstaller') {
$dep['channel'] = 'pear.php.net';
$s = array ('type' => $map[$dtype]);
if (isset ($dep['channel'])) {
$s['channel'] = $dep['channel'];
if (isset ($dep['uri'])) {
if (isset ($dep['name'])) {
$s['name'] = $dep['name'];
if (isset ($dep['conflicts'])) {
if (!isset ($dep['min']) &&
$s['optional'] = $optional;
} elseif (isset ($dep['min']) &&
$s['version'] = $dep['min'];
$s1['version'] = $dep['max'];
if (isset ($dep['channel'])) {
$s1['channel'] = $dep['channel'];
$s['name'] = $dep['name'];
$s1['name'] = $dep['name'];
$s['optional'] = $optional;
$s1['optional'] = $optional;
} elseif (isset ($dep['min'])) {
if (isset ($dep['exclude']) &&
$dep['exclude'] == $dep['min']) {
$s['version'] = $dep['min'];
$s['optional'] = $optional;
$s['name'] = $dep['name'];
} elseif (isset ($dep['max'])) {
if (isset ($dep['exclude']) &&
$dep['exclude'] == $dep['max']) {
$s['version'] = $dep['max'];
$s['optional'] = $optional;
$s['name'] = $dep['name'];
* @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false
if (isset ($this->_packageInfo ['phprelease'])) {
if (isset ($this->_packageInfo ['extsrcrelease'])) {
if (isset ($this->_packageInfo ['extbinrelease'])) {
if (isset ($this->_packageInfo ['zendextsrcrelease'])) {
if (isset ($this->_packageInfo ['zendextbinrelease'])) {
if (isset ($this->_packageInfo ['bundle'])) {
return $this->_packageInfo [$type];
if (isset ($this->_packageInfo ['changelog'])) {
return $this->_packageInfo ['changelog'];
return isset ($this->_packageInfo ['dependencies']);
if (isset ($this->_packageInfo ['zendextsrcrelease'])) {
if (isset ($this->_packageInfo ['zendextbinrelease'])) {
if (isset ($this->_packageInfo ['extbinrelease']) ||
isset ($this->_packageInfo ['zendextbinrelease'])) {
return array ('channel' => $this->_packageInfo ['srcchannel'],
'package' => $this->_packageInfo ['srcpackage']);
if (isset ($this->_packageInfo ['bundle'])) {
return $this->_packageInfo ['contents']['bundledpackage'];
if (isset ($this->_packageInfo ['_lastmodified'])) {
return $this->_packageInfo ['_lastmodified'];
* Get the contents of a file listed within the package.xml
if ($this->_archiveFile == $this->_packageFile ) { // unpacked
$dir = dirname($this->_packageFile );
$file = $dir . DIRECTORY_SEPARATOR . $file;
array (DIRECTORY_SEPARATOR , DIRECTORY_SEPARATOR ), $file);
$tar = &new Archive_Tar ($this->_archiveFile );
if ($file != 'package.xml' && $file != 'package2.xml') {
$file = $tar->extractInString ($file);
$tar->popErrorHandling ();
require_once 'PEAR/PackageFile/v2/rw.php';
if (!isset ($this->$name)) {
if ($name == '_config' || $name == '_logger'|| $name == '_registry' ||
$a->$name = &$this->$name;
$a->$name = $this->$name;
require_once 'PEAR/PackageFile/Generator/v2.php';
if (!isset ($this->_v2Validator ) ||
!is_a($this->_v2Validator , 'PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
$this->_v2Validator = new PEAR_PackageFile_v2_Validator;
function validate($state = PEAR_VALIDATE_NORMAL )
if (!isset ($this->_packageInfo ) || !is_array($this->_packageInfo )) {
if (!isset ($this->_v2Validator ) ||
!is_a($this->_v2Validator , 'PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
$this->_v2Validator = new PEAR_PackageFile_v2_Validator;
if (isset ($this->_packageInfo ['xsdversion'])) {
unset ($this->_packageInfo ['xsdversion']);
return $this->_v2Validator ->validate($this, $state);
if (!isset ($this->_tasksNs )) {
if (isset ($this->_packageInfo ['attribs'])) {
foreach ($this->_packageInfo ['attribs'] as $name => $value) {
if ($value == 'http://pear.php.net/dtd/tasks-1.0') {
* Determine whether a task name is a valid task. Custom tasks may be defined
* using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task>
* Note that this method will auto-load the task class file and test for the existence
* of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class
* PEAR_Task_mycustom_task
// transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace
$task = str_replace(array ($this->_tasksNs . ':', '-'), array ('', ' '), $task);
return " PEAR_Task_$task";
$fp = @fopen(" PEAR/Task/$taskfile.php" , 'r', true );
require_once " PEAR/Task/$taskfile.php";
return " PEAR_Task_$task";
* Key-friendly array_splice
* @param tagname to splice a value in before
* @param mixed the value to splice in
* @param string the new tag name
function _ksplice ($array, $key, $value, $newkey)
$before[$newkey] = $value;
* @param array a list of possible keys, in the order they may occur
* @param mixed contents of the new package.xml tag
function _insertBefore ($array, $keys, $contents, $newkey)
foreach ($keys as $key) {
if (isset ($array[$key])) {
return $array = $this->_ksplice ($array, $key, $contents, $newkey);
$array[$newkey] = $contents;
* @param subsection of {@link $_packageInfo}
* @param array|stringtag contents
* tagname => array(list of tag names that follow this one),
* childtagname => array(list of child tag names that follow this one),
* This allows construction of nested tags
function _mergeTag ($manip, $contents, $order)
foreach ($order as $tag => $curorder) {
if (!isset ($manip[$tag])) {
// ensure that the tag is set up
$manip = $this->_insertBefore ($manip, $curorder, array (), $tag);
$manip[$tag] = $this->_mergeTag ($manip[$tag], $contents, array_slice($order, 1 ));
if (is_array($manip[$tag]) && !empty ($manip[$tag]) && isset ($manip[$tag][0 ])) {
$manip[$tag][] = $contents;
if (!count($manip[$tag])) {
$manip[$tag] = $contents;
$manip[$tag] = array ($manip[$tag]);
$manip[$tag][] = $contents;
Documentation generated on Wed, 06 Jul 2011 23:31:37 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.
|