Source for file Validator.php
Documentation is available at Validator.php
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | 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.102 2007/06/10 04:16:51 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>
class PEAR_PackageFile_v2_Validator
* @var PEAR_PackageFile_v2
* @param PEAR_PackageFile_v2
function validate (&$pf, $state = PEAR_VALIDATE_NORMAL )
$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) {
if (!isset ($this->_packageInfo) || !is_array($this->_packageInfo)) {
if (!isset ($this->_packageInfo['attribs']['version']) ||
($this->_packageInfo['attribs']['version'] != '2.0' &&
$this->_packageInfo['attribs']['version'] != '2.1')) {
$this->_noPackageVersion ();
'*extends', // can't be multiple, but this works fine
'+lead', // these all need content checks
'license->?uri->?filesource',
'contents', //special validation needed
'dependencies', //special validation needed
'*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
'+phprelease|+extsrcrelease|+extbinrelease|' .
'+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed
$test = $this->_packageInfo;
if (isset ($test['dependencies']) &&
isset ($test['dependencies']['required']) &&
isset ($test['dependencies']['required']['pearinstaller']) &&
isset ($test['dependencies']['required']['pearinstaller']['min']) &&
$test['dependencies']['required']['pearinstaller']['min'], '<')) {
$this->_pearVersionTooLow ($test['dependencies']['required']['pearinstaller']['min']);
// ignore post-installation array fields
unset ($test['filelist']);
unset ($test['_lastmodified']);
unset ($test['#binarypackage']);
unset ($test['_lastversion']);
if (!$this->_stupidSchemaValidate ($structure,
if (empty ($this->_packageInfo['name'])) {
$this->_tagCannotBeEmpty ('name');
if (isset ($this->_packageInfo['uri'])) {
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');
if (isset ($this->_packageInfo['contents']['file'])) {
$this->_filelistCannotContainFile ('contents');
$this->_validateMaintainers ();
$this->_validateStabilityVersion ();
$roles = $this->_packageInfo['usesrole'];
if (!is_array($roles) || !isset ($roles[0 ])) {
foreach ($roles as $role) {
if (!isset ($role['role'])) {
$this->_usesroletaskMustHaveRoleTask ('usesrole', 'role');
if (!isset ($role['channel'])) {
if (!isset ($role['uri'])) {
$this->_usesroletaskMustHaveChannelOrUri ($role['role'], 'usesrole');
} elseif (!isset ($role['package'])) {
$this->_usesroletaskMustHavePackage ($role['role'], 'usesrole');
$roles = $this->_packageInfo['usestask'];
if (!is_array($roles) || !isset ($roles[0 ])) {
foreach ($roles as $role) {
if (!isset ($role['task'])) {
$this->_usesroletaskMustHaveRoleTask ('usestask', 'task');
if (!isset ($role['channel'])) {
if (!isset ($role['uri'])) {
$this->_usesroletaskMustHaveChannelOrUri ($role['task'], 'usestask');
} elseif (!isset ($role['package'])) {
$this->_usesroletaskMustHavePackage ($role['task'], 'usestask');
$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 );
$this->_unknownChannel ($this->_pf->getChannel ());
$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 ());
$this->_stack->push (__FUNCTION__ , 'error',
array ('channel' => $chan->getName (),
'package' => $this->_pf->getPackage ()),
'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->_pf->getPackageType () == 'bundle') {
if ($this->_analyzeBundledPackages ()) {
$this->_filesValid = $this->_pf->_filesValid = true;
$this->_pf->_isValid = $this->_isValid = 0;
if (!$this->_analyzePhpFiles ()) {
$this->_pf->_isValid = $this->_isValid = 0;
$this->_filesValid = $this->_pf->_filesValid = true;
return $this->_pf->_isValid = $this->_isValid = $state;
return $this->_pf->_isValid = $this->_isValid = 0;
function _stupidSchemaValidate ($structure, $xml, $root)
while ($key == 'attribs' || $key == '_contents') {
$unfoundtags = $optionaltags = array ();
foreach ($structure as $struc) {
$test = $this->_processStructure ($struc);
if (isset ($test['choices'])) {
foreach ($test['choices'] as $choice) {
if ($key == $choice['tag']) {
while ($key == 'attribs' || $key == '_contents') {
$unfoundtags = $optionaltags = array ();
if ($key && $key != $choice['tag'] && isset ($choice['multiple'])) {
$unfoundtags[] = $choice['tag'];
$optionaltags[] = $choice['tag'];
$ret &= $this->_processAttribs ($choice, $tag, $root);
$unfoundtags[] = $choice['tag'];
if (!isset ($choice['multiple']) || $choice['multiple'] != '*') {
$optionaltags[] = $choice['tag'];
$this->_invalidTagOrder ($unfoundtags, $key, $root);
if ($key != $test['tag']) {
if (isset ($test['multiple']) && $test['multiple'] != '*') {
$unfoundtags[] = $test['tag'];
$this->_invalidTagOrder ($unfoundtags, $key, $root);
$unfoundtags[] = $test['tag'];
$optionaltags[] = $test['tag'];
if (!isset ($test['multiple'])) {
$this->_invalidTagOrder ($unfoundtags, $key, $root);
$unfoundtags = $optionaltags = array ();
while ($key == 'attribs' || $key == '_contents') {
if ($key && $key != $test['tag'] && isset ($test['multiple'])) {
$unfoundtags[] = $test['tag'];
$optionaltags[] = $test['tag'];
$ret &= $this->_processAttribs ($test, $tag, $root);
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);
$this->_invalidTagOrder ('*no tags allowed here*', $key, $root);
while ($key = next($keys)) {
$this->_invalidTagOrder ('*no tags allowed here*', $key, $root);
function _processAttribs ($choice, $tag, $context)
if (isset ($choice['attribs'])) {
foreach ($tags as $i => $tag) {
if (!is_array($tag) || !isset ($tag['attribs'])) {
foreach ($choice['attribs'] as $attrib) {
$ret &= $this->_tagHasNoAttribs ($choice['tag'],
foreach ($choice['attribs'] as $attrib) {
if (!isset ($tag['attribs'][$attrib])) {
$ret &= $this->_tagMissingAttribute ($choice['tag'],
function _processStructure ($key)
$ret['choices'] = array ();
foreach ($pieces as $piece) {
$ret['choices'][] = $this->_processStructure ($piece);
if ($multi == '+' || $multi == '*') {
$ret['multiple'] = $key{0 };
$ret['attribs'] = $attrs;
function _validateStabilityVersion ()
$structure = array ('release', 'api');
$a = $this->_stupidSchemaValidate ($structure, $this->_packageInfo['version'], '<version>');
$a &= $this->_stupidSchemaValidate ($structure, $this->_packageInfo['stability'], '<stability>');
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_packageInfo['version']['release'])) {
$this->_invalidVersion ('release', $this->_packageInfo['version']['release']);
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$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 ()
foreach (array ('lead', 'developer', 'contributor', 'helper') as $type) {
if (!isset ($this->_packageInfo[$type])) {
if (isset ($this->_packageInfo[$type][0 ])) {
foreach ($this->_packageInfo[$type] as $lead) {
$this->_stupidSchemaValidate ($structure, $lead, '<' . $type . '>');
$this->_stupidSchemaValidate ($structure, $this->_packageInfo[$type],
function _validatePhpDep ($dep, $installcondition = false )
$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]+)?\\z/',
$this->_invalidVersion ($type . '<min>', $dep['min']);
if (isset ($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
$this->_invalidVersion ($type . '<max>', $dep['max']);
if (isset ($dep['exclude'])) {
$dep['exclude'] = array ($dep['exclude']);
foreach ($dep['exclude'] as $exclude) {
'/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
$this->_invalidVersion ($type . '<exclude>', $exclude);
function _validatePearinstallerDep ($dep)
$this->_stupidSchemaValidate ($structure, $dep, '<dependencies><required><pearinstaller>');
if (isset ($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion ('<dependencies><required><pearinstaller><min>',
if (isset ($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion ('<dependencies><required><pearinstaller><max>',
if (isset ($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion ('<dependencies><required><pearinstaller><recommended>',
if (isset ($dep['exclude'])) {
$dep['exclude'] = array ($dep['exclude']);
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion ('<dependencies><required><pearinstaller><exclude>',
function _validatePackageDep ($dep, $group, $type = '<package>')
if (isset ($dep['uri'])) {
if (isset ($dep['conflicts'])) {
if (isset ($dep['conflicts'])) {
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*)?\\z/',
$this->_invalidVersion ('<dependencies>' . $group . $type . '<min>', $dep['min']);
if (isset ($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion ('<dependencies>' . $group . $type . '<max>', $dep['max']);
if (isset ($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion ('<dependencies>' . $group . $type . '<recommended>',
if (isset ($dep['exclude'])) {
$dep['exclude'] = array ($dep['exclude']);
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion ('<dependencies>' . $group . $type . '<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'])) {
$type = '<installcondition><extension>';
$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*)?\\z/',
$this->_invalidVersion (substr($type, 1 ) . '<min', $dep['min']);
if (isset ($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion (substr($type, 1 ) . '<max', $dep['max']);
if (isset ($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion (substr($type, 1 ) . '<recommended', $dep['recommended']);
if (isset ($dep['exclude'])) {
$dep['exclude'] = array ($dep['exclude']);
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion (substr($type, 1 ) . '<exclude', $exclude);
function _validateOsDep ($dep, $installcondition = false )
$type = $installcondition ? '<installcondition><os>' : '<dependencies><required><os>';
if ($this->_stupidSchemaValidate ($structure, $dep, $type)) {
if ($dep['name'] == '*') {
$this->_cannotConflictWithAllOs ($type);
function _validateArchDep ($dep, $installcondition = false )
$type = $installcondition ? '<installcondition><arch>' : '<dependencies><required><arch>';
$this->_stupidSchemaValidate ($structure, $dep, $type);
function _validateInstallConditions ($cond, $release)
if (!$this->_stupidSchemaValidate ($structure,
foreach (array ('php', 'extension', 'os', 'arch') as $type) {
if (isset ($cond[$type])) {
if (!is_array($iter) || !isset ($iter[0 ])) {
foreach ($iter as $package) {
if ($type == 'extension') {
$this->{" _validate{$type}Dep" }($package, false , true );
$this->{" _validate{$type}Dep" }($package, true );
function _validateDependencies ()
if (!$this->_stupidSchemaValidate ($structure,
$this->_packageInfo ['dependencies'], '<dependencies>')) {
foreach (array ('required', 'optional') as $simpledep) {
if (isset ($this->_packageInfo ['dependencies'][$simpledep])) {
if ($simpledep == 'optional') {
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];
foreach ($iter as $package) {
if ($type != 'extension') {
if (isset ($package['uri'])) {
if (isset ($package['channel'])) {
$this->_UrlOrChannel ($type,
if (!isset ($package['channel'])) {
$this->_NoChannel ($type, $package['name']);
$this->{" _validate{$type}Dep" }($package, " <$simpledep>" );
if ($simpledep == 'optional') {
foreach (array ('php', 'pearinstaller', 'os', 'arch') as $type) {
if (isset ($this->_packageInfo ['dependencies'][$simpledep][$type])) {
$iter = $this->_packageInfo ['dependencies'][$simpledep][$type];
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);
foreach ($groups as $group) {
if ($this->_stupidSchemaValidate ($structure, $group, '<group>')) {
$this->_invalidDepGroupName ($group['attribs']['name']);
foreach (array ('package', 'subpackage', 'extension') as $type) {
if (isset ($group[$type])) {
foreach ($iter as $package) {
if ($type != 'extension') {
if (isset ($package['uri'])) {
if (isset ($package['channel'])) {
$this->_UrlOrChannelGroup ($type,
if (!isset ($package['channel'])) {
$this->_NoChannelGroup ($type,
$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 .= '<name>' . $package['name'] . '</name>';
$this->_stupidSchemaValidate ($required, $package, $type);
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion (substr($type, 1 ) . '<min', $package['min']);
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$this->_invalidVersion (substr($type, 1 ) . '<max', $package['max']);
$package['exclude'] = array ($package['exclude']);
foreach ($package['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$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) {
$this->_bundledPackagesMustBeFilename ();
function _validateFilelist ($list = false , $allowignore = false , $dirs = '')
$list = $this->_packageInfo ['contents'];
if (isset ($this->_packageInfo ['bundle'])) {
return $this->_validateBundle ($list);
'*dir->name->?baseinstalldir',
'*file->name->role->?baseinstalldir->?md5sum'
if (isset ($list['dir']) && isset ($list['file'])) {
// stave off validation errors without requiring a set order.
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;
$dirname = '<dir name="' . $list['attribs']['name'] . '">';
// file contains .. parent directory or . cur directory
$this->_invalidDirName ($list['attribs']['name']);
$res = $this->_stupidSchemaValidate ($struc, $list, $dirname);
if ($allowignore && $res) {
$ignored_or_installed = array ();
$this->_pf ->getFilelist ();
$fcontents = $this->_pf ->getContents ();
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');
$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;
// file contains .. parent directory or . cur directory references
$this->_invalidFileInstallAs ($file['attribs']['name'],
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');
$this->_ignoreAndInstallAs ($file['attribs']['name']);
if (!$allowignore && isset ($list['file'])) {
$this->_oldStyleFileNotAllowed ();
if (!isset ($list['file'][0 ])) {
$list['file'] = array ($list['file']);
foreach ($list['file'] as $i => $file)
if (isset ($file['attribs']) && isset ($file['attribs']['name'])) {
if ($file['attribs']['name']{0 } == '.' &&
$file['attribs']['name']{1 } == '/') {
// name is something like "./doc/whatever.txt"
$this->_invalidFileName ($file['attribs']['name'], $dirname);
// file contains .. parent directory or . cur directory
$this->_invalidFileName ($file['attribs']['name'], $dirname);
if (isset ($file['attribs']) && isset ($file['attribs']['role'])) {
if (!$this->_validateRole ($file['attribs']['role'])) {
if (isset ($this->_packageInfo ['usesrole'])) {
$roles = $this->_packageInfo ['usesrole'];
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']);
$params = array ('role' => $role['role'],
'package' => $this->_pf ->_registry ->
parsedPackageNameToString (array ('package' =>
$role['package'], 'channel' => $role['channel']),
$this->_stack ->push ('_mustInstallRole', 'error', $params, $msg);
$this->_invalidFileRole ($file['attribs']['name'],
$dirname, $file['attribs']['role']);
if (!isset ($file['attribs'])) {
$save = $file['attribs'];
$save['name'] = $dirs . '/' . $save['name'];
foreach ($file as $task => $value) {
if ($tagClass = $this->_pf ->getTask ($task)) {
if (!is_array($value) || !isset ($value[0 ])) {
$this->_pf , $v, $this->_pf ->_config , $save);
$this->_invalidTask ($task, $ret, isset ($save['name']) ?
if (isset ($this->_packageInfo ['usestask'])) {
$roles = $this->_packageInfo ['usestask'];
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']);
$params = array ('task' => $role['task'],
'package' => $this->_pf ->_registry ->
parsedPackageNameToString (array ('package' =>
$role['package'], 'channel' => $role['channel']),
$this->_stack ->push ('_mustInstallTask', 'error',
$this->_unknownTask ($task, $save['name']);
if (isset ($list['ignore'])) {
$this->_ignoreNotAllowed ('ignore');
if (isset ($list['install'])) {
$this->_ignoreNotAllowed ('install');
if (isset ($list['file'])) {
$this->_fileNotAllowed ('file');
if (isset ($list['dir'])) {
$this->_fileNotAllowed ('dir');
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 = $dir['attribs']['name'];
$newdirs = $dirs . '/' . $dir['attribs']['name'];
$this->_validateFilelist ($dir, $allowignore, $newdirs);
function _validateRelease ()
if (isset ($this->_packageInfo ['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 (!isset ($releases[0 ])) {
$releases = array ($releases);
foreach ($releases as $rel) {
$this->_stupidSchemaValidate (array (
), $rel, '<phprelease>');
foreach (array ('', 'zend') as $prefix) {
$releasetype = $prefix . 'extsrcrelease';
if (isset ($this->_packageInfo [$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 (!isset ($releases[0 ])) {
$releases = array ($releases);
foreach ($releases as $rel) {
$this->_stupidSchemaValidate (array (
'*configureoption->name->prompt->?default',
), $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) {
$this->_binaryPackageMustBePackagename ();
$releasetype = 'extbinrelease';
if (isset ($this->_packageInfo [$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 (!isset ($releases[0 ])) {
$releases = array ($releases);
foreach ($releases as $rel) {
$this->_stupidSchemaValidate (array (
), $rel, '<' . $releasetype . '>');
if (isset ($this->_packageInfo ['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 (
foreach ($releases as $rel) {
$this->_validateInstallConditions ($rel['installconditions'],
" <$release><installconditions>" );
$this->_validateFilelist ($rel['filelist'], true );
* This is here to allow role extension through plugins
function _validateRole ($role)
function _pearVersionTooLow ($version)
$this->_stack ->push (__FUNCTION__ , 'error',
array ('version' => $version),
'This package.xml requires PEAR version %version% to parse properly, we are ' .
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 _oldStyleFileNotAllowed ()
$this->_stack ->push (__FUNCTION__ , 'error', array (),
'Old-style <file>name</file> is not allowed. Use' .
'<file name="name" role="role"/>');
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,
'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,
'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%" in directory "%dir%" cannot begin with "./" or contain ".."');
function _invalidFileInstallAs ($file, $as)
$this->_stack ->push (__FUNCTION__ , 'error', array (
'file' => $file, 'as' => $as),
'File "%file%" <install as="%as%"/> cannot contain "./" or contain ".."');
function _invalidDirName ($dir)
$this->_stack ->push (__FUNCTION__ , 'error', array (
'Directory "%dir%" cannot begin with "./" or contain ".."');
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 ' .
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,
'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,
'Required dependency <%type%> "%name%" must have either url OR ' .
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 ' .
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');
$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,
'Stability type <%type%> is not a valid stability (%value%), must be one of ' .
function _invalidTask ($task, $ret, $file)
$info = array ('attrib' => $ret[1 ], 'task' => $task, 'file' => $file);
$msg = 'task <%task%> is missing attribute "%attrib%" in file %file%';
$info = array ('task' => $task, 'file' => $file);
$msg = 'task <%task%> has no attributes in file %file%';
$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%"';
$info = array ('reason' => $ret[1 ], 'task' => $task, 'file' => $file);
$msg = 'task <%task%> in file %file% is invalid because of "%reason%"';
$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 ' .
function _bundledPackagesMustBeFilename ()
$this->_stack ->push (__FUNCTION__ , 'error', array (),
'<bundledpackage> tags must contain only the filename of a package release ' .
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%> for role "%role%" must contain either <uri>, or <channel> and <package>');
function _usesroletaskMustHavePackage ($role, $tag)
$this->_stack ->push (__FUNCTION__ , 'error', array ('role' => $role, 'tag' => $tag),
'<%tag%> for role "%role%" 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 ('name' => $name),
'Invalid dependency group name "%name%"');
function _multipleToplevelDirNotAllowed ()
$this->_stack ->push (__FUNCTION__ , 'error', array (),
'Multiple top-level <dir> tags are not allowed. Enclose them ' .
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->_pf ->getPackageType () == 'bundle') {
if (!isset ($this->_pf ->_packageFile )) {
$dir_prefix = dirname($this->_pf ->_packageFile );
$log = isset ($this->_pf ->_logger ) ? array (&$this->_pf ->_logger , 'log') :
$info = $this->_pf ->getContents ();
$info = $info['bundledpackage'];
foreach ($info as $package) {
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) {
$this->_fileNotFound ($dir_prefix . DIRECTORY_SEPARATOR . $package);
$ret = $pkg->fromAnyFile ($dir_prefix . DIRECTORY_SEPARATOR . $package,
$inf = $ret->getUserInfo ();
function _analyzePhpFiles ()
if (!isset ($this->_pf ->_packageFile )) {
$this->_cannotValidateNoPathSet ();
$dir_prefix = dirname($this->_pf ->_packageFile );
$log = isset ($this->_pf ->_logger ) ? array (&$this->_pf ->_logger , 'log') :
$info = $this->_pf ->getContents ();
if (!$info || !isset ($info['dir']['file'])) {
$this->_tagCannotBeEmpty ('contents><dir');
$info = $info['dir']['file'];
if (isset ($info['attribs'])) {
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
$this->_fileNotFound ($dir_prefix . DIRECTORY_SEPARATOR . $file);
$srcinfo = $this->analyzeSourceCode ($dir_prefix . DIRECTORY_SEPARATOR . $file);
$provides = array_merge($provides, $this->_buildProvidesArray ($srcinfo));
$this->_packageName = $pn = $this->_pf ->getPackage ();
foreach ($provides as $key => $what) {
if (isset ($what['explicit']) || !$what) {
// skip conformance checks if the provides entry is
// specified in the package.xml file
$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') {
$this->_stack ->push (__FUNCTION__ , 'warning',
array ('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn),
'in %file%: %type% "%name%" not prefixed with package name "%package%"');
* 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
function analyzeSourceCode ($file, $string = false )
$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');
define('T_DOC_COMMENT', T_COMMENT );
if (!$fp = @fopen($file, "r")) {
for ($i = 0; $i < sizeof($tokens); $i++) {
@list($token, $data) = $tokens[$i];
print token_name($token) . ' ';
$current_class_level = -1;
$current_function_level = -1;
$declared_classes = array ();
$declared_interfaces = array ();
$declared_functions = array ();
$declared_methods = array ();
$used_functions = array ();
for ($i = 0; $i < sizeof($tokens); $i++ ) {
list ($token, $data) = $tokens[$i];
if ($token != '"' && $token != T_END_HEREDOC ) {
$current_function_level = -1;
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{': $brace_level++; continue 2;
if ($current_class_level == $brace_level) {
$current_class_level = -1;
if ($current_function_level == $brace_level) {
$current_function_level = -1;
case '[': $bracket_level++; continue 2;
case ']': $bracket_level--; continue 2;
case '(': $paren_level++; continue 2;
case ')': $paren_level--; continue 2;
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%"');
array ('public', 'private', 'protected', 'abstract',
'interface', 'implements', 'throw')
$this->_stack ->push (__FUNCTION__ , 'warning', array (
'Error, PHP5 token encountered in %file%,' .
' analysis should be in PHP5');
if ($look_for == T_CLASS ) {
$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 ) {
$current_function = " $current_class::$data";
$declared_methods[$current_class][] = $data;
} elseif ($current_interface) {
$current_function = " $current_interface::$data";
$declared_methods[$current_interface][] = $data;
$current_function = $data;
$declared_functions[] = $current_function;
$current_function_level = $brace_level;
} elseif ($look_for == T_NEW ) {
$used_classes[$data] = true;
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%"');
$class = $tokens[$i - 1 ][1 ];
$used_classes[$class] = true;
"declared_classes" => $declared_classes,
"declared_interfaces" => $declared_interfaces,
"declared_methods" => $declared_methods,
"declared_functions" => $declared_functions,
"inheritance" => $extends,
"implements" => $implements,
* Build a "provides" array from data returned by
* analyzeSourceCode(). The format of the built array is like
* 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
* @param array $srcinfo array with information about a source file
* as returned by the analyzeSourceCode() method.
function _buildProvidesArray ($srcinfo)
$file = basename($srcinfo['source_file']);
$pn = $this->_pf ->getPackage ();
foreach ($srcinfo['declared_classes'] as $class) {
if (isset ($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])) {
array ('file'=> $file, 'type' => 'function', 'name' => $function);
foreach ($srcinfo['declared_functions'] as $function) {
$key = " function;$function";
if ($function{0 } == '_' || isset ($providesret[$key])) {
$warnings[] = "in1 " . $file . " : function \"$function\" not prefixed with package name \"$pn\"";
array ('file'=> $file, 'type' => 'function', 'name' => $function);
Documentation generated on Mon, 11 Mar 2019 15:09:40 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|