/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/Parser/v1.php |
---|
New file |
0,0 → 1,461 |
<?php |
/** |
* package.xml parsing class, package.xml version 1.0 |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: v1.php,v 1.22 2006/03/27 05:25:48 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 1.4.0a1 |
*/ |
/** |
* package.xml abstraction class |
*/ |
require_once 'PEAR/PackageFile/v1.php'; |
/** |
* Parser for package.xml version 1.0 |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: @PEAR-VER@ |
* @link http://pear.php.net/package/PEAR |
* @since Class available since Release 1.4.0a1 |
*/ |
class PEAR_PackageFile_Parser_v1 |
{ |
var $_registry; |
var $_config; |
var $_logger; |
/** |
* BC hack to allow PEAR_Common::infoFromString() to sort of |
* work with the version 2.0 format - there's no filelist though |
* @param PEAR_PackageFile_v2 |
*/ |
function fromV2($packagefile) |
{ |
$info = $packagefile->getArray(true); |
$ret = new PEAR_PackageFile_v1; |
$ret->fromArray($info['old']); |
} |
function setConfig(&$c) |
{ |
$this->_config = &$c; |
$this->_registry = &$c->getRegistry(); |
} |
function setLogger(&$l) |
{ |
$this->_logger = &$l; |
} |
/** |
* @param string contents of package.xml file, version 1.0 |
* @return bool success of parsing |
*/ |
function parse($data, $file, $archive = false) |
{ |
if (!extension_loaded('xml')) { |
return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension'); |
} |
$xp = xml_parser_create(); |
if (!$xp) { |
return PEAR::raiseError('Cannot create xml parser for parsing package.xml'); |
} |
xml_set_object($xp, $this); |
xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0'); |
xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0'); |
xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); |
$this->element_stack = array(); |
$this->_packageInfo = array('provides' => array()); |
$this->current_element = false; |
unset($this->dir_install); |
$this->_packageInfo['filelist'] = array(); |
$this->filelist =& $this->_packageInfo['filelist']; |
$this->dir_names = array(); |
$this->in_changelog = false; |
$this->d_i = 0; |
$this->cdata = ''; |
$this->_isValid = true; |
if (!xml_parse($xp, $data, 1)) { |
$code = xml_get_error_code($xp); |
$line = xml_get_current_line_number($xp); |
xml_parser_free($xp); |
return PEAR::raiseError(sprintf("XML error: %s at line %d", |
$str = xml_error_string($code), $line), 2); |
} |
xml_parser_free($xp); |
$pf = new PEAR_PackageFile_v1; |
$pf->setConfig($this->_config); |
if (isset($this->_logger)) { |
$pf->setLogger($this->_logger); |
} |
$pf->setPackagefile($file, $archive); |
$pf->fromArray($this->_packageInfo); |
return $pf; |
} |
// {{{ _unIndent() |
/** |
* Unindent given string |
* |
* @param string $str The string that has to be unindented. |
* @return string |
* @access private |
*/ |
function _unIndent($str) |
{ |
// remove leading newlines |
$str = preg_replace('/^[\r\n]+/', '', $str); |
// find whitespace at the beginning of the first line |
$indent_len = strspn($str, " \t"); |
$indent = substr($str, 0, $indent_len); |
$data = ''; |
// remove the same amount of whitespace from following lines |
foreach (explode("\n", $str) as $line) { |
if (substr($line, 0, $indent_len) == $indent) { |
$data .= substr($line, $indent_len) . "\n"; |
} |
} |
return $data; |
} |
// Support for package DTD v1.0: |
// {{{ _element_start_1_0() |
/** |
* XML parser callback for ending elements. Used for version 1.0 |
* packages. |
* |
* @param resource $xp XML parser resource |
* @param string $name name of ending element |
* |
* @return void |
* |
* @access private |
*/ |
function _element_start_1_0($xp, $name, $attribs) |
{ |
array_push($this->element_stack, $name); |
$this->current_element = $name; |
$spos = sizeof($this->element_stack) - 2; |
$this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; |
$this->current_attributes = $attribs; |
$this->cdata = ''; |
switch ($name) { |
case 'dir': |
if ($this->in_changelog) { |
break; |
} |
if (array_key_exists('name', $attribs) && $attribs['name'] != '/') { |
$attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), |
$attribs['name']); |
if (strrpos($attribs['name'], '/') == strlen($attribs['name']) - 1) { |
$attribs['name'] = substr($attribs['name'], 0, |
strlen($attribs['name']) - 1); |
} |
if (strpos($attribs['name'], '/') === 0) { |
$attribs['name'] = substr($attribs['name'], 1); |
} |
$this->dir_names[] = $attribs['name']; |
} |
if (isset($attribs['baseinstalldir'])) { |
$this->dir_install = $attribs['baseinstalldir']; |
} |
if (isset($attribs['role'])) { |
$this->dir_role = $attribs['role']; |
} |
break; |
case 'file': |
if ($this->in_changelog) { |
break; |
} |
if (isset($attribs['name'])) { |
$path = ''; |
if (count($this->dir_names)) { |
foreach ($this->dir_names as $dir) { |
$path .= $dir . '/'; |
} |
} |
$path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), |
$attribs['name']); |
unset($attribs['name']); |
$this->current_path = $path; |
$this->filelist[$path] = $attribs; |
// Set the baseinstalldir only if the file don't have this attrib |
if (!isset($this->filelist[$path]['baseinstalldir']) && |
isset($this->dir_install)) |
{ |
$this->filelist[$path]['baseinstalldir'] = $this->dir_install; |
} |
// Set the Role |
if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { |
$this->filelist[$path]['role'] = $this->dir_role; |
} |
} |
break; |
case 'replace': |
if (!$this->in_changelog) { |
$this->filelist[$this->current_path]['replacements'][] = $attribs; |
} |
break; |
case 'maintainers': |
$this->_packageInfo['maintainers'] = array(); |
$this->m_i = 0; // maintainers array index |
break; |
case 'maintainer': |
// compatibility check |
if (!isset($this->_packageInfo['maintainers'])) { |
$this->_packageInfo['maintainers'] = array(); |
$this->m_i = 0; |
} |
$this->_packageInfo['maintainers'][$this->m_i] = array(); |
$this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i]; |
break; |
case 'changelog': |
$this->_packageInfo['changelog'] = array(); |
$this->c_i = 0; // changelog array index |
$this->in_changelog = true; |
break; |
case 'release': |
if ($this->in_changelog) { |
$this->_packageInfo['changelog'][$this->c_i] = array(); |
$this->current_release = &$this->_packageInfo['changelog'][$this->c_i]; |
} else { |
$this->current_release = &$this->_packageInfo; |
} |
break; |
case 'deps': |
if (!$this->in_changelog) { |
$this->_packageInfo['release_deps'] = array(); |
} |
break; |
case 'dep': |
// dependencies array index |
if (!$this->in_changelog) { |
$this->d_i++; |
isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false; |
$this->_packageInfo['release_deps'][$this->d_i] = $attribs; |
} |
break; |
case 'configureoptions': |
if (!$this->in_changelog) { |
$this->_packageInfo['configure_options'] = array(); |
} |
break; |
case 'configureoption': |
if (!$this->in_changelog) { |
$this->_packageInfo['configure_options'][] = $attribs; |
} |
break; |
case 'provides': |
if (empty($attribs['type']) || empty($attribs['name'])) { |
break; |
} |
$attribs['explicit'] = true; |
$this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs; |
break; |
case 'package' : |
if (isset($attribs['version'])) { |
$this->_packageInfo['xsdversion'] = trim($attribs['version']); |
} else { |
$this->_packageInfo['xsdversion'] = '1.0'; |
} |
if (isset($attribs['packagerversion'])) { |
$this->_packageInfo['packagerversion'] = $attribs['packagerversion']; |
} |
break; |
} |
} |
// }}} |
// {{{ _element_end_1_0() |
/** |
* XML parser callback for ending elements. Used for version 1.0 |
* packages. |
* |
* @param resource $xp XML parser resource |
* @param string $name name of ending element |
* |
* @return void |
* |
* @access private |
*/ |
function _element_end_1_0($xp, $name) |
{ |
$data = trim($this->cdata); |
switch ($name) { |
case 'name': |
switch ($this->prev_element) { |
case 'package': |
$this->_packageInfo['package'] = $data; |
break; |
case 'maintainer': |
$this->current_maintainer['name'] = $data; |
break; |
} |
break; |
case 'extends' : |
$this->_packageInfo['extends'] = $data; |
break; |
case 'summary': |
$this->_packageInfo['summary'] = $data; |
break; |
case 'description': |
$data = $this->_unIndent($this->cdata); |
$this->_packageInfo['description'] = $data; |
break; |
case 'user': |
$this->current_maintainer['handle'] = $data; |
break; |
case 'email': |
$this->current_maintainer['email'] = $data; |
break; |
case 'role': |
$this->current_maintainer['role'] = $data; |
break; |
case 'version': |
//$data = ereg_replace ('[^a-zA-Z0-9._\-]', '_', $data); |
if ($this->in_changelog) { |
$this->current_release['version'] = $data; |
} else { |
$this->_packageInfo['version'] = $data; |
} |
break; |
case 'date': |
if ($this->in_changelog) { |
$this->current_release['release_date'] = $data; |
} else { |
$this->_packageInfo['release_date'] = $data; |
} |
break; |
case 'notes': |
// try to "de-indent" release notes in case someone |
// has been over-indenting their xml ;-) |
$data = $this->_unIndent($this->cdata); |
if ($this->in_changelog) { |
$this->current_release['release_notes'] = $data; |
} else { |
$this->_packageInfo['release_notes'] = $data; |
} |
break; |
case 'warnings': |
if ($this->in_changelog) { |
$this->current_release['release_warnings'] = $data; |
} else { |
$this->_packageInfo['release_warnings'] = $data; |
} |
break; |
case 'state': |
if ($this->in_changelog) { |
$this->current_release['release_state'] = $data; |
} else { |
$this->_packageInfo['release_state'] = $data; |
} |
break; |
case 'license': |
if ($this->in_changelog) { |
$this->current_release['release_license'] = $data; |
} else { |
$this->_packageInfo['release_license'] = $data; |
} |
break; |
case 'dep': |
if ($data && !$this->in_changelog) { |
$this->_packageInfo['release_deps'][$this->d_i]['name'] = $data; |
} |
break; |
case 'dir': |
if ($this->in_changelog) { |
break; |
} |
array_pop($this->dir_names); |
break; |
case 'file': |
if ($this->in_changelog) { |
break; |
} |
if ($data) { |
$path = ''; |
if (count($this->dir_names)) { |
foreach ($this->dir_names as $dir) { |
$path .= $dir . '/'; |
} |
} |
$path .= $data; |
$this->filelist[$path] = $this->current_attributes; |
// Set the baseinstalldir only if the file don't have this attrib |
if (!isset($this->filelist[$path]['baseinstalldir']) && |
isset($this->dir_install)) |
{ |
$this->filelist[$path]['baseinstalldir'] = $this->dir_install; |
} |
// Set the Role |
if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { |
$this->filelist[$path]['role'] = $this->dir_role; |
} |
} |
break; |
case 'maintainer': |
if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) { |
$this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead'; |
} |
$this->m_i++; |
break; |
case 'release': |
if ($this->in_changelog) { |
$this->c_i++; |
} |
break; |
case 'changelog': |
$this->in_changelog = false; |
break; |
} |
array_pop($this->element_stack); |
$spos = sizeof($this->element_stack) - 1; |
$this->current_element = ($spos > 0) ? $this->element_stack[$spos] : ''; |
$this->cdata = ''; |
} |
// }}} |
// {{{ _pkginfo_cdata_1_0() |
/** |
* XML parser callback for character data. Used for version 1.0 |
* packages. |
* |
* @param resource $xp XML parser resource |
* @param string $name character data |
* |
* @return void |
* |
* @access private |
*/ |
function _pkginfo_cdata_1_0($xp, $data) |
{ |
if (isset($this->cdata)) { |
$this->cdata .= $data; |
} |
} |
// }}} |
} |
?> |
/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/Parser/v2.php |
---|
New file |
0,0 → 1,115 |
<?php |
/** |
* package.xml parsing class, package.xml version 2.0 |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: v2.php,v 1.19 2006/01/23 17:39:52 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 1.4.0a1 |
*/ |
/** |
* base xml parser class |
*/ |
require_once 'PEAR/XMLParser.php'; |
require_once 'PEAR/PackageFile/v2.php'; |
/** |
* Parser for package.xml version 2.0 |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: @PEAR-VER@ |
* @link http://pear.php.net/package/PEAR |
* @since Class available since Release 1.4.0a1 |
*/ |
class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser |
{ |
var $_config; |
var $_logger; |
var $_registry; |
function setConfig(&$c) |
{ |
$this->_config = &$c; |
$this->_registry = &$c->getRegistry(); |
} |
function setLogger(&$l) |
{ |
$this->_logger = &$l; |
} |
/** |
* Unindent given string |
* |
* @param string $str The string that has to be unindented. |
* @return string |
* @access private |
*/ |
function _unIndent($str) |
{ |
// remove leading newlines |
$str = preg_replace('/^[\r\n]+/', '', $str); |
// find whitespace at the beginning of the first line |
$indent_len = strspn($str, " \t"); |
$indent = substr($str, 0, $indent_len); |
$data = ''; |
// remove the same amount of whitespace from following lines |
foreach (explode("\n", $str) as $line) { |
if (substr($line, 0, $indent_len) == $indent) { |
$data .= substr($line, $indent_len) . "\n"; |
} |
} |
return $data; |
} |
/** |
* post-process data |
* |
* @param string $data |
* @param string $element element name |
*/ |
function postProcess($data, $element) |
{ |
if ($element == 'notes') { |
return trim($this->_unIndent($data)); |
} |
return trim($data); |
} |
/** |
* @param string |
* @param string file name of the package.xml |
* @param string|false name of the archive this package.xml came from, if any |
* @param string class name to instantiate and return. This must be PEAR_PackageFile_v2 or |
* a subclass |
* @return PEAR_PackageFile_v2 |
*/ |
function &parse($data, $file, $archive = false, $class = 'PEAR_PackageFile_v2') |
{ |
if (PEAR::isError($err = parent::parse($data, $file))) { |
return $err; |
} |
$ret = new $class; |
$ret->setConfig($this->_config); |
if (isset($this->_logger)) { |
$ret->setLogger($this->_logger); |
} |
$ret->fromArray($this->_unserializedData); |
$ret->setPackagefile($file, $archive); |
return $ret; |
} |
} |
?> |
/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/v1.php |
---|
New file |
0,0 → 1,1603 |
<?php |
/** |
* PEAR_PackageFile_v1, package.xml version 1.0 |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: v1.php,v 1.72 2006/10/31 02:54:41 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 1.4.0a1 |
*/ |
/** |
* For error handling |
*/ |
require_once 'PEAR/ErrorStack.php'; |
/** |
* Error code if parsing is attempted with no xml extension |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); |
/** |
* Error code if creating the xml parser resource fails |
*/ |
define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); |
/** |
* Error code used for all sax xml parsing errors |
*/ |
define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); |
/** |
* Error code used when there is no name |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); |
/** |
* Error code when a package name is not valid |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); |
/** |
* Error code used when no summary is parsed |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); |
/** |
* Error code for summaries that are more than 1 line |
*/ |
define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); |
/** |
* Error code used when no description is present |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); |
/** |
* Error code used when no license is present |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); |
/** |
* Error code used when a <version> version number is not present |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); |
/** |
* Error code used when a <version> version number is invalid |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); |
/** |
* Error code when release state is missing |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); |
/** |
* Error code when release state is invalid |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); |
/** |
* Error code when release state is missing |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); |
/** |
* Error code when release state is invalid |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); |
/** |
* Error code when no release notes are found |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); |
/** |
* Error code when no maintainers are found |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); |
/** |
* Error code when a maintainer has no handle |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); |
/** |
* Error code when a maintainer has no handle |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); |
/** |
* Error code when a maintainer has no name |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); |
/** |
* Error code when a maintainer has no email |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); |
/** |
* Error code when a maintainer has no handle |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); |
/** |
* Error code when a dependency is not a PHP dependency, but has no name |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); |
/** |
* Error code when a dependency has no type (pkg, php, etc.) |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); |
/** |
* Error code when a dependency has no relation (lt, ge, has, etc.) |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); |
/** |
* Error code when a dependency is not a 'has' relation, but has no version |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); |
/** |
* Error code when a dependency has an invalid relation |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); |
/** |
* Error code when a dependency has an invalid type |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); |
/** |
* Error code when a dependency has an invalid optional option |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); |
/** |
* Error code when a dependency is a pkg dependency, and has an invalid package name |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); |
/** |
* Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel |
*/ |
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); |
/** |
* Error code when rel="has" and version attribute is present. |
*/ |
define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); |
/** |
* Error code when type="php" and dependency name is present |
*/ |
define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); |
/** |
* Error code when a configure option has no name |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); |
/** |
* Error code when a configure option has no name |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); |
/** |
* Error code when a file in the filelist has an invalid role |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); |
/** |
* Error code when a file in the filelist has no role |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); |
/** |
* Error code when analyzing a php source file that has parse errors |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); |
/** |
* Error code when analyzing a php source file reveals a source element |
* without a package name prefix |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); |
/** |
* Error code when an unknown channel is specified |
*/ |
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); |
/** |
* Error code when no files are found in the filelist |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); |
/** |
* Error code when a file is not valid php according to _analyzeSourceCode() |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); |
/** |
* Error code when the channel validator returns an error or warning |
*/ |
define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); |
/** |
* Error code when a php5 package is packaged in php4 (analysis doesn't work) |
*/ |
define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); |
/** |
* Error code when a file is listed in package.xml but does not exist |
*/ |
define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); |
/** |
* Error code when a <dep type="php" rel="not"... is encountered (use rel="ne") |
*/ |
define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48); |
/** |
* Error code when a package.xml contains non-ISO-8859-1 characters |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49); |
/** |
* Error code when a dependency is not a 'has' relation, but has no version |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50); |
/** |
* Error code when a package has no lead developer |
*/ |
define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51); |
/** |
* Error code when a filename begins with "." |
*/ |
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52); |
/** |
* package.xml encapsulator |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.5.1 |
* @link http://pear.php.net/package/PEAR |
* @since Class available since Release 1.4.0a1 |
*/ |
class PEAR_PackageFile_v1 |
{ |
/** |
* @access private |
* @var PEAR_ErrorStack |
* @access private |
*/ |
var $_stack; |
/** |
* A registry object, used to access the package name validation regex for non-standard channels |
* @var PEAR_Registry |
* @access private |
*/ |
var $_registry; |
/** |
* An object that contains a log method that matches PEAR_Common::log's signature |
* @var object |
* @access private |
*/ |
var $_logger; |
/** |
* Parsed package information |
* @var array |
* @access private |
*/ |
var $_packageInfo; |
/** |
* path to package.xml |
* @var string |
* @access private |
*/ |
var $_packageFile; |
/** |
* path to package .tgz or false if this is a local/extracted package.xml |
* @var string |
* @access private |
*/ |
var $_archiveFile; |
/** |
* @var int |
* @access private |
*/ |
var $_isValid = 0; |
/** |
* Determines whether this packagefile was initialized only with partial package info |
* |
* If this package file was constructed via parsing REST, it will only contain |
* |
* - package name |
* - channel name |
* - dependencies |
* @var boolean |
* @access private |
*/ |
var $_incomplete = true; |
/** |
* @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack |
* @param string Name of Error Stack class to use. |
*/ |
function PEAR_PackageFile_v1() |
{ |
$this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); |
$this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); |
$this->_isValid = 0; |
} |
function installBinary($installer) |
{ |
return false; |
} |
function isExtension($name) |
{ |
return false; |
} |
function setConfig(&$config) |
{ |
$this->_config = &$config; |
$this->_registry = &$config->getRegistry(); |
} |
function setRequestedGroup() |
{ |
// placeholder |
} |
/** |
* For saving in the registry. |
* |
* Set the last version that was installed |
* @param string |
*/ |
function setLastInstalledVersion($version) |
{ |
$this->_packageInfo['_lastversion'] = $version; |
} |
/** |
* @return string|false |
*/ |
function getLastInstalledVersion() |
{ |
if (isset($this->_packageInfo['_lastversion'])) { |
return $this->_packageInfo['_lastversion']; |
} |
return false; |
} |
function getInstalledBinary() |
{ |
return false; |
} |
function listPostinstallScripts() |
{ |
return false; |
} |
function initPostinstallScripts() |
{ |
return false; |
} |
function setLogger(&$logger) |
{ |
if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { |
return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); |
} |
$this->_logger = &$logger; |
} |
function setPackagefile($file, $archive = false) |
{ |
$this->_packageFile = $file; |
$this->_archiveFile = $archive ? $archive : $file; |
} |
function getPackageFile() |
{ |
return isset($this->_packageFile) ? $this->_packageFile : false; |
} |
function getPackageType() |
{ |
return 'php'; |
} |
function getArchiveFile() |
{ |
return $this->_archiveFile; |
} |
function packageInfo($field) |
{ |
if (!is_string($field) || empty($field) || |
!isset($this->_packageInfo[$field])) { |
return false; |
} |
return $this->_packageInfo[$field]; |
} |
function setDirtree($path) |
{ |
if (!isset($this->_packageInfo['dirtree'])) { |
$this->_packageInfo['dirtree'] = array(); |
} |
$this->_packageInfo['dirtree'][$path] = true; |
} |
function getDirtree() |
{ |
if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { |
return $this->_packageInfo['dirtree']; |
} |
return false; |
} |
function resetDirtree() |
{ |
unset($this->_packageInfo['dirtree']); |
} |
function fromArray($pinfo) |
{ |
$this->_incomplete = false; |
$this->_packageInfo = $pinfo; |
} |
function isIncomplete() |
{ |
return $this->_incomplete; |
} |
function getChannel() |
{ |
return 'pear.php.net'; |
} |
function getUri() |
{ |
return false; |
} |
function getTime() |
{ |
return false; |
} |
function getExtends() |
{ |
if (isset($this->_packageInfo['extends'])) { |
return $this->_packageInfo['extends']; |
} |
return false; |
} |
/** |
* @return array |
*/ |
function toArray() |
{ |
if (!$this->validate(PEAR_VALIDATE_NORMAL)) { |
return false; |
} |
return $this->getArray(); |
} |
function getArray() |
{ |
return $this->_packageInfo; |
} |
function getName() |
{ |
return $this->getPackage(); |
} |
function getPackage() |
{ |
if (isset($this->_packageInfo['package'])) { |
return $this->_packageInfo['package']; |
} |
return false; |
} |
/** |
* WARNING - don't use this unless you know what you are doing |
*/ |
function setRawPackage($package) |
{ |
$this->_packageInfo['package'] = $package; |
} |
function setPackage($package) |
{ |
$this->_packageInfo['package'] = $package; |
$this->_isValid = false; |
} |
function getVersion() |
{ |
if (isset($this->_packageInfo['version'])) { |
return $this->_packageInfo['version']; |
} |
return false; |
} |
function setVersion($version) |
{ |
$this->_packageInfo['version'] = $version; |
$this->_isValid = false; |
} |
function clearMaintainers() |
{ |
unset($this->_packageInfo['maintainers']); |
} |
function getMaintainers() |
{ |
if (isset($this->_packageInfo['maintainers'])) { |
return $this->_packageInfo['maintainers']; |
} |
return false; |
} |
/** |
* Adds a new maintainer - no checking of duplicates is performed, use |
* updatemaintainer for that purpose. |
*/ |
function addMaintainer($role, $handle, $name, $email) |
{ |
$this->_packageInfo['maintainers'][] = |
array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); |
$this->_isValid = false; |
} |
function updateMaintainer($role, $handle, $name, $email) |
{ |
$found = false; |
if (!isset($this->_packageInfo['maintainers']) || |
!is_array($this->_packageInfo['maintainers'])) { |
return $this->addMaintainer($role, $handle, $name, $email); |
} |
foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { |
if ($maintainer['handle'] == $handle) { |
$found = $i; |
break; |
} |
} |
if ($found !== false) { |
unset($this->_packageInfo['maintainers'][$found]); |
$this->_packageInfo['maintainers'] = |
array_values($this->_packageInfo['maintainers']); |
} |
$this->addMaintainer($role, $handle, $name, $email); |
} |
function deleteMaintainer($handle) |
{ |
$found = false; |
foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { |
if ($maintainer['handle'] == $handle) { |
$found = $i; |
break; |
} |
} |
if ($found !== false) { |
unset($this->_packageInfo['maintainers'][$found]); |
$this->_packageInfo['maintainers'] = |
array_values($this->_packageInfo['maintainers']); |
return true; |
} |
return false; |
} |
function getState() |
{ |
if (isset($this->_packageInfo['release_state'])) { |
return $this->_packageInfo['release_state']; |
} |
return false; |
} |
function setRawState($state) |
{ |
$this->_packageInfo['release_state'] = $state; |
} |
function setState($state) |
{ |
$this->_packageInfo['release_state'] = $state; |
$this->_isValid = false; |
} |
function getDate() |
{ |
if (isset($this->_packageInfo['release_date'])) { |
return $this->_packageInfo['release_date']; |
} |
return false; |
} |
function setDate($date) |
{ |
$this->_packageInfo['release_date'] = $date; |
$this->_isValid = false; |
} |
function getLicense() |
{ |
if (isset($this->_packageInfo['release_license'])) { |
return $this->_packageInfo['release_license']; |
} |
return false; |
} |
function setLicense($date) |
{ |
$this->_packageInfo['release_license'] = $date; |
$this->_isValid = false; |
} |
function getSummary() |
{ |
if (isset($this->_packageInfo['summary'])) { |
return $this->_packageInfo['summary']; |
} |
return false; |
} |
function setSummary($summary) |
{ |
$this->_packageInfo['summary'] = $summary; |
$this->_isValid = false; |
} |
function getDescription() |
{ |
if (isset($this->_packageInfo['description'])) { |
return $this->_packageInfo['description']; |
} |
return false; |
} |
function setDescription($desc) |
{ |
$this->_packageInfo['description'] = $desc; |
$this->_isValid = false; |
} |
function getNotes() |
{ |
if (isset($this->_packageInfo['release_notes'])) { |
return $this->_packageInfo['release_notes']; |
} |
return false; |
} |
function setNotes($notes) |
{ |
$this->_packageInfo['release_notes'] = $notes; |
$this->_isValid = false; |
} |
function getDeps() |
{ |
if (isset($this->_packageInfo['release_deps'])) { |
return $this->_packageInfo['release_deps']; |
} |
return false; |
} |
/** |
* Reset dependencies prior to adding new ones |
*/ |
function clearDeps() |
{ |
unset($this->_packageInfo['release_deps']); |
} |
function addPhpDep($version, $rel) |
{ |
$this->_isValid = false; |
$this->_packageInfo['release_deps'][] = |
array('type' => 'php', |
'rel' => $rel, |
'version' => $version); |
} |
function addPackageDep($name, $version, $rel, $optional = 'no') |
{ |
$this->_isValid = false; |
$dep = |
array('type' => 'pkg', |
'name' => $name, |
'rel' => $rel, |
'optional' => $optional); |
if ($rel != 'has' && $rel != 'not') { |
$dep['version'] = $version; |
} |
$this->_packageInfo['release_deps'][] = $dep; |
} |
function addExtensionDep($name, $version, $rel, $optional = 'no') |
{ |
$this->_isValid = false; |
$this->_packageInfo['release_deps'][] = |
array('type' => 'ext', |
'name' => $name, |
'rel' => $rel, |
'version' => $version, |
'optional' => $optional); |
} |
/** |
* WARNING - do not use this function directly unless you know what you're doing |
*/ |
function setDeps($deps) |
{ |
$this->_packageInfo['release_deps'] = $deps; |
} |
function hasDeps() |
{ |
return isset($this->_packageInfo['release_deps']) && |
count($this->_packageInfo['release_deps']); |
} |
function getDependencyGroup($group) |
{ |
return false; |
} |
function isCompatible($pf) |
{ |
return false; |
} |
function isSubpackageOf($p) |
{ |
return $p->isSubpackage($this); |
} |
function isSubpackage($p) |
{ |
return false; |
} |
function dependsOn($package, $channel) |
{ |
if (strtolower($channel) != 'pear.php.net') { |
return false; |
} |
if (!($deps = $this->getDeps())) { |
return false; |
} |
foreach ($deps as $dep) { |
if ($dep['type'] != 'pkg') { |
continue; |
} |
if (strtolower($dep['name']) == strtolower($package)) { |
return true; |
} |
} |
return false; |
} |
function getConfigureOptions() |
{ |
if (isset($this->_packageInfo['configure_options'])) { |
return $this->_packageInfo['configure_options']; |
} |
return false; |
} |
function hasConfigureOptions() |
{ |
return isset($this->_packageInfo['configure_options']) && |
count($this->_packageInfo['configure_options']); |
} |
function addConfigureOption($name, $prompt, $default = false) |
{ |
$o = array('name' => $name, 'prompt' => $prompt); |
if ($default !== false) { |
$o['default'] = $default; |
} |
if (!isset($this->_packageInfo['configure_options'])) { |
$this->_packageInfo['configure_options'] = array(); |
} |
$this->_packageInfo['configure_options'][] = $o; |
} |
function clearConfigureOptions() |
{ |
unset($this->_packageInfo['configure_options']); |
} |
function getProvides() |
{ |
if (isset($this->_packageInfo['provides'])) { |
return $this->_packageInfo['provides']; |
} |
return false; |
} |
function getProvidesExtension() |
{ |
return false; |
} |
function addFile($dir, $file, $attrs) |
{ |
$dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); |
if ($dir == '/' || $dir == '') { |
$dir = ''; |
} else { |
$dir .= '/'; |
} |
$file = $dir . $file; |
$file = preg_replace('![\\/]+!', '/', $file); |
$this->_packageInfo['filelist'][$file] = $attrs; |
} |
function getInstallationFilelist() |
{ |
return $this->getFilelist(); |
} |
function getFilelist() |
{ |
if (isset($this->_packageInfo['filelist'])) { |
return $this->_packageInfo['filelist']; |
} |
return false; |
} |
function setFileAttribute($file, $attr, $value) |
{ |
$this->_packageInfo['filelist'][$file][$attr] = $value; |
} |
function resetFilelist() |
{ |
$this->_packageInfo['filelist'] = array(); |
} |
function setInstalledAs($file, $path) |
{ |
if ($path) { |
return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; |
} |
unset($this->_packageInfo['filelist'][$file]['installed_as']); |
} |
function installedFile($file, $atts) |
{ |
if (isset($this->_packageInfo['filelist'][$file])) { |
$this->_packageInfo['filelist'][$file] = |
array_merge($this->_packageInfo['filelist'][$file], $atts); |
} else { |
$this->_packageInfo['filelist'][$file] = $atts; |
} |
} |
function getChangelog() |
{ |
if (isset($this->_packageInfo['changelog'])) { |
return $this->_packageInfo['changelog']; |
} |
return false; |
} |
function getPackagexmlVersion() |
{ |
return '1.0'; |
} |
/** |
* Wrapper to {@link PEAR_ErrorStack::getErrors()} |
* @param boolean determines whether to purge the error stack after retrieving |
* @return array |
*/ |
function getValidationWarnings($purge = true) |
{ |
return $this->_stack->getErrors($purge); |
} |
// }}} |
/** |
* Validation error. Also marks the object contents as invalid |
* @param error code |
* @param array error information |
* @access private |
*/ |
function _validateError($code, $params = array()) |
{ |
$this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); |
$this->_isValid = false; |
} |
/** |
* Validation warning. Does not mark the object contents invalid. |
* @param error code |
* @param array error information |
* @access private |
*/ |
function _validateWarning($code, $params = array()) |
{ |
$this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); |
} |
/** |
* @param integer error code |
* @access protected |
*/ |
function _getErrorMessage() |
{ |
return array( |
PEAR_PACKAGEFILE_ERROR_NO_NAME => |
'Missing Package Name', |
PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => |
'No summary found', |
PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => |
'Summary should be on one line', |
PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => |
'Missing description', |
PEAR_PACKAGEFILE_ERROR_NO_LICENSE => |
'Missing license', |
PEAR_PACKAGEFILE_ERROR_NO_VERSION => |
'No release version found', |
PEAR_PACKAGEFILE_ERROR_NO_STATE => |
'No release state found', |
PEAR_PACKAGEFILE_ERROR_NO_DATE => |
'No release date found', |
PEAR_PACKAGEFILE_ERROR_NO_NOTES => |
'No release notes found', |
PEAR_PACKAGEFILE_ERROR_NO_LEAD => |
'Package must have at least one lead maintainer', |
PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => |
'No maintainers found, at least one must be defined', |
PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => |
'Maintainer %index% has no handle (user ID at channel server)', |
PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => |
'Maintainer %index% has no role', |
PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => |
'Maintainer %index% has no name', |
PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => |
'Maintainer %index% has no email', |
PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => |
'Dependency %index% is not a php dependency, and has no name', |
PEAR_PACKAGEFILE_ERROR_NO_DEPREL => |
'Dependency %index% has no relation (rel)', |
PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => |
'Dependency %index% has no type', |
PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => |
'PHP Dependency %index% has a name attribute of "%name%" which will be' . |
' ignored!', |
PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => |
'Dependency %index% is not a rel="has" or rel="not" dependency, ' . |
'and has no version', |
PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => |
'Dependency %index% is a type="php" dependency, ' . |
'and has no version', |
PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => |
'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', |
PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => |
'Dependency %index% has invalid optional value "%opt%", should be yes or no', |
PEAR_PACKAGEFILE_PHP_NO_NOT => |
'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . |
' to exclude specific versions', |
PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => |
'Configure Option %index% has no name', |
PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => |
'Configure Option %index% has no prompt', |
PEAR_PACKAGEFILE_ERROR_NO_FILES => |
'No files in <filelist> section of package.xml', |
PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => |
'File "%file%" has no role, expecting one of "%roles%"', |
PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => |
'File "%file%" has invalid role "%role%", expecting one of "%roles%"', |
PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => |
'File "%file%" cannot start with ".", cannot package or install', |
PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => |
'Parser error: invalid PHP found in file "%file%"', |
PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => |
'in %file%: %type% "%name%" not prefixed with package name "%package%"', |
PEAR_PACKAGEFILE_ERROR_INVALID_FILE => |
'Parser error: invalid PHP file "%file%"', |
PEAR_PACKAGEFILE_ERROR_CHANNELVAL => |
'Channel validator error: field "%field%" - %reason%', |
PEAR_PACKAGEFILE_ERROR_PHP5 => |
'Error, PHP5 token encountered in %file%, analysis should be in PHP5', |
PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => |
'File "%file%" in package.xml does not exist', |
PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => |
'Package.xml contains non-ISO-8859-1 characters, and may not validate', |
); |
} |
/** |
* Validate XML package definition file. |
* |
* @access public |
* @return boolean |
*/ |
function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) |
{ |
if (($this->_isValid & $state) == $state) { |
return true; |
} |
$this->_isValid = true; |
$info = $this->_packageInfo; |
if (empty($info['package'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); |
$this->_packageName = $pn = 'unknown'; |
} else { |
$this->_packageName = $pn = $info['package']; |
} |
if (empty($info['summary'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); |
} elseif (strpos(trim($info['summary']), "\n") !== false) { |
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, |
array('summary' => $info['summary'])); |
} |
if (empty($info['description'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); |
} |
if (empty($info['release_license'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); |
} |
if (empty($info['version'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); |
} |
if (empty($info['release_state'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); |
} |
if (empty($info['release_date'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); |
} |
if (empty($info['release_notes'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); |
} |
if (empty($info['maintainers'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); |
} else { |
$haslead = false; |
$i = 1; |
foreach ($info['maintainers'] as $m) { |
if (empty($m['handle'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, |
array('index' => $i)); |
} |
if (empty($m['role'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, |
array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); |
} elseif ($m['role'] == 'lead') { |
$haslead = true; |
} |
if (empty($m['name'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, |
array('index' => $i)); |
} |
if (empty($m['email'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, |
array('index' => $i)); |
} |
$i++; |
} |
if (!$haslead) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); |
} |
} |
if (!empty($info['release_deps'])) { |
$i = 1; |
foreach ($info['release_deps'] as $d) { |
if (!isset($d['type']) || empty($d['type'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, |
array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); |
continue; |
} |
if (!isset($d['rel']) || empty($d['rel'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, |
array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); |
continue; |
} |
if (!empty($d['optional'])) { |
if (!in_array($d['optional'], array('yes', 'no'))) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, |
array('index' => $i, 'opt' => $d['optional'])); |
} |
} |
if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, |
array('index' => $i)); |
} elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { |
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, |
array('index' => $i, 'rel' => $d['rel'])); |
} |
if ($d['type'] == 'php' && !empty($d['name'])) { |
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, |
array('index' => $i, 'name' => $d['name'])); |
} elseif ($d['type'] != 'php' && empty($d['name'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, |
array('index' => $i)); |
} |
if ($d['type'] == 'php' && empty($d['version'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, |
array('index' => $i)); |
} |
if (($d['rel'] == 'not') && ($d['type'] == 'php')) { |
$this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, |
array('index' => $i)); |
} |
$i++; |
} |
} |
if (!empty($info['configure_options'])) { |
$i = 1; |
foreach ($info['configure_options'] as $c) { |
if (empty($c['name'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, |
array('index' => $i)); |
} |
if (empty($c['prompt'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, |
array('index' => $i)); |
} |
$i++; |
} |
} |
if (empty($info['filelist'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); |
$errors[] = 'no files'; |
} else { |
foreach ($info['filelist'] as $file => $fa) { |
if (empty($fa['role'])) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, |
array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); |
continue; |
} elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, |
array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); |
} |
if ($file{0} == '.' && $file{1} == '/') { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, |
array('file' => $file)); |
} |
} |
} |
if (isset($this->_registry) && $this->_isValid) { |
$chan = $this->_registry->getChannel('pear.php.net'); |
if (PEAR::isError($chan)) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); |
return $this->_isValid = 0; |
} |
$validator = $chan->getValidationObject(); |
$validator->setPackageFile($this); |
$validator->validate($state); |
$failures = $validator->getFailures(); |
foreach ($failures['errors'] as $error) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); |
} |
foreach ($failures['warnings'] as $warning) { |
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); |
} |
} |
if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { |
if ($this->_analyzePhpFiles()) { |
$this->_isValid = true; |
} |
} |
if ($this->_isValid) { |
return $this->_isValid = $state; |
} |
return $this->_isValid = 0; |
} |
function _analyzePhpFiles() |
{ |
if (!$this->_isValid) { |
return false; |
} |
if (!isset($this->_packageFile)) { |
return false; |
} |
$dir_prefix = dirname($this->_packageFile); |
$common = new PEAR_Common; |
$log = isset($this->_logger) ? array(&$this->_logger, 'log') : |
array($common, 'log'); |
$info = $this->getFilelist(); |
foreach ($info as $file => $fa) { |
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, |
array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); |
continue; |
} |
if ($fa['role'] == 'php' && $dir_prefix) { |
call_user_func_array($log, array(1, "Analyzing $file")); |
$srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); |
if ($srcinfo) { |
$this->_buildProvidesArray($srcinfo); |
} |
} |
} |
$this->_packageName = $pn = $this->getPackage(); |
$pnl = strlen($pn); |
if (isset($this->_packageInfo['provides'])) { |
foreach ((array) $this->_packageInfo['provides'] as $key => $what) { |
if (isset($what['explicit'])) { |
// skip conformance checks if the provides entry is |
// specified in the package.xml file |
continue; |
} |
extract($what); |
if ($type == 'class') { |
if (!strncasecmp($name, $pn, $pnl)) { |
continue; |
} |
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, |
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); |
} elseif ($type == 'function') { |
if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { |
continue; |
} |
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, |
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); |
} |
} |
} |
return $this->_isValid; |
} |
/** |
* Get the default xml generator object |
* |
* @return PEAR_PackageFile_Generator_v1 |
*/ |
function &getDefaultGenerator() |
{ |
if (!class_exists('PEAR_PackageFile_Generator_v1')) { |
require_once 'PEAR/PackageFile/Generator/v1.php'; |
} |
$a = &new PEAR_PackageFile_Generator_v1($this); |
return $a; |
} |
/** |
* Get the contents of a file listed within the package.xml |
* @param string |
* @return string |
*/ |
function getFileContents($file) |
{ |
if ($this->_archiveFile == $this->_packageFile) { // unpacked |
$dir = dirname($this->_packageFile); |
$file = $dir . DIRECTORY_SEPARATOR . $file; |
$file = str_replace(array('/', '\\'), |
array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); |
if (file_exists($file) && is_readable($file)) { |
return implode('', file($file)); |
} |
} else { // tgz |
if (!class_exists('Archive_Tar')) { |
require_once 'Archive/Tar.php'; |
} |
$tar = &new Archive_Tar($this->_archiveFile); |
$tar->pushErrorHandling(PEAR_ERROR_RETURN); |
if ($file != 'package.xml' && $file != 'package2.xml') { |
$file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; |
} |
$file = $tar->extractInString($file); |
$tar->popErrorHandling(); |
if (PEAR::isError($file)) { |
return PEAR::raiseError("Cannot locate file '$file' in archive"); |
} |
return $file; |
} |
} |
// {{{ analyzeSourceCode() |
/** |
* Analyze the source code of the given PHP file |
* |
* @param string Filename of the PHP file |
* @return mixed |
* @access private |
*/ |
function _analyzeSourceCode($file) |
{ |
if (!function_exists("token_get_all")) { |
return false; |
} |
if (!defined('T_DOC_COMMENT')) { |
define('T_DOC_COMMENT', T_COMMENT); |
} |
if (!defined('T_INTERFACE')) { |
define('T_INTERFACE', -1); |
} |
if (!defined('T_IMPLEMENTS')) { |
define('T_IMPLEMENTS', -1); |
} |
if (!$fp = @fopen($file, "r")) { |
return false; |
} |
fclose($fp); |
$contents = file_get_contents($file); |
$tokens = token_get_all($contents); |
/* |
for ($i = 0; $i < sizeof($tokens); $i++) { |
@list($token, $data) = $tokens[$i]; |
if (is_string($token)) { |
var_dump($token); |
} else { |
print token_name($token) . ' '; |
var_dump(rtrim($data)); |
} |
} |
*/ |
$look_for = 0; |
$paren_level = 0; |
$bracket_level = 0; |
$brace_level = 0; |
$lastphpdoc = ''; |
$current_class = ''; |
$current_interface = ''; |
$current_class_level = -1; |
$current_function = ''; |
$current_function_level = -1; |
$declared_classes = array(); |
$declared_interfaces = array(); |
$declared_functions = array(); |
$declared_methods = array(); |
$used_classes = array(); |
$used_functions = array(); |
$extends = array(); |
$implements = array(); |
$nodeps = array(); |
$inquote = false; |
$interface = false; |
for ($i = 0; $i < sizeof($tokens); $i++) { |
if (is_array($tokens[$i])) { |
list($token, $data) = $tokens[$i]; |
} else { |
$token = $tokens[$i]; |
$data = ''; |
} |
if ($inquote) { |
if ($token != '"' && $token != T_END_HEREDOC) { |
continue; |
} else { |
$inquote = false; |
continue; |
} |
} |
switch ($token) { |
case T_WHITESPACE : |
continue; |
case ';': |
if ($interface) { |
$current_function = ''; |
$current_function_level = -1; |
} |
break; |
case '"': |
case T_START_HEREDOC: |
$inquote = true; |
break; |
case T_CURLY_OPEN: |
case T_DOLLAR_OPEN_CURLY_BRACES: |
case '{': $brace_level++; continue 2; |
case '}': |
$brace_level--; |
if ($current_class_level == $brace_level) { |
$current_class = ''; |
$current_class_level = -1; |
} |
if ($current_function_level == $brace_level) { |
$current_function = ''; |
$current_function_level = -1; |
} |
continue 2; |
case '[': $bracket_level++; continue 2; |
case ']': $bracket_level--; continue 2; |
case '(': $paren_level++; continue 2; |
case ')': $paren_level--; continue 2; |
case T_INTERFACE: |
$interface = true; |
case T_CLASS: |
if (($current_class_level != -1) || ($current_function_level != -1)) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, |
array('file' => $file)); |
return false; |
} |
case T_FUNCTION: |
case T_NEW: |
case T_EXTENDS: |
case T_IMPLEMENTS: |
$look_for = $token; |
continue 2; |
case T_STRING: |
if (version_compare(zend_version(), '2.0', '<')) { |
if (in_array(strtolower($data), |
array('public', 'private', 'protected', 'abstract', |
'interface', 'implements', 'throw') |
)) { |
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, |
array($file)); |
} |
} |
if ($look_for == T_CLASS) { |
$current_class = $data; |
$current_class_level = $brace_level; |
$declared_classes[] = $current_class; |
} elseif ($look_for == T_INTERFACE) { |
$current_interface = $data; |
$current_class_level = $brace_level; |
$declared_interfaces[] = $current_interface; |
} elseif ($look_for == T_IMPLEMENTS) { |
$implements[$current_class] = $data; |
} elseif ($look_for == T_EXTENDS) { |
$extends[$current_class] = $data; |
} elseif ($look_for == T_FUNCTION) { |
if ($current_class) { |
$current_function = "$current_class::$data"; |
$declared_methods[$current_class][] = $data; |
} elseif ($current_interface) { |
$current_function = "$current_interface::$data"; |
$declared_methods[$current_interface][] = $data; |
} else { |
$current_function = $data; |
$declared_functions[] = $current_function; |
} |
$current_function_level = $brace_level; |
$m = array(); |
} elseif ($look_for == T_NEW) { |
$used_classes[$data] = true; |
} |
$look_for = 0; |
continue 2; |
case T_VARIABLE: |
$look_for = 0; |
continue 2; |
case T_DOC_COMMENT: |
case T_COMMENT: |
if (preg_match('!^/\*\*\s!', $data)) { |
$lastphpdoc = $data; |
if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { |
$nodeps = array_merge($nodeps, $m[1]); |
} |
} |
continue 2; |
case T_DOUBLE_COLON: |
if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { |
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, |
array('file' => $file)); |
return false; |
} |
$class = $tokens[$i - 1][1]; |
if (strtolower($class) != 'parent') { |
$used_classes[$class] = true; |
} |
continue 2; |
} |
} |
return array( |
"source_file" => $file, |
"declared_classes" => $declared_classes, |
"declared_interfaces" => $declared_interfaces, |
"declared_methods" => $declared_methods, |
"declared_functions" => $declared_functions, |
"used_classes" => array_diff(array_keys($used_classes), $nodeps), |
"inheritance" => $extends, |
"implements" => $implements, |
); |
} |
/** |
* Build a "provides" array from data returned by |
* analyzeSourceCode(). The format of the built array is like |
* this: |
* |
* array( |
* 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), |
* ... |
* ) |
* |
* |
* @param array $srcinfo array with information about a source file |
* as returned by the analyzeSourceCode() method. |
* |
* @return void |
* |
* @access private |
* |
*/ |
function _buildProvidesArray($srcinfo) |
{ |
if (!$this->_isValid) { |
return false; |
} |
$file = basename($srcinfo['source_file']); |
$pn = $this->getPackage(); |
$pnl = strlen($pn); |
foreach ($srcinfo['declared_classes'] as $class) { |
$key = "class;$class"; |
if (isset($this->_packageInfo['provides'][$key])) { |
continue; |
} |
$this->_packageInfo['provides'][$key] = |
array('file'=> $file, 'type' => 'class', 'name' => $class); |
if (isset($srcinfo['inheritance'][$class])) { |
$this->_packageInfo['provides'][$key]['extends'] = |
$srcinfo['inheritance'][$class]; |
} |
} |
foreach ($srcinfo['declared_methods'] as $class => $methods) { |
foreach ($methods as $method) { |
$function = "$class::$method"; |
$key = "function;$function"; |
if ($method{0} == '_' || !strcasecmp($method, $class) || |
isset($this->_packageInfo['provides'][$key])) { |
continue; |
} |
$this->_packageInfo['provides'][$key] = |
array('file'=> $file, 'type' => 'function', 'name' => $function); |
} |
} |
foreach ($srcinfo['declared_functions'] as $function) { |
$key = "function;$function"; |
if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { |
continue; |
} |
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { |
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; |
} |
$this->_packageInfo['provides'][$key] = |
array('file'=> $file, 'type' => 'function', 'name' => $function); |
} |
} |
// }}} |
} |
?> |
/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/v2.php |
---|
New file |
0,0 → 1,2039 |
<?php |
/** |
* PEAR_PackageFile_v2, package.xml version 2.0 |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: v2.php,v 1.136 2007/02/20 00:16:12 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 1.4.0a1 |
*/ |
/** |
* For error handling |
*/ |
require_once 'PEAR/ErrorStack.php'; |
/** |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.5.1 |
* @link http://pear.php.net/package/PEAR |
* @since Class available since Release 1.4.0a1 |
*/ |
class PEAR_PackageFile_v2 |
{ |
/** |
* Parsed package information |
* @var array |
* @access private |
*/ |
var $_packageInfo = array(); |
/** |
* path to package .tgz or false if this is a local/extracted package.xml |
* @var string|false |
* @access private |
*/ |
var $_archiveFile; |
/** |
* path to package .xml or false if this is an abstract parsed-from-string xml |
* @var string|false |
* @access private |
*/ |
var $_packageFile; |
/** |
* This is used by file analysis routines to log progress information |
* @var PEAR_Common |
* @access protected |
*/ |
var $_logger; |
/** |
* 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 |
* @var int |
* @access private |
*/ |
var $_isValid = 0; |
/** |
* True if the filelist has been validated |
* @param bool |
*/ |
var $_filesValid = false; |
/** |
* @var PEAR_Registry |
* @access protected |
*/ |
var $_registry; |
/** |
* @var PEAR_Config |
* @access protected |
*/ |
var $_config; |
/** |
* Optional Dependency group requested for installation |
* @var string |
* @access private |
*/ |
var $_requestedGroup = false; |
/** |
* @var PEAR_ErrorStack |
* @access protected |
*/ |
var $_stack; |
/** |
* Namespace prefix used for tasks in this package.xml - use tasks: whenever possible |
*/ |
var $_tasksNs; |
/** |
* Determines whether this packagefile was initialized only with partial package info |
* |
* If this package file was constructed via parsing REST, it will only contain |
* |
* - package name |
* - channel name |
* - dependencies |
* @var boolean |
* @access private |
*/ |
var $_incomplete = true; |
/** |
* @var PEAR_PackageFile_v2_Validator |
*/ |
var $_v2Validator; |
/** |
* The constructor merely sets up the private error stack |
*/ |
function PEAR_PackageFile_v2() |
{ |
$this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); |
$this->_isValid = false; |
} |
/** |
* To make unit-testing easier |
* @param PEAR_Frontend_* |
* @param array options |
* @param PEAR_Config |
* @return PEAR_Downloader |
* @access protected |
*/ |
function &getPEARDownloader(&$i, $o, &$c) |
{ |
$z = &new PEAR_Downloader($i, $o, $c); |
return $z; |
} |
/** |
* To make unit-testing easier |
* @param PEAR_Config |
* @param array options |
* @param array package name as returned from {@link PEAR_Registry::parsePackageName()} |
* @param int PEAR_VALIDATE_* constant |
* @return PEAR_Dependency2 |
* @access protected |
*/ |
function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) |
{ |
if (!class_exists('PEAR_Dependency2')) { |
require_once 'PEAR/Dependency2.php'; |
} |
$z = &new PEAR_Dependency2($c, $o, $p, $s); |
return $z; |
} |
function getInstalledBinary() |
{ |
return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : |
false; |
} |
/** |
* Installation of source package has failed, attempt to download and install the |
* binary version of this package. |
* @param PEAR_Installer |
* @return array|false |
*/ |
function installBinary(&$installer) |
{ |
if (!OS_WINDOWS) { |
$a = false; |
return $a; |
} |
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { |
$releasetype = $this->getPackageType() . 'release'; |
if (!is_array($installer->getInstallPackages())) { |
$a = false; |
return $a; |
} |
foreach ($installer->getInstallPackages() as $p) { |
if ($p->isExtension($this->_packageInfo['providesextension'])) { |
if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { |
$a = false; |
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()); |
} |
} |
$dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), |
$installer->config); |
$verbose = $dl->config->get('verbose'); |
$dl->config->set('verbose', -1); |
foreach ($params as $param) { |
PEAR::pushErrorHandling(PEAR_ERROR_RETURN); |
$ret = $dl->download(array($param)); |
PEAR::popErrorHandling(); |
if (is_array($ret) && count($ret)) { |
break; |
} |
} |
$dl->config->set('verbose', $verbose); |
if (is_array($ret)) { |
if (count($ret) == 1) { |
$pf = $ret[0]->getPackageFile(); |
PEAR::pushErrorHandling(PEAR_ERROR_RETURN); |
$err = $installer->install($ret[0]); |
PEAR::popErrorHandling(); |
if (is_array($err)) { |
$this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); |
// "install" self, so all dependencies will work transparently |
$this->_registry->addPackage2($this); |
$installer->log(0, 'Download and install of binary extension "' . |
$this->_registry->parsedPackageNameToString( |
array('channel' => $pf->getChannel(), |
'package' => $pf->getPackage()), true) . '" successful'); |
$a = array($ret[0], $err); |
return $a; |
} |
$installer->log(0, 'Download and install of binary extension "' . |
$this->_registry->parsedPackageNameToString( |
array('channel' => $pf->getChannel(), |
'package' => $pf->getPackage()), true) . '" failed'); |
} |
} |
} |
} |
$a = false; |
return $a; |
} |
/** |
* @return string|false Extension name |
*/ |
function getProvidesExtension() |
{ |
if (in_array($this->getPackageType(), |
array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { |
if (isset($this->_packageInfo['providesextension'])) { |
return $this->_packageInfo['providesextension']; |
} |
} |
return false; |
} |
/** |
* @param string Extension name |
* @return bool |
*/ |
function isExtension($extension) |
{ |
if (in_array($this->getPackageType(), |
array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { |
return $this->_packageInfo['providesextension'] == $extension; |
} |
return false; |
} |
/** |
* Tests whether every part of the package.xml 1.0 is represented in |
* this package.xml 2.0 |
* @param PEAR_PackageFile_v1 |
* @return bool |
*/ |
function isEquivalent($pf1) |
{ |
if (!$pf1) { |
return true; |
} |
if ($this->getPackageType() == 'bundle') { |
return false; |
} |
$this->_stack->getErrors(true); |
if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { |
return false; |
} |
$pass = true; |
if ($pf1->getPackage() != $this->getPackage()) { |
$this->_differentPackage($pf1->getPackage()); |
$pass = false; |
} |
if ($pf1->getVersion() != $this->getVersion()) { |
$this->_differentVersion($pf1->getVersion()); |
$pass = false; |
} |
if (trim($pf1->getSummary()) != $this->getSummary()) { |
$this->_differentSummary($pf1->getSummary()); |
$pass = false; |
} |
if (preg_replace('/\s+/', '', $pf1->getDescription()) != |
preg_replace('/\s+/', '', $this->getDescription())) { |
$this->_differentDescription($pf1->getDescription()); |
$pass = false; |
} |
if ($pf1->getState() != $this->getState()) { |
$this->_differentState($pf1->getState()); |
$pass = false; |
} |
if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), |
preg_replace('/\s+/', '', $pf1->getNotes()))) { |
$this->_differentNotes($pf1->getNotes()); |
$pass = false; |
} |
$mymaintainers = $this->getMaintainers(); |
$yourmaintainers = $pf1->getMaintainers(); |
for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { |
$reset = false; |
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']); |
$pass = false; |
} |
if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { |
$this->_differentEmail($mymaintainers[$i2]['handle'], |
$yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); |
$pass = false; |
} |
if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { |
$this->_differentName($mymaintainers[$i2]['handle'], |
$yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); |
$pass = false; |
} |
unset($mymaintainers[$i2]); |
$mymaintainers = array_values($mymaintainers); |
unset($yourmaintainers[$i1]); |
$yourmaintainers = array_values($yourmaintainers); |
$reset = true; |
break; |
} |
} |
if ($reset) { |
$i1 = -1; |
} |
} |
$this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); |
$filelist = $this->getFilelist(); |
foreach ($pf1->getFilelist() as $file => $atts) { |
if (!isset($filelist[$file])) { |
$this->_missingFile($file); |
$pass = false; |
} |
} |
return $pass; |
} |
function _differentPackage($package) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('package' => $package, |
'self' => $this->getPackage()), |
'package.xml 1.0 package "%package%" does not match "%self%"'); |
} |
function _differentVersion($version) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('version' => $version, |
'self' => $this->getVersion()), |
'package.xml 1.0 version "%version%" does not match "%self%"'); |
} |
function _differentState($state) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('state' => $state, |
'self' => $this->getState()), |
'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) |
{ |
if ($my) { |
array_walk($my, create_function('&$i, $k', '$i = $i["handle"];')); |
$this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), |
'package.xml 2.0 has unmatched extra maintainers "%handles%"'); |
} |
if ($yours) { |
array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];')); |
$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) . '...'; |
$truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : |
substr($this->getNotes(), 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) . '...'; |
$truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : |
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) . '...'); |
$truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : |
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 |
*/ |
function setRawState($state) |
{ |
$this->_packageInfo['stability']['release'] = $state; |
} |
/** |
* WARNING - do not use this function unless you know what you're doing |
*/ |
function setRawCompatible($compatible) |
{ |
$this->_packageInfo['compatible'] = $compatible; |
} |
/** |
* WARNING - do not use this function unless you know what you're doing |
*/ |
function setRawPackage($package) |
{ |
$this->_packageInfo['name'] = $package; |
} |
/** |
* WARNING - do not use this function unless you know what you're doing |
*/ |
function setRawChannel($channel) |
{ |
$this->_packageInfo['channel'] = $channel; |
} |
function setRequestedGroup($group) |
{ |
$this->_requestedGroup = $group; |
} |
function getRequestedGroup() |
{ |
if (isset($this->_requestedGroup)) { |
return $this->_requestedGroup; |
} |
return false; |
} |
/** |
* For saving in the registry. |
* |
* Set the last version that was installed |
* @param string |
*/ |
function setLastInstalledVersion($version) |
{ |
$this->_packageInfo['_lastversion'] = $version; |
} |
/** |
* @return string|false |
*/ |
function getLastInstalledVersion() |
{ |
if (isset($this->_packageInfo['_lastversion'])) { |
return $this->_packageInfo['_lastversion']; |
} |
return false; |
} |
/** |
* Determines whether this package.xml has post-install scripts or not |
* @return array|false |
*/ |
function listPostinstallScripts() |
{ |
$filelist = $this->getFilelist(); |
$contents = $this->getContents(); |
$contents = $contents['dir']['file']; |
if (!is_array($contents) || !isset($contents[0])) { |
$contents = array($contents); |
} |
$taskfiles = array(); |
foreach ($contents as $file) { |
$atts = $file['attribs']; |
unset($file['attribs']); |
if (count($file)) { |
$taskfiles[$atts['name']] = $file; |
} |
} |
$common = new PEAR_Common; |
$common->debug = $this->_config->get('verbose'); |
$this->_scripts = array(); |
$ret = array(); |
foreach ($taskfiles as $name => $tasks) { |
if (!isset($filelist[$name])) { |
// ignored files will not be in the filelist |
continue; |
} |
$atts = $filelist[$name]; |
foreach ($tasks as $tag => $raw) { |
$task = $this->getTask($tag); |
$task = &new $task($this->_config, $common, PEAR_TASK_INSTALL); |
if ($task->isScript()) { |
$ret[] = $filelist[$name]['installed_as']; |
} |
} |
} |
if (count($ret)) { |
return $ret; |
} |
return false; |
} |
/** |
* Initialize post-install scripts for running |
* |
* This method can be used to detect post-install scripts, as the return value |
* indicates whether any exist |
* @return bool |
*/ |
function initPostinstallScripts() |
{ |
$filelist = $this->getFilelist(); |
$contents = $this->getContents(); |
$contents = $contents['dir']['file']; |
if (!is_array($contents) || !isset($contents[0])) { |
$contents = array($contents); |
} |
$taskfiles = array(); |
foreach ($contents as $file) { |
$atts = $file['attribs']; |
unset($file['attribs']); |
if (count($file)) { |
$taskfiles[$atts['name']] = $file; |
} |
} |
$common = new PEAR_Common; |
$common->debug = $this->_config->get('verbose'); |
$this->_scripts = array(); |
foreach ($taskfiles as $name => $tasks) { |
if (!isset($filelist[$name])) { |
// file was not installed due to installconditions |
continue; |
} |
$atts = $filelist[$name]; |
foreach ($tasks as $tag => $raw) { |
$taskname = $this->getTask($tag); |
$task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL); |
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']); |
if (!$res) { |
continue; // skip this file |
} |
if (PEAR::isError($res)) { |
return $res; |
} |
$assign = &$task; |
$this->_scripts[] = &$assign; |
} |
} |
if (count($this->_scripts)) { |
return true; |
} |
return false; |
} |
function runPostinstallScripts() |
{ |
if ($this->initPostinstallScripts()) { |
$ui = &PEAR_Frontend::singleton(); |
if ($ui) { |
$ui->runPostinstallScripts($this->_scripts, $this); |
} |
} |
} |
/** |
* Convert a recursive set of <dir> and <file> tags into a single <dir> tag with |
* <file> tags. |
*/ |
function flattenFilelist() |
{ |
if (isset($this->_packageInfo['bundle'])) { |
return; |
} |
$filelist = array(); |
if (isset($this->_packageInfo['contents']['dir']['dir'])) { |
$this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); |
if (!isset($filelist[1])) { |
$filelist = $filelist[0]; |
} |
$this->_packageInfo['contents']['dir']['file'] = $filelist; |
unset($this->_packageInfo['contents']['dir']['dir']); |
} else { |
// 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'])) { |
continue; |
} |
$this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] |
= $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; |
} |
} else { |
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|false any recursively inherited baeinstalldir attribute |
* @param string private recursion variable |
* @return array |
* @access protected |
*/ |
function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') |
{ |
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 = '*unknown*'; |
} else { |
$name = $subdir['attribs']['name']; |
} |
$newpath = empty($path) ? $name : |
$path . '/' . $name; |
$this->_getFlattenedFilelist($files, $subdir, |
$baseinstall, $newpath); |
} |
} |
if (isset($dir['file'])) { |
if (!isset($dir['file'][0])) { |
$dir['file'] = array($dir['file']); |
} |
foreach ($dir['file'] as $file) { |
$attrs = $file['attribs']; |
$name = $attrs['name']; |
if ($baseinstall && !isset($attrs['baseinstalldir'])) { |
$attrs['baseinstalldir'] = $baseinstall; |
} |
$attrs['name'] = empty($path) ? $name : $path . '/' . $name; |
$attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), |
$attrs['name']); |
$file['attribs'] = $attrs; |
$files[] = $file; |
} |
} |
} |
function setConfig(&$config) |
{ |
$this->_config = &$config; |
$this->_registry = &$config->getRegistry(); |
} |
function setLogger(&$logger) |
{ |
if (!is_object($logger) || !method_exists($logger, 'log')) { |
return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); |
} |
$this->_logger = &$logger; |
} |
/** |
* WARNING - do not use this function directly unless you know what you're doing |
*/ |
function setDeps($deps) |
{ |
$this->_packageInfo['dependencies'] = $deps; |
} |
/** |
* WARNING - do not use this function directly unless you know what you're doing |
*/ |
function setCompatible($compat) |
{ |
$this->_packageInfo['compatible'] = $compat; |
} |
function setPackagefile($file, $archive = false) |
{ |
$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 array |
*/ |
function getValidationWarnings($purge = true) |
{ |
return $this->_stack->getErrors($purge); |
} |
function getPackageFile() |
{ |
return $this->_packageFile; |
} |
function getArchiveFile() |
{ |
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 |
* @param array |
*/ |
function fromArray($pinfo) |
{ |
unset($pinfo['old']); |
unset($pinfo['xsdversion']); |
$this->_incomplete = false; |
$this->_packageInfo = $pinfo; |
} |
function isIncomplete() |
{ |
return $this->_incomplete; |
} |
/** |
* @return array |
*/ |
function toArray($forreg = false) |
{ |
if (!$this->validate(PEAR_VALIDATE_NORMAL)) { |
return false; |
} |
return $this->getArray($forreg); |
} |
function getArray($forReg = false) |
{ |
if ($forReg) { |
$arr = $this->_packageInfo; |
$arr['old'] = array(); |
$arr['old']['version'] = $this->getVersion(); |
$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['old']['maintainers'] = $this->getMaintainers(); |
$arr['xsdversion'] = '2.0'; |
return $arr; |
} else { |
$info = $this->_packageInfo; |
unset($info['dirtree']); |
if (isset($info['_lastversion'])) { |
unset($info['_lastversion']); |
} |
if (isset($info['#binarypackage'])) { |
unset($info['#binarypackage']); |
} |
return $info; |
} |
} |
function packageInfo($field) |
{ |
$arr = $this->getArray(true); |
if ($field == 'state') { |
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])) { |
if (!is_string($arr['old'][$field])) { |
return null; |
} |
return $arr['old'][$field]; |
} |
if (isset($arr[$field])) { |
if (!is_string($arr[$field])) { |
return null; |
} |
return $arr[$field]; |
} |
return null; |
} |
function getName() |
{ |
return $this->getPackage(); |
} |
function getPackage() |
{ |
if (isset($this->_packageInfo['name'])) { |
return $this->_packageInfo['name']; |
} |
return false; |
} |
function getChannel() |
{ |
if (isset($this->_packageInfo['uri'])) { |
return '__uri'; |
} |
if (isset($this->_packageInfo['channel'])) { |
return strtolower($this->_packageInfo['channel']); |
} |
return false; |
} |
function getUri() |
{ |
if (isset($this->_packageInfo['uri'])) { |
return $this->_packageInfo['uri']; |
} |
return false; |
} |
function getExtends() |
{ |
if (isset($this->_packageInfo['extends'])) { |
return $this->_packageInfo['extends']; |
} |
return false; |
} |
function getSummary() |
{ |
if (isset($this->_packageInfo['summary'])) { |
return $this->_packageInfo['summary']; |
} |
return false; |
} |
function getDescription() |
{ |
if (isset($this->_packageInfo['description'])) { |
return $this->_packageInfo['description']; |
} |
return false; |
} |
function getMaintainers($raw = false) |
{ |
if (!isset($this->_packageInfo['lead'])) { |
return false; |
} |
if ($raw) { |
$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; |
return $ret; |
} else { |
$ret = array(); |
$leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : |
array($this->_packageInfo['lead']); |
foreach ($leads as $lead) { |
$s = $lead; |
$s['handle'] = $s['user']; |
unset($s['user']); |
$s['role'] = 'lead'; |
$ret[] = $s; |
} |
if (isset($this->_packageInfo['developer'])) { |
$leads = isset($this->_packageInfo['developer'][0]) ? |
$this->_packageInfo['developer'] : |
array($this->_packageInfo['developer']); |
foreach ($leads as $maintainer) { |
$s = $maintainer; |
$s['handle'] = $s['user']; |
unset($s['user']); |
$s['role'] = 'developer'; |
$ret[] = $s; |
} |
} |
if (isset($this->_packageInfo['contributor'])) { |
$leads = isset($this->_packageInfo['contributor'][0]) ? |
$this->_packageInfo['contributor'] : |
array($this->_packageInfo['contributor']); |
foreach ($leads as $maintainer) { |
$s = $maintainer; |
$s['handle'] = $s['user']; |
unset($s['user']); |
$s['role'] = 'contributor'; |
$ret[] = $s; |
} |
} |
if (isset($this->_packageInfo['helper'])) { |
$leads = isset($this->_packageInfo['helper'][0]) ? |
$this->_packageInfo['helper'] : |
array($this->_packageInfo['helper']); |
foreach ($leads as $maintainer) { |
$s = $maintainer; |
$s['handle'] = $s['user']; |
unset($s['user']); |
$s['role'] = 'helper'; |
$ret[] = $s; |
} |
} |
return $ret; |
} |
return false; |
} |
function getLeads() |
{ |
if (isset($this->_packageInfo['lead'])) { |
return $this->_packageInfo['lead']; |
} |
return false; |
} |
function getDevelopers() |
{ |
if (isset($this->_packageInfo['developer'])) { |
return $this->_packageInfo['developer']; |
} |
return false; |
} |
function getContributors() |
{ |
if (isset($this->_packageInfo['contributor'])) { |
return $this->_packageInfo['contributor']; |
} |
return false; |
} |
function getHelpers() |
{ |
if (isset($this->_packageInfo['helper'])) { |
return $this->_packageInfo['helper']; |
} |
return false; |
} |
function setDate($date) |
{ |
if (!isset($this->_packageInfo['date'])) { |
// ensure that the extends tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('time', 'version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', |
'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); |
} |
$this->_packageInfo['date'] = $date; |
$this->_isValid = 0; |
} |
function setTime($time) |
{ |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['time'])) { |
// ensure that the time tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', |
'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); |
} |
$this->_packageInfo['time'] = $time; |
} |
function getDate() |
{ |
if (isset($this->_packageInfo['date'])) { |
return $this->_packageInfo['date']; |
} |
return false; |
} |
function getTime() |
{ |
if (isset($this->_packageInfo['time'])) { |
return $this->_packageInfo['time']; |
} |
return false; |
} |
/** |
* @param package|api version category to return |
*/ |
function getVersion($key = 'release') |
{ |
if (isset($this->_packageInfo['version'][$key])) { |
return $this->_packageInfo['version'][$key]; |
} |
return false; |
} |
function getStability() |
{ |
if (isset($this->_packageInfo['stability'])) { |
return $this->_packageInfo['stability']; |
} |
return false; |
} |
function getState($key = 'release') |
{ |
if (isset($this->_packageInfo['stability'][$key])) { |
return $this->_packageInfo['stability'][$key]; |
} |
return false; |
} |
function getLicense($raw = false) |
{ |
if (isset($this->_packageInfo['license'])) { |
if ($raw) { |
return $this->_packageInfo['license']; |
} |
if (is_array($this->_packageInfo['license'])) { |
return $this->_packageInfo['license']['_content']; |
} else { |
return $this->_packageInfo['license']; |
} |
} |
return false; |
} |
function getLicenseLocation() |
{ |
if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { |
return false; |
} |
return $this->_packageInfo['license']['attribs']; |
} |
function getNotes() |
{ |
if (isset($this->_packageInfo['notes'])) { |
return $this->_packageInfo['notes']; |
} |
return false; |
} |
/** |
* Return the <usesrole> tag contents, if any |
* @return array|false |
*/ |
function getUsesrole() |
{ |
if (isset($this->_packageInfo['usesrole'])) { |
return $this->_packageInfo['usesrole']; |
} |
return false; |
} |
/** |
* Return the <usestask> tag contents, if any |
* @return array|false |
*/ |
function getUsestask() |
{ |
if (isset($this->_packageInfo['usestask'])) { |
return $this->_packageInfo['usestask']; |
} |
return false; |
} |
/** |
* This should only be used to retrieve filenames and install attributes |
*/ |
function getFilelist($preserve = false) |
{ |
if (isset($this->_packageInfo['filelist']) && !$preserve) { |
return $this->_packageInfo['filelist']; |
} |
$this->flattenFilelist(); |
if ($contents = $this->getContents()) { |
$ret = array(); |
if (!isset($contents['dir']['file'][0])) { |
$contents['dir']['file'] = array($contents['dir']['file']); |
} |
foreach ($contents['dir']['file'] as $file) { |
$name = $file['attribs']['name']; |
if (!$preserve) { |
$file = $file['attribs']; |
} |
$ret[$name] = $file; |
} |
if (!$preserve) { |
$this->_packageInfo['filelist'] = $ret; |
} |
return $ret; |
} |
return false; |
} |
/** |
* Return configure options array, if any |
* |
* @return array|false |
*/ |
function getConfigureOptions() |
{ |
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { |
return false; |
} |
$releases = $this->getReleases(); |
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']; |
} |
return false; |
} |
/** |
* This is only used at install-time, after all serialization |
* is over. |
*/ |
function resetFilelist() |
{ |
$this->_packageInfo['filelist'] = array(); |
} |
/** |
* Retrieve a list of files that should be installed on this computer |
* @return array |
*/ |
function getInstallationFilelist($forfilecheck = false) |
{ |
$contents = $this->getFilelist(true); |
if (isset($contents['dir']['attribs']['baseinstalldir'])) { |
$base = $contents['dir']['attribs']['baseinstalldir']; |
} |
if (isset($this->_packageInfo['bundle'])) { |
return PEAR::raiseError( |
'Exception: bundles should be handled in download code only'); |
} |
$release = $this->getReleases(); |
if ($release) { |
if (!isset($release[0])) { |
if (!isset($release['installconditions']) && !isset($release['filelist'])) { |
if ($forfilecheck) { |
return $this->getFilelist(); |
} |
return $contents; |
} |
$release = array($release); |
} |
$depchecker = &$this->getPEARDependency2($this->_config, array(), |
array('channel' => $this->getChannel(), 'package' => $this->getPackage()), |
PEAR_VALIDATE_INSTALLING); |
foreach ($release as $instance) { |
if (isset($instance['installconditions'])) { |
$installconditions = $instance['installconditions']; |
if (is_array($installconditions)) { |
PEAR::pushErrorHandling(PEAR_ERROR_RETURN); |
foreach ($installconditions as $type => $conditions) { |
if (!isset($conditions[0])) { |
$conditions = array($conditions); |
} |
foreach ($conditions as $condition) { |
$ret = $depchecker->{"validate{$type}Dependency"}($condition); |
if (PEAR::isError($ret)) { |
PEAR::popErrorHandling(); |
continue 3; // skip this release |
} |
} |
} |
PEAR::popErrorHandling(); |
} |
} |
// this is the release to use |
if (isset($instance['filelist'])) { |
// ignore files |
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'] = |
$as['attribs']['as']; |
} |
} |
} |
if ($forfilecheck) { |
foreach ($contents as $file => $attrs) { |
$contents[$file] = $attrs['attribs']; |
} |
} |
return $contents; |
} |
} else { // simple release - no installconditions or install-as |
if ($forfilecheck) { |
return $this->getFilelist(); |
} |
return $contents; |
} |
// no releases matched |
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 |
* is over. |
* @param string file name |
* @param string installed path |
*/ |
function setInstalledAs($file, $path) |
{ |
if ($path) { |
return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; |
} |
unset($this->_packageInfo['filelist'][$file]['installed_as']); |
} |
function getInstalledLocation($file) |
{ |
if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { |
return $this->_packageInfo['filelist'][$file]['installed_as']; |
} |
return false; |
} |
/** |
* This is only used at install-time, after all serialization |
* is over. |
*/ |
function installedFile($file, $atts) |
{ |
if (isset($this->_packageInfo['filelist'][$file])) { |
$this->_packageInfo['filelist'][$file] = |
array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); |
} else { |
$this->_packageInfo['filelist'][$file] = $atts['attribs']; |
} |
} |
/** |
* Retrieve the contents tag |
*/ |
function getContents() |
{ |
if (isset($this->_packageInfo['contents'])) { |
return $this->_packageInfo['contents']; |
} |
return false; |
} |
/** |
* @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 |
*/ |
function setFileAttribute($filename, $attr, $value, $index = false) |
{ |
$this->_isValid = 0; |
if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { |
$this->_filesValid = false; |
} |
if ($index !== false && |
isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { |
$this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; |
return true; |
} |
if (!isset($this->_packageInfo['contents']['dir']['file'])) { |
return false; |
} |
$files = $this->_packageInfo['contents']['dir']['file']; |
if (!isset($files[0])) { |
$files = array($files); |
$ind = false; |
} else { |
$ind = true; |
} |
foreach ($files as $i => $file) { |
if (isset($file['attribs'])) { |
if ($file['attribs']['name'] == $filename) { |
if ($ind) { |
$this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; |
} else { |
$this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; |
} |
return true; |
} |
} |
} |
return false; |
} |
function setDirtree($path) |
{ |
if (!isset($this->_packageInfo['dirtree'])) { |
$this->_packageInfo['dirtree'] = array(); |
} |
$this->_packageInfo['dirtree'][$path] = true; |
} |
function getDirtree() |
{ |
if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { |
return $this->_packageInfo['dirtree']; |
} |
return false; |
} |
function resetDirtree() |
{ |
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 |
* @return boolean |
*/ |
function isCompatible($pf) |
{ |
if (!isset($this->_packageInfo['compatible'])) { |
return false; |
} |
if (!isset($this->_packageInfo['channel'])) { |
return false; |
} |
$me = $pf->getVersion(); |
$compatible = $this->_packageInfo['compatible']; |
if (!isset($compatible[0])) { |
$compatible = array($compatible); |
} |
$found = false; |
foreach ($compatible as $info) { |
if (strtolower($info['name']) == strtolower($pf->getPackage())) { |
if (strtolower($info['channel']) == strtolower($pf->getChannel())) { |
$found = true; |
break; |
} |
} |
} |
if (!$found) { |
return false; |
} |
if (isset($info['exclude'])) { |
if (!isset($info['exclude'][0])) { |
$info['exclude'] = array($info['exclude']); |
} |
foreach ($info['exclude'] as $exclude) { |
if (version_compare($me, $exclude, '==')) { |
return false; |
} |
} |
} |
if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { |
return true; |
} |
return false; |
} |
/** |
* @return array|false |
*/ |
function getCompatible() |
{ |
if (isset($this->_packageInfo['compatible'])) { |
return $this->_packageInfo['compatible']; |
} |
return false; |
} |
function getDependencies() |
{ |
if (isset($this->_packageInfo['dependencies'])) { |
return $this->_packageInfo['dependencies']; |
} |
return false; |
} |
function isSubpackageOf($p) |
{ |
return $p->isSubpackage($this); |
} |
/** |
* 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 |
* @return bool |
*/ |
function isSubpackage($p) |
{ |
$sub = array(); |
if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { |
$sub = $this->_packageInfo['dependencies']['required']['subpackage']; |
if (!isset($sub[0])) { |
$sub = array($sub); |
} |
} |
if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { |
$sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; |
if (!isset($sub1[0])) { |
$sub1 = array($sub1); |
} |
$sub = array_merge($sub, $sub1); |
} |
if (isset($this->_packageInfo['dependencies']['group'])) { |
$group = $this->_packageInfo['dependencies']['group']; |
if (!isset($group[0])) { |
$group = array($group); |
} |
foreach ($group as $deps) { |
if (isset($deps['subpackage'])) { |
$sub2 = $deps['subpackage']; |
if (!isset($sub2[0])) { |
$sub2 = array($sub2); |
} |
$sub = array_merge($sub, $sub2); |
} |
} |
} |
foreach ($sub as $dep) { |
if (strtolower($dep['name']) == strtolower($p->getPackage())) { |
if (isset($dep['channel'])) { |
if (strtolower($dep['channel']) == strtolower($p->getChannel())) { |
return true; |
} |
} else { |
if ($dep['uri'] == $p->getURI()) { |
return true; |
} |
} |
} |
} |
return false; |
} |
function dependsOn($package, $channel) |
{ |
if (!($deps = $this->getDependencies())) { |
return false; |
} |
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'; |
if (strtolower($dep['name']) == strtolower($package) && |
$depchannel == $channel) { |
return true; |
} |
} |
} |
} |
if (isset($deps['group'])) { |
if (!isset($deps['group'][0])) { |
$dep['group'] = array($deps['group']); |
} |
foreach ($deps['group'] as $group) { |
if (isset($group[$type])) { |
if (!is_array($group[$type])) { |
$group[$type] = array($group[$type]); |
} |
foreach ($group[$type] as $dep) { |
$depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; |
if (strtolower($dep['name']) == strtolower($package) && |
$depchannel == $channel) { |
return true; |
} |
} |
} |
} |
} |
} |
return false; |
} |
/** |
* Get the contents of a dependency group |
* @param string |
* @return array|false |
*/ |
function getDependencyGroup($name) |
{ |
$name = strtolower($name); |
if (!isset($this->_packageInfo['dependencies']['group'])) { |
return false; |
} |
$groups = $this->_packageInfo['dependencies']['group']; |
if (!isset($groups[0])) { |
$groups = array($groups); |
} |
foreach ($groups as $group) { |
if (strtolower($group['attribs']['name']) == $name) { |
return $group; |
} |
} |
return false; |
} |
/** |
* 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 |
* @return array|false |
*/ |
function getDeps($raw = false, $nopearinstaller = false) |
{ |
if (isset($this->_packageInfo['dependencies'])) { |
if ($raw) { |
return $this->_packageInfo['dependencies']; |
} |
$ret = array(); |
$map = array( |
'php' => 'php', |
'package' => 'pkg', |
'subpackage' => 'pkg', |
'extension' => 'ext', |
'os' => 'os', |
'pearinstaller' => 'pkg', |
); |
foreach (array('required', 'optional') as $type) { |
$optional = ($type == 'optional') ? 'yes' : 'no'; |
if (!isset($this->_packageInfo['dependencies'][$type])) { |
continue; |
} |
foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { |
if ($dtype == 'pearinstaller' && $nopearinstaller) { |
continue; |
} |
if (!isset($deps[0])) { |
$deps = array($deps); |
} |
foreach ($deps as $dep) { |
if (!isset($map[$dtype])) { |
// no support for arch type |
continue; |
} |
if ($dtype == 'pearinstaller') { |
$dep['name'] = 'PEAR'; |
$dep['channel'] = 'pear.php.net'; |
} |
$s = array('type' => $map[$dtype]); |
if (isset($dep['channel'])) { |
$s['channel'] = $dep['channel']; |
} |
if (isset($dep['uri'])) { |
$s['uri'] = $dep['uri']; |
} |
if (isset($dep['name'])) { |
$s['name'] = $dep['name']; |
} |
if (isset($dep['conflicts'])) { |
$s['rel'] = 'not'; |
} else { |
if (!isset($dep['min']) && |
!isset($dep['max'])) { |
$s['rel'] = 'has'; |
$s['optional'] = $optional; |
} elseif (isset($dep['min']) && |
isset($dep['max'])) { |
$s['rel'] = 'ge'; |
$s1 = $s; |
$s1['rel'] = 'le'; |
$s['version'] = $dep['min']; |
$s1['version'] = $dep['max']; |
if (isset($dep['channel'])) { |
$s1['channel'] = $dep['channel']; |
} |
if ($dtype != 'php') { |
$s['name'] = $dep['name']; |
$s1['name'] = $dep['name']; |
} |
$s['optional'] = $optional; |
$s1['optional'] = $optional; |
$ret[] = $s1; |
} elseif (isset($dep['min'])) { |
if (isset($dep['exclude']) && |
$dep['exclude'] == $dep['min']) { |
$s['rel'] = 'gt'; |
} else { |
$s['rel'] = 'ge'; |
} |
$s['version'] = $dep['min']; |
$s['optional'] = $optional; |
if ($dtype != 'php') { |
$s['name'] = $dep['name']; |
} |
} elseif (isset($dep['max'])) { |
if (isset($dep['exclude']) && |
$dep['exclude'] == $dep['max']) { |
$s['rel'] = 'lt'; |
} else { |
$s['rel'] = 'le'; |
} |
$s['version'] = $dep['max']; |
$s['optional'] = $optional; |
if ($dtype != 'php') { |
$s['name'] = $dep['name']; |
} |
} |
} |
$ret[] = $s; |
} |
} |
} |
if (count($ret)) { |
return $ret; |
} |
} |
return false; |
} |
/** |
* @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false |
*/ |
function getPackageType() |
{ |
if (isset($this->_packageInfo['phprelease'])) { |
return 'php'; |
} |
if (isset($this->_packageInfo['extsrcrelease'])) { |
return 'extsrc'; |
} |
if (isset($this->_packageInfo['extbinrelease'])) { |
return 'extbin'; |
} |
if (isset($this->_packageInfo['zendextsrcrelease'])) { |
return 'zendextsrc'; |
} |
if (isset($this->_packageInfo['zendextbinrelease'])) { |
return 'zendextbin'; |
} |
if (isset($this->_packageInfo['bundle'])) { |
return 'bundle'; |
} |
return false; |
} |
/** |
* @return array|false |
*/ |
function getReleases() |
{ |
$type = $this->getPackageType(); |
if ($type != 'bundle') { |
$type .= 'release'; |
} |
if ($this->getPackageType() && isset($this->_packageInfo[$type])) { |
return $this->_packageInfo[$type]; |
} |
return false; |
} |
/** |
* @return array |
*/ |
function getChangelog() |
{ |
if (isset($this->_packageInfo['changelog'])) { |
return $this->_packageInfo['changelog']; |
} |
return false; |
} |
function hasDeps() |
{ |
return isset($this->_packageInfo['dependencies']); |
} |
function getPackagexmlVersion() |
{ |
if (isset($this->_packageInfo['zendextsrcrelease'])) { |
return '2.1'; |
} |
if (isset($this->_packageInfo['zendextbinrelease'])) { |
return '2.1'; |
} |
return '2.0'; |
} |
/** |
* @return array|false |
*/ |
function getSourcePackage() |
{ |
if (isset($this->_packageInfo['extbinrelease']) || |
isset($this->_packageInfo['zendextbinrelease'])) { |
return array('channel' => $this->_packageInfo['srcchannel'], |
'package' => $this->_packageInfo['srcpackage']); |
} |
return false; |
} |
function getBundledPackages() |
{ |
if (isset($this->_packageInfo['bundle'])) { |
return $this->_packageInfo['contents']['bundledpackage']; |
} |
return false; |
} |
function getLastModified() |
{ |
if (isset($this->_packageInfo['_lastmodified'])) { |
return $this->_packageInfo['_lastmodified']; |
} |
return false; |
} |
/** |
* Get the contents of a file listed within the package.xml |
* @param string |
* @return string |
*/ |
function getFileContents($file) |
{ |
if ($this->_archiveFile == $this->_packageFile) { // unpacked |
$dir = dirname($this->_packageFile); |
$file = $dir . DIRECTORY_SEPARATOR . $file; |
$file = str_replace(array('/', '\\'), |
array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); |
if (file_exists($file) && is_readable($file)) { |
return implode('', file($file)); |
} |
} else { // tgz |
$tar = &new Archive_Tar($this->_archiveFile); |
$tar->pushErrorHandling(PEAR_ERROR_RETURN); |
if ($file != 'package.xml' && $file != 'package2.xml') { |
$file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; |
} |
$file = $tar->extractInString($file); |
$tar->popErrorHandling(); |
if (PEAR::isError($file)) { |
return PEAR::raiseError("Cannot locate file '$file' in archive"); |
} |
return $file; |
} |
} |
function &getRW() |
{ |
if (!class_exists('PEAR_PackageFile_v2_rw')) { |
require_once 'PEAR/PackageFile/v2/rw.php'; |
} |
$a = new PEAR_PackageFile_v2_rw; |
foreach (get_object_vars($this) as $name => $unused) { |
if (!isset($this->$name)) { |
continue; |
} |
if ($name == '_config' || $name == '_logger'|| $name == '_registry' || |
$name == '_stack') { |
$a->$name = &$this->$name; |
} else { |
$a->$name = $this->$name; |
} |
} |
return $a; |
} |
function &getDefaultGenerator() |
{ |
if (!class_exists('PEAR_PackageFile_Generator_v2')) { |
require_once 'PEAR/PackageFile/Generator/v2.php'; |
} |
$a = &new PEAR_PackageFile_Generator_v2($this); |
return $a; |
} |
function analyzeSourceCode($file, $string = false) |
{ |
if (!isset($this->_v2Validator) || |
!is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { |
if (!class_exists('PEAR_PackageFile_v2_Validator')) { |
require_once 'PEAR/PackageFile/v2/Validator.php'; |
} |
$this->_v2Validator = new PEAR_PackageFile_v2_Validator; |
} |
return $this->_v2Validator->analyzeSourceCode($file, $string); |
} |
function validate($state = PEAR_VALIDATE_NORMAL) |
{ |
if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { |
return false; |
} |
if (!isset($this->_v2Validator) || |
!is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { |
if (!class_exists('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); |
} |
function getTasksNs() |
{ |
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') { |
$this->_tasksNs = str_replace('xmlns:', '', $name); |
break; |
} |
} |
} |
} |
return $this->_tasksNs; |
} |
/** |
* 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 |
* @param string |
* @return boolean |
*/ |
function getTask($task) |
{ |
$this->getTasksNs(); |
// transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace |
$task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); |
$task = str_replace(' ', '/', ucwords($task)); |
$ps = (strtolower(substr(PHP_OS, 0, 3)) == 'win') ? ';' : ':'; |
foreach (explode($ps, ini_get('include_path')) as $path) { |
if (file_exists($path . "/PEAR/Task/$task.php")) { |
include_once "PEAR/Task/$task.php"; |
$task = str_replace('/', '_', $task); |
if (class_exists("PEAR_Task_$task")) { |
return "PEAR_Task_$task"; |
} |
} |
} |
return false; |
} |
/** |
* 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) |
{ |
$offset = array_search($key, array_keys($array)); |
$after = array_slice($array, $offset); |
$before = array_slice($array, 0, $offset); |
$before[$newkey] = $value; |
return array_merge($before, $after); |
} |
/** |
* @param array a list of possible keys, in the order they may occur |
* @param mixed contents of the new package.xml tag |
* @param string tag name |
* @access private |
*/ |
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; |
return $array; |
} |
/** |
* @param subsection of {@link $_packageInfo} |
* @param array|string tag contents |
* @param array format: |
* <pre> |
* array( |
* tagname => array(list of tag names that follow this one), |
* childtagname => array(list of child tag names that follow this one), |
* ) |
* </pre> |
* |
* This allows construction of nested tags |
* @access private |
*/ |
function _mergeTag($manip, $contents, $order) |
{ |
if (count($order)) { |
foreach ($order as $tag => $curorder) { |
if (!isset($manip[$tag])) { |
// ensure that the tag is set up |
$manip = $this->_insertBefore($manip, $curorder, array(), $tag); |
} |
if (count($order) > 1) { |
$manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); |
return $manip; |
} |
} |
} else { |
return $manip; |
} |
if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { |
$manip[$tag][] = $contents; |
} else { |
if (!count($manip[$tag])) { |
$manip[$tag] = $contents; |
} else { |
$manip[$tag] = array($manip[$tag]); |
$manip[$tag][] = $contents; |
} |
} |
return $manip; |
} |
} |
?> |
/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/Generator/v1.php |
---|
New file |
0,0 → 1,1272 |
<?php |
/** |
* package.xml generation class, package.xml version 1.0 |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: v1.php,v 1.72 2006/05/10 02:56:19 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 1.4.0a1 |
*/ |
/** |
* needed for PEAR_VALIDATE_* constants |
*/ |
require_once 'PEAR/Validate.php'; |
require_once 'System.php'; |
require_once 'PEAR/PackageFile/v2.php'; |
/** |
* This class converts a PEAR_PackageFile_v1 object into any output format. |
* |
* Supported output formats include array, XML string, and a PEAR_PackageFile_v2 |
* object, for converting package.xml 1.0 into package.xml 2.0 with no sweat. |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.5.1 |
* @link http://pear.php.net/package/PEAR |
* @since Class available since Release 1.4.0a1 |
*/ |
class PEAR_PackageFile_Generator_v1 |
{ |
/** |
* @var PEAR_PackageFile_v1 |
*/ |
var $_packagefile; |
function PEAR_PackageFile_Generator_v1(&$packagefile) |
{ |
$this->_packagefile = &$packagefile; |
} |
function getPackagerVersion() |
{ |
return '1.5.1'; |
} |
/** |
* @param PEAR_Packager |
* @param bool if true, a .tgz is written, otherwise a .tar is written |
* @param string|null directory in which to save the .tgz |
* @return string|PEAR_Error location of package or error object |
*/ |
function toTgz(&$packager, $compress = true, $where = null) |
{ |
require_once 'Archive/Tar.php'; |
if ($where === null) { |
if (!($where = System::mktemp(array('-d')))) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed'); |
} |
} elseif (!@System::mkDir(array('-p', $where))) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' . |
' not be created'); |
} |
if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && |
!is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' . |
' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"'); |
} |
if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: invalid package file'); |
} |
$pkginfo = $this->_packagefile->getArray(); |
$ext = $compress ? '.tgz' : '.tar'; |
$pkgver = $pkginfo['package'] . '-' . $pkginfo['version']; |
$dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; |
if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) && |
!is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: cannot create tgz file "' . |
getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"'); |
} |
if ($pkgfile = $this->_packagefile->getPackageFile()) { |
$pkgdir = dirname(realpath($pkgfile)); |
$pkgfile = basename($pkgfile); |
} else { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: package file object must ' . |
'be created from a real file'); |
} |
// {{{ Create the package file list |
$filelist = array(); |
$i = 0; |
foreach ($this->_packagefile->getFilelist() as $fname => $atts) { |
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname; |
if (!file_exists($file)) { |
return PEAR::raiseError("File does not exist: $fname"); |
} else { |
$filelist[$i++] = $file; |
if (!isset($atts['md5sum'])) { |
$this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($file)); |
} |
$packager->log(2, "Adding file $fname"); |
} |
} |
// }}} |
$packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); |
if ($packagexml) { |
$tar =& new Archive_Tar($dest_package, $compress); |
$tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors |
// ----- Creates with the package.xml file |
$ok = $tar->createModify(array($packagexml), '', $where); |
if (PEAR::isError($ok)) { |
return $ok; |
} elseif (!$ok) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); |
} |
// ----- Add the content of the package |
if (!$tar->addModify($filelist, $pkgver, $pkgdir)) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); |
} |
return $dest_package; |
} |
} |
/** |
* @param string|null directory to place the package.xml in, or null for a temporary dir |
* @param int one of the PEAR_VALIDATE_* constants |
* @param string name of the generated file |
* @param bool if true, then no analysis will be performed on role="php" files |
* @return string|PEAR_Error path to the created file on success |
*/ |
function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml', |
$nofilechecking = false) |
{ |
if (!$this->_packagefile->validate($state, $nofilechecking)) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: invalid package.xml', |
null, null, null, $this->_packagefile->getValidationWarnings()); |
} |
if ($where === null) { |
if (!($where = System::mktemp(array('-d')))) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: mktemp failed'); |
} |
} elseif (!@System::mkDir(array('-p', $where))) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: "' . $where . '" could' . |
' not be created'); |
} |
$newpkgfile = $where . DIRECTORY_SEPARATOR . $name; |
$np = @fopen($newpkgfile, 'wb'); |
if (!$np) { |
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: unable to save ' . |
"$name as $newpkgfile"); |
} |
fwrite($np, $this->toXml($state, true)); |
fclose($np); |
return $newpkgfile; |
} |
/** |
* fix both XML encoding to be UTF8, and replace standard XML entities < > " & ' |
* |
* @param string $string |
* @return string |
* @access private |
*/ |
function _fixXmlEncoding($string) |
{ |
if (version_compare(phpversion(), '5.0.0', 'lt')) { |
$string = utf8_encode($string); |
} |
return strtr($string, array( |
'&' => '&', |
'>' => '>', |
'<' => '<', |
'"' => '"', |
'\'' => ''' )); |
} |
/** |
* Return an XML document based on the package info (as returned |
* by the PEAR_Common::infoFrom* methods). |
* |
* @return string XML data |
*/ |
function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false) |
{ |
$this->_packagefile->setDate(date('Y-m-d')); |
if (!$this->_packagefile->validate($state, $nofilevalidation)) { |
return false; |
} |
$pkginfo = $this->_packagefile->getArray(); |
static $maint_map = array( |
"handle" => "user", |
"name" => "name", |
"email" => "email", |
"role" => "role", |
); |
$ret = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; |
$ret .= "<!DOCTYPE package SYSTEM \"http://pear.php.net/dtd/package-1.0\">\n"; |
$ret .= "<package version=\"1.0\" packagerversion=\"1.5.1\">\n" . |
" <name>$pkginfo[package]</name>"; |
if (isset($pkginfo['extends'])) { |
$ret .= "\n<extends>$pkginfo[extends]</extends>"; |
} |
$ret .= |
"\n <summary>".$this->_fixXmlEncoding($pkginfo['summary'])."</summary>\n" . |
" <description>".trim($this->_fixXmlEncoding($pkginfo['description']))."\n </description>\n" . |
" <maintainers>\n"; |
foreach ($pkginfo['maintainers'] as $maint) { |
$ret .= " <maintainer>\n"; |
foreach ($maint_map as $idx => $elm) { |
$ret .= " <$elm>"; |
$ret .= $this->_fixXmlEncoding($maint[$idx]); |
$ret .= "</$elm>\n"; |
} |
$ret .= " </maintainer>\n"; |
} |
$ret .= " </maintainers>\n"; |
$ret .= $this->_makeReleaseXml($pkginfo, false, $state); |
if (isset($pkginfo['changelog']) && count($pkginfo['changelog']) > 0) { |
$ret .= " <changelog>\n"; |
foreach ($pkginfo['changelog'] as $oldrelease) { |
$ret .= $this->_makeReleaseXml($oldrelease, true); |
} |
$ret .= " </changelog>\n"; |
} |
$ret .= "</package>\n"; |
return $ret; |
} |
// }}} |
// {{{ _makeReleaseXml() |
/** |
* Generate part of an XML description with release information. |
* |
* @param array $pkginfo array with release information |
* @param bool $changelog whether the result will be in a changelog element |
* |
* @return string XML data |
* |
* @access private |
*/ |
function _makeReleaseXml($pkginfo, $changelog = false, $state = PEAR_VALIDATE_NORMAL) |
{ |
// XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!! |
$indent = $changelog ? " " : ""; |
$ret = "$indent <release>\n"; |
if (!empty($pkginfo['version'])) { |
$ret .= "$indent <version>$pkginfo[version]</version>\n"; |
} |
if (!empty($pkginfo['release_date'])) { |
$ret .= "$indent <date>$pkginfo[release_date]</date>\n"; |
} |
if (!empty($pkginfo['release_license'])) { |
$ret .= "$indent <license>$pkginfo[release_license]</license>\n"; |
} |
if (!empty($pkginfo['release_state'])) { |
$ret .= "$indent <state>$pkginfo[release_state]</state>\n"; |
} |
if (!empty($pkginfo['release_notes'])) { |
$ret .= "$indent <notes>".trim($this->_fixXmlEncoding($pkginfo['release_notes'])) |
."\n$indent </notes>\n"; |
} |
if (!empty($pkginfo['release_warnings'])) { |
$ret .= "$indent <warnings>".$this->_fixXmlEncoding($pkginfo['release_warnings'])."</warnings>\n"; |
} |
if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) { |
$ret .= "$indent <deps>\n"; |
foreach ($pkginfo['release_deps'] as $dep) { |
$ret .= "$indent <dep type=\"$dep[type]\" rel=\"$dep[rel]\""; |
if (isset($dep['version'])) { |
$ret .= " version=\"$dep[version]\""; |
} |
if (isset($dep['optional'])) { |
$ret .= " optional=\"$dep[optional]\""; |
} |
if (isset($dep['name'])) { |
$ret .= ">$dep[name]</dep>\n"; |
} else { |
$ret .= "/>\n"; |
} |
} |
$ret .= "$indent </deps>\n"; |
} |
if (isset($pkginfo['configure_options'])) { |
$ret .= "$indent <configureoptions>\n"; |
foreach ($pkginfo['configure_options'] as $c) { |
$ret .= "$indent <configureoption name=\"". |
$this->_fixXmlEncoding($c['name']) . "\""; |
if (isset($c['default'])) { |
$ret .= " default=\"" . $this->_fixXmlEncoding($c['default']) . "\""; |
} |
$ret .= " prompt=\"" . $this->_fixXmlEncoding($c['prompt']) . "\""; |
$ret .= "/>\n"; |
} |
$ret .= "$indent </configureoptions>\n"; |
} |
if (isset($pkginfo['provides'])) { |
foreach ($pkginfo['provides'] as $key => $what) { |
$ret .= "$indent <provides type=\"$what[type]\" "; |
$ret .= "name=\"$what[name]\" "; |
if (isset($what['extends'])) { |
$ret .= "extends=\"$what[extends]\" "; |
} |
$ret .= "/>\n"; |
} |
} |
if (isset($pkginfo['filelist'])) { |
$ret .= "$indent <filelist>\n"; |
if ($state ^ PEAR_VALIDATE_PACKAGING) { |
$ret .= $this->recursiveXmlFilelist($pkginfo['filelist']); |
} else { |
foreach ($pkginfo['filelist'] as $file => $fa) { |
if (!isset($fa['role'])) { |
$fa['role'] = ''; |
} |
$ret .= "$indent <file role=\"$fa[role]\""; |
if (isset($fa['baseinstalldir'])) { |
$ret .= ' baseinstalldir="' . |
$this->_fixXmlEncoding($fa['baseinstalldir']) . '"'; |
} |
if (isset($fa['md5sum'])) { |
$ret .= " md5sum=\"$fa[md5sum]\""; |
} |
if (isset($fa['platform'])) { |
$ret .= " platform=\"$fa[platform]\""; |
} |
if (!empty($fa['install-as'])) { |
$ret .= ' install-as="' . |
$this->_fixXmlEncoding($fa['install-as']) . '"'; |
} |
$ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; |
if (empty($fa['replacements'])) { |
$ret .= "/>\n"; |
} else { |
$ret .= ">\n"; |
foreach ($fa['replacements'] as $r) { |
$ret .= "$indent <replace"; |
foreach ($r as $k => $v) { |
$ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; |
} |
$ret .= "/>\n"; |
} |
$ret .= "$indent </file>\n"; |
} |
} |
} |
$ret .= "$indent </filelist>\n"; |
} |
$ret .= "$indent </release>\n"; |
return $ret; |
} |
/** |
* @param array |
* @access protected |
*/ |
function recursiveXmlFilelist($list) |
{ |
$this->_dirs = array(); |
foreach ($list as $file => $attributes) { |
$this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes); |
} |
return $this->_formatDir($this->_dirs); |
} |
/** |
* @param array |
* @param array |
* @param string|null |
* @param array|null |
* @access private |
*/ |
function _addDir(&$dirs, $dir, $file = null, $attributes = null) |
{ |
if ($dir == array() || $dir == array('.')) { |
$dirs['files'][basename($file)] = $attributes; |
return; |
} |
$curdir = array_shift($dir); |
if (!isset($dirs['dirs'][$curdir])) { |
$dirs['dirs'][$curdir] = array(); |
} |
$this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes); |
} |
/** |
* @param array |
* @param string |
* @param string |
* @access private |
*/ |
function _formatDir($dirs, $indent = '', $curdir = '') |
{ |
$ret = ''; |
if (!count($dirs)) { |
return ''; |
} |
if (isset($dirs['dirs'])) { |
uksort($dirs['dirs'], 'strnatcasecmp'); |
foreach ($dirs['dirs'] as $dir => $contents) { |
$usedir = "$curdir/$dir"; |
$ret .= "$indent <dir name=\"$dir\">\n"; |
$ret .= $this->_formatDir($contents, "$indent ", $usedir); |
$ret .= "$indent </dir> <!-- $usedir -->\n"; |
} |
} |
if (isset($dirs['files'])) { |
uksort($dirs['files'], 'strnatcasecmp'); |
foreach ($dirs['files'] as $file => $attribs) { |
$ret .= $this->_formatFile($file, $attribs, $indent); |
} |
} |
return $ret; |
} |
/** |
* @param string |
* @param array |
* @param string |
* @access private |
*/ |
function _formatFile($file, $attributes, $indent) |
{ |
$ret = "$indent <file role=\"$attributes[role]\""; |
if (isset($attributes['baseinstalldir'])) { |
$ret .= ' baseinstalldir="' . |
$this->_fixXmlEncoding($attributes['baseinstalldir']) . '"'; |
} |
if (isset($attributes['md5sum'])) { |
$ret .= " md5sum=\"$attributes[md5sum]\""; |
} |
if (isset($attributes['platform'])) { |
$ret .= " platform=\"$attributes[platform]\""; |
} |
if (!empty($attributes['install-as'])) { |
$ret .= ' install-as="' . |
$this->_fixXmlEncoding($attributes['install-as']) . '"'; |
} |
$ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; |
if (empty($attributes['replacements'])) { |
$ret .= "/>\n"; |
} else { |
$ret .= ">\n"; |
foreach ($attributes['replacements'] as $r) { |
$ret .= "$indent <replace"; |
foreach ($r as $k => $v) { |
$ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; |
} |
$ret .= "/>\n"; |
} |
$ret .= "$indent </file>\n"; |
} |
return $ret; |
} |
// {{{ _unIndent() |
/** |
* Unindent given string (?) |
* |
* @param string $str The string that has to be unindented. |
* @return string |
* @access private |
*/ |
function _unIndent($str) |
{ |
// remove leading newlines |
$str = preg_replace('/^[\r\n]+/', '', $str); |
// find whitespace at the beginning of the first line |
$indent_len = strspn($str, " \t"); |
$indent = substr($str, 0, $indent_len); |
$data = ''; |
// remove the same amount of whitespace from following lines |
foreach (explode("\n", $str) as $line) { |
if (substr($line, 0, $indent_len) == $indent) { |
$data .= substr($line, $indent_len) . "\n"; |
} |
} |
return $data; |
} |
/** |
* @return array |
*/ |
function dependenciesToV2() |
{ |
$arr = array(); |
$this->_convertDependencies2_0($arr); |
return $arr['dependencies']; |
} |
/** |
* Convert a package.xml version 1.0 into version 2.0 |
* |
* Note that this does a basic conversion, to allow more advanced |
* features like bundles and multiple releases |
* @param string the classname to instantiate and return. This must be |
* PEAR_PackageFile_v2 or a descendant |
* @param boolean if true, only valid, deterministic package.xml 1.0 as defined by the |
* strictest parameters will be converted |
* @return PEAR_PackageFile_v2|PEAR_Error |
*/ |
function &toV2($class = 'PEAR_PackageFile_v2', $strict = false) |
{ |
if ($strict) { |
if (!$this->_packagefile->validate()) { |
$a = PEAR::raiseError('invalid package.xml version 1.0 cannot be converted' . |
' to version 2.0', null, null, null, |
$this->_packagefile->getValidationWarnings(true)); |
return $a; |
} |
} |
$arr = array( |
'attribs' => array( |
'version' => '2.0', |
'xmlns' => 'http://pear.php.net/dtd/package-2.0', |
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', |
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
'xsi:schemaLocation' => "http://pear.php.net/dtd/tasks-1.0\n" . |
"http://pear.php.net/dtd/tasks-1.0.xsd\n" . |
"http://pear.php.net/dtd/package-2.0\n" . |
'http://pear.php.net/dtd/package-2.0.xsd', |
), |
'name' => $this->_packagefile->getPackage(), |
'channel' => 'pear.php.net', |
); |
$arr['summary'] = $this->_packagefile->getSummary(); |
$arr['description'] = $this->_packagefile->getDescription(); |
$maintainers = $this->_packagefile->getMaintainers(); |
foreach ($maintainers as $maintainer) { |
if ($maintainer['role'] != 'lead') { |
continue; |
} |
$new = array( |
'name' => $maintainer['name'], |
'user' => $maintainer['handle'], |
'email' => $maintainer['email'], |
'active' => 'yes', |
); |
$arr['lead'][] = $new; |
} |
if (!isset($arr['lead'])) { // some people... you know? |
$arr['lead'] = array( |
'name' => 'unknown', |
'user' => 'unknown', |
'email' => 'noleadmaintainer@example.com', |
'active' => 'no', |
); |
} |
if (count($arr['lead']) == 1) { |
$arr['lead'] = $arr['lead'][0]; |
} |
foreach ($maintainers as $maintainer) { |
if ($maintainer['role'] == 'lead') { |
continue; |
} |
$new = array( |
'name' => $maintainer['name'], |
'user' => $maintainer['handle'], |
'email' => $maintainer['email'], |
'active' => 'yes', |
); |
$arr[$maintainer['role']][] = $new; |
} |
if (isset($arr['developer']) && count($arr['developer']) == 1) { |
$arr['developer'] = $arr['developer'][0]; |
} |
if (isset($arr['contributor']) && count($arr['contributor']) == 1) { |
$arr['contributor'] = $arr['contributor'][0]; |
} |
if (isset($arr['helper']) && count($arr['helper']) == 1) { |
$arr['helper'] = $arr['helper'][0]; |
} |
$arr['date'] = $this->_packagefile->getDate(); |
$arr['version'] = |
array( |
'release' => $this->_packagefile->getVersion(), |
'api' => $this->_packagefile->getVersion(), |
); |
$arr['stability'] = |
array( |
'release' => $this->_packagefile->getState(), |
'api' => $this->_packagefile->getState(), |
); |
$licensemap = |
array( |
'php' => 'http://www.php.net/license', |
'php license' => 'http://www.php.net/license', |
'lgpl' => 'http://www.gnu.org/copyleft/lesser.html', |
'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', |
'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php', |
'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php', |
'mit' => 'http://www.opensource.org/licenses/mit-license.php', |
'gpl' => 'http://www.gnu.org/copyleft/gpl.html', |
'apache' => 'http://www.opensource.org/licenses/apache2.0.php' |
); |
if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) { |
$arr['license'] = array( |
'attribs' => array('uri' => |
$licensemap[strtolower($this->_packagefile->getLicense())]), |
'_content' => $this->_packagefile->getLicense() |
); |
} else { |
// don't use bogus uri |
$arr['license'] = $this->_packagefile->getLicense(); |
} |
$arr['notes'] = $this->_packagefile->getNotes(); |
$temp = array(); |
$arr['contents'] = $this->_convertFilelist2_0($temp); |
$this->_convertDependencies2_0($arr); |
$release = ($this->_packagefile->getConfigureOptions() || $this->_isExtension) ? |
'extsrcrelease' : 'phprelease'; |
if ($release == 'extsrcrelease') { |
$arr['channel'] = 'pecl.php.net'; |
$arr['providesextension'] = $arr['name']; // assumption |
} |
$arr[$release] = array(); |
if ($this->_packagefile->getConfigureOptions()) { |
$arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions(); |
foreach ($arr[$release]['configureoption'] as $i => $opt) { |
$arr[$release]['configureoption'][$i] = array('attribs' => $opt); |
} |
if (count($arr[$release]['configureoption']) == 1) { |
$arr[$release]['configureoption'] = $arr[$release]['configureoption'][0]; |
} |
} |
$this->_convertRelease2_0($arr[$release], $temp); |
if ($release == 'extsrcrelease' && count($arr[$release]) > 1) { |
// multiple extsrcrelease tags added in PEAR 1.4.1 |
$arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1'; |
} |
if ($cl = $this->_packagefile->getChangelog()) { |
foreach ($cl as $release) { |
$rel = array(); |
$rel['version'] = |
array( |
'release' => $release['version'], |
'api' => $release['version'], |
); |
if (!isset($release['release_state'])) { |
$release['release_state'] = 'stable'; |
} |
$rel['stability'] = |
array( |
'release' => $release['release_state'], |
'api' => $release['release_state'], |
); |
if (isset($release['release_date'])) { |
$rel['date'] = $release['release_date']; |
} else { |
$rel['date'] = date('Y-m-d'); |
} |
if (isset($release['release_license'])) { |
if (isset($licensemap[strtolower($release['release_license'])])) { |
$uri = $licensemap[strtolower($release['release_license'])]; |
} else { |
$uri = 'http://www.example.com'; |
} |
$rel['license'] = array( |
'attribs' => array('uri' => $uri), |
'_content' => $release['release_license'] |
); |
} else { |
$rel['license'] = $arr['license']; |
} |
if (!isset($release['release_notes'])) { |
$release['release_notes'] = 'no release notes'; |
} |
$rel['notes'] = $release['release_notes']; |
$arr['changelog']['release'][] = $rel; |
} |
} |
$ret = new $class; |
$ret->setConfig($this->_packagefile->_config); |
if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) { |
$ret->setLogger($this->_packagefile->_logger); |
} |
$ret->fromArray($arr); |
return $ret; |
} |
/** |
* @param array |
* @param bool |
* @access private |
*/ |
function _convertDependencies2_0(&$release, $internal = false) |
{ |
$peardep = array('pearinstaller' => |
array('min' => '1.4.0b1')); // this is a lot safer |
$required = $optional = array(); |
$release['dependencies'] = array(); |
if ($this->_packagefile->hasDeps()) { |
foreach ($this->_packagefile->getDeps() as $dep) { |
if (!isset($dep['optional']) || $dep['optional'] == 'no') { |
$required[] = $dep; |
} else { |
$optional[] = $dep; |
} |
} |
foreach (array('required', 'optional') as $arr) { |
$deps = array(); |
foreach ($$arr as $dep) { |
// organize deps by dependency type and name |
if (!isset($deps[$dep['type']])) { |
$deps[$dep['type']] = array(); |
} |
if (isset($dep['name'])) { |
$deps[$dep['type']][$dep['name']][] = $dep; |
} else { |
$deps[$dep['type']][] = $dep; |
} |
} |
do { |
if (isset($deps['php'])) { |
$php = array(); |
if (count($deps['php']) > 1) { |
$php = $this->_processPhpDeps($deps['php']); |
} else { |
if (!isset($deps['php'][0])) { |
list($key, $blah) = each ($deps['php']); // stupid buggy versions |
$deps['php'] = array($blah[0]); |
} |
$php = $this->_processDep($deps['php'][0]); |
if (!$php) { |
break; // poor mans throw |
} |
} |
$release['dependencies'][$arr]['php'] = $php; |
} |
} while (false); |
do { |
if (isset($deps['pkg'])) { |
$pkg = array(); |
$pkg = $this->_processMultipleDepsName($deps['pkg']); |
if (!$pkg) { |
break; // poor mans throw |
} |
$release['dependencies'][$arr]['package'] = $pkg; |
} |
} while (false); |
do { |
if (isset($deps['ext'])) { |
$pkg = array(); |
$pkg = $this->_processMultipleDepsName($deps['ext']); |
$release['dependencies'][$arr]['extension'] = $pkg; |
} |
} while (false); |
// skip sapi - it's not supported so nobody will have used it |
// skip os - it's not supported in 1.0 |
} |
} |
if (isset($release['dependencies']['required'])) { |
$release['dependencies']['required'] = |
array_merge($peardep, $release['dependencies']['required']); |
} else { |
$release['dependencies']['required'] = $peardep; |
} |
if (!isset($release['dependencies']['required']['php'])) { |
$release['dependencies']['required']['php'] = |
array('min' => '4.0.0'); |
} |
$order = array(); |
$bewm = $release['dependencies']['required']; |
$order['php'] = $bewm['php']; |
$order['pearinstaller'] = $bewm['pearinstaller']; |
isset($bewm['package']) ? $order['package'] = $bewm['package'] :0; |
isset($bewm['extension']) ? $order['extension'] = $bewm['extension'] :0; |
$release['dependencies']['required'] = $order; |
} |
/** |
* @param array |
* @access private |
*/ |
function _convertFilelist2_0(&$package) |
{ |
$ret = array('dir' => |
array( |
'attribs' => array('name' => '/'), |
'file' => array() |
) |
); |
$package['platform'] = |
$package['install-as'] = array(); |
$this->_isExtension = false; |
foreach ($this->_packagefile->getFilelist() as $name => $file) { |
$file['name'] = $name; |
if (isset($file['role']) && $file['role'] == 'src') { |
$this->_isExtension = true; |
} |
if (isset($file['replacements'])) { |
$repl = $file['replacements']; |
unset($file['replacements']); |
} else { |
unset($repl); |
} |
if (isset($file['install-as'])) { |
$package['install-as'][$name] = $file['install-as']; |
unset($file['install-as']); |
} |
if (isset($file['platform'])) { |
$package['platform'][$name] = $file['platform']; |
unset($file['platform']); |
} |
$file = array('attribs' => $file); |
if (isset($repl)) { |
foreach ($repl as $replace ) { |
$file['tasks:replace'][] = array('attribs' => $replace); |
} |
if (count($repl) == 1) { |
$file['tasks:replace'] = $file['tasks:replace'][0]; |
} |
} |
$ret['dir']['file'][] = $file; |
} |
return $ret; |
} |
/** |
* Post-process special files with install-as/platform attributes and |
* make the release tag. |
* |
* This complex method follows this work-flow to create the release tags: |
* |
* <pre> |
* - if any install-as/platform exist, create a generic release and fill it with |
* o <install as=..> tags for <file name=... install-as=...> |
* o <install as=..> tags for <file name=... platform=!... install-as=..> |
* o <ignore> tags for <file name=... platform=...> |
* o <ignore> tags for <file name=... platform=... install-as=..> |
* - create a release for each platform encountered and fill with |
* o <install as..> tags for <file name=... install-as=...> |
* o <install as..> tags for <file name=... platform=this platform install-as=..> |
* o <install as..> tags for <file name=... platform=!other platform install-as=..> |
* o <ignore> tags for <file name=... platform=!this platform> |
* o <ignore> tags for <file name=... platform=other platform> |
* o <ignore> tags for <file name=... platform=other platform install-as=..> |
* o <ignore> tags for <file name=... platform=!this platform install-as=..> |
* </pre> |
* |
* It does this by accessing the $package parameter, which contains an array with |
* indices: |
* |
* - platform: mapping of file => OS the file should be installed on |
* - install-as: mapping of file => installed name |
* - osmap: mapping of OS => list of files that should be installed |
* on that OS |
* - notosmap: mapping of OS => list of files that should not be |
* installed on that OS |
* |
* @param array |
* @param array |
* @access private |
*/ |
function _convertRelease2_0(&$release, $package) |
{ |
//- if any install-as/platform exist, create a generic release and fill it with |
if (count($package['platform']) || count($package['install-as'])) { |
$generic = array(); |
$genericIgnore = array(); |
foreach ($package['install-as'] as $file => $as) { |
//o <install as=..> tags for <file name=... install-as=...> |
if (!isset($package['platform'][$file])) { |
$generic[] = $file; |
continue; |
} |
//o <install as=..> tags for <file name=... platform=!... install-as=..> |
if (isset($package['platform'][$file]) && |
$package['platform'][$file]{0} == '!') { |
$generic[] = $file; |
continue; |
} |
//o <ignore> tags for <file name=... platform=... install-as=..> |
if (isset($package['platform'][$file]) && |
$package['platform'][$file]{0} != '!') { |
$genericIgnore[] = $file; |
continue; |
} |
} |
foreach ($package['platform'] as $file => $platform) { |
if (isset($package['install-as'][$file])) { |
continue; |
} |
if ($platform{0} != '!') { |
//o <ignore> tags for <file name=... platform=...> |
$genericIgnore[] = $file; |
} |
} |
if (count($package['platform'])) { |
$oses = $notplatform = $platform = array(); |
foreach ($package['platform'] as $file => $os) { |
// get a list of oses |
if ($os{0} == '!') { |
if (isset($oses[substr($os, 1)])) { |
continue; |
} |
$oses[substr($os, 1)] = count($oses); |
} else { |
if (isset($oses[$os])) { |
continue; |
} |
$oses[$os] = count($oses); |
} |
} |
//- create a release for each platform encountered and fill with |
foreach ($oses as $os => $releaseNum) { |
$release[$releaseNum]['installconditions']['os']['name'] = $os; |
$release[$releaseNum]['filelist'] = array('install' => array(), |
'ignore' => array()); |
foreach ($package['install-as'] as $file => $as) { |
//o <install as=..> tags for <file name=... install-as=...> |
if (!isset($package['platform'][$file])) { |
$release[$releaseNum]['filelist']['install'][] = |
array( |
'attribs' => array( |
'name' => $file, |
'as' => $as, |
), |
); |
continue; |
} |
//o <install as..> tags for |
// <file name=... platform=this platform install-as=..> |
if (isset($package['platform'][$file]) && |
$package['platform'][$file] == $os) { |
$release[$releaseNum]['filelist']['install'][] = |
array( |
'attribs' => array( |
'name' => $file, |
'as' => $as, |
), |
); |
continue; |
} |
//o <install as..> tags for |
// <file name=... platform=!other platform install-as=..> |
if (isset($package['platform'][$file]) && |
$package['platform'][$file] != "!$os" && |
$package['platform'][$file]{0} == '!') { |
$release[$releaseNum]['filelist']['install'][] = |
array( |
'attribs' => array( |
'name' => $file, |
'as' => $as, |
), |
); |
continue; |
} |
//o <ignore> tags for |
// <file name=... platform=!this platform install-as=..> |
if (isset($package['platform'][$file]) && |
$package['platform'][$file] == "!$os") { |
$release[$releaseNum]['filelist']['ignore'][] = |
array( |
'attribs' => array( |
'name' => $file, |
), |
); |
continue; |
} |
//o <ignore> tags for |
// <file name=... platform=other platform install-as=..> |
if (isset($package['platform'][$file]) && |
$package['platform'][$file]{0} != '!' && |
$package['platform'][$file] != $os) { |
$release[$releaseNum]['filelist']['ignore'][] = |
array( |
'attribs' => array( |
'name' => $file, |
), |
); |
continue; |
} |
} |
foreach ($package['platform'] as $file => $platform) { |
if (isset($package['install-as'][$file])) { |
continue; |
} |
//o <ignore> tags for <file name=... platform=!this platform> |
if ($platform == "!$os") { |
$release[$releaseNum]['filelist']['ignore'][] = |
array( |
'attribs' => array( |
'name' => $file, |
), |
); |
continue; |
} |
//o <ignore> tags for <file name=... platform=other platform> |
if ($platform{0} != '!' && $platform != $os) { |
$release[$releaseNum]['filelist']['ignore'][] = |
array( |
'attribs' => array( |
'name' => $file, |
), |
); |
} |
} |
if (!count($release[$releaseNum]['filelist']['install'])) { |
unset($release[$releaseNum]['filelist']['install']); |
} |
if (!count($release[$releaseNum]['filelist']['ignore'])) { |
unset($release[$releaseNum]['filelist']['ignore']); |
} |
} |
if (count($generic) || count($genericIgnore)) { |
$release[count($oses)] = array(); |
if (count($generic)) { |
foreach ($generic as $file) { |
if (isset($package['install-as'][$file])) { |
$installas = $package['install-as'][$file]; |
} else { |
$installas = $file; |
} |
$release[count($oses)]['filelist']['install'][] = |
array( |
'attribs' => array( |
'name' => $file, |
'as' => $installas, |
) |
); |
} |
} |
if (count($genericIgnore)) { |
foreach ($genericIgnore as $file) { |
$release[count($oses)]['filelist']['ignore'][] = |
array( |
'attribs' => array( |
'name' => $file, |
) |
); |
} |
} |
} |
// cleanup |
foreach ($release as $i => $rel) { |
if (isset($rel['filelist']['install']) && |
count($rel['filelist']['install']) == 1) { |
$release[$i]['filelist']['install'] = |
$release[$i]['filelist']['install'][0]; |
} |
if (isset($rel['filelist']['ignore']) && |
count($rel['filelist']['ignore']) == 1) { |
$release[$i]['filelist']['ignore'] = |
$release[$i]['filelist']['ignore'][0]; |
} |
} |
if (count($release) == 1) { |
$release = $release[0]; |
} |
} else { |
// no platform atts, but some install-as atts |
foreach ($package['install-as'] as $file => $value) { |
$release['filelist']['install'][] = |
array( |
'attribs' => array( |
'name' => $file, |
'as' => $value |
) |
); |
} |
if (count($release['filelist']['install']) == 1) { |
$release['filelist']['install'] = $release['filelist']['install'][0]; |
} |
} |
} |
} |
/** |
* @param array |
* @return array |
* @access private |
*/ |
function _processDep($dep) |
{ |
if ($dep['type'] == 'php') { |
if ($dep['rel'] == 'has') { |
// come on - everyone has php! |
return false; |
} |
} |
$php = array(); |
if ($dep['type'] != 'php') { |
$php['name'] = $dep['name']; |
if ($dep['type'] == 'pkg') { |
$php['channel'] = 'pear.php.net'; |
} |
} |
switch ($dep['rel']) { |
case 'gt' : |
$php['min'] = $dep['version']; |
$php['exclude'] = $dep['version']; |
break; |
case 'ge' : |
if (!isset($dep['version'])) { |
if ($dep['type'] == 'php') { |
if (isset($dep['name'])) { |
$dep['version'] = $dep['name']; |
} |
} |
} |
$php['min'] = $dep['version']; |
break; |
case 'lt' : |
$php['max'] = $dep['version']; |
$php['exclude'] = $dep['version']; |
break; |
case 'le' : |
$php['max'] = $dep['version']; |
break; |
case 'eq' : |
$php['min'] = $dep['version']; |
$php['max'] = $dep['version']; |
break; |
case 'ne' : |
$php['exclude'] = $dep['version']; |
break; |
case 'not' : |
$php['conflicts'] = 'yes'; |
break; |
} |
return $php; |
} |
/** |
* @param array |
* @return array |
*/ |
function _processPhpDeps($deps) |
{ |
$test = array(); |
foreach ($deps as $dep) { |
$test[] = $this->_processDep($dep); |
} |
$min = array(); |
$max = array(); |
foreach ($test as $dep) { |
if (!$dep) { |
continue; |
} |
if (isset($dep['min'])) { |
$min[$dep['min']] = count($min); |
} |
if (isset($dep['max'])) { |
$max[$dep['max']] = count($max); |
} |
} |
if (count($min) > 0) { |
uksort($min, 'version_compare'); |
} |
if (count($max) > 0) { |
uksort($max, 'version_compare'); |
} |
if (count($min)) { |
// get the highest minimum |
$min = array_pop($a = array_flip($min)); |
} else { |
$min = false; |
} |
if (count($max)) { |
// get the lowest maximum |
$max = array_shift($a = array_flip($max)); |
} else { |
$max = false; |
} |
if ($min) { |
$php['min'] = $min; |
} |
if ($max) { |
$php['max'] = $max; |
} |
$exclude = array(); |
foreach ($test as $dep) { |
if (!isset($dep['exclude'])) { |
continue; |
} |
$exclude[] = $dep['exclude']; |
} |
if (count($exclude)) { |
$php['exclude'] = $exclude; |
} |
return $php; |
} |
/** |
* process multiple dependencies that have a name, like package deps |
* @param array |
* @return array |
* @access private |
*/ |
function _processMultipleDepsName($deps) |
{ |
$tests = array(); |
foreach ($deps as $name => $dep) { |
foreach ($dep as $d) { |
$tests[$name][] = $this->_processDep($d); |
} |
} |
foreach ($tests as $name => $test) { |
$php = array(); |
$min = array(); |
$max = array(); |
$php['name'] = $name; |
foreach ($test as $dep) { |
if (!$dep) { |
continue; |
} |
if (isset($dep['channel'])) { |
$php['channel'] = 'pear.php.net'; |
} |
if (isset($dep['conflicts']) && $dep['conflicts'] == 'yes') { |
$php['conflicts'] = 'yes'; |
} |
if (isset($dep['min'])) { |
$min[$dep['min']] = count($min); |
} |
if (isset($dep['max'])) { |
$max[$dep['max']] = count($max); |
} |
} |
if (count($min) > 0) { |
uksort($min, 'version_compare'); |
} |
if (count($max) > 0) { |
uksort($max, 'version_compare'); |
} |
if (count($min)) { |
// get the highest minimum |
$min = array_pop($a = array_flip($min)); |
} else { |
$min = false; |
} |
if (count($max)) { |
// get the lowest maximum |
$max = array_shift($a = array_flip($max)); |
} else { |
$max = false; |
} |
if ($min) { |
$php['min'] = $min; |
} |
if ($max) { |
$php['max'] = $max; |
} |
$exclude = array(); |
foreach ($test as $dep) { |
if (!isset($dep['exclude'])) { |
continue; |
} |
$exclude[] = $dep['exclude']; |
} |
if (count($exclude)) { |
$php['exclude'] = $exclude; |
} |
$ret[] = $php; |
} |
return $ret; |
} |
} |
?> |
/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/Generator/v2.php |
---|
New file |
0,0 → 1,1527 |
<?php |
/** |
* package.xml generation class, package.xml version 2.0 |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @author Stephan Schmidt (original XML_Serializer code) |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: v2.php,v 1.35 2006/03/25 21:09:08 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 1.4.0a1 |
*/ |
/** |
* file/dir manipulation routines |
*/ |
require_once 'System.php'; |
/** |
* This class converts a PEAR_PackageFile_v2 object into any output format. |
* |
* Supported output formats include array, XML string (using S. Schmidt's |
* XML_Serializer, slightly customized) |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @author Stephan Schmidt (original XML_Serializer code) |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.5.1 |
* @link http://pear.php.net/package/PEAR |
* @since Class available since Release 1.4.0a1 |
*/ |
class PEAR_PackageFile_Generator_v2 |
{ |
/** |
* default options for the serialization |
* @access private |
* @var array $_defaultOptions |
*/ |
var $_defaultOptions = array( |
'indent' => ' ', // string used for indentation |
'linebreak' => "\n", // string used for newlines |
'typeHints' => false, // automatically add type hin attributes |
'addDecl' => true, // add an XML declaration |
'defaultTagName' => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names |
'classAsTagName' => false, // use classname for objects in indexed arrays |
'keyAttribute' => '_originalKey', // attribute where original key is stored |
'typeAttribute' => '_type', // attribute for type (only if typeHints => true) |
'classAttribute' => '_class', // attribute for class of objects (only if typeHints => true) |
'scalarAsAttributes' => false, // scalar values (strings, ints,..) will be serialized as attribute |
'prependAttributes' => '', // prepend string for attributes |
'indentAttributes' => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column |
'mode' => 'simplexml', // use 'simplexml' to use parent name as tagname if transforming an indexed array |
'addDoctype' => false, // add a doctype declaration |
'doctype' => null, // supply a string or an array with id and uri ({@see PEAR_PackageFile_Generator_v2_PEAR_PackageFile_Generator_v2_XML_Util::getDoctypeDeclaration()} |
'rootName' => 'package', // name of the root tag |
'rootAttributes' => array( |
'version' => '2.0', |
'xmlns' => 'http://pear.php.net/dtd/package-2.0', |
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', |
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 |
http://pear.php.net/dtd/tasks-1.0.xsd |
http://pear.php.net/dtd/package-2.0 |
http://pear.php.net/dtd/package-2.0.xsd', |
), // attributes of the root tag |
'attributesArray' => 'attribs', // all values in this key will be treated as attributes |
'contentName' => '_content', // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray |
'beautifyFilelist' => false, |
'encoding' => 'UTF-8', |
); |
/** |
* options for the serialization |
* @access private |
* @var array $options |
*/ |
var $options = array(); |
/** |
* current tag depth |
* @var integer $_tagDepth |
*/ |
var $_tagDepth = 0; |
/** |
* serilialized representation of the data |
* @var string $_serializedData |
*/ |
var $_serializedData = null; |
/** |
* @var PEAR_PackageFile_v2 |
*/ |
var $_packagefile; |
/** |
* @param PEAR_PackageFile_v2 |
*/ |
function PEAR_PackageFile_Generator_v2(&$packagefile) |
{ |
$this->_packagefile = &$packagefile; |
} |
/** |
* @return string |
*/ |
function getPackagerVersion() |
{ |
return '1.5.1'; |
} |
/** |
* @param PEAR_Packager |
* @param bool generate a .tgz or a .tar |
* @param string|null temporary directory to package in |
*/ |
function toTgz(&$packager, $compress = true, $where = null) |
{ |
$a = null; |
return $this->toTgz2($packager, $a, $compress, $where); |
} |
/** |
* Package up both a package.xml and package2.xml for the same release |
* @param PEAR_Packager |
* @param PEAR_PackageFile_v1 |
* @param bool generate a .tgz or a .tar |
* @param string|null temporary directory to package in |
*/ |
function toTgz2(&$packager, &$pf1, $compress = true, $where = null) |
{ |
require_once 'Archive/Tar.php'; |
if (!$this->_packagefile->isEquivalent($pf1)) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . |
basename($pf1->getPackageFile()) . |
'" is not equivalent to "' . basename($this->_packagefile->getPackageFile()) |
. '"'); |
} |
if ($where === null) { |
if (!($where = System::mktemp(array('-d')))) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed'); |
} |
} elseif (!@System::mkDir(array('-p', $where))) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' . |
' not be created'); |
} |
if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && |
!is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' . |
' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"'); |
} |
if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml'); |
} |
$ext = $compress ? '.tgz' : '.tar'; |
$pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion(); |
$dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; |
if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) && |
!is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' . |
getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"'); |
} |
if ($pkgfile = $this->_packagefile->getPackageFile()) { |
$pkgdir = dirname(realpath($pkgfile)); |
$pkgfile = basename($pkgfile); |
} else { |
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' . |
'be created from a real file'); |
} |
// {{{ Create the package file list |
$filelist = array(); |
$i = 0; |
$this->_packagefile->flattenFilelist(); |
$contents = $this->_packagefile->getContents(); |
if (isset($contents['bundledpackage'])) { // bundles of packages |
$contents = $contents['bundledpackage']; |
if (!isset($contents[0])) { |
$contents = array($contents); |
} |
$packageDir = $where; |
foreach ($contents as $i => $package) { |
$fname = $package; |
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname; |
if (!file_exists($file)) { |
return $packager->raiseError("File does not exist: $fname"); |
} |
$tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; |
System::mkdir(array('-p', dirname($tfile))); |
copy($file, $tfile); |
$filelist[$i++] = $tfile; |
$packager->log(2, "Adding package $fname"); |
} |
} else { // normal packages |
$contents = $contents['dir']['file']; |
if (!isset($contents[0])) { |
$contents = array($contents); |
} |
$packageDir = $where; |
foreach ($contents as $i => $file) { |
$fname = $file['attribs']['name']; |
$atts = $file['attribs']; |
$orig = $file; |
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname; |
if (!file_exists($file)) { |
return $packager->raiseError("File does not exist: $fname"); |
} else { |
$tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; |
unset($orig['attribs']); |
if (count($orig)) { // file with tasks |
// run any package-time tasks |
$contents = file_get_contents($file); |
foreach ($orig as $tag => $raw) { |
$tag = str_replace($this->_packagefile->getTasksNs() . ':', '', $tag); |
$task = "PEAR_Task_$tag"; |
$task = &new $task($this->_packagefile->_config, |
$this->_packagefile->_logger, |
PEAR_TASK_PACKAGE); |
$task->init($raw, $atts, null); |
$res = $task->startSession($this->_packagefile, $contents, $tfile); |
if (!$res) { |
continue; // skip this task |
} |
if (PEAR::isError($res)) { |
return $res; |
} |
$contents = $res; // save changes |
System::mkdir(array('-p', dirname($tfile))); |
$wp = fopen($tfile, "wb"); |
fwrite($wp, $contents); |
fclose($wp); |
} |
} |
if (!file_exists($tfile)) { |
System::mkdir(array('-p', dirname($tfile))); |
copy($file, $tfile); |
} |
$filelist[$i++] = $tfile; |
$this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1); |
$packager->log(2, "Adding file $fname"); |
} |
} |
} |
// }}} |
if ($pf1 !== null) { |
$name = 'package2.xml'; |
} else { |
$name = 'package.xml'; |
} |
$packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name); |
if ($packagexml) { |
$tar =& new Archive_Tar($dest_package, $compress); |
$tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors |
// ----- Creates with the package.xml file |
$ok = $tar->createModify(array($packagexml), '', $where); |
if (PEAR::isError($ok)) { |
return $packager->raiseError($ok); |
} elseif (!$ok) { |
return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name . |
' failed'); |
} |
// ----- Add the content of the package |
if (!$tar->addModify($filelist, $pkgver, $where)) { |
return $packager->raiseError( |
'PEAR_Packagefile_v2::toTgz(): tarball creation failed'); |
} |
// add the package.xml version 1.0 |
if ($pf1 !== null) { |
$pfgen = &$pf1->getDefaultGenerator(); |
$packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING, |
'package.xml', true); |
if (!$tar->addModify(array($packagexml1), '', $where)) { |
return $packager->raiseError( |
'PEAR_Packagefile_v2::toTgz(): adding package.xml failed'); |
} |
} |
return $dest_package; |
} |
} |
function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml') |
{ |
if (!$this->_packagefile->validate($state)) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml', |
null, null, null, $this->_packagefile->getValidationWarnings()); |
} |
if ($where === null) { |
if (!($where = System::mktemp(array('-d')))) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed'); |
} |
} elseif (!@System::mkDir(array('-p', $where))) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' . |
' not be created'); |
} |
$newpkgfile = $where . DIRECTORY_SEPARATOR . $name; |
$np = @fopen($newpkgfile, 'wb'); |
if (!$np) { |
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' . |
"$name as $newpkgfile"); |
} |
fwrite($np, $this->toXml($state)); |
fclose($np); |
return $newpkgfile; |
} |
function &toV2() |
{ |
return $this->_packagefile; |
} |
/** |
* Return an XML document based on the package info (as returned |
* by the PEAR_Common::infoFrom* methods). |
* |
* @return string XML data |
*/ |
function toXml($state = PEAR_VALIDATE_NORMAL, $options = array()) |
{ |
$this->_packagefile->setDate(date('Y-m-d')); |
$this->_packagefile->setTime(date('H:i:s')); |
if (!$this->_packagefile->validate($state)) { |
return false; |
} |
if (is_array($options)) { |
$this->options = array_merge($this->_defaultOptions, $options); |
} else { |
$this->options = $this->_defaultOptions; |
} |
$arr = $this->_packagefile->getArray(); |
if (isset($arr['filelist'])) { |
unset($arr['filelist']); |
} |
if (isset($arr['_lastversion'])) { |
unset($arr['_lastversion']); |
} |
if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) { |
$use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']); |
unset($arr['contents']['dir']['file']); |
if (isset($use['dir'])) { |
$arr['contents']['dir']['dir'] = $use['dir']; |
} |
if (isset($use['file'])) { |
$arr['contents']['dir']['file'] = $use['file']; |
} |
$this->options['beautifyFilelist'] = true; |
} |
$arr['attribs']['packagerversion'] = '1.5.1'; |
if ($this->serialize($arr, $options)) { |
return $this->_serializedData . "\n"; |
} |
return false; |
} |
function _recursiveXmlFilelist($list) |
{ |
$dirs = array(); |
if (isset($list['attribs'])) { |
$file = $list['attribs']['name']; |
unset($list['attribs']['name']); |
$attributes = $list['attribs']; |
$this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes); |
} else { |
foreach ($list as $a) { |
$file = $a['attribs']['name']; |
$attributes = $a['attribs']; |
unset($a['attribs']); |
$this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a); |
} |
} |
$this->_formatDir($dirs); |
$this->_deFormat($dirs); |
return $dirs; |
} |
function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null) |
{ |
if (!$tasks) { |
$tasks = array(); |
} |
if ($dir == array() || $dir == array('.')) { |
$dirs['file'][basename($file)] = $tasks; |
$attributes['name'] = basename($file); |
$dirs['file'][basename($file)]['attribs'] = $attributes; |
return; |
} |
$curdir = array_shift($dir); |
if (!isset($dirs['dir'][$curdir])) { |
$dirs['dir'][$curdir] = array(); |
} |
$this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks); |
} |
function _formatDir(&$dirs) |
{ |
if (!count($dirs)) { |
return array(); |
} |
$newdirs = array(); |
if (isset($dirs['dir'])) { |
$newdirs['dir'] = $dirs['dir']; |
} |
if (isset($dirs['file'])) { |
$newdirs['file'] = $dirs['file']; |
} |
$dirs = $newdirs; |
if (isset($dirs['dir'])) { |
uksort($dirs['dir'], 'strnatcasecmp'); |
foreach ($dirs['dir'] as $dir => $contents) { |
$this->_formatDir($dirs['dir'][$dir]); |
} |
} |
if (isset($dirs['file'])) { |
uksort($dirs['file'], 'strnatcasecmp'); |
}; |
} |
function _deFormat(&$dirs) |
{ |
if (!count($dirs)) { |
return array(); |
} |
$newdirs = array(); |
if (isset($dirs['dir'])) { |
foreach ($dirs['dir'] as $dir => $contents) { |
$newdir = array(); |
$newdir['attribs']['name'] = $dir; |
$this->_deFormat($contents); |
foreach ($contents as $tag => $val) { |
$newdir[$tag] = $val; |
} |
$newdirs['dir'][] = $newdir; |
} |
if (count($newdirs['dir']) == 1) { |
$newdirs['dir'] = $newdirs['dir'][0]; |
} |
} |
if (isset($dirs['file'])) { |
foreach ($dirs['file'] as $name => $file) { |
$newdirs['file'][] = $file; |
} |
if (count($newdirs['file']) == 1) { |
$newdirs['file'] = $newdirs['file'][0]; |
} |
} |
$dirs = $newdirs; |
} |
/** |
* reset all options to default options |
* |
* @access public |
* @see setOption(), XML_Unserializer() |
*/ |
function resetOptions() |
{ |
$this->options = $this->_defaultOptions; |
} |
/** |
* set an option |
* |
* You can use this method if you do not want to set all options in the constructor |
* |
* @access public |
* @see resetOption(), XML_Serializer() |
*/ |
function setOption($name, $value) |
{ |
$this->options[$name] = $value; |
} |
/** |
* sets several options at once |
* |
* You can use this method if you do not want to set all options in the constructor |
* |
* @access public |
* @see resetOption(), XML_Unserializer(), setOption() |
*/ |
function setOptions($options) |
{ |
$this->options = array_merge($this->options, $options); |
} |
/** |
* serialize data |
* |
* @access public |
* @param mixed $data data to serialize |
* @return boolean true on success, pear error on failure |
*/ |
function serialize($data, $options = null) |
{ |
// if options have been specified, use them instead |
// of the previously defined ones |
if (is_array($options)) { |
$optionsBak = $this->options; |
if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) { |
$this->options = array_merge($this->_defaultOptions, $options); |
} else { |
$this->options = array_merge($this->options, $options); |
} |
} |
else { |
$optionsBak = null; |
} |
// start depth is zero |
$this->_tagDepth = 0; |
$this->_serializedData = ''; |
// serialize an array |
if (is_array($data)) { |
if (isset($this->options['rootName'])) { |
$tagName = $this->options['rootName']; |
} else { |
$tagName = 'array'; |
} |
$this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']); |
} |
// add doctype declaration |
if ($this->options['addDoctype'] === true) { |
$this->_serializedData = PEAR_PackageFile_Generator_v2_XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype']) |
. $this->options['linebreak'] |
. $this->_serializedData; |
} |
// build xml declaration |
if ($this->options['addDecl']) { |
$atts = array(); |
if (isset($this->options['encoding']) ) { |
$encoding = $this->options['encoding']; |
} else { |
$encoding = null; |
} |
$this->_serializedData = PEAR_PackageFile_Generator_v2_XML_Util::getXMLDeclaration('1.0', $encoding) |
. $this->options['linebreak'] |
. $this->_serializedData; |
} |
if ($optionsBak !== null) { |
$this->options = $optionsBak; |
} |
return true; |
} |
/** |
* get the result of the serialization |
* |
* @access public |
* @return string serialized XML |
*/ |
function getSerializedData() |
{ |
if ($this->_serializedData == null ) { |
return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION); |
} |
return $this->_serializedData; |
} |
/** |
* serialize any value |
* |
* This method checks for the type of the value and calls the appropriate method |
* |
* @access private |
* @param mixed $value |
* @param string $tagName |
* @param array $attributes |
* @return string |
*/ |
function _serializeValue($value, $tagName = null, $attributes = array()) |
{ |
if (is_array($value)) { |
$xml = $this->_serializeArray($value, $tagName, $attributes); |
} elseif (is_object($value)) { |
$xml = $this->_serializeObject($value, $tagName); |
} else { |
$tag = array( |
'qname' => $tagName, |
'attributes' => $attributes, |
'content' => $value |
); |
$xml = $this->_createXMLTag($tag); |
} |
return $xml; |
} |
/** |
* serialize an array |
* |
* @access private |
* @param array $array array to serialize |
* @param string $tagName name of the root tag |
* @param array $attributes attributes for the root tag |
* @return string $string serialized data |
* @uses PEAR_PackageFile_Generator_v2_XML_Util::isValidName() to check, whether key has to be substituted |
*/ |
function _serializeArray(&$array, $tagName = null, $attributes = array()) |
{ |
$_content = null; |
/** |
* check for special attributes |
*/ |
if ($this->options['attributesArray'] !== null) { |
if (isset($array[$this->options['attributesArray']])) { |
$attributes = $array[$this->options['attributesArray']]; |
unset($array[$this->options['attributesArray']]); |
} |
/** |
* check for special content |
*/ |
if ($this->options['contentName'] !== null) { |
if (isset($array[$this->options['contentName']])) { |
$_content = $array[$this->options['contentName']]; |
unset($array[$this->options['contentName']]); |
} |
} |
} |
/* |
* if mode is set to simpleXML, check whether |
* the array is associative or indexed |
*/ |
if (is_array($array) && $this->options['mode'] == 'simplexml') { |
$indexed = true; |
if (!count($array)) { |
$indexed = false; |
} |
foreach ($array as $key => $val) { |
if (!is_int($key)) { |
$indexed = false; |
break; |
} |
} |
if ($indexed && $this->options['mode'] == 'simplexml') { |
$string = ''; |
foreach ($array as $key => $val) { |
if ($this->options['beautifyFilelist'] && $tagName == 'dir') { |
if (!isset($this->_curdir)) { |
$this->_curdir = ''; |
} |
$savedir = $this->_curdir; |
if (isset($val['attribs'])) { |
if ($val['attribs']['name'] == '/') { |
$this->_curdir = '/'; |
} else { |
if ($this->_curdir == '/') { |
$this->_curdir = ''; |
} |
$this->_curdir .= '/' . $val['attribs']['name']; |
} |
} |
} |
$string .= $this->_serializeValue( $val, $tagName, $attributes); |
if ($this->options['beautifyFilelist'] && $tagName == 'dir') { |
$string .= ' <!-- ' . $this->_curdir . ' -->'; |
if (empty($savedir)) { |
unset($this->_curdir); |
} else { |
$this->_curdir = $savedir; |
} |
} |
$string .= $this->options['linebreak']; |
// do indentation |
if ($this->options['indent']!==null && $this->_tagDepth>0) { |
$string .= str_repeat($this->options['indent'], $this->_tagDepth); |
} |
} |
return rtrim($string); |
} |
} |
if ($this->options['scalarAsAttributes'] === true) { |
foreach ($array as $key => $value) { |
if (is_scalar($value) && (PEAR_PackageFile_Generator_v2_XML_Util::isValidName($key) === true)) { |
unset($array[$key]); |
$attributes[$this->options['prependAttributes'].$key] = $value; |
} |
} |
} |
// check for empty array => create empty tag |
if (empty($array)) { |
$tag = array( |
'qname' => $tagName, |
'content' => $_content, |
'attributes' => $attributes |
); |
} else { |
$this->_tagDepth++; |
$tmp = $this->options['linebreak']; |
foreach ($array as $key => $value) { |
// do indentation |
if ($this->options['indent']!==null && $this->_tagDepth>0) { |
$tmp .= str_repeat($this->options['indent'], $this->_tagDepth); |
} |
// copy key |
$origKey = $key; |
// key cannot be used as tagname => use default tag |
$valid = PEAR_PackageFile_Generator_v2_XML_Util::isValidName($key); |
if (PEAR::isError($valid)) { |
if ($this->options['classAsTagName'] && is_object($value)) { |
$key = get_class($value); |
} else { |
$key = $this->options['defaultTagName']; |
} |
} |
$atts = array(); |
if ($this->options['typeHints'] === true) { |
$atts[$this->options['typeAttribute']] = gettype($value); |
if ($key !== $origKey) { |
$atts[$this->options['keyAttribute']] = (string)$origKey; |
} |
} |
if ($this->options['beautifyFilelist'] && $key == 'dir') { |
if (!isset($this->_curdir)) { |
$this->_curdir = ''; |
} |
$savedir = $this->_curdir; |
if (isset($value['attribs'])) { |
if ($value['attribs']['name'] == '/') { |
$this->_curdir = '/'; |
} else { |
$this->_curdir .= '/' . $value['attribs']['name']; |
} |
} |
} |
if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) { |
$value .= str_repeat($this->options['indent'], $this->_tagDepth); |
} |
$tmp .= $this->_createXMLTag(array( |
'qname' => $key, |
'attributes' => $atts, |
'content' => $value ) |
); |
if ($this->options['beautifyFilelist'] && $key == 'dir') { |
if (isset($value['attribs'])) { |
$tmp .= ' <!-- ' . $this->_curdir . ' -->'; |
if (empty($savedir)) { |
unset($this->_curdir); |
} else { |
$this->_curdir = $savedir; |
} |
} |
} |
$tmp .= $this->options['linebreak']; |
} |
$this->_tagDepth--; |
if ($this->options['indent']!==null && $this->_tagDepth>0) { |
$tmp .= str_repeat($this->options['indent'], $this->_tagDepth); |
} |
if (trim($tmp) === '') { |
$tmp = null; |
} |
$tag = array( |
'qname' => $tagName, |
'content' => $tmp, |
'attributes' => $attributes |
); |
} |
if ($this->options['typeHints'] === true) { |
if (!isset($tag['attributes'][$this->options['typeAttribute']])) { |
$tag['attributes'][$this->options['typeAttribute']] = 'array'; |
} |
} |
$string = $this->_createXMLTag($tag, false); |
return $string; |
} |
/** |
* create a tag from an array |
* this method awaits an array in the following format |
* array( |
* 'qname' => $tagName, |
* 'attributes' => array(), |
* 'content' => $content, // optional |
* 'namespace' => $namespace // optional |
* 'namespaceUri' => $namespaceUri // optional |
* ) |
* |
* @access private |
* @param array $tag tag definition |
* @param boolean $replaceEntities whether to replace XML entities in content or not |
* @return string $string XML tag |
*/ |
function _createXMLTag( $tag, $replaceEntities = true ) |
{ |
if ($this->options['indentAttributes'] !== false) { |
$multiline = true; |
$indent = str_repeat($this->options['indent'], $this->_tagDepth); |
if ($this->options['indentAttributes'] == '_auto') { |
$indent .= str_repeat(' ', (strlen($tag['qname'])+2)); |
} else { |
$indent .= $this->options['indentAttributes']; |
} |
} else { |
$multiline = false; |
$indent = false; |
} |
if (is_array($tag['content'])) { |
if (empty($tag['content'])) { |
$tag['content'] = ''; |
} |
} elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') { |
$tag['content'] = ''; |
} |
if (is_scalar($tag['content']) || is_null($tag['content'])) { |
if ($this->options['encoding'] == 'UTF-8' && |
version_compare(phpversion(), '5.0.0', 'lt')) { |
$encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML; |
} else { |
$encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML; |
} |
$tag = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak'], $encoding); |
} elseif (is_array($tag['content'])) { |
$tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']); |
} elseif (is_object($tag['content'])) { |
$tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']); |
} elseif (is_resource($tag['content'])) { |
settype($tag['content'], 'string'); |
$tag = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities); |
} |
return $tag; |
} |
} |
// well, it's one way to do things without extra deps ... |
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
// +----------------------------------------------------------------------+ |
// | PHP Version 4 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2002 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available at through the world-wide-web at | |
// | http://www.php.net/license/2_02.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Stephan Schmidt <schst@php-tools.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id: v2.php,v 1.35 2006/03/25 21:09:08 cellog Exp $ |
/** |
* error code for invalid chars in XML name |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_CHARS", 51); |
/** |
* error code for invalid chars in XML name |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_START", 52); |
/** |
* error code for non-scalar tag content |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NON_SCALAR_CONTENT", 60); |
/** |
* error code for missing tag name |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NO_TAG_NAME", 61); |
/** |
* replace XML entities |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES", 1); |
/** |
* embedd content in a CData Section |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_CDATA_SECTION", 2); |
/** |
* do not replace entitites |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE", 0); |
/** |
* replace all XML entitites |
* This setting will replace <, >, ", ' and & |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML", 1); |
/** |
* replace only required XML entitites |
* This setting will replace <, " and & |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED", 2); |
/** |
* replace HTML entitites |
* @link http://www.php.net/htmlentities |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML", 3); |
/** |
* replace all XML entitites, and encode from ISO-8859-1 to UTF-8 |
* This setting will replace <, >, ", ' and & |
*/ |
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML", 4); |
/** |
* utility class for working with XML documents |
* |
* customized version of XML_Util 0.6.0 |
* |
* @category XML |
* @package PEAR |
* @version 0.6.0 |
* @author Stephan Schmidt <schst@php.net> |
* @author Gregory Beaver <cellog@php.net> |
*/ |
class PEAR_PackageFile_Generator_v2_XML_Util { |
/** |
* return API version |
* |
* @access public |
* @static |
* @return string $version API version |
*/ |
function apiVersion() |
{ |
return "0.6"; |
} |
/** |
* replace XML entities |
* |
* With the optional second parameter, you may select, which |
* entities should be replaced. |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // replace XML entites: |
* $string = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities("This string contains < & >."); |
* </code> |
* |
* @access public |
* @static |
* @param string string where XML special chars should be replaced |
* @param integer setting for entities in attribute values (one of PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML) |
* @return string string with replaced chars |
*/ |
function replaceEntities($string, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML) |
{ |
switch ($replaceEntities) { |
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML: |
return strtr(utf8_encode($string),array( |
'&' => '&', |
'>' => '>', |
'<' => '<', |
'"' => '"', |
'\'' => ''' )); |
break; |
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML: |
return strtr($string,array( |
'&' => '&', |
'>' => '>', |
'<' => '<', |
'"' => '"', |
'\'' => ''' )); |
break; |
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED: |
return strtr($string,array( |
'&' => '&', |
'<' => '<', |
'"' => '"' )); |
break; |
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML: |
return htmlspecialchars($string); |
break; |
} |
return $string; |
} |
/** |
* build an xml declaration |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // get an XML declaration: |
* $xmlDecl = PEAR_PackageFile_Generator_v2_XML_Util::getXMLDeclaration("1.0", "UTF-8", true); |
* </code> |
* |
* @access public |
* @static |
* @param string $version xml version |
* @param string $encoding character encoding |
* @param boolean $standAlone document is standalone (or not) |
* @return string $decl xml declaration |
* @uses PEAR_PackageFile_Generator_v2_XML_Util::attributesToString() to serialize the attributes of the XML declaration |
*/ |
function getXMLDeclaration($version = "1.0", $encoding = null, $standalone = null) |
{ |
$attributes = array( |
"version" => $version, |
); |
// add encoding |
if ($encoding !== null) { |
$attributes["encoding"] = $encoding; |
} |
// add standalone, if specified |
if ($standalone !== null) { |
$attributes["standalone"] = $standalone ? "yes" : "no"; |
} |
return sprintf("<?xml%s?>", PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($attributes, false)); |
} |
/** |
* build a document type declaration |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // get a doctype declaration: |
* $xmlDecl = PEAR_PackageFile_Generator_v2_XML_Util::getDocTypeDeclaration("rootTag","myDocType.dtd"); |
* </code> |
* |
* @access public |
* @static |
* @param string $root name of the root tag |
* @param string $uri uri of the doctype definition (or array with uri and public id) |
* @param string $internalDtd internal dtd entries |
* @return string $decl doctype declaration |
* @since 0.2 |
*/ |
function getDocTypeDeclaration($root, $uri = null, $internalDtd = null) |
{ |
if (is_array($uri)) { |
$ref = sprintf( ' PUBLIC "%s" "%s"', $uri["id"], $uri["uri"] ); |
} elseif (!empty($uri)) { |
$ref = sprintf( ' SYSTEM "%s"', $uri ); |
} else { |
$ref = ""; |
} |
if (empty($internalDtd)) { |
return sprintf("<!DOCTYPE %s%s>", $root, $ref); |
} else { |
return sprintf("<!DOCTYPE %s%s [\n%s\n]>", $root, $ref, $internalDtd); |
} |
} |
/** |
* create string representation of an attribute list |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // build an attribute string |
* $att = array( |
* "foo" => "bar", |
* "argh" => "tomato" |
* ); |
* |
* $attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($att); |
* </code> |
* |
* @access public |
* @static |
* @param array $attributes attribute array |
* @param boolean|array $sort sort attribute list alphabetically, may also be an assoc array containing the keys 'sort', 'multiline', 'indent', 'linebreak' and 'entities' |
* @param boolean $multiline use linebreaks, if more than one attribute is given |
* @param string $indent string used for indentation of multiline attributes |
* @param string $linebreak string used for linebreaks of multiline attributes |
* @param integer $entities setting for entities in attribute values (one of PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML) |
* @return string string representation of the attributes |
* @uses PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities() to replace XML entities in attribute values |
* @todo allow sort also to be an options array |
*/ |
function attributesToString($attributes, $sort = true, $multiline = false, $indent = ' ', $linebreak = "\n", $entities = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML) |
{ |
/** |
* second parameter may be an array |
*/ |
if (is_array($sort)) { |
if (isset($sort['multiline'])) { |
$multiline = $sort['multiline']; |
} |
if (isset($sort['indent'])) { |
$indent = $sort['indent']; |
} |
if (isset($sort['linebreak'])) { |
$multiline = $sort['linebreak']; |
} |
if (isset($sort['entities'])) { |
$entities = $sort['entities']; |
} |
if (isset($sort['sort'])) { |
$sort = $sort['sort']; |
} else { |
$sort = true; |
} |
} |
$string = ''; |
if (is_array($attributes) && !empty($attributes)) { |
if ($sort) { |
ksort($attributes); |
} |
if( !$multiline || count($attributes) == 1) { |
foreach ($attributes as $key => $value) { |
if ($entities != PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE) { |
$value = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($value, $entities); |
} |
$string .= ' '.$key.'="'.$value.'"'; |
} |
} else { |
$first = true; |
foreach ($attributes as $key => $value) { |
if ($entities != PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE) { |
$value = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($value, $entities); |
} |
if ($first) { |
$string .= " ".$key.'="'.$value.'"'; |
$first = false; |
} else { |
$string .= $linebreak.$indent.$key.'="'.$value.'"'; |
} |
} |
} |
} |
return $string; |
} |
/** |
* create a tag |
* |
* This method will call PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray(), which |
* is more flexible. |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // create an XML tag: |
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createTag("myNs:myTag", array("foo" => "bar"), "This is inside the tag", "http://www.w3c.org/myNs#"); |
* </code> |
* |
* @access public |
* @static |
* @param string $qname qualified tagname (including namespace) |
* @param array $attributes array containg attributes |
* @param mixed $content |
* @param string $namespaceUri URI of the namespace |
* @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both |
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line |
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column) |
* @param string $linebreak string used for linebreaks |
* @param string $encoding encoding that should be used to translate content |
* @return string $string XML tag |
* @see PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray() |
* @uses PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray() to create the tag |
*/ |
function createTag($qname, $attributes = array(), $content = null, $namespaceUri = null, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML) |
{ |
$tag = array( |
"qname" => $qname, |
"attributes" => $attributes |
); |
// add tag content |
if ($content !== null) { |
$tag["content"] = $content; |
} |
// add namespace Uri |
if ($namespaceUri !== null) { |
$tag["namespaceUri"] = $namespaceUri; |
} |
return PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $linebreak, $encoding); |
} |
/** |
* create a tag from an array |
* this method awaits an array in the following format |
* <pre> |
* array( |
* "qname" => $qname // qualified name of the tag |
* "namespace" => $namespace // namespace prefix (optional, if qname is specified or no namespace) |
* "localpart" => $localpart, // local part of the tagname (optional, if qname is specified) |
* "attributes" => array(), // array containing all attributes (optional) |
* "content" => $content, // tag content (optional) |
* "namespaceUri" => $namespaceUri // namespaceUri for the given namespace (optional) |
* ) |
* </pre> |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* $tag = array( |
* "qname" => "foo:bar", |
* "namespaceUri" => "http://foo.com", |
* "attributes" => array( "key" => "value", "argh" => "fruit&vegetable" ), |
* "content" => "I'm inside the tag", |
* ); |
* // creating a tag with qualified name and namespaceUri |
* $string = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag); |
* </code> |
* |
* @access public |
* @static |
* @param array $tag tag definition |
* @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both |
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line |
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column) |
* @param string $linebreak string used for linebreaks |
* @return string $string XML tag |
* @see PEAR_PackageFile_Generator_v2_XML_Util::createTag() |
* @uses PEAR_PackageFile_Generator_v2_XML_Util::attributesToString() to serialize the attributes of the tag |
* @uses PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName() to get local part and namespace of a qualified name |
*/ |
function createTagFromArray($tag, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML) |
{ |
if (isset($tag["content"]) && !is_scalar($tag["content"])) { |
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "Supplied non-scalar value as tag content", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NON_SCALAR_CONTENT ); |
} |
if (!isset($tag['qname']) && !isset($tag['localPart'])) { |
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( 'You must either supply a qualified name (qname) or local tag name (localPart).', PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NO_TAG_NAME ); |
} |
// if no attributes hav been set, use empty attributes |
if (!isset($tag["attributes"]) || !is_array($tag["attributes"])) { |
$tag["attributes"] = array(); |
} |
// qualified name is not given |
if (!isset($tag["qname"])) { |
// check for namespace |
if (isset($tag["namespace"]) && !empty($tag["namespace"])) { |
$tag["qname"] = $tag["namespace"].":".$tag["localPart"]; |
} else { |
$tag["qname"] = $tag["localPart"]; |
} |
// namespace URI is set, but no namespace |
} elseif (isset($tag["namespaceUri"]) && !isset($tag["namespace"])) { |
$parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName($tag["qname"]); |
$tag["localPart"] = $parts["localPart"]; |
if (isset($parts["namespace"])) { |
$tag["namespace"] = $parts["namespace"]; |
} |
} |
if (isset($tag["namespaceUri"]) && !empty($tag["namespaceUri"])) { |
// is a namespace given |
if (isset($tag["namespace"]) && !empty($tag["namespace"])) { |
$tag["attributes"]["xmlns:".$tag["namespace"]] = $tag["namespaceUri"]; |
} else { |
// define this Uri as the default namespace |
$tag["attributes"]["xmlns"] = $tag["namespaceUri"]; |
} |
} |
// check for multiline attributes |
if ($multiline === true) { |
if ($indent === "_auto") { |
$indent = str_repeat(" ", (strlen($tag["qname"])+2)); |
} |
} |
// create attribute list |
$attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($tag["attributes"], true, $multiline, $indent, $linebreak ); |
if (!isset($tag["content"]) || (string)$tag["content"] == '') { |
$tag = sprintf("<%s%s />", $tag["qname"], $attList); |
} else { |
if ($replaceEntities == PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES) { |
$tag["content"] = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($tag["content"], $encoding); |
} elseif ($replaceEntities == PEAR_PackageFile_Generator_v2_XML_Util_CDATA_SECTION) { |
$tag["content"] = PEAR_PackageFile_Generator_v2_XML_Util::createCDataSection($tag["content"]); |
} |
$tag = sprintf("<%s%s>%s</%s>", $tag["qname"], $attList, $tag["content"], $tag["qname"] ); |
} |
return $tag; |
} |
/** |
* create a start element |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // create an XML start element: |
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createStartElement("myNs:myTag", array("foo" => "bar") ,"http://www.w3c.org/myNs#"); |
* </code> |
* |
* @access public |
* @static |
* @param string $qname qualified tagname (including namespace) |
* @param array $attributes array containg attributes |
* @param string $namespaceUri URI of the namespace |
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line |
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column) |
* @param string $linebreak string used for linebreaks |
* @return string $string XML start element |
* @see PEAR_PackageFile_Generator_v2_XML_Util::createEndElement(), PEAR_PackageFile_Generator_v2_XML_Util::createTag() |
*/ |
function createStartElement($qname, $attributes = array(), $namespaceUri = null, $multiline = false, $indent = '_auto', $linebreak = "\n") |
{ |
// if no attributes hav been set, use empty attributes |
if (!isset($attributes) || !is_array($attributes)) { |
$attributes = array(); |
} |
if ($namespaceUri != null) { |
$parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName($qname); |
} |
// check for multiline attributes |
if ($multiline === true) { |
if ($indent === "_auto") { |
$indent = str_repeat(" ", (strlen($qname)+2)); |
} |
} |
if ($namespaceUri != null) { |
// is a namespace given |
if (isset($parts["namespace"]) && !empty($parts["namespace"])) { |
$attributes["xmlns:".$parts["namespace"]] = $namespaceUri; |
} else { |
// define this Uri as the default namespace |
$attributes["xmlns"] = $namespaceUri; |
} |
} |
// create attribute list |
$attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($attributes, true, $multiline, $indent, $linebreak); |
$element = sprintf("<%s%s>", $qname, $attList); |
return $element; |
} |
/** |
* create an end element |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // create an XML start element: |
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createEndElement("myNs:myTag"); |
* </code> |
* |
* @access public |
* @static |
* @param string $qname qualified tagname (including namespace) |
* @return string $string XML end element |
* @see PEAR_PackageFile_Generator_v2_XML_Util::createStartElement(), PEAR_PackageFile_Generator_v2_XML_Util::createTag() |
*/ |
function createEndElement($qname) |
{ |
$element = sprintf("</%s>", $qname); |
return $element; |
} |
/** |
* create an XML comment |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // create an XML start element: |
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createComment("I am a comment"); |
* </code> |
* |
* @access public |
* @static |
* @param string $content content of the comment |
* @return string $comment XML comment |
*/ |
function createComment($content) |
{ |
$comment = sprintf("<!-- %s -->", $content); |
return $comment; |
} |
/** |
* create a CData section |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // create a CData section |
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createCDataSection("I am content."); |
* </code> |
* |
* @access public |
* @static |
* @param string $data data of the CData section |
* @return string $string CData section with content |
*/ |
function createCDataSection($data) |
{ |
return sprintf("<![CDATA[%s]]>", $data); |
} |
/** |
* split qualified name and return namespace and local part |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // split qualified tag |
* $parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName("xslt:stylesheet"); |
* </code> |
* the returned array will contain two elements: |
* <pre> |
* array( |
* "namespace" => "xslt", |
* "localPart" => "stylesheet" |
* ); |
* </pre> |
* |
* @access public |
* @static |
* @param string $qname qualified tag name |
* @param string $defaultNs default namespace (optional) |
* @return array $parts array containing namespace and local part |
*/ |
function splitQualifiedName($qname, $defaultNs = null) |
{ |
if (strstr($qname, ':')) { |
$tmp = explode(":", $qname); |
return array( |
"namespace" => $tmp[0], |
"localPart" => $tmp[1] |
); |
} |
return array( |
"namespace" => $defaultNs, |
"localPart" => $qname |
); |
} |
/** |
* check, whether string is valid XML name |
* |
* <p>XML names are used for tagname, attribute names and various |
* other, lesser known entities.</p> |
* <p>An XML name may only consist of alphanumeric characters, |
* dashes, undescores and periods, and has to start with a letter |
* or an underscore. |
* </p> |
* |
* <code> |
* require_once 'XML/Util.php'; |
* |
* // verify tag name |
* $result = PEAR_PackageFile_Generator_v2_XML_Util::isValidName("invalidTag?"); |
* if (PEAR_PackageFile_Generator_v2_XML_Util::isError($result)) { |
* print "Invalid XML name: " . $result->getMessage(); |
* } |
* </code> |
* |
* @access public |
* @static |
* @param string $string string that should be checked |
* @return mixed $valid true, if string is a valid XML name, PEAR error otherwise |
* @todo support for other charsets |
*/ |
function isValidName($string) |
{ |
// check for invalid chars |
if (!preg_match("/^[[:alnum:]_\-.]$/", $string{0})) { |
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "XML names may only start with letter or underscore", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_START ); |
} |
// check for invalid chars |
if (!preg_match("/^([a-zA-Z_]([a-zA-Z0-9_\-\.]*)?:)?[a-zA-Z_]([a-zA-Z0-9_\-\.]+)?$/", $string)) { |
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "XML names may only contain alphanumeric chars, period, hyphen, colon and underscores", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_CHARS ); |
} |
// XML name is valid |
return true; |
} |
/** |
* replacement for PEAR_PackageFile_Generator_v2_XML_Util::raiseError |
* |
* Avoids the necessity to always require |
* PEAR.php |
* |
* @access public |
* @param string error message |
* @param integer error code |
* @return object PEAR_Error |
*/ |
function raiseError($msg, $code) |
{ |
require_once 'PEAR.php'; |
return PEAR::raiseError($msg, $code); |
} |
} |
?> |
/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/v2/rw.php |
---|
New file |
0,0 → 1,1601 |
<?php |
/** |
* PEAR_PackageFile_v2, package.xml version 2.0, read/write version |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: rw.php,v 1.19 2006/10/30 04:12:02 cellog Exp $ |
* @link http://pear.php.net/package/PEAR |
* @since File available since Release 1.4.0a8 |
*/ |
/** |
* For base class |
*/ |
require_once 'PEAR/PackageFile/v2.php'; |
/** |
* @category pear |
* @package PEAR |
* @author Greg Beaver <cellog@php.net> |
* @copyright 1997-2006 The PHP Group |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version Release: 1.5.1 |
* @link http://pear.php.net/package/PEAR |
* @since Class available since Release 1.4.0a8 |
*/ |
class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 |
{ |
/** |
* @param string Extension name |
* @return bool success of operation |
*/ |
function setProvidesExtension($extension) |
{ |
if (in_array($this->getPackageType(), |
array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { |
if (!isset($this->_packageInfo['providesextension'])) { |
// ensure that the channel tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', |
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'bundle', 'changelog'), |
$extension, 'providesextension'); |
} |
$this->_packageInfo['providesextension'] = $extension; |
return true; |
} |
return false; |
} |
function setPackage($package) |
{ |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['attribs'])) { |
$this->_packageInfo = array_merge(array('attribs' => array( |
'version' => '2.0', |
'xmlns' => 'http://pear.php.net/dtd/package-2.0', |
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', |
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 |
http://pear.php.net/dtd/tasks-1.0.xsd |
http://pear.php.net/dtd/package-2.0 |
http://pear.php.net/dtd/package-2.0.xsd', |
)), $this->_packageInfo); |
} |
if (!isset($this->_packageInfo['name'])) { |
return $this->_packageInfo = array_merge(array('name' => $package), |
$this->_packageInfo); |
} |
$this->_packageInfo['name'] = $package; |
} |
/** |
* set this as a package.xml version 2.1 |
* @access private |
*/ |
function _setPackageVersion2_1() |
{ |
$info = array( |
'version' => '2.1', |
'xmlns' => 'http://pear.php.net/dtd/package-2.1', |
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', |
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 |
http://pear.php.net/dtd/tasks-1.0.xsd |
http://pear.php.net/dtd/package-2.1 |
http://pear.php.net/dtd/package-2.1.xsd', |
); |
if (!isset($this->_packageInfo['attribs'])) { |
$this->_packageInfo = array_merge(array('attribs' => $info), $this->_packageInfo); |
} else { |
$this->_packageInfo['attribs'] = $info; |
} |
} |
function setUri($uri) |
{ |
unset($this->_packageInfo['channel']); |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['uri'])) { |
// ensure that the uri tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('extends', 'summary', 'description', 'lead', |
'developer', 'contributor', 'helper', 'date', 'time', 'version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), $uri, 'uri'); |
} |
$this->_packageInfo['uri'] = $uri; |
} |
function setChannel($channel) |
{ |
unset($this->_packageInfo['uri']); |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['channel'])) { |
// ensure that the channel tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('extends', 'summary', 'description', 'lead', |
'developer', 'contributor', 'helper', 'date', 'time', 'version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), $channel, 'channel'); |
} |
$this->_packageInfo['channel'] = $channel; |
} |
function setExtends($extends) |
{ |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['extends'])) { |
// ensure that the extends tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('summary', 'description', 'lead', |
'developer', 'contributor', 'helper', 'date', 'time', 'version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), $extends, 'extends'); |
} |
$this->_packageInfo['extends'] = $extends; |
} |
function setSummary($summary) |
{ |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['summary'])) { |
// ensure that the summary tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('description', 'lead', |
'developer', 'contributor', 'helper', 'date', 'time', 'version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), $summary, 'summary'); |
} |
$this->_packageInfo['summary'] = $summary; |
} |
function setDescription($desc) |
{ |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['description'])) { |
// ensure that the description tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('lead', |
'developer', 'contributor', 'helper', 'date', 'time', 'version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), $desc, 'description'); |
} |
$this->_packageInfo['description'] = $desc; |
} |
/** |
* Adds a new maintainer - no checking of duplicates is performed, use |
* updatemaintainer for that purpose. |
*/ |
function addMaintainer($role, $handle, $name, $email, $active = 'yes') |
{ |
if (!in_array($role, array('lead', 'developer', 'contributor', 'helper'))) { |
return false; |
} |
if (isset($this->_packageInfo[$role])) { |
if (!isset($this->_packageInfo[$role][0])) { |
$this->_packageInfo[$role] = array($this->_packageInfo[$role]); |
} |
$this->_packageInfo[$role][] = |
array( |
'name' => $name, |
'user' => $handle, |
'email' => $email, |
'active' => $active, |
); |
} else { |
$testarr = array('lead', |
'developer', 'contributor', 'helper', 'date', 'time', 'version', |
'stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', |
'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'); |
foreach (array('lead', 'developer', 'contributor', 'helper') as $testrole) { |
array_shift($testarr); |
if ($role == $testrole) { |
break; |
} |
} |
if (!isset($this->_packageInfo[$role])) { |
// ensure that the extends tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, $testarr, |
array(), $role); |
} |
$this->_packageInfo[$role] = |
array( |
'name' => $name, |
'user' => $handle, |
'email' => $email, |
'active' => $active, |
); |
} |
$this->_isValid = 0; |
} |
function updateMaintainer($newrole, $handle, $name, $email, $active = 'yes') |
{ |
$found = false; |
foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { |
if (!isset($this->_packageInfo[$role])) { |
continue; |
} |
$info = $this->_packageInfo[$role]; |
if (!isset($info[0])) { |
if ($info['user'] == $handle) { |
$found = true; |
break; |
} |
} |
foreach ($info as $i => $maintainer) { |
if ($maintainer['user'] == $handle) { |
$found = $i; |
break 2; |
} |
} |
} |
if ($found === false) { |
return $this->addMaintainer($newrole, $handle, $name, $email, $active); |
} |
if ($found !== false) { |
if ($found === true) { |
unset($this->_packageInfo[$role]); |
} else { |
unset($this->_packageInfo[$role][$found]); |
$this->_packageInfo[$role] = array_values($this->_packageInfo[$role]); |
} |
} |
$this->addMaintainer($newrole, $handle, $name, $email, $active); |
$this->_isValid = 0; |
} |
function deleteMaintainer($handle) |
{ |
$found = false; |
foreach (array('lead', 'developer', 'contributor', 'helper') as $role) { |
if (!isset($this->_packageInfo[$role])) { |
continue; |
} |
if (!isset($this->_packageInfo[$role][0])) { |
$this->_packageInfo[$role] = array($this->_packageInfo[$role]); |
} |
foreach ($this->_packageInfo[$role] as $i => $maintainer) { |
if ($maintainer['user'] == $handle) { |
$found = $i; |
break; |
} |
} |
if ($found !== false) { |
unset($this->_packageInfo[$role][$found]); |
if (!count($this->_packageInfo[$role]) && $role == 'lead') { |
$this->_isValid = 0; |
} |
if (!count($this->_packageInfo[$role])) { |
unset($this->_packageInfo[$role]); |
return true; |
} |
$this->_packageInfo[$role] = |
array_values($this->_packageInfo[$role]); |
if (count($this->_packageInfo[$role]) == 1) { |
$this->_packageInfo[$role] = $this->_packageInfo[$role][0]; |
} |
return true; |
} |
if (count($this->_packageInfo[$role]) == 1) { |
$this->_packageInfo[$role] = $this->_packageInfo[$role][0]; |
} |
} |
return false; |
} |
function setReleaseVersion($version) |
{ |
if (isset($this->_packageInfo['version']) && |
isset($this->_packageInfo['version']['release'])) { |
unset($this->_packageInfo['version']['release']); |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array( |
'version' => array('stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), |
'release' => array('api'))); |
$this->_isValid = 0; |
} |
function setAPIVersion($version) |
{ |
if (isset($this->_packageInfo['version']) && |
isset($this->_packageInfo['version']['api'])) { |
unset($this->_packageInfo['version']['api']); |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array( |
'version' => array('stability', 'license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), |
'api' => array())); |
$this->_isValid = 0; |
} |
/** |
* snapshot|devel|alpha|beta|stable |
*/ |
function setReleaseStability($state) |
{ |
if (isset($this->_packageInfo['stability']) && |
isset($this->_packageInfo['stability']['release'])) { |
unset($this->_packageInfo['stability']['release']); |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array( |
'stability' => array('license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), |
'release' => array('api'))); |
$this->_isValid = 0; |
} |
/** |
* @param devel|alpha|beta|stable |
*/ |
function setAPIStability($state) |
{ |
if (isset($this->_packageInfo['stability']) && |
isset($this->_packageInfo['stability']['api'])) { |
unset($this->_packageInfo['stability']['api']); |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array( |
'stability' => array('license', 'notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), |
'api' => array())); |
$this->_isValid = 0; |
} |
function setLicense($license, $uri = false, $filesource = false) |
{ |
if (!isset($this->_packageInfo['license'])) { |
// ensure that the license tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('notes', 'contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), 0, 'license'); |
} |
if ($uri || $filesource) { |
$attribs = array(); |
if ($uri) { |
$attribs['uri'] = $uri; |
} |
$uri = true; // for test below |
if ($filesource) { |
$attribs['filesource'] = $filesource; |
} |
} |
$license = $uri ? array('attribs' => $attribs, '_content' => $license) : $license; |
$this->_packageInfo['license'] = $license; |
$this->_isValid = 0; |
} |
function setNotes($notes) |
{ |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['notes'])) { |
// ensure that the notes tag is set up in the right location |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('contents', 'compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'extbinrelease', 'bundle', 'changelog'), $notes, 'notes'); |
} |
$this->_packageInfo['notes'] = $notes; |
} |
/** |
* This is only used at install-time, after all serialization |
* is over. |
* @param string file name |
* @param string installed path |
*/ |
function setInstalledAs($file, $path) |
{ |
if ($path) { |
return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; |
} |
unset($this->_packageInfo['filelist'][$file]['installed_as']); |
} |
/** |
* This is only used at install-time, after all serialization |
* is over. |
*/ |
function installedFile($file, $atts) |
{ |
if (isset($this->_packageInfo['filelist'][$file])) { |
$this->_packageInfo['filelist'][$file] = |
array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); |
} else { |
$this->_packageInfo['filelist'][$file] = $atts['attribs']; |
} |
} |
/** |
* Reset the listing of package contents |
* @param string base installation dir for the whole package, if any |
*/ |
function clearContents($baseinstall = false) |
{ |
$this->_filesValid = false; |
$this->_isValid = 0; |
if (!isset($this->_packageInfo['contents'])) { |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('compatible', |
'dependencies', 'providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', |
'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'bundle', 'changelog'), array(), 'contents'); |
} |
if ($this->getPackageType() != 'bundle') { |
$this->_packageInfo['contents'] = |
array('dir' => array('attribs' => array('name' => '/'))); |
if ($baseinstall) { |
$this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall; |
} |
} |
} |
/** |
* @param string relative path of the bundled package. |
*/ |
function addBundledPackage($path) |
{ |
if ($this->getPackageType() != 'bundle') { |
return false; |
} |
$this->_filesValid = false; |
$this->_isValid = 0; |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $path, array( |
'contents' => array('compatible', 'dependencies', 'providesextension', |
'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease', |
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'bundle', 'changelog'), |
'bundledpackage' => array())); |
} |
/** |
* @param string file name |
* @param PEAR_Task_Common a read/write task |
*/ |
function addTaskToFile($filename, $task) |
{ |
if (!method_exists($task, 'getXml')) { |
return false; |
} |
if (!method_exists($task, 'getName')) { |
return false; |
} |
if (!method_exists($task, 'validate')) { |
return false; |
} |
if (!$task->validate()) { |
return false; |
} |
if (!isset($this->_packageInfo['contents']['dir']['file'])) { |
return false; |
} |
$this->getTasksNs(); // discover the tasks namespace if not done already |
$files = $this->_packageInfo['contents']['dir']['file']; |
if (!isset($files[0])) { |
$files = array($files); |
$ind = false; |
} else { |
$ind = true; |
} |
foreach ($files as $i => $file) { |
if (isset($file['attribs'])) { |
if ($file['attribs']['name'] == $filename) { |
if ($ind) { |
$t = isset($this->_packageInfo['contents']['dir']['file'][$i] |
['attribs'][$this->_tasksNs . |
':' . $task->getName()]) ? |
$this->_packageInfo['contents']['dir']['file'][$i] |
['attribs'][$this->_tasksNs . |
':' . $task->getName()] : false; |
if ($t && !isset($t[0])) { |
$this->_packageInfo['contents']['dir']['file'][$i] |
[$this->_tasksNs . ':' . $task->getName()] = array($t); |
} |
$this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs . |
':' . $task->getName()][] = $task->getXml(); |
} else { |
$t = isset($this->_packageInfo['contents']['dir']['file'] |
['attribs'][$this->_tasksNs . |
':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file'] |
['attribs'][$this->_tasksNs . |
':' . $task->getName()] : false; |
if ($t && !isset($t[0])) { |
$this->_packageInfo['contents']['dir']['file'] |
[$this->_tasksNs . ':' . $task->getName()] = array($t); |
} |
$this->_packageInfo['contents']['dir']['file'][$this->_tasksNs . |
':' . $task->getName()][] = $task->getXml(); |
} |
return true; |
} |
} |
} |
return false; |
} |
/** |
* @param string path to the file |
* @param string filename |
* @param array extra attributes |
*/ |
function addFile($dir, $file, $attrs) |
{ |
if ($this->getPackageType() == 'bundle') { |
return false; |
} |
$this->_filesValid = false; |
$this->_isValid = 0; |
$dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); |
if ($dir == '/' || $dir == '') { |
$dir = ''; |
} else { |
$dir .= '/'; |
} |
$attrs['name'] = $dir . $file; |
if (!isset($this->_packageInfo['contents'])) { |
// ensure that the contents tag is set up |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, |
array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', |
'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'bundle', 'changelog'), array(), 'contents'); |
} |
if (isset($this->_packageInfo['contents']['dir']['file'])) { |
if (!isset($this->_packageInfo['contents']['dir']['file'][0])) { |
$this->_packageInfo['contents']['dir']['file'] = |
array($this->_packageInfo['contents']['dir']['file']); |
} |
$this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs; |
} else { |
$this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs; |
} |
} |
/** |
* @param string Dependent package name |
* @param string Dependent package's channel name |
* @param string minimum version of specified package that this release is guaranteed to be |
* compatible with |
* @param string maximum version of specified package that this release is guaranteed to be |
* compatible with |
* @param string versions of specified package that this release is not compatible with |
*/ |
function addCompatiblePackage($name, $channel, $min, $max, $exclude = false) |
{ |
$this->_isValid = 0; |
$set = array( |
'name' => $name, |
'channel' => $channel, |
'min' => $min, |
'max' => $max, |
); |
if ($exclude) { |
$set['exclude'] = $exclude; |
} |
$this->_isValid = 0; |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( |
'compatible' => array('dependencies', 'providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') |
)); |
} |
/** |
* Removes the <usesrole> tag entirely |
*/ |
function resetUsesrole() |
{ |
if (isset($this->_packageInfo['usesrole'])) { |
unset($this->_packageInfo['usesrole']); |
} |
} |
/** |
* @param string |
* @param string package name or uri |
* @param string channel name if non-uri |
*/ |
function addUsesrole($role, $packageOrUri, $channel = false) { |
$set = array('role' => $role); |
if ($channel) { |
$set['package'] = $packageOrUri; |
$set['channel'] = $channel; |
} else { |
$set['uri'] = $packageOrUri; |
} |
$this->_isValid = 0; |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( |
'usesrole' => array('usestask', 'srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') |
)); |
} |
/** |
* Removes the <usestask> tag entirely |
*/ |
function resetUsestask() |
{ |
if (isset($this->_packageInfo['usestask'])) { |
unset($this->_packageInfo['usestask']); |
} |
} |
/** |
* @param string |
* @param string package name or uri |
* @param string channel name if non-uri |
*/ |
function addUsestask($task, $packageOrUri, $channel = false) { |
$set = array('task' => $task); |
if ($channel) { |
$set['package'] = $packageOrUri; |
$set['channel'] = $channel; |
} else { |
$set['uri'] = $packageOrUri; |
} |
$this->_isValid = 0; |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array( |
'usestask' => array('srcpackage', 'srcuri', |
'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog') |
)); |
} |
/** |
* Remove all compatible tags |
*/ |
function clearCompatible() |
{ |
unset($this->_packageInfo['compatible']); |
} |
/** |
* Reset dependencies prior to adding new ones |
*/ |
function clearDeps() |
{ |
if (!isset($this->_packageInfo['dependencies'])) { |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(), |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'))); |
} |
$this->_packageInfo['dependencies'] = array(); |
} |
/** |
* @param string minimum PHP version allowed |
* @param string maximum PHP version allowed |
* @param array $exclude incompatible PHP versions |
*/ |
function setPhpDep($min, $max = false, $exclude = false) |
{ |
$this->_isValid = 0; |
$dep = |
array( |
'min' => $min, |
); |
if ($max) { |
$dep['max'] = $max; |
} |
if ($exclude) { |
if (count($exclude) == 1) { |
$exclude = $exclude[0]; |
} |
$dep['exclude'] = $exclude; |
} |
if (isset($this->_packageInfo['dependencies']['required']['php'])) { |
$this->_stack->push(__FUNCTION__, 'warning', array('dep' => |
$this->_packageInfo['dependencies']['required']['php']), |
'warning: PHP dependency already exists, overwriting'); |
unset($this->_packageInfo['dependencies']['required']['php']); |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
'required' => array('optional', 'group'), |
'php' => array('pearinstaller', 'package', 'subpackage', 'extension', 'os', 'arch') |
)); |
return true; |
} |
/** |
* @param string minimum allowed PEAR installer version |
* @param string maximum allowed PEAR installer version |
* @param string recommended PEAR installer version |
* @param array incompatible version of the PEAR installer |
*/ |
function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false) |
{ |
$this->_isValid = 0; |
$dep = |
array( |
'min' => $min, |
); |
if ($max) { |
$dep['max'] = $max; |
} |
if ($recommended) { |
$dep['recommended'] = $recommended; |
} |
if ($exclude) { |
if (count($exclude) == 1) { |
$exclude = $exclude[0]; |
} |
$dep['exclude'] = $exclude; |
} |
if (isset($this->_packageInfo['dependencies']['required']['pearinstaller'])) { |
$this->_stack->push(__FUNCTION__, 'warning', array('dep' => |
$this->_packageInfo['dependencies']['required']['pearinstaller']), |
'warning: PEAR Installer dependency already exists, overwriting'); |
unset($this->_packageInfo['dependencies']['required']['pearinstaller']); |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
'required' => array('optional', 'group'), |
'pearinstaller' => array('package', 'subpackage', 'extension', 'os', 'arch') |
)); |
} |
/** |
* Mark a package as conflicting with this package |
* @param string package name |
* @param string package channel |
* @param string extension this package provides, if any |
* @param string|false minimum version required |
* @param string|false maximum version allowed |
* @param array|false versions to exclude from installation |
*/ |
function addConflictingPackageDepWithChannel($name, $channel, |
$providesextension = false, $min = false, $max = false, $exclude = false) |
{ |
$this->_isValid = 0; |
$dep = $this->_constructDep($name, $channel, false, $min, $max, false, |
$exclude, $providesextension, false, true); |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
'required' => array('optional', 'group'), |
'package' => array('subpackage', 'extension', 'os', 'arch') |
)); |
} |
/** |
* Mark a package as conflicting with this package |
* @param string package name |
* @param string package channel |
* @param string extension this package provides, if any |
*/ |
function addConflictingPackageDepWithUri($name, $uri, $providesextension = false) |
{ |
$this->_isValid = 0; |
$dep = |
array( |
'name' => $name, |
'uri' => $uri, |
'conflicts' => '', |
); |
if ($providesextension) { |
$dep['providesextension'] = $providesextension; |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
'required' => array('optional', 'group'), |
'package' => array('subpackage', 'extension', 'os', 'arch') |
)); |
} |
function addDependencyGroup($name, $hint) |
{ |
$this->_isValid = 0; |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, |
array('attribs' => array('name' => $name, 'hint' => $hint)), |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
'group' => array(), |
)); |
} |
/** |
* @param string package name |
* @param string|false channel name, false if this is a uri |
* @param string|false uri name, false if this is a channel |
* @param string|false minimum version required |
* @param string|false maximum version allowed |
* @param string|false recommended installation version |
* @param array|false versions to exclude from installation |
* @param string extension this package provides, if any |
* @param bool if true, tells the installer to ignore the default optional dependency group |
* when installing this package |
* @param bool if true, tells the installer to negate this dependency (conflicts) |
* @return array |
* @access private |
*/ |
function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude, |
$providesextension = false, $nodefault = false, |
$conflicts = false) |
{ |
$dep = |
array( |
'name' => $name, |
); |
if ($channel) { |
$dep['channel'] = $channel; |
} elseif ($uri) { |
$dep['uri'] = $uri; |
} |
if ($min) { |
$dep['min'] = $min; |
} |
if ($max) { |
$dep['max'] = $max; |
} |
if ($recommended) { |
$dep['recommended'] = $recommended; |
} |
if ($exclude) { |
if (is_array($exclude) && count($exclude) == 1) { |
$exclude = $exclude[0]; |
} |
$dep['exclude'] = $exclude; |
} |
if ($conflicts) { |
$dep['conflicts'] = ''; |
} |
if ($nodefault) { |
$dep['nodefault'] = ''; |
} |
if ($providesextension) { |
$dep['providesextension'] = $providesextension; |
} |
return $dep; |
} |
/** |
* @param package|subpackage |
* @param string group name |
* @param string package name |
* @param string package channel |
* @param string minimum version |
* @param string maximum version |
* @param string recommended version |
* @param array|false optional excluded versions |
* @param string extension this package provides, if any |
* @param bool if true, tells the installer to ignore the default optional dependency group |
* when installing this package |
* @return bool false if the dependency group has not been initialized with |
* {@link addDependencyGroup()}, or a subpackage is added with |
* a providesextension |
*/ |
function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false, |
$max = false, $recommended = false, $exclude = false, |
$providesextension = false, $nodefault = false) |
{ |
if ($type == 'subpackage' && $providesextension) { |
return false; // subpackages must be php packages |
} |
$dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, |
$providesextension, $nodefault); |
return $this->_addGroupDependency($type, $dep, $groupname); |
} |
/** |
* @param package|subpackage |
* @param string group name |
* @param string package name |
* @param string package uri |
* @param string extension this package provides, if any |
* @param bool if true, tells the installer to ignore the default optional dependency group |
* when installing this package |
* @return bool false if the dependency group has not been initialized with |
* {@link addDependencyGroup()} |
*/ |
function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false, |
$nodefault = false) |
{ |
if ($type == 'subpackage' && $providesextension) { |
return false; // subpackages must be php packages |
} |
$dep = $this->_constructDep($name, false, $uri, false, false, false, false, |
$providesextension, $nodefault); |
return $this->_addGroupDependency($type, $dep, $groupname); |
} |
/** |
* @param string group name (must be pre-existing) |
* @param string extension name |
* @param string minimum version allowed |
* @param string maximum version allowed |
* @param string recommended version |
* @param array incompatible versions |
*/ |
function addGroupExtensionDep($groupname, $name, $min = false, $max = false, |
$recommended = false, $exclude = false) |
{ |
$this->_isValid = 0; |
$dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); |
return $this->_addGroupDependency('extension', $dep, $groupname); |
} |
/** |
* @param package|subpackage|extension |
* @param array dependency contents |
* @param string name of the dependency group to add this to |
* @return boolean |
* @access private |
*/ |
function _addGroupDependency($type, $dep, $groupname) |
{ |
$arr = array('subpackage', 'extension'); |
if ($type != 'package') { |
array_shift($arr); |
} |
if ($type == 'extension') { |
array_shift($arr); |
} |
if (!isset($this->_packageInfo['dependencies']['group'])) { |
return false; |
} else { |
if (!isset($this->_packageInfo['dependencies']['group'][0])) { |
if ($this->_packageInfo['dependencies']['group']['attribs']['name'] == $groupname) { |
$this->_packageInfo['dependencies']['group'] = $this->_mergeTag( |
$this->_packageInfo['dependencies']['group'], $dep, |
array( |
$type => $arr |
)); |
$this->_isValid = 0; |
return true; |
} else { |
return false; |
} |
} else { |
foreach ($this->_packageInfo['dependencies']['group'] as $i => $group) { |
if ($group['attribs']['name'] == $groupname) { |
$this->_packageInfo['dependencies']['group'][$i] = $this->_mergeTag( |
$this->_packageInfo['dependencies']['group'][$i], $dep, |
array( |
$type => $arr |
)); |
$this->_isValid = 0; |
return true; |
} |
} |
return false; |
} |
} |
} |
/** |
* @param optional|required |
* @param string package name |
* @param string package channel |
* @param string minimum version |
* @param string maximum version |
* @param string recommended version |
* @param string extension this package provides, if any |
* @param bool if true, tells the installer to ignore the default optional dependency group |
* when installing this package |
* @param array|false optional excluded versions |
*/ |
function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false, |
$recommended = false, $exclude = false, |
$providesextension = false, $nodefault = false) |
{ |
if (!in_array($type, array('optional', 'required'), true)) { |
$type = 'required'; |
} |
$this->_isValid = 0; |
$arr = array('optional', 'group'); |
if ($type != 'required') { |
array_shift($arr); |
} |
$dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, |
$providesextension, $nodefault); |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
$type => $arr, |
'package' => array('subpackage', 'extension', 'os', 'arch') |
)); |
} |
/** |
* @param optional|required |
* @param string name of the package |
* @param string uri of the package |
* @param string extension this package provides, if any |
* @param bool if true, tells the installer to ignore the default optional dependency group |
* when installing this package |
*/ |
function addPackageDepWithUri($type, $name, $uri, $providesextension = false, |
$nodefault = false) |
{ |
$this->_isValid = 0; |
$arr = array('optional', 'group'); |
if ($type != 'required') { |
array_shift($arr); |
} |
$dep = $this->_constructDep($name, false, $uri, false, false, false, false, |
$providesextension, $nodefault); |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
$type => $arr, |
'package' => array('subpackage', 'extension', 'os', 'arch') |
)); |
} |
/** |
* @param optional|required optional, required |
* @param string package name |
* @param string package channel |
* @param string minimum version |
* @param string maximum version |
* @param string recommended version |
* @param array incompatible versions |
* @param bool if true, tells the installer to ignore the default optional dependency group |
* when installing this package |
*/ |
function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false, |
$recommended = false, $exclude = false, |
$nodefault = false) |
{ |
$this->_isValid = 0; |
$arr = array('optional', 'group'); |
if ($type != 'required') { |
array_shift($arr); |
} |
$dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude, |
$nodefault); |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
$type => $arr, |
'subpackage' => array('extension', 'os', 'arch') |
)); |
} |
/** |
* @param optional|required optional, required |
* @param string package name |
* @param string package uri for download |
* @param bool if true, tells the installer to ignore the default optional dependency group |
* when installing this package |
*/ |
function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false) |
{ |
$this->_isValid = 0; |
$arr = array('optional', 'group'); |
if ($type != 'required') { |
array_shift($arr); |
} |
$dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault); |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
$type => $arr, |
'subpackage' => array('extension', 'os', 'arch') |
)); |
} |
/** |
* @param optional|required optional, required |
* @param string extension name |
* @param string minimum version |
* @param string maximum version |
* @param string recommended version |
* @param array incompatible versions |
*/ |
function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false, |
$exclude = false) |
{ |
$this->_isValid = 0; |
$arr = array('optional', 'group'); |
if ($type != 'required') { |
array_shift($arr); |
} |
$dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
$type => $arr, |
'extension' => array('os', 'arch') |
)); |
} |
/** |
* @param string Operating system name |
* @param boolean true if this package cannot be installed on this OS |
*/ |
function addOsDep($name, $conflicts = false) |
{ |
$this->_isValid = 0; |
$dep = array('name' => $name); |
if ($conflicts) { |
$dep['conflicts'] = ''; |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
'required' => array('optional', 'group'), |
'os' => array('arch') |
)); |
} |
/** |
* @param string Architecture matching pattern |
* @param boolean true if this package cannot be installed on this architecture |
*/ |
function addArchDep($pattern, $conflicts = false) |
{ |
$this->_isValid = 0; |
$dep = array('pattern' => $pattern); |
if ($conflicts) { |
$dep['conflicts'] = ''; |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep, |
array( |
'dependencies' => array('providesextension', 'usesrole', 'usestask', |
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'), |
'required' => array('optional', 'group'), |
'arch' => array() |
)); |
} |
/** |
* Set the kind of package, and erase all release tags |
* |
* - a php package is a PEAR-style package |
* - an extbin package is a PECL-style extension binary |
* - an extsrc package is a PECL-style source for a binary |
* - an zendextbin package is a PECL-style zend extension binary |
* - an zendextsrc package is a PECL-style source for a zend extension binary |
* - a bundle package is a collection of other pre-packaged packages |
* @param php|extbin|extsrc|zendextsrc|zendextbin|bundle |
* @return bool success |
*/ |
function setPackageType($type) |
{ |
$this->_isValid = 0; |
if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc', |
'zendextbin', 'bundle'))) { |
return false; |
} |
if (in_array($type, array('zendextsrc', 'zendextbin'))) { |
$this->_setPackageVersion2_1(); |
} |
if ($type != 'bundle') { |
$type .= 'release'; |
} |
foreach (array('phprelease', 'extbinrelease', 'extsrcrelease', |
'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) { |
unset($this->_packageInfo[$test]); |
} |
if (!isset($this->_packageInfo[$type])) { |
// ensure that the release tag is set up |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'), |
array(), $type); |
} |
$this->_packageInfo[$type] = array(); |
return true; |
} |
/** |
* @return bool true if package type is set up |
*/ |
function addRelease() |
{ |
if ($type = $this->getPackageType()) { |
if ($type != 'bundle') { |
$type .= 'release'; |
} |
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(), |
array($type => array('changelog'))); |
return true; |
} |
return false; |
} |
/** |
* Get the current release tag in order to add to it |
* @param bool returns only releases that have installcondition if true |
* @return array|null |
*/ |
function &_getCurrentRelease($strict = true) |
{ |
if ($p = $this->getPackageType()) { |
if ($strict) { |
if ($p == 'extsrc' || $p == 'zendextsrc') { |
$a = null; |
return $a; |
} |
} |
if ($p != 'bundle') { |
$p .= 'release'; |
} |
if (isset($this->_packageInfo[$p][0])) { |
return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1]; |
} else { |
return $this->_packageInfo[$p]; |
} |
} else { |
$a = null; |
return $a; |
} |
} |
/** |
* Add a file to the current release that should be installed under a different name |
* @param string <contents> path to file |
* @param string name the file should be installed as |
*/ |
function addInstallAs($path, $as) |
{ |
$r = &$this->_getCurrentRelease(); |
if ($r === null) { |
return false; |
} |
$this->_isValid = 0; |
$r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)), |
array( |
'filelist' => array(), |
'install' => array('ignore') |
)); |
} |
/** |
* Add a file to the current release that should be ignored |
* @param string <contents> path to file |
* @return bool success of operation |
*/ |
function addIgnore($path) |
{ |
$r = &$this->_getCurrentRelease(); |
if ($r === null) { |
return false; |
} |
$this->_isValid = 0; |
$r = $this->_mergeTag($r, array('attribs' => array('name' => $path)), |
array( |
'filelist' => array(), |
'ignore' => array() |
)); |
} |
/** |
* Add an extension binary package for this extension source code release |
* |
* Note that the package must be from the same channel as the extension source package |
* @param string |
*/ |
function addBinarypackage($package) |
{ |
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { |
return false; |
} |
$r = &$this->_getCurrentRelease(false); |
if ($r === null) { |
return false; |
} |
$this->_isValid = 0; |
$r = $this->_mergeTag($r, $package, |
array( |
'binarypackage' => array('filelist'), |
)); |
} |
/** |
* Add a configureoption to an extension source package |
* @param string |
* @param string |
* @param string |
*/ |
function addConfigureOption($name, $prompt, $default = null) |
{ |
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { |
return false; |
} |
$r = &$this->_getCurrentRelease(false); |
if ($r === null) { |
return false; |
} |
$opt = array('attribs' => array('name' => $name, 'prompt' => $prompt)); |
if ($default !== null) { |
$opt['default'] = $default; |
} |
$this->_isValid = 0; |
$r = $this->_mergeTag($r, $opt, |
array( |
'configureoption' => array('binarypackage', 'filelist'), |
)); |
} |
/** |
* Set an installation condition based on php version for the current release set |
* @param string minimum version |
* @param string maximum version |
* @param false|array incompatible versions of PHP |
*/ |
function setPhpInstallCondition($min, $max, $exclude = false) |
{ |
$r = &$this->_getCurrentRelease(); |
if ($r === null) { |
return false; |
} |
$this->_isValid = 0; |
if (isset($r['installconditions']['php'])) { |
unset($r['installconditions']['php']); |
} |
$dep = array('min' => $min, 'max' => $max); |
if ($exclude) { |
if (is_array($exclude) && count($exclude) == 1) { |
$exclude = $exclude[0]; |
} |
$dep['exclude'] = $exclude; |
} |
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('configureoption', 'binarypackage', |
'filelist'), |
'php' => array('extension', 'os', 'arch') |
)); |
} else { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('filelist'), |
'php' => array('extension', 'os', 'arch') |
)); |
} |
} |
/** |
* @param optional|required optional, required |
* @param string extension name |
* @param string minimum version |
* @param string maximum version |
* @param string recommended version |
* @param array incompatible versions |
*/ |
function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false, |
$exclude = false) |
{ |
$r = &$this->_getCurrentRelease(); |
if ($r === null) { |
return false; |
} |
$this->_isValid = 0; |
$dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude); |
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('configureoption', 'binarypackage', |
'filelist'), |
'extension' => array('os', 'arch') |
)); |
} else { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('filelist'), |
'extension' => array('os', 'arch') |
)); |
} |
} |
/** |
* Set an installation condition based on operating system for the current release set |
* @param string OS name |
* @param bool whether this OS is incompatible with the current release |
*/ |
function setOsInstallCondition($name, $conflicts = false) |
{ |
$r = &$this->_getCurrentRelease(); |
if ($r === null) { |
return false; |
} |
$this->_isValid = 0; |
if (isset($r['installconditions']['os'])) { |
unset($r['installconditions']['os']); |
} |
$dep = array('name' => $name); |
if ($conflicts) { |
$dep['conflicts'] = ''; |
} |
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('configureoption', 'binarypackage', |
'filelist'), |
'os' => array('arch') |
)); |
} else { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('filelist'), |
'os' => array('arch') |
)); |
} |
} |
/** |
* Set an installation condition based on architecture for the current release set |
* @param string architecture pattern |
* @param bool whether this arch is incompatible with the current release |
*/ |
function setArchInstallCondition($pattern, $conflicts = false) |
{ |
$r = &$this->_getCurrentRelease(); |
if ($r === null) { |
return false; |
} |
$this->_isValid = 0; |
if (isset($r['installconditions']['arch'])) { |
unset($r['installconditions']['arch']); |
} |
$dep = array('pattern' => $pattern); |
if ($conflicts) { |
$dep['conflicts'] = ''; |
} |
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('configureoption', 'binarypackage', |
'filelist'), |
'arch' => array() |
)); |
} else { |
$r = $this->_mergeTag($r, $dep, |
array( |
'installconditions' => array('filelist'), |
'arch' => array() |
)); |
} |
} |
/** |
* For extension binary releases, this is used to specify either the |
* static URI to a source package, or the package name and channel of the extsrc/zendextsrc |
* package it is based on. |
* @param string Package name, or full URI to source package (extsrc/zendextsrc type) |
*/ |
function setSourcePackage($packageOrUri) |
{ |
$this->_isValid = 0; |
if (isset($this->_packageInfo['channel'])) { |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease', |
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'bundle', 'changelog'), |
$packageOrUri, 'srcpackage'); |
} else { |
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease', |
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', |
'bundle', 'changelog'), $packageOrUri, 'srcuri'); |
} |
} |
/** |
* Generate a valid change log entry from the current package.xml |
* @param string|false |
*/ |
function generateChangeLogEntry($notes = false) |
{ |
return array( |
'version' => |
array( |
'release' => $this->getVersion('release'), |
'api' => $this->getVersion('api'), |
), |
'stability' => |
$this->getStability(), |
'date' => $this->getDate(), |
'license' => $this->getLicense(true), |
'notes' => $notes ? $notes : $this->getNotes() |
); |
} |
/** |
* @param string release version to set change log notes for |
* @param array output of {@link generateChangeLogEntry()} |
*/ |
function setChangelogEntry($releaseversion, $contents) |
{ |
if (!isset($this->_packageInfo['changelog'])) { |
$this->_packageInfo['changelog']['release'] = $contents; |
return; |
} |
if (!isset($this->_packageInfo['changelog']['release'][0])) { |
if ($this->_packageInfo['changelog']['release']['version']['release'] == $releaseversion) { |
$this->_packageInfo['changelog']['release'] = array( |
$this->_packageInfo['changelog']['release']); |
} else { |
$this->_packageInfo['changelog']['release'] = array( |
$this->_packageInfo['changelog']['release']); |
return $this->_packageInfo['changelog']['release'][] = $contents; |
} |
} |
foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) { |
if (isset($changelog['version']) && |
strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) { |
$curlog = $index; |
} |
} |
if (isset($curlog)) { |
$this->_packageInfo['changelog']['release'][$curlog] = $contents; |
} else { |
$this->_packageInfo['changelog']['release'][] = $contents; |
} |
} |
/** |
* Remove the changelog entirely |
*/ |
function clearChangeLog() |
{ |
unset($this->_packageInfo['changelog']); |
} |
} |
?> |
/branches/v1.2-democrite/bibliotheque/pear/PEAR/PackageFile/v2/Validator.php |
---|
New file |
0,0 → 1,2058 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PHP Version 5 | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2004 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 3.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available through the world-wide-web at the following url: | |
// | http://www.php.net/license/3_0.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Author: Greg Beaver <cellog@php.net> | |
// | | |
// +----------------------------------------------------------------------+ |
// |
// $Id: Validator.php,v 1.97 2007/02/10 05:56:18 cellog Exp $ |
/** |
* Private validation class used by PEAR_PackageFile_v2 - do not use directly, its |
* sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller |
* @author Greg Beaver <cellog@php.net> |
* @access private |
*/ |
class PEAR_PackageFile_v2_Validator |
{ |
/** |
* @var array |
*/ |
var $_packageInfo; |
/** |
* @var PEAR_PackageFile_v2 |
*/ |
var $_pf; |
/** |
* @var PEAR_ErrorStack |
*/ |
var $_stack; |
/** |
* @var int |
*/ |
var $_isValid = 0; |
/** |
* @var int |
*/ |
var $_filesValid = 0; |
/** |
* @var int |
*/ |
var $_curState = 0; |
/** |
* @param PEAR_PackageFile_v2 |
* @param int |
*/ |
function validate(&$pf, $state = PEAR_VALIDATE_NORMAL) |
{ |
$this->_pf = &$pf; |
$this->_curState = $state; |
$this->_packageInfo = $this->_pf->getArray(); |
$this->_isValid = $this->_pf->_isValid; |
$this->_filesValid = $this->_pf->_filesValid; |
$this->_stack = &$pf->_stack; |
$this->_stack->getErrors(true); |
if (($this->_isValid & $state) == $state) { |
return true; |
} |
if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { |
return false; |
} |
if (!isset($this->_packageInfo['attribs']['version']) || |
($this->_packageInfo['attribs']['version'] != '2.0' && |
$this->_packageInfo['attribs']['version'] != '2.1')) { |
$this->_noPackageVersion(); |
} |
$structure = |
array( |
'name', |
'channel|uri', |
'*extends', // can't be multiple, but this works fine |
'summary', |
'description', |
'+lead', // these all need content checks |
'*developer', |
'*contributor', |
'*helper', |
'date', |
'*time', |
'version', |
'stability', |
'license->?uri->?filesource', |
'notes', |
'contents', //special validation needed |
'*compatible', |
'dependencies', //special validation needed |
'*usesrole', |
'*usestask', // reserve these for 1.4.0a1 to implement |
// this will allow a package.xml to gracefully say it |
// needs a certain package installed in order to implement a role or task |
'*providesextension', |
'*srcpackage|*srcuri', |
'+phprelease|+extsrcrelease|+extbinrelease|' . |
'+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed |
'*changelog', |
); |
$test = $this->_packageInfo; |
if (isset($test['dependencies']) && |
isset($test['dependencies']['required']) && |
isset($test['dependencies']['required']['pearinstaller']) && |
isset($test['dependencies']['required']['pearinstaller']['min']) && |
version_compare('1.5.1', |
$test['dependencies']['required']['pearinstaller']['min'], '<')) { |
$this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); |
return false; |
} |
// ignore post-installation array fields |
if (array_key_exists('filelist', $test)) { |
unset($test['filelist']); |
} |
if (array_key_exists('_lastmodified', $test)) { |
unset($test['_lastmodified']); |
} |
if (array_key_exists('#binarypackage', $test)) { |
unset($test['#binarypackage']); |
} |
if (array_key_exists('old', $test)) { |
unset($test['old']); |
} |
if (array_key_exists('_lastversion', $test)) { |
unset($test['_lastversion']); |
} |
if (!$this->_stupidSchemaValidate($structure, |
$test, '<package>')) { |
return false; |
} |
if (empty($this->_packageInfo['name'])) { |
$this->_tagCannotBeEmpty('name'); |
} |
if (isset($this->_packageInfo['uri'])) { |
$test = 'uri'; |
} else { |
$test = 'channel'; |
} |
if (empty($this->_packageInfo[$test])) { |
$this->_tagCannotBeEmpty($test); |
} |
if (is_array($this->_packageInfo['license']) && |
(!isset($this->_packageInfo['license']['_content']) || |
empty($this->_packageInfo['license']['_content']))) { |
$this->_tagCannotBeEmpty('license'); |
} elseif (empty($this->_packageInfo['license'])) { |
$this->_tagCannotBeEmpty('license'); |
} |
if (empty($this->_packageInfo['summary'])) { |
$this->_tagCannotBeEmpty('summary'); |
} |
if (empty($this->_packageInfo['description'])) { |
$this->_tagCannotBeEmpty('description'); |
} |
if (empty($this->_packageInfo['date'])) { |
$this->_tagCannotBeEmpty('date'); |
} |
if (empty($this->_packageInfo['notes'])) { |
$this->_tagCannotBeEmpty('notes'); |
} |
if (isset($this->_packageInfo['time']) && empty($this->_packageInfo['time'])) { |
$this->_tagCannotBeEmpty('time'); |
} |
if (isset($this->_packageInfo['dependencies'])) { |
$this->_validateDependencies(); |
} |
if (isset($this->_packageInfo['compatible'])) { |
$this->_validateCompatible(); |
} |
if (!isset($this->_packageInfo['bundle'])) { |
if (empty($this->_packageInfo['contents'])) { |
$this->_tagCannotBeEmpty('contents'); |
} |
if (!isset($this->_packageInfo['contents']['dir'])) { |
$this->_filelistMustContainDir('contents'); |
return false; |
} |
if (isset($this->_packageInfo['contents']['file'])) { |
$this->_filelistCannotContainFile('contents'); |
return false; |
} |
} |
$this->_validateMaintainers(); |
$this->_validateStabilityVersion(); |
$fail = false; |
if (array_key_exists('usesrole', $this->_packageInfo)) { |
$roles = $this->_packageInfo['usesrole']; |
if (!is_array($roles) || !isset($roles[0])) { |
$roles = array($roles); |
} |
foreach ($roles as $role) { |
if (!isset($role['role'])) { |
$this->_usesroletaskMustHaveRoleTask('usesrole', 'role'); |
$fail = true; |
} else { |
if (!isset($role['channel'])) { |
if (!isset($role['uri'])) { |
$this->_usesroletaskMustHaveChannelOrUri($role['role'], 'usesrole'); |
$fail = true; |
} |
} elseif (!isset($role['package'])) { |
$this->_usesroletaskMustHavePackage($role['role'], 'usesrole'); |
$fail = true; |
} |
} |
} |
} |
if (array_key_exists('usestask', $this->_packageInfo)) { |
$roles = $this->_packageInfo['usestask']; |
if (!is_array($roles) || !isset($roles[0])) { |
$roles = array($roles); |
} |
foreach ($roles as $role) { |
if (!isset($role['task'])) { |
$this->_usesroletaskMustHaveRoleTask('usestask', 'task'); |
$fail = true; |
} else { |
if (!isset($role['channel'])) { |
if (!isset($role['uri'])) { |
$this->_usesroletaskMustHaveChannelOrUri($role['task'], 'usestask'); |
$fail = true; |
} |
} elseif (!isset($role['package'])) { |
$this->_usesroletaskMustHavePackage($role['task'], 'usestask'); |
$fail = true; |
} |
} |
} |
} |
if ($fail) { |
return false; |
} |
$list = $this->_packageInfo['contents']; |
if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) { |
$this->_multipleToplevelDirNotAllowed(); |
return $this->_isValid = 0; |
} |
$this->_validateFilelist(); |
$this->_validateRelease(); |
if (!$this->_stack->hasErrors()) { |
$chan = $this->_pf->_registry->getChannel($this->_pf->getChannel(), true); |
if (PEAR::isError($chan)) { |
$this->_unknownChannel($this->_pf->getChannel()); |
} else { |
$valpack = $chan->getValidationPackage(); |
// for channel validator packages, always use the default PEAR validator. |
// otherwise, they can't be installed or packaged |
$validator = $chan->getValidationObject($this->_pf->getPackage()); |
if (!$validator) { |
$this->_stack->push(__FUNCTION__, 'error', |
array_merge( |
array('channel' => $chan->getName(), |
'package' => $this->_pf->getPackage()), |
$valpack |
), |
'package "%channel%/%package%" cannot be properly validated without ' . |
'validation package "%channel%/%name%-%version%"'); |
return $this->_isValid = 0; |
} |
$validator->setPackageFile($this->_pf); |
$validator->validate($state); |
$failures = $validator->getFailures(); |
foreach ($failures['errors'] as $error) { |
$this->_stack->push(__FUNCTION__, 'error', $error, |
'Channel validator error: field "%field%" - %reason%'); |
} |
foreach ($failures['warnings'] as $warning) { |
$this->_stack->push(__FUNCTION__, 'warning', $warning, |
'Channel validator warning: field "%field%" - %reason%'); |
} |
} |
} |
$this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error'); |
if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) { |
if ($this->_pf->getPackageType() == 'bundle') { |
if ($this->_analyzeBundledPackages()) { |
$this->_filesValid = $this->_pf->_filesValid = true; |
} else { |
$this->_pf->_isValid = $this->_isValid = 0; |
} |
} else { |
if (!$this->_analyzePhpFiles()) { |
$this->_pf->_isValid = $this->_isValid = 0; |
} else { |
$this->_filesValid = $this->_pf->_filesValid = true; |
} |
} |
} |
if ($this->_isValid) { |
return $this->_pf->_isValid = $this->_isValid = $state; |
} |
return $this->_pf->_isValid = $this->_isValid = 0; |
} |
function _stupidSchemaValidate($structure, $xml, $root) |
{ |
if (!is_array($xml)) { |
$xml = array(); |
} |
$keys = array_keys($xml); |
reset($keys); |
$key = current($keys); |
while ($key == 'attribs' || $key == '_contents') { |
$key = next($keys); |
} |
$unfoundtags = $optionaltags = array(); |
$ret = true; |
$mismatch = false; |
foreach ($structure as $struc) { |
if ($key) { |
$tag = $xml[$key]; |
} |
$test = $this->_processStructure($struc); |
if (isset($test['choices'])) { |
$loose = true; |
foreach ($test['choices'] as $choice) { |
if ($key == $choice['tag']) { |
$key = next($keys); |
while ($key == 'attribs' || $key == '_contents') { |
$key = next($keys); |
} |
$unfoundtags = $optionaltags = array(); |
$mismatch = false; |
if ($key && $key != $choice['tag'] && isset($choice['multiple'])) { |
$unfoundtags[] = $choice['tag']; |
$optionaltags[] = $choice['tag']; |
if ($key) { |
$mismatch = true; |
} |
} |
$ret &= $this->_processAttribs($choice, $tag, $root); |
continue 2; |
} else { |
$unfoundtags[] = $choice['tag']; |
$mismatch = true; |
} |
if (!isset($choice['multiple']) || $choice['multiple'] != '*') { |
$loose = false; |
} else { |
$optionaltags[] = $choice['tag']; |
} |
} |
if (!$loose) { |
$this->_invalidTagOrder($unfoundtags, $key, $root); |
return false; |
} |
} else { |
if ($key != $test['tag']) { |
if (isset($test['multiple']) && $test['multiple'] != '*') { |
$unfoundtags[] = $test['tag']; |
$this->_invalidTagOrder($unfoundtags, $key, $root); |
return false; |
} else { |
if ($key) { |
$mismatch = true; |
} |
$unfoundtags[] = $test['tag']; |
$optionaltags[] = $test['tag']; |
} |
if (!isset($test['multiple'])) { |
$this->_invalidTagOrder($unfoundtags, $key, $root); |
return false; |
} |
continue; |
} else { |
$unfoundtags = $optionaltags = array(); |
$mismatch = false; |
} |
$key = next($keys); |
while ($key == 'attribs' || $key == '_contents') { |
$key = next($keys); |
} |
if ($key && $key != $test['tag'] && isset($test['multiple'])) { |
$unfoundtags[] = $test['tag']; |
$optionaltags[] = $test['tag']; |
$mismatch = true; |
} |
$ret &= $this->_processAttribs($test, $tag, $root); |
continue; |
} |
} |
if (!$mismatch && count($optionaltags)) { |
// don't error out on any optional tags |
$unfoundtags = array_diff($unfoundtags, $optionaltags); |
} |
if (count($unfoundtags)) { |
$this->_invalidTagOrder($unfoundtags, $key, $root); |
} elseif ($key) { |
// unknown tags |
$this->_invalidTagOrder('*no tags allowed here*', $key, $root); |
while ($key = next($keys)) { |
$this->_invalidTagOrder('*no tags allowed here*', $key, $root); |
} |
} |
return $ret; |
} |
function _processAttribs($choice, $tag, $context) |
{ |
if (isset($choice['attribs'])) { |
if (!is_array($tag)) { |
$tag = array($tag); |
} |
$tags = $tag; |
if (!isset($tags[0])) { |
$tags = array($tags); |
} |
$ret = true; |
foreach ($tags as $i => $tag) { |
if (!is_array($tag) || !isset($tag['attribs'])) { |
foreach ($choice['attribs'] as $attrib) { |
if ($attrib{0} != '?') { |
$ret &= $this->_tagHasNoAttribs($choice['tag'], |
$context); |
continue 2; |
} |
} |
} |
foreach ($choice['attribs'] as $attrib) { |
if ($attrib{0} != '?') { |
if (!isset($tag['attribs'][$attrib])) { |
$ret &= $this->_tagMissingAttribute($choice['tag'], |
$attrib, $context); |
} |
} |
} |
} |
return $ret; |
} |
return true; |
} |
function _processStructure($key) |
{ |
$ret = array(); |
if (count($pieces = explode('|', $key)) > 1) { |
$ret['choices'] = array(); |
foreach ($pieces as $piece) { |
$ret['choices'][] = $this->_processStructure($piece); |
} |
return $ret; |
} |
$multi = $key{0}; |
if ($multi == '+' || $multi == '*') { |
$ret['multiple'] = $key{0}; |
$key = substr($key, 1); |
} |
if (count($attrs = explode('->', $key)) > 1) { |
$ret['tag'] = array_shift($attrs); |
$ret['attribs'] = $attrs; |
} else { |
$ret['tag'] = $key; |
} |
return $ret; |
} |
function _validateStabilityVersion() |
{ |
$structure = array('release', 'api'); |
$a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], '<version>'); |
$a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], '<stability>'); |
if ($a) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$this->_packageInfo['version']['release'])) { |
$this->_invalidVersion('release', $this->_packageInfo['version']['release']); |
} |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$this->_packageInfo['version']['api'])) { |
$this->_invalidVersion('api', $this->_packageInfo['version']['api']); |
} |
if (!in_array($this->_packageInfo['stability']['release'], |
array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) { |
$this->_invalidState('release', $this->_packageinfo['stability']['release']); |
} |
if (!in_array($this->_packageInfo['stability']['api'], |
array('devel', 'alpha', 'beta', 'stable'))) { |
$this->_invalidState('api', $this->_packageinfo['stability']['api']); |
} |
} |
} |
function _validateMaintainers() |
{ |
$structure = |
array( |
'name', |
'user', |
'email', |
'active', |
); |
foreach (array('lead', 'developer', 'contributor', 'helper') as $type) { |
if (!isset($this->_packageInfo[$type])) { |
continue; |
} |
if (isset($this->_packageInfo[$type][0])) { |
foreach ($this->_packageInfo[$type] as $lead) { |
$this->_stupidSchemaValidate($structure, $lead, '<' . $type . '>'); |
} |
} else { |
$this->_stupidSchemaValidate($structure, $this->_packageInfo[$type], |
'<' . $type . '>'); |
} |
} |
} |
function _validatePhpDep($dep, $installcondition = false) |
{ |
$structure = array( |
'min', |
'*max', |
'*exclude', |
); |
$type = $installcondition ? '<installcondition><php>' : '<dependencies><required><php>'; |
$this->_stupidSchemaValidate($structure, $dep, $type); |
if (isset($dep['min'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/', |
$dep['min'])) { |
$this->_invalidVersion($type . '<min>', $dep['min']); |
} |
} |
if (isset($dep['max'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/', |
$dep['max'])) { |
$this->_invalidVersion($type . '<max>', $dep['max']); |
} |
} |
if (isset($dep['exclude'])) { |
if (!is_array($dep['exclude'])) { |
$dep['exclude'] = array($dep['exclude']); |
} |
foreach ($dep['exclude'] as $exclude) { |
if (!preg_match( |
'/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/', |
$exclude)) { |
$this->_invalidVersion($type . '<exclude>', $exclude); |
} |
} |
} |
} |
function _validatePearinstallerDep($dep) |
{ |
$structure = array( |
'min', |
'*max', |
'*recommended', |
'*exclude', |
); |
$this->_stupidSchemaValidate($structure, $dep, '<dependencies><required><pearinstaller>'); |
if (isset($dep['min'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['min'])) { |
$this->_invalidVersion('<dependencies><required><pearinstaller><min>', |
$dep['min']); |
} |
} |
if (isset($dep['max'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['max'])) { |
$this->_invalidVersion('<dependencies><required><pearinstaller><max>', |
$dep['max']); |
} |
} |
if (isset($dep['recommended'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['recommended'])) { |
$this->_invalidVersion('<dependencies><required><pearinstaller><recommended>', |
$dep['recommended']); |
} |
} |
if (isset($dep['exclude'])) { |
if (!is_array($dep['exclude'])) { |
$dep['exclude'] = array($dep['exclude']); |
} |
foreach ($dep['exclude'] as $exclude) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$exclude)) { |
$this->_invalidVersion('<dependencies><required><pearinstaller><exclude>', |
$exclude); |
} |
} |
} |
} |
function _validatePackageDep($dep, $group, $type = '<package>') |
{ |
if (isset($dep['uri'])) { |
if (isset($dep['conflicts'])) { |
$structure = array( |
'name', |
'uri', |
'conflicts', |
'*providesextension', |
); |
} else { |
$structure = array( |
'name', |
'uri', |
'*providesextension', |
); |
} |
} else { |
if (isset($dep['conflicts'])) { |
$structure = array( |
'name', |
'channel', |
'*min', |
'*max', |
'*exclude', |
'conflicts', |
'*providesextension', |
); |
} else { |
$structure = array( |
'name', |
'channel', |
'*min', |
'*max', |
'*recommended', |
'*exclude', |
'*nodefault', |
'*providesextension', |
); |
} |
} |
if (isset($dep['name'])) { |
$type .= '<name>' . $dep['name'] . '</name>'; |
} |
$this->_stupidSchemaValidate($structure, $dep, '<dependencies>' . $group . $type); |
if (isset($dep['uri']) && (isset($dep['min']) || isset($dep['max']) || |
isset($dep['recommended']) || isset($dep['exclude']))) { |
$this->_uriDepsCannotHaveVersioning('<dependencies>' . $group . $type); |
} |
if (isset($dep['channel']) && strtolower($dep['channel']) == '__uri') { |
$this->_DepchannelCannotBeUri('<dependencies>' . $group . $type); |
} |
if (isset($dep['min'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['min'])) { |
$this->_invalidVersion('<dependencies>' . $group . $type . '<min>', $dep['min']); |
} |
} |
if (isset($dep['max'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['max'])) { |
$this->_invalidVersion('<dependencies>' . $group . $type . '<max>', $dep['max']); |
} |
} |
if (isset($dep['recommended'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['recommended'])) { |
$this->_invalidVersion('<dependencies>' . $group . $type . '<recommended>', |
$dep['recommended']); |
} |
} |
if (isset($dep['exclude'])) { |
if (!is_array($dep['exclude'])) { |
$dep['exclude'] = array($dep['exclude']); |
} |
foreach ($dep['exclude'] as $exclude) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$exclude)) { |
$this->_invalidVersion('<dependencies>' . $group . $type . '<exclude>', |
$exclude); |
} |
} |
} |
} |
function _validateSubpackageDep($dep, $group) |
{ |
$this->_validatePackageDep($dep, $group, '<subpackage>'); |
if (isset($dep['providesextension'])) { |
$this->_subpackageCannotProvideExtension(isset($dep['name']) ? $dep['name'] : ''); |
} |
if (isset($dep['conflicts'])) { |
$this->_subpackagesCannotConflict(isset($dep['name']) ? $dep['name'] : ''); |
} |
} |
function _validateExtensionDep($dep, $group = false, $installcondition = false) |
{ |
if (isset($dep['conflicts'])) { |
$structure = array( |
'name', |
'*min', |
'*max', |
'*exclude', |
'conflicts', |
); |
} else { |
$structure = array( |
'name', |
'*min', |
'*max', |
'*recommended', |
'*exclude', |
); |
} |
if ($installcondition) { |
$type = '<installcondition><extension>'; |
} else { |
$type = '<dependencies>' . $group . '<extension>'; |
} |
if (isset($dep['name'])) { |
$type .= '<name>' . $dep['name'] . '</name>'; |
} |
$this->_stupidSchemaValidate($structure, $dep, $type); |
if (isset($dep['min'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['min'])) { |
$this->_invalidVersion(substr($type, 1) . '<min', $dep['min']); |
} |
} |
if (isset($dep['max'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['max'])) { |
$this->_invalidVersion(substr($type, 1) . '<max', $dep['max']); |
} |
} |
if (isset($dep['recommended'])) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$dep['recommended'])) { |
$this->_invalidVersion(substr($type, 1) . '<recommended', $dep['recommended']); |
} |
} |
if (isset($dep['exclude'])) { |
if (!is_array($dep['exclude'])) { |
$dep['exclude'] = array($dep['exclude']); |
} |
foreach ($dep['exclude'] as $exclude) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$exclude)) { |
$this->_invalidVersion(substr($type, 1) . '<exclude', $exclude); |
} |
} |
} |
} |
function _validateOsDep($dep, $installcondition = false) |
{ |
$structure = array( |
'name', |
'*conflicts', |
); |
$type = $installcondition ? '<installcondition><os>' : '<dependencies><required><os>'; |
if ($this->_stupidSchemaValidate($structure, $dep, $type)) { |
if ($dep['name'] == '*') { |
if (array_key_exists('conflicts', $dep)) { |
$this->_cannotConflictWithAllOs($type); |
} |
} |
} |
} |
function _validateArchDep($dep, $installcondition = false) |
{ |
$structure = array( |
'pattern', |
'*conflicts', |
); |
$type = $installcondition ? '<installcondition><arch>' : '<dependencies><required><arch>'; |
$this->_stupidSchemaValidate($structure, $dep, $type); |
} |
function _validateInstallConditions($cond, $release) |
{ |
$structure = array( |
'*php', |
'*extension', |
'*os', |
'*arch', |
); |
if (!$this->_stupidSchemaValidate($structure, |
$cond, $release)) { |
return false; |
} |
foreach (array('php', 'extension', 'os', 'arch') as $type) { |
if (isset($cond[$type])) { |
$iter = $cond[$type]; |
if (!is_array($iter) || !isset($iter[0])) { |
$iter = array($iter); |
} |
foreach ($iter as $package) { |
if ($type == 'extension') { |
$this->{"_validate{$type}Dep"}($package, false, true); |
} else { |
$this->{"_validate{$type}Dep"}($package, true); |
} |
} |
} |
} |
} |
function _validateDependencies() |
{ |
$structure = array( |
'required', |
'*optional', |
'*group->name->hint' |
); |
if (!$this->_stupidSchemaValidate($structure, |
$this->_packageInfo['dependencies'], '<dependencies>')) { |
return false; |
} |
foreach (array('required', 'optional') as $simpledep) { |
if (isset($this->_packageInfo['dependencies'][$simpledep])) { |
if ($simpledep == 'optional') { |
$structure = array( |
'*package', |
'*subpackage', |
'*extension', |
); |
} else { |
$structure = array( |
'php', |
'pearinstaller', |
'*package', |
'*subpackage', |
'*extension', |
'*os', |
'*arch', |
); |
} |
if ($this->_stupidSchemaValidate($structure, |
$this->_packageInfo['dependencies'][$simpledep], |
"<dependencies><$simpledep>")) { |
foreach (array('package', 'subpackage', 'extension') as $type) { |
if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { |
$iter = $this->_packageInfo['dependencies'][$simpledep][$type]; |
if (!isset($iter[0])) { |
$iter = array($iter); |
} |
foreach ($iter as $package) { |
if ($type != 'extension') { |
if (isset($package['uri'])) { |
if (isset($package['channel'])) { |
$this->_UrlOrChannel($type, |
$package['name']); |
} |
} else { |
if (!isset($package['channel'])) { |
$this->_NoChannel($type, $package['name']); |
} |
} |
} |
$this->{"_validate{$type}Dep"}($package, "<$simpledep>"); |
} |
} |
} |
if ($simpledep == 'optional') { |
continue; |
} |
foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) { |
if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { |
$iter = $this->_packageInfo['dependencies'][$simpledep][$type]; |
if (!isset($iter[0])) { |
$iter = array($iter); |
} |
foreach ($iter as $package) { |
$this->{"_validate{$type}Dep"}($package); |
} |
} |
} |
} |
} |
} |
if (isset($this->_packageInfo['dependencies']['group'])) { |
$groups = $this->_packageInfo['dependencies']['group']; |
if (!isset($groups[0])) { |
$groups = array($groups); |
} |
$structure = array( |
'*package', |
'*subpackage', |
'*extension', |
); |
foreach ($groups as $group) { |
if ($this->_stupidSchemaValidate($structure, $group, '<group>')) { |
if (!PEAR_Validate::validGroupName($group['attribs']['name'])) { |
$this->_invalidDepGroupName($group['attribs']['name']); |
} |
foreach (array('package', 'subpackage', 'extension') as $type) { |
if (isset($group[$type])) { |
$iter = $group[$type]; |
if (!isset($iter[0])) { |
$iter = array($iter); |
} |
foreach ($iter as $package) { |
if ($type != 'extension') { |
if (isset($package['uri'])) { |
if (isset($package['channel'])) { |
$this->_UrlOrChannelGroup($type, |
$package['name'], |
$group['name']); |
} |
} else { |
if (!isset($package['channel'])) { |
$this->_NoChannelGroup($type, |
$package['name'], |
$group['name']); |
} |
} |
} |
$this->{"_validate{$type}Dep"}($package, '<group name="' . |
$group['attribs']['name'] . '">'); |
} |
} |
} |
} |
} |
} |
} |
function _validateCompatible() |
{ |
$compat = $this->_packageInfo['compatible']; |
if (!isset($compat[0])) { |
$compat = array($compat); |
} |
$required = array('name', 'channel', 'min', 'max', '*exclude'); |
foreach ($compat as $package) { |
$type = '<compatible>'; |
if (is_array($package) && array_key_exists('name', $package)) { |
$type .= '<name>' . $package['name'] . '</name>'; |
} |
$this->_stupidSchemaValidate($required, $package, $type); |
if (is_array($package) && array_key_exists('min', $package)) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$package['min'])) { |
$this->_invalidVersion(substr($type, 1) . '<min', $package['min']); |
} |
} |
if (is_array($package) && array_key_exists('max', $package)) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$package['max'])) { |
$this->_invalidVersion(substr($type, 1) . '<max', $package['max']); |
} |
} |
if (is_array($package) && array_key_exists('exclude', $package)) { |
if (!is_array($package['exclude'])) { |
$package['exclude'] = array($package['exclude']); |
} |
foreach ($package['exclude'] as $exclude) { |
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/', |
$exclude)) { |
$this->_invalidVersion(substr($type, 1) . '<exclude', $exclude); |
} |
} |
} |
} |
} |
function _validateBundle($list) |
{ |
if (!is_array($list) || !isset($list['bundledpackage'])) { |
return $this->_NoBundledPackages(); |
} |
if (!is_array($list['bundledpackage']) || !isset($list['bundledpackage'][0])) { |
return $this->_AtLeast2BundledPackages(); |
} |
foreach ($list['bundledpackage'] as $package) { |
if (!is_string($package)) { |
$this->_bundledPackagesMustBeFilename(); |
} |
} |
} |
function _validateFilelist($list = false, $allowignore = false, $dirs = '') |
{ |
$iscontents = false; |
if (!$list) { |
$iscontents = true; |
$list = $this->_packageInfo['contents']; |
if (isset($this->_packageInfo['bundle'])) { |
return $this->_validateBundle($list); |
} |
} |
if ($allowignore) { |
$struc = array( |
'*install->name->as', |
'*ignore->name' |
); |
} else { |
$struc = array( |
'*dir->name->?baseinstalldir', |
'*file->name->role->?baseinstalldir->?md5sum' |
); |
if (isset($list['dir']) && isset($list['file'])) { |
// stave off validation errors without requiring a set order. |
$_old = $list; |
if (isset($list['attribs'])) { |
$list = array('attribs' => $_old['attribs']); |
} |
$list['dir'] = $_old['dir']; |
$list['file'] = $_old['file']; |
} |
} |
if (!isset($list['attribs']) || !isset($list['attribs']['name'])) { |
$unknown = $allowignore ? '<filelist>' : '<dir name="*unknown*">'; |
$dirname = $iscontents ? '<contents>' : $unknown; |
} else { |
$dirname = '<dir name="' . $list['attribs']['name'] . '">'; |
} |
$res = $this->_stupidSchemaValidate($struc, $list, $dirname); |
if ($allowignore && $res) { |
$ignored_or_installed = array(); |
$this->_pf->getFilelist(); |
$fcontents = $this->_pf->getContents(); |
$filelist = array(); |
if (!isset($fcontents['dir']['file'][0])) { |
$fcontents['dir']['file'] = array($fcontents['dir']['file']); |
} |
foreach ($fcontents['dir']['file'] as $file) { |
$filelist[$file['attribs']['name']] = true; |
} |
if (isset($list['install'])) { |
if (!isset($list['install'][0])) { |
$list['install'] = array($list['install']); |
} |
foreach ($list['install'] as $file) { |
if (!isset($filelist[$file['attribs']['name']])) { |
$this->_notInContents($file['attribs']['name'], 'install'); |
continue; |
} |
if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { |
$this->_multipleInstallAs($file['attribs']['name']); |
} |
if (!isset($ignored_or_installed[$file['attribs']['name']])) { |
$ignored_or_installed[$file['attribs']['name']] = array(); |
} |
$ignored_or_installed[$file['attribs']['name']][] = 1; |
} |
} |
if (isset($list['ignore'])) { |
if (!isset($list['ignore'][0])) { |
$list['ignore'] = array($list['ignore']); |
} |
foreach ($list['ignore'] as $file) { |
if (!isset($filelist[$file['attribs']['name']])) { |
$this->_notInContents($file['attribs']['name'], 'ignore'); |
continue; |
} |
if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { |
$this->_ignoreAndInstallAs($file['attribs']['name']); |
} |
} |
} |
} |
if (!$allowignore && isset($list['file'])) { |
if (!isset($list['file'][0])) { |
// single file |
$list['file'] = array($list['file']); |
} |
foreach ($list['file'] as $i => $file) |
{ |
if (isset($file['attribs']) && isset($file['attribs']['name']) && |
$file['attribs']['name']{0} == '.' && |
$file['attribs']['name']{1} == '/') { |
// name is something like "./doc/whatever.txt" |
$this->_invalidFileName($file['attribs']['name']); |
} |
if (isset($file['attribs']) && isset($file['attribs']['role'])) { |
if (!$this->_validateRole($file['attribs']['role'])) { |
if (isset($this->_packageInfo['usesrole'])) { |
$roles = $this->_packageInfo['usesrole']; |
if (!isset($roles[0])) { |
$roles = array($roles); |
} |
foreach ($roles as $role) { |
if ($role['role'] = $file['attribs']['role']) { |
$msg = 'This package contains role "%role%" and requires ' . |
'package "%package%" to be used'; |
if (isset($role['uri'])) { |
$params = array('role' => $role['role'], |
'package' => $role['uri']); |
} else { |
$params = array('role' => $role['role'], |
'package' => $this->_pf->_registry-> |
parsedPackageNameToString(array('package' => |
$role['package'], 'channel' => $role['channel']), |
true)); |
} |
$this->_stack->push('_mustInstallRole', 'error', $params, $msg); |
} |
} |
} |
$this->_invalidFileRole($file['attribs']['name'], |
$dirname, $file['attribs']['role']); |
} |
} |
if (!isset($file['attribs'])) { |
continue; |
} |
$save = $file['attribs']; |
if ($dirs) { |
$save['name'] = $dirs . '/' . $save['name']; |
} |
unset($file['attribs']); |
if (count($file) && $this->_curState != PEAR_VALIDATE_DOWNLOADING) { // has tasks |
foreach ($file as $task => $value) { |
if ($tagClass = $this->_pf->getTask($task)) { |
if (!is_array($value) || !isset($value[0])) { |
$value = array($value); |
} |
foreach ($value as $v) { |
$ret = call_user_func(array($tagClass, 'validateXml'), |
$this->_pf, $v, $this->_pf->_config, $save); |
if (is_array($ret)) { |
$this->_invalidTask($task, $ret, isset($save['name']) ? |
$save['name'] : ''); |
} |
} |
} else { |
if (isset($this->_packageInfo['usestask'])) { |
$roles = $this->_packageInfo['usestask']; |
if (!isset($roles[0])) { |
$roles = array($roles); |
} |
foreach ($roles as $role) { |
if ($role['task'] = $task) { |
$msg = 'This package contains task "%task%" and requires ' . |
'package "%package%" to be used'; |
if (isset($role['uri'])) { |
$params = array('task' => $role['task'], |
'package' => $role['uri']); |
} else { |
$params = array('task' => $role['task'], |
'package' => $this->_pf->_registry-> |
parsedPackageNameToString(array('package' => |
$role['package'], 'channel' => $role['channel']), |
true)); |
} |
$this->_stack->push('_mustInstallTask', 'error', |
$params, $msg); |
} |
} |
} |
$this->_unknownTask($task, $save['name']); |
} |
} |
} |
} |
} |
if (isset($list['ignore'])) { |
if (!$allowignore) { |
$this->_ignoreNotAllowed('ignore'); |
} |
} |
if (isset($list['install'])) { |
if (!$allowignore) { |
$this->_ignoreNotAllowed('install'); |
} |
} |
if (isset($list['file'])) { |
if ($allowignore) { |
$this->_fileNotAllowed('file'); |
} |
} |
if (isset($list['dir'])) { |
if ($allowignore) { |
$this->_fileNotAllowed('dir'); |
} else { |
if (!isset($list['dir'][0])) { |
$list['dir'] = array($list['dir']); |
} |
foreach ($list['dir'] as $dir) { |
if (isset($dir['attribs']) && isset($dir['attribs']['name'])) { |
if ($dir['attribs']['name'] == '/' || |
!isset($this->_packageInfo['contents']['dir']['dir'])) { |
// always use nothing if the filelist has already been flattened |
$newdirs = ''; |
} elseif ($dirs == '') { |
$newdirs = $dir['attribs']['name']; |
} else { |
$newdirs = $dirs . '/' . $dir['attribs']['name']; |
} |
} else { |
$newdirs = $dirs; |
} |
$this->_validateFilelist($dir, $allowignore, $newdirs); |
} |
} |
} |
} |
function _validateRelease() |
{ |
if (isset($this->_packageInfo['phprelease'])) { |
$release = 'phprelease'; |
if (isset($this->_packageInfo['providesextension'])) { |
$this->_cannotProvideExtension($release); |
} |
if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { |
$this->_cannotHaveSrcpackage($release); |
} |
$releases = $this->_packageInfo['phprelease']; |
if (!is_array($releases)) { |
return true; |
} |
if (!isset($releases[0])) { |
$releases = array($releases); |
} |
foreach ($releases as $rel) { |
$this->_stupidSchemaValidate(array( |
'*installconditions', |
'*filelist', |
), $rel, '<phprelease>'); |
} |
} |
foreach (array('', 'zend') as $prefix) { |
$releasetype = $prefix . 'extsrcrelease'; |
if (isset($this->_packageInfo[$releasetype])) { |
$release = $releasetype; |
if (!isset($this->_packageInfo['providesextension'])) { |
$this->_mustProvideExtension($release); |
} |
if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { |
$this->_cannotHaveSrcpackage($release); |
} |
$releases = $this->_packageInfo[$releasetype]; |
if (!is_array($releases)) { |
return true; |
} |
if (!isset($releases[0])) { |
$releases = array($releases); |
} |
foreach ($releases as $rel) { |
$this->_stupidSchemaValidate(array( |
'*installconditions', |
'*configureoption->name->prompt->?default', |
'*binarypackage', |
'*filelist', |
), $rel, '<' . $releasetype . '>'); |
if (isset($rel['binarypackage'])) { |
if (!is_array($rel['binarypackage']) || !isset($rel['binarypackage'][0])) { |
$rel['binarypackage'] = array($rel['binarypackage']); |
} |
foreach ($rel['binarypackage'] as $bin) { |
if (!is_string($bin)) { |
$this->_binaryPackageMustBePackagename(); |
} |
} |
} |
} |
} |
$releasetype = 'extbinrelease'; |
if (isset($this->_packageInfo[$releasetype])) { |
$release = $releasetype; |
if (!isset($this->_packageInfo['providesextension'])) { |
$this->_mustProvideExtension($release); |
} |
if (isset($this->_packageInfo['channel']) && |
!isset($this->_packageInfo['srcpackage'])) { |
$this->_mustSrcPackage($release); |
} |
if (isset($this->_packageInfo['uri']) && !isset($this->_packageInfo['srcuri'])) { |
$this->_mustSrcuri($release); |
} |
$releases = $this->_packageInfo[$releasetype]; |
if (!is_array($releases)) { |
return true; |
} |
if (!isset($releases[0])) { |
$releases = array($releases); |
} |
foreach ($releases as $rel) { |
$this->_stupidSchemaValidate(array( |
'*installconditions', |
'*filelist', |
), $rel, '<' . $releasetype . '>'); |
} |
} |
} |
if (isset($this->_packageInfo['bundle'])) { |
$release = 'bundle'; |
if (isset($this->_packageInfo['providesextension'])) { |
$this->_cannotProvideExtension($release); |
} |
if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { |
$this->_cannotHaveSrcpackage($release); |
} |
$releases = $this->_packageInfo['bundle']; |
if (!is_array($releases) || !isset($releases[0])) { |
$releases = array($releases); |
} |
foreach ($releases as $rel) { |
$this->_stupidSchemaValidate(array( |
'*installconditions', |
'*filelist', |
), $rel, '<bundle>'); |
} |
} |
foreach ($releases as $rel) { |
if (is_array($rel) && array_key_exists('installconditions', $rel)) { |
$this->_validateInstallConditions($rel['installconditions'], |
"<$release><installconditions>"); |
} |
if (is_array($rel) && array_key_exists('filelist', $rel)) { |
if ($rel['filelist']) { |
$this->_validateFilelist($rel['filelist'], true); |
} |
} |
} |
} |
/** |
* This is here to allow role extension through plugins |
* @param string |
*/ |
function _validateRole($role) |
{ |
return in_array($role, PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())); |
} |
function _pearVersionTooLow($version) |
{ |
$this->_stack->push(__FUNCTION__, 'error', |
array('version' => $version), |
'This package.xml requires PEAR version %version% to parse properly, we are ' . |
'version 1.5.1'); |
} |
function _invalidTagOrder($oktags, $actual, $root) |
{ |
$this->_stack->push(__FUNCTION__, 'error', |
array('oktags' => $oktags, 'actual' => $actual, 'root' => $root), |
'Invalid tag order in %root%, found <%actual%> expected one of "%oktags%"'); |
} |
function _ignoreNotAllowed($type) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type), |
'<%type%> is not allowed inside global <contents>, only inside ' . |
'<phprelease>/<extbinrelease>/<zendextbinrelease>, use <dir> and <file> only'); |
} |
function _fileNotAllowed($type) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type), |
'<%type%> is not allowed inside release <filelist>, only inside ' . |
'<contents>, use <ignore> and <install> only'); |
} |
function _tagMissingAttribute($tag, $attr, $context) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, |
'attribute' => $attr, 'context' => $context), |
'tag <%tag%> in context "%context%" has no attribute "%attribute%"'); |
} |
function _tagHasNoAttribs($tag, $context) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, |
'context' => $context), |
'tag <%tag%> has no attributes in context "%context%"'); |
} |
function _invalidInternalStructure() |
{ |
$this->_stack->push(__FUNCTION__, 'exception', array(), |
'internal array was not generated by compatible parser, or extreme parser error, cannot continue'); |
} |
function _invalidFileRole($file, $dir, $role) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array( |
'file' => $file, 'dir' => $dir, 'role' => $role, |
'roles' => PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())), |
'File "%file%" in directory "%dir%" has invalid role "%role%", should be one of %roles%'); |
} |
function _invalidFileName($file, $dir) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array( |
'file' => $file), |
'File "%file%" cannot begin with "."'); |
} |
function _filelistCannotContainFile($filelist) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), |
'<%tag%> can only contain <dir>, contains <file>. Use ' . |
'<dir name="/"> as the first dir element'); |
} |
function _filelistMustContainDir($filelist) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), |
'<%tag%> must contain <dir>. Use <dir name="/"> as the ' . |
'first dir element'); |
} |
function _tagCannotBeEmpty($tag) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), |
'<%tag%> cannot be empty (<%tag%/>)'); |
} |
function _UrlOrChannel($type, $name) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, |
'name' => $name), |
'Required dependency <%type%> "%name%" can have either url OR ' . |
'channel attributes, and not both'); |
} |
function _NoChannel($type, $name) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, |
'name' => $name), |
'Required dependency <%type%> "%name%" must have either url OR ' . |
'channel attributes'); |
} |
function _UrlOrChannelGroup($type, $name, $group) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, |
'name' => $name, 'group' => $group), |
'Group "%group%" dependency <%type%> "%name%" can have either url OR ' . |
'channel attributes, and not both'); |
} |
function _NoChannelGroup($type, $name, $group) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, |
'name' => $name, 'group' => $group), |
'Group "%group%" dependency <%type%> "%name%" must have either url OR ' . |
'channel attributes'); |
} |
function _unknownChannel($channel) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('channel' => $channel), |
'Unknown channel "%channel%"'); |
} |
function _noPackageVersion() |
{ |
$this->_stack->push(__FUNCTION__, 'error', array(), |
'package.xml <package> tag has no version attribute, or version is not 2.0'); |
} |
function _NoBundledPackages() |
{ |
$this->_stack->push(__FUNCTION__, 'error', array(), |
'No <bundledpackage> tag was found in <contents>, required for bundle packages'); |
} |
function _AtLeast2BundledPackages() |
{ |
$this->_stack->push(__FUNCTION__, 'error', array(), |
'At least 2 packages must be bundled in a bundle package'); |
} |
function _ChannelOrUri($name) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('name' => $name), |
'Bundled package "%name%" can have either a uri or a channel, not both'); |
} |
function _noChildTag($child, $tag) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('child' => $child, 'tag' => $tag), |
'Tag <%tag%> is missing child tag <%child%>'); |
} |
function _invalidVersion($type, $value) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value), |
'Version type <%type%> is not a valid version (%value%)'); |
} |
function _invalidState($type, $value) |
{ |
$states = array('stable', 'beta', 'alpha', 'devel'); |
if ($type != 'api') { |
$states[] = 'snapshot'; |
} |
if (strtolower($value) == 'rc') { |
$this->_stack->push(__FUNCTION__, 'error', |
array('version' => $this->_packageInfo['version']['release']), |
'RC is not a state, it is a version postfix, try %version%RC1, stability beta'); |
} |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value, |
'types' => $states), |
'Stability type <%type%> is not a valid stability (%value%), must be one of ' . |
'%types%'); |
} |
function _invalidTask($task, $ret, $file) |
{ |
switch ($ret[0]) { |
case PEAR_TASK_ERROR_MISSING_ATTRIB : |
$info = array('attrib' => $ret[1], 'task' => $task, 'file' => $file); |
$msg = 'task <%task%> is missing attribute "%attrib%" in file %file%'; |
break; |
case PEAR_TASK_ERROR_NOATTRIBS : |
$info = array('task' => $task, 'file' => $file); |
$msg = 'task <%task%> has no attributes in file %file%'; |
break; |
case PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE : |
$info = array('attrib' => $ret[1], 'values' => $ret[3], |
'was' => $ret[2], 'task' => $task, 'file' => $file); |
$msg = 'task <%task%> attribute "%attrib%" has the wrong value "%was%" '. |
'in file %file%, expecting one of "%values%"'; |
break; |
case PEAR_TASK_ERROR_INVALID : |
$info = array('reason' => $ret[1], 'task' => $task, 'file' => $file); |
$msg = 'task <%task%> in file %file% is invalid because of "%reason%"'; |
break; |
} |
$this->_stack->push(__FUNCTION__, 'error', $info, $msg); |
} |
function _unknownTask($task, $file) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('task' => $task, 'file' => $file), |
'Unknown task "%task%" passed in file <file name="%file%">'); |
} |
function _subpackageCannotProvideExtension($name) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('name' => $name), |
'Subpackage dependency "%name%" cannot use <providesextension>, ' . |
'only package dependencies can use this tag'); |
} |
function _subpackagesCannotConflict($name) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('name' => $name), |
'Subpackage dependency "%name%" cannot use <conflicts/>, ' . |
'only package dependencies can use this tag'); |
} |
function _cannotProvideExtension($release) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release), |
'<%release%> packages cannot use <providesextension>, only extbinrelease, extsrcrelease, zendextsrcrelease, and zendextbinrelease can provide a PHP extension'); |
} |
function _mustProvideExtension($release) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release), |
'<%release%> packages must use <providesextension> to indicate which PHP extension is provided'); |
} |
function _cannotHaveSrcpackage($release) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release), |
'<%release%> packages cannot specify a source code package, only extension binaries may use the <srcpackage> tag'); |
} |
function _mustSrcPackage($release) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release), |
'<extbinrelease>/<zendextbinrelease> packages must specify a source code package with <srcpackage>'); |
} |
function _mustSrcuri($release) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release), |
'<extbinrelease>/<zendextbinrelease> packages must specify a source code package with <srcuri>'); |
} |
function _uriDepsCannotHaveVersioning($type) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type), |
'%type%: dependencies with a <uri> tag cannot have any versioning information'); |
} |
function _conflictingDepsCannotHaveVersioning($type) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type), |
'%type%: conflicting dependencies cannot have versioning info, use <exclude> to ' . |
'exclude specific versions of a dependency'); |
} |
function _DepchannelCannotBeUri($type) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type), |
'%type%: channel cannot be __uri, this is a pseudo-channel reserved for uri ' . |
'dependencies only'); |
} |
function _bundledPackagesMustBeFilename() |
{ |
$this->_stack->push(__FUNCTION__, 'error', array(), |
'<bundledpackage> tags must contain only the filename of a package release ' . |
'in the bundle'); |
} |
function _binaryPackageMustBePackagename() |
{ |
$this->_stack->push(__FUNCTION__, 'error', array(), |
'<binarypackage> tags must contain the name of a package that is ' . |
'a compiled version of this extsrc/zendextsrc package'); |
} |
function _fileNotFound($file) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file), |
'File "%file%" in package.xml does not exist'); |
} |
function _notInContents($file, $tag) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file, 'tag' => $tag), |
'<%tag% name="%file%"> is invalid, file is not in <contents>'); |
} |
function _cannotValidateNoPathSet() |
{ |
$this->_stack->push(__FUNCTION__, 'error', array(), |
'Cannot validate files, no path to package file is set (use setPackageFile())'); |
} |
function _usesroletaskMustHaveChannelOrUri($role, $tag) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), |
'<%tag%> must contain either <uri>, or <channel> and <package>'); |
} |
function _usesroletaskMustHavePackage($role, $tag) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), |
'<%tag%> must contain <package>'); |
} |
function _usesroletaskMustHaveRoleTask($tag, $type) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'type' => $type), |
'<%tag%> must contain <%type%> defining the %type% to be used'); |
} |
function _cannotConflictWithAllOs($type) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), |
'%tag% cannot conflict with all OSes'); |
} |
function _invalidDepGroupName($name) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('group' => $name), |
'Invalid dependency group name "%name%"'); |
} |
function _multipleToplevelDirNotAllowed() |
{ |
$this->_stack->push(__FUNCTION__, 'error', array(), |
'Multiple top-level <dir> tags are not allowed. Enclose them ' . |
'in a <dir name="/">'); |
} |
function _multipleInstallAs($file) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file), |
'Only one <install> tag is allowed for file "%file%"'); |
} |
function _ignoreAndInstallAs($file) |
{ |
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file), |
'Cannot have both <ignore> and <install> tags for file "%file%"'); |
} |
function _analyzeBundledPackages() |
{ |
if (!$this->_isValid) { |
return false; |
} |
if (!$this->_pf->getPackageType() == 'bundle') { |
return false; |
} |
if (!isset($this->_pf->_packageFile)) { |
return false; |
} |
$dir_prefix = dirname($this->_pf->_packageFile); |
$log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : |
array('PEAR_Common', 'log'); |
$info = $this->_pf->getContents(); |
$info = $info['bundledpackage']; |
if (!is_array($info)) { |
$info = array($info); |
} |
$pkg = &new PEAR_PackageFile($this->_pf->_config); |
foreach ($info as $package) { |
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) { |
$this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package); |
$this->_isValid = 0; |
continue; |
} |
call_user_func_array($log, array(1, "Analyzing bundled package $package")); |
PEAR::pushErrorHandling(PEAR_ERROR_RETURN); |
$ret = $pkg->fromAnyFile($dir_prefix . DIRECTORY_SEPARATOR . $package, |
PEAR_VALIDATE_NORMAL); |
PEAR::popErrorHandling(); |
if (PEAR::isError($ret)) { |
call_user_func_array($log, array(0, "ERROR: package $package is not a valid " . |
'package')); |
$inf = $ret->getUserInfo(); |
if (is_array($inf)) { |
foreach ($inf as $err) { |
call_user_func_array($log, array(1, $err['message'])); |
} |
} |
return false; |
} |
} |
return true; |
} |
function _analyzePhpFiles() |
{ |
if (!$this->_isValid) { |
return false; |
} |
if (!isset($this->_pf->_packageFile)) { |
$this->_cannotValidateNoPathSet(); |
return false; |
} |
$dir_prefix = dirname($this->_pf->_packageFile); |
$common = new PEAR_Common; |
$log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : |
array(&$common, 'log'); |
$info = $this->_pf->getContents(); |
if (!$info || !isset($info['dir']['file'])) { |
$this->_tagCannotBeEmpty('contents><dir'); |
return false; |
} |
$info = $info['dir']['file']; |
if (isset($info['attribs'])) { |
$info = array($info); |
} |
$provides = array(); |
foreach ($info as $fa) { |
$fa = $fa['attribs']; |
$file = $fa['name']; |
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { |
$this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $file); |
$this->_isValid = 0; |
continue; |
} |
if (in_array($fa['role'], PEAR_Installer_Role::getPhpRoles()) && $dir_prefix) { |
call_user_func_array($log, array(1, "Analyzing $file")); |
$srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); |
if ($srcinfo) { |
$provides = array_merge($provides, $this->_buildProvidesArray($srcinfo)); |
} |
} |
} |
$this->_packageName = $pn = $this->_pf->getPackage(); |
$pnl = strlen($pn); |
foreach ($provides as $key => $what) { |
if (isset($what['explicit']) || !$what) { |
// skip conformance checks if the provides entry is |
// specified in the package.xml file |
continue; |
} |
extract($what); |
if ($type == 'class') { |
if (!strncasecmp($name, $pn, $pnl)) { |
continue; |
} |
$this->_stack->push(__FUNCTION__, 'warning', |
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), |
'in %file%: %type% "%name%" not prefixed with package name "%package%"'); |
} elseif ($type == 'function') { |
if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { |
continue; |
} |
$this->_stack->push(__FUNCTION__, 'warning', |
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), |
'in %file%: %type% "%name%" not prefixed with package name "%package%"'); |
} |
} |
return $this->_isValid; |
} |
/** |
* Analyze the source code of the given PHP file |
* |
* @param string Filename of the PHP file |
* @param boolean whether to analyze $file as the file contents |
* @return mixed |
*/ |
function analyzeSourceCode($file, $string = false) |
{ |
if (!function_exists("token_get_all")) { |
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file), |
'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer'); |
return false; |
} |
if (!defined('T_DOC_COMMENT')) { |
define('T_DOC_COMMENT', T_COMMENT); |
} |
if (!defined('T_INTERFACE')) { |
define('T_INTERFACE', -1); |
} |
if (!defined('T_IMPLEMENTS')) { |
define('T_IMPLEMENTS', -1); |
} |
if ($string) { |
$contents = $file; |
} else { |
if (!$fp = @fopen($file, "r")) { |
return false; |
} |
fclose($fp); |
$contents = file_get_contents($file); |
} |
$tokens = token_get_all($contents); |
/* |
for ($i = 0; $i < sizeof($tokens); $i++) { |
@list($token, $data) = $tokens[$i]; |
if (is_string($token)) { |
var_dump($token); |
} else { |
print token_name($token) . ' '; |
var_dump(rtrim($data)); |
} |
} |
*/ |
$look_for = 0; |
$paren_level = 0; |
$bracket_level = 0; |
$brace_level = 0; |
$lastphpdoc = ''; |
$current_class = ''; |
$current_interface = ''; |
$current_class_level = -1; |
$current_function = ''; |
$current_function_level = -1; |
$declared_classes = array(); |
$declared_interfaces = array(); |
$declared_functions = array(); |
$declared_methods = array(); |
$used_classes = array(); |
$used_functions = array(); |
$extends = array(); |
$implements = array(); |
$nodeps = array(); |
$inquote = false; |
$interface = false; |
for ($i = 0; $i < sizeof($tokens); $i++) { |
if (is_array($tokens[$i])) { |
list($token, $data) = $tokens[$i]; |
} else { |
$token = $tokens[$i]; |
$data = ''; |
} |
if ($inquote) { |
if ($token != '"' && $token != T_END_HEREDOC) { |
continue; |
} else { |
$inquote = false; |
continue; |
} |
} |
switch ($token) { |
case T_WHITESPACE : |
continue; |
case ';': |
if ($interface) { |
$current_function = ''; |
$current_function_level = -1; |
} |
break; |
case '"': |
case T_START_HEREDOC: |
$inquote = true; |
break; |
case T_CURLY_OPEN: |
case T_DOLLAR_OPEN_CURLY_BRACES: |
case '{': $brace_level++; continue 2; |
case '}': |
$brace_level--; |
if ($current_class_level == $brace_level) { |
$current_class = ''; |
$current_class_level = -1; |
} |
if ($current_function_level == $brace_level) { |
$current_function = ''; |
$current_function_level = -1; |
} |
continue 2; |
case '[': $bracket_level++; continue 2; |
case ']': $bracket_level--; continue 2; |
case '(': $paren_level++; continue 2; |
case ')': $paren_level--; continue 2; |
case T_INTERFACE: |
$interface = true; |
case T_CLASS: |
if (($current_class_level != -1) || ($current_function_level != -1)) { |
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file), |
'Parser error: invalid PHP found in file "%file%"'); |
return false; |
} |
case T_FUNCTION: |
case T_NEW: |
case T_EXTENDS: |
case T_IMPLEMENTS: |
$look_for = $token; |
continue 2; |
case T_STRING: |
if (version_compare(zend_version(), '2.0', '<')) { |
if (in_array(strtolower($data), |
array('public', 'private', 'protected', 'abstract', |
'interface', 'implements', 'throw') |
)) { |
$this->_stack->push(__FUNCTION__, 'warning', array( |
'file' => $file), |
'Error, PHP5 token encountered in %file%,' . |
' analysis should be in PHP5'); |
} |
} |
if ($look_for == T_CLASS) { |
$current_class = $data; |
$current_class_level = $brace_level; |
$declared_classes[] = $current_class; |
} elseif ($look_for == T_INTERFACE) { |
$current_interface = $data; |
$current_class_level = $brace_level; |
$declared_interfaces[] = $current_interface; |
} elseif ($look_for == T_IMPLEMENTS) { |
$implements[$current_class] = $data; |
} elseif ($look_for == T_EXTENDS) { |
$extends[$current_class] = $data; |
} elseif ($look_for == T_FUNCTION) { |
if ($current_class) { |
$current_function = "$current_class::$data"; |
$declared_methods[$current_class][] = $data; |
} elseif ($current_interface) { |
$current_function = "$current_interface::$data"; |
$declared_methods[$current_interface][] = $data; |
} else { |
$current_function = $data; |
$declared_functions[] = $current_function; |
} |
$current_function_level = $brace_level; |
$m = array(); |
} elseif ($look_for == T_NEW) { |
$used_classes[$data] = true; |
} |
$look_for = 0; |
continue 2; |
case T_VARIABLE: |
$look_for = 0; |
continue 2; |
case T_DOC_COMMENT: |
case T_COMMENT: |
if (preg_match('!^/\*\*\s!', $data)) { |
$lastphpdoc = $data; |
if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { |
$nodeps = array_merge($nodeps, $m[1]); |
} |
} |
continue 2; |
case T_DOUBLE_COLON: |
if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { |
$this->_stack->push(__FUNCTION__, 'warning', array('file' => $file), |
'Parser error: invalid PHP found in file "%file%"'); |
return false; |
} |
$class = $tokens[$i - 1][1]; |
if (strtolower($class) != 'parent') { |
$used_classes[$class] = true; |
} |
continue 2; |
} |
} |
return array( |
"source_file" => $file, |
"declared_classes" => $declared_classes, |
"declared_interfaces" => $declared_interfaces, |
"declared_methods" => $declared_methods, |
"declared_functions" => $declared_functions, |
"used_classes" => array_diff(array_keys($used_classes), $nodeps), |
"inheritance" => $extends, |
"implements" => $implements, |
); |
} |
/** |
* Build a "provides" array from data returned by |
* analyzeSourceCode(). The format of the built array is like |
* this: |
* |
* array( |
* 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), |
* ... |
* ) |
* |
* |
* @param array $srcinfo array with information about a source file |
* as returned by the analyzeSourceCode() method. |
* |
* @return void |
* |
* @access private |
* |
*/ |
function _buildProvidesArray($srcinfo) |
{ |
if (!$this->_isValid) { |
return array(); |
} |
$providesret = array(); |
$file = basename($srcinfo['source_file']); |
$pn = $this->_pf->getPackage(); |
$pnl = strlen($pn); |
foreach ($srcinfo['declared_classes'] as $class) { |
$key = "class;$class"; |
if (isset($providesret[$key])) { |
continue; |
} |
$providesret[$key] = |
array('file'=> $file, 'type' => 'class', 'name' => $class); |
if (isset($srcinfo['inheritance'][$class])) { |
$providesret[$key]['extends'] = |
$srcinfo['inheritance'][$class]; |
} |
} |
foreach ($srcinfo['declared_methods'] as $class => $methods) { |
foreach ($methods as $method) { |
$function = "$class::$method"; |
$key = "function;$function"; |
if ($method{0} == '_' || !strcasecmp($method, $class) || |
isset($providesret[$key])) { |
continue; |
} |
$providesret[$key] = |
array('file'=> $file, 'type' => 'function', 'name' => $function); |
} |
} |
foreach ($srcinfo['declared_functions'] as $function) { |
$key = "function;$function"; |
if ($function{0} == '_' || isset($providesret[$key])) { |
continue; |
} |
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { |
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; |
} |
$providesret[$key] = |
array('file'=> $file, 'type' => 'function', 'name' => $function); |
} |
return $providesret; |
} |
} |
?> |