static function authorities() { static $authorities = null; if ($authorities) { return $authorities; } $d = \PEAR2\Pyrus\Main::getDataPath() . DIRECTORY_SEPARATOR . 'x509rootcerts'; // for running out of svn if (!file_exists($d)) { $d = realpath(__DIR__ . '/../../../../data/x509rootcerts'); } else { if (strpos($d, 'phar://') === 0) { if (!file_exists($temp = Config::current()->temp_dir . DIRECTORY_SEPARATOR . 'x509rootcerts')) { mkdir($temp, 0755, true); } // openssl can't process these from within a phar (pity) foreach (static::$authorities as $i => $authority) { copy($d . DIRECTORY_SEPARATOR . $authority, $temp . DIRECTORY_SEPARATOR . $authority); $authorities[$i] = $temp . DIRECTORY_SEPARATOR . $authority; } return $authorities; } } $authorities = static::$authorities; foreach ($authorities as $i => $authority) { $authorities[$i] = $d . DIRECTORY_SEPARATOR . $authority; } return $authorities; }
/** * @param string * @param string file name of the channel.xml * * @return \PEAR2\Pyrus\ChannelFile\v1 */ function parse($data, $file = false, $class = 'PEAR2\Pyrus\ChannelFile\v1') { $ret = new $class; if (!$ret instanceof \PEAR2\Pyrus\ChannelFile\v1) { throw new \PEAR2\Pyrus\ChannelFile\Exception('Class ' . $class . ' passed to parse() must be a child class of \PEAR2\Pyrus\ChannelFile\v1'); } $schema = \PEAR2\Pyrus\Main::getDataPath() . '/channel-1.0.xsd'; // for running out of svn if (!file_exists($schema)) { $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/channel-1.0.xsd'; } try { if ($file) { $ret->fromArray(parent::parse($data, $schema)); } else { $ret->fromArray(parent::parseString($data, $schema)); } } catch (\Exception $e) { throw new \PEAR2\Pyrus\ChannelFile\Exception('Invalid channel.xml', null, $e); } return $ret; }
function validate(\PEAR2\Pyrus\PackageInterface $package, array $file) { $parser = new \PEAR2\Pyrus\XMLParser(); $schemapath = \PEAR2\Pyrus\Main::getDataPath(); if (!file_exists(\PEAR2\Pyrus\Main::getDataPath() . '/customcommand-2.0.xsd')) { $schemapath = realpath(__DIR__ . '/../../../../../data'); } $taskschema = $schemapath . '/customcommand-2.0.xsd'; try { $taskinfo = $parser->parse($package->getFilePath($file['attribs']['name']), $taskschema); } catch (\Exception $e) { throw new \PEAR2\Pyrus\Installer\Role\Exception('Invalid custom command definition file,' . ' file does not conform to the schema', $e); } }
protected function getDefaultChannel($channel) { $xml = \PEAR2\Pyrus\Main::getDataPath() . '/default_channels/' . $channel . '.xml'; if (!file_exists($xml)) { $xml = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/default_channels/' . $channel . '.xml'; } $parser = new \PEAR2\Pyrus\ChannelFile\Parser\v1(); $info = $parser->parse($xml, true); return new Channel($this, $info->getArray()); }
/** * @param \PEAR2\Pyrus\PackageFile\v2 * @param int */ function validate(\PEAR2\Pyrus\PackageInterface $pf, $state = \PEAR2\Pyrus\Validate::NORMAL) { $this->errors = new \PEAR2\MultiErrors; if (!$pf->schemaOK) { // this package.xml was created from scratch, not loaded from an existing // package.xml $dom = new \DOMDocument; libxml_use_internal_errors(true); libxml_clear_errors(); $dom->loadXML($pf); $a = $pf->toArray(); if ($a['package']['attribs']['version'] == '2.1') { $schema = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.1.xsd'; // for running out of cvs if (!file_exists($schema)) { $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/package-2.1.xsd'; } } else { $schema = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.0.xsd'; // for running out of cvs if (!file_exists($schema)) { $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/package-2.0.xsd'; } } $dom->schemaValidate($schema); $causes = array(); foreach (libxml_get_errors() as $error) { $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception("Line " . $error->line . ': ' . $error->message); } if (count($this->errors)) { throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml, does' . ' not validate against schema', $this->errors); } } $this->_pf = $pf; $this->_curState = $state; $this->_packageInfo = $this->_pf->toArray(); $this->_packageInfo = $this->_packageInfo['package']; if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { return false; } $myversion = self::VERSION; if ($myversion === '@PACKAGE_VERSION@') { // we're running from CVS, assume we're 2.0.0 $myversion = '2.0.0'; } $test = $this->_packageInfo; if (isset($test['dependencies']) && isset($test['dependencies']['required']) && isset($test['dependencies']['required']['pearinstaller']) && isset($test['dependencies']['required']['pearinstaller']['min']) && version_compare($myversion, $test['dependencies']['required']['pearinstaller']['min'], '<')) { $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception( 'This package.xml requires PEAR version ' . $test['dependencies']['required']['pearinstaller']['min'] . ' to parse properly, we are version ' . $myversion); } $fail = false; foreach ($pf->contents as $file) { // leverage the hidden iterators to do our validation $name = $file->dir . $file->name; if ($name[0] == '.' && $name[1] == '/') { // name is something like "./doc/whatever.txt" $this->errors->E_ERROR[] = new \PEAR2\Pyrus\Package\Exception( 'File "' . $name . '" cannot begin with "."'); continue; } if (!$this->_validateRole($file->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->role) { if (isset($role['uri'])) { $package = $role['uri']; } else { $package = \PEAR2\Pyrus\Config:: parsedPackageNameToString(array('package' => $role['package'], 'channel' => $role['channel']), true); } $msg = 'This package contains role "' . $file->role . '" and requires package "' . $package . '" to be used'; $this->errors->E_WARNING[] = new \PEAR2\Pyrus\PackageFile\Exception($msg); } } } $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception( 'File "' . $name . '" has invalid role "' . $file->role . '", should be one of ' . implode(', ', \PEAR2\Pyrus\Installer\Role::getValidRoles($this->_pf->getPackageType()))); } if (count($file->tasks) && $this->_curState != \PEAR2\Pyrus\Validate::DOWNLOADING) { // has tasks $save = $file->getArrayCopy(); foreach ($file->tasks as $task => $value) { if ($tagClass = \PEAR2\Pyrus\Task\Common::getTask($task)) { if (!is_array($value) || !isset($value[0])) { $value = array($value); } foreach ($value as $v) { try { $ret = $tagClass::validateXml($this->_pf, $v, $save['attribs'], $file->name); } catch (\PEAR2\Pyrus\Task\Exception $e) { $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception('Invalid task $task', $e); } } } 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) { if (isset($role['uri'])) { $package = $role['uri']; } else { $package = \PEAR2\Pyrus\Config:: parsedPackageNameToString(array('package' => $role['package'], 'channel' => $role['channel']), true); } $msg = 'This package contains task "' . str_replace($this->_pf->getTasksNs() . ':', '', $task) . '" and requires package "' . $package . '" to be used'; $this->errors->E_WARNING[] = new \PEAR2\Pyrus\PackageFile\Exception($msg); } } } $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception( 'Unknown task "' . $task . '" passed in file <file name="' . $name . '">'); } } } } $this->_validateRelease(); if (count($this->errors->E_ERROR)) { throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors); } try { $validator = \PEAR2\Pyrus\Config::current() ->channelregistry[$this->_pf->channel] ->getValidationObject($this->_pf->name); } catch (\PEAR2\Pyrus\Config\Exception $e) { throw new \PEAR2\Pyrus\PackageFile\Exception( 'Unable to process channel-specific configuration for channel ' . $this->_pf->getChannel(), $e); } catch (\Exception $e) { $valpack = \PEAR2\Pyrus\Config::current() ->channelregistry[$this->_pf->channel]->getValidationPackage(); $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception( 'Unknown channel ' . $this->_pf->channel); $this->errors->E_ERROR[] = new \PEAR2\Pyrus\PackageFile\Exception( 'package "' . $this->_pf->channel . '/' . $this->_pf->name . '" cannot be properly validated without validation package "' . $this->_pf->channel . '/' . $valpack['name'] . '-' . $valpack['version'] . '"'); } try { $validator->setPackageFile($this->_pf); $validator->setChannel(\PEAR2\Pyrus\Config::current() ->channelregistry[$this->_pf->channel]); $validator->validate($state); // merge in errors from channel-specific validation $this->errors[] = $validator->getFailures(); } catch (\Exception $e) { $this->errors->E_ERROR[] = $e; } if (count($this->errors->E_ERROR)) { throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors); } if ($state == \PEAR2\Pyrus\Validate::PACKAGING) { if ($this->_pf->type == 'bundle') { if (!$this->_analyzeBundledPackages()) { throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors); } } else { if (!$this->_analyzePhpFiles()) { throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml', $this->errors); } } } return $state; }
/** * Scan through the Command directory looking for classes * and see what commands they implement. * @param string which directory to look for classes, defaults to * the Installer/Roles subdirectory of * the directory from where this file (__FILE__) is * included. * * @return bool TRUE on success, a PEAR error on failure * @access public * @static */ static function registerRoles($dir = null) { self::$_roles = array(); $parser = new \PEAR2\Pyrus\XMLParser; if ($dir === null) { $dir = __DIR__ . '/Role'; } if (!file_exists($dir) || !is_dir($dir)) { throw new Role\Exception("registerRoles: opendir($dir) failed"); } $dp = @opendir($dir); if (empty($dp)) { throw new Role\Exception("registerRoles: opendir($dir) failed"); } $schemapath = \PEAR2\Pyrus\Main::getDataPath() . '/customrole-2.0.xsd'; if (!file_exists($schemapath)) { $schemapath = realpath(__DIR__ . '/../../../data/customrole-2.0.xsd'); } while ($entry = readdir($dp)) { if ($entry{0} == '.' || substr($entry, -4) != '.xml') { continue; } $role = strtolower(basename($entry, '.xml')); // List of roles if (!isset(self::$_roles[$role])) { $file = "$dir/$entry"; $data = $parser->parse($file, $schemapath); $data = $data['role']; if (!is_array($data['releasetypes'])) { $data['releasetypes'] = array($data['releasetypes']); } self::$_roles[$role] = $data; } } closedir($dp); $roles = self::$_roles; ksort($roles); self::$_roles = $roles; self::getBaseinstallRoles(true); self::getInstallableRoles(true); self::getValidRoles('****', true); return true; }
function addDeveloperCommands($type) { $schemapath = \PEAR2\Pyrus\Main::getDataPath() . '/customcommand-2.0.xsd'; $defaultcommands = \PEAR2\Pyrus\Main::getDataPath() . '/' . $type . 'commands.xml'; if (!file_exists($schemapath)) { $schemapath = realpath(__DIR__ . '/../../../../data/customcommand-2.0.xsd'); $defaultcommands = realpath(__DIR__ . '/../../../../data/' . $type . 'commands.xml'); } $parser = new \PEAR2\Pyrus\XMLParser(); $commands = $parser->parse($defaultcommands, $schemapath); $commands = $commands['commands']['command']; \PEAR2\Pyrus\PluginRegistry::addCommand($commands); }
/** * Validate the xml against the channel schema. * */ function validate() { if (!isset($this->_xml)) { $this->__toString(); } $a = new \PEAR2\Pyrus\XMLParser(); $schema = \PEAR2\Pyrus\Main::getDataPath() . '/channel-1.0.xsd'; // for running out of svn if (!file_exists($schema)) { $schema = dirname(dirname(dirname(dirname(__DIR__)))) . '/data/channel-1.0.xsd'; } try { $a->parseString($this->_xml, $schema); return true; } catch (\Exception $e) { throw new \PEAR2\Pyrus\Channel\Exception('Invalid channel.xml', $e); } }
/** * Parses a string containing package xml and returns an object * * @param string $data data to parse * @param string|false $file name of the archive this package.xml came from, if any * @param string $class class name to instantiate and return. * This must be PEAR2\Pyrus\PackageFile\v2 or a subclass * @param int $state what state we are currently in * * @return \PEAR2\Pyrus\PackageFile\v2 */ function parse($data, $file = false, $class = 'PEAR2\\Pyrus\\PackageFile\\v2', $state = \PEAR2\Pyrus\Validate::NORMAL) { $this->_inContents = false; $this->_path = ''; $this->_files = array(); $this->_lastDepth = $this->_lastFileDepth = 0; $this->_inFile = 0; $ret = new $class(); if (!$ret instanceof \PEAR2\Pyrus\PackageFile\v2) { throw new \PEAR2\Pyrus\PackageFile\Exception('Class ' . $class . ' passed to parse() must be a child class of \\PEAR2\\Pyrus\\PackageFile\\v2'); } if (preg_match('/<package[^>]+version="2.1"/', $data)) { $schema = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.1.xsd'; // for running out of cvs if (!file_exists($schema)) { $schema = dirname(dirname(dirname(dirname(dirname(__DIR__))))) . '/data/package-2.1.xsd'; } } elseif (preg_match('/<package[^>]+version="2.0"/', $data)) { $schema = \PEAR2\Pyrus\Main::getDataPath() . '/package-2.0.xsd'; // for running out of cvs if (!file_exists($schema)) { $schema = dirname(dirname(dirname(dirname(dirname(__DIR__))))) . '/data/package-2.0.xsd'; } } else { throw new \PEAR2\Pyrus\PackageFile\Exception('Cannot process package.xml version 1.0', -3); } try { $ret->fromArray(parent::parseString($data, $schema)); } catch (\Exception $e) { throw new \PEAR2\Pyrus\PackageFile\Exception('Invalid package.xml', $e); } $ret->setFileList($this->_files); $ret->setBaseInstallDirs($this->_baseinstalldirs); $ret->setPackagefile($file); return $ret; }