/** * Save package REST based on a release * * @param \Pyrus\Package $new */ function saveInfo(\Pyrus\Package $new) { $reader = new \Pyrus\XMLParser(); $deprecated = false; if (file_exists($this->rest . DIRECTORY_SEPARATOR . 'p' . DIRECTORY_SEPARATOR . 'info.xml')) { $oldinfo = $reader->parse($this->rest . DIRECTORY_SEPARATOR . 'p' . DIRECTORY_SEPARATOR . 'info.xml'); if (isset($oldinfo['p']['dp'])) { $deprecated = array('dp' => $oldinfo['p']['dp'], 'dc' => $oldinfo['p']['dc']); } } $xml = array(); $xml['n'] = $new->name; $xml['c'] = $this->channel->name; $categories = new Categories($this->channel); $category = $categories->getPackageCategory($new->name); $xml['ca'] = array('attribs' => array('xlink:href' => $this->getCategoryRESTLink(urlencode($category))), '_content' => $category); $xml['l'] = $new->license['name']; $xml['s'] = $new->summary; $xml['d'] = $new->description; $xml['r'] = array('attribs' => $this->getReleaseRESTLink(strtolower($new->name))); if ($a = $new->extends) { $xml['pa'] = array('attribs' => array('xlink:href' => $this->getPackageRESTLink(strtolower($a) . '/info.xml')), '_content' => $a); } $xmlinf = $this->_getProlog('p', 'package'); $xml['attribs'] = $xmlinf['p']['attribs']; $xml = array('p' => $xml); $this->savePackageREST(strtolower($new->name) . '/info.xml', $xml); }
/** * Save package REST based on a release * * @param \Pyrus\Package $new */ function saveInfo(\Pyrus\Package $new) { $reader = new \Pyrus\XMLParser(); $deprecated = false; if (file_exists($this->rest . DIRECTORY_SEPARATOR . 'p' . DIRECTORY_SEPARATOR . 'info.xml')) { $oldinfo = $reader->parse($this->rest . DIRECTORY_SEPARATOR . 'p' . DIRECTORY_SEPARATOR . 'info.xml'); if (isset($oldinfo['p']['dp'])) { $deprecated = array('dp' => $oldinfo['p']['dp'], 'dc' => $oldinfo['p']['dc']); } } $xml = array(); $xml['n'] = $new->name; $xml['c'] = $this->channel; try { $category = PEAR2_SimpleChannelServer_Categories::getPackageCategory($new->name); } catch (PEAR2_SimpleChannelServer_Categories_Exception $e) { $categories = PEAR2_SimpleChannelServer_Categories::create('Default', 'This is the default category'); $categories->linkPackageToCategory($new->name, 'Default'); $category = PEAR2_SimpleChannelServer_Categories::getPackageCategory($new->name); } $xml['ca'] = array('attribs' => array('xlink:href' => $this->getCategoryRESTLink($category)), '_content' => $category); $xml['l'] = $new->license['name']; $xml['s'] = $new->summary; $xml['d'] = $new->description; $xml['r'] = array('attribs' => $this->getReleaseRESTLink(strtolower($new->name))); if ($a = $new->extends) { $xml['pa'] = array('attribs' => array('xlink:href' => $this->getPackageRESTLink(strtolower($a) . '/info.xml')), '_content' => $a); } $xmlinf = $this->_getProlog('p', 'package'); $xml['attribs'] = $xmlinf['p']['attribs']; $xml = array('p' => $xml); $this->savePackageREST(strtolower($new->name) . '/info.xml', $xml); }
function validate(\Pyrus\PackageInterface $package, array $file) { $parser = new \Pyrus\XMLParser(); $schemapath = \Pyrus\Main::getDataPath(); $taskschema = $schemapath . '/customcommand-2.0.xsd'; try { $taskinfo = $parser->parse($package->getFilePath($file['attribs']['name']), $taskschema); } catch (\Exception $e) { throw new \Pyrus\Installer\Role\Exception('Invalid custom command definition file,' . ' file does not conform to the schema', $e); } }
/** * Grab information on a maintainer * * @param string $handle The user's handle eg: cellog * * @return array */ function getInfo($handle) { $path = $this->getRESTPath('m', strtolower($handle) . '/info.xml'); $reader = new \Pyrus\XMLParser(); if (!file_exists($path)) { return false; } try { $info = $reader->parse($path); return $info['m']; } catch (\Exception $e) { throw new Exception('Cannot read information on ' . 'developer ' . $handle, $e); } }
/** * Save packagesinfo.xml for a category * * @param string $category Category to update packages info for * * @return void */ function savePackagesInfo($category) { $xml = array(); $pdir = $this->rest . DIRECTORY_SEPARATOR . 'p'; $rdir = $this->rest . DIRECTORY_SEPARATOR . 'r'; $packages = $this->_categories->packagesInCategory($category); $reader = new \Pyrus\XMLParser(); clearstatcache(); $xml['pi'] = array(); foreach ($packages as $package) { $next = array(); if (!file_exists($pdir . DIRECTORY_SEPARATOR . strtolower($package) . DIRECTORY_SEPARATOR . 'info.xml')) { continue; } $f = $reader->parse($pdir . DIRECTORY_SEPARATOR . strtolower($package) . DIRECTORY_SEPARATOR . 'info.xml'); unset($f['p']['attribs']); $next['p'] = $f['p']; if (file_exists($rdir . DIRECTORY_SEPARATOR . strtolower($package) . DIRECTORY_SEPARATOR . 'allreleases.xml')) { $r = $reader->parse($rdir . DIRECTORY_SEPARATOR . strtolower($package) . DIRECTORY_SEPARATOR . 'allreleases.xml'); unset($r['a']['attribs']); unset($r['a']['p']); unset($r['a']['c']); $next['a'] = $r['a']; $dirhandle = opendir($rdir . DIRECTORY_SEPARATOR . strtolower($package)); while (false !== ($entry = readdir($dirhandle))) { if (strpos($entry, 'deps.') === 0) { $version = str_replace(array('deps.', '.txt'), array('', ''), $entry); $next['deps'] = array(); $next['deps']['v'] = $version; $next['deps']['d'] = file_get_contents($rdir . DIRECTORY_SEPARATOR . strtolower($package) . DIRECTORY_SEPARATOR . $entry); } } } $xml['pi'][] = $next; } $xmlinf = $this->_getProlog('f', 'categorypackageinfo'); $xmlinf['f'][] = $xml; $this->saveCategoryREST(urlencode($category) . DIRECTORY_SEPARATOR . 'packagesinfo.xml', $xmlinf); }
/** * Validate the xml against the channel schema. * */ function validate() { if (!isset($this->_xml)) { $this->__toString(); } $a = new \Pyrus\XMLParser(); $schema = \Pyrus\Main::getDataPath() . '/channel-1.0.xsd'; try { $a->parseString($this->_xml, $schema); return true; } catch (\Exception $e) { throw new \Pyrus\Channel\Exception('Invalid channel.xml', $e); } }
public function add(\Pyrus\ChannelInterface $channel, $update = false, $lastmodified = false) { if ($this->readonly) { throw new Exception('Cannot add channel, registry is read-only'); } if (!is_writable($this->_channelPath)) { throw new Exception('Cannot add channel ' . $channel->name . ', channel registry path is not writable'); } $this->lazyInit(); $channel->validate(); $exists = $this->exists($channel->name); if ($exists && 1 !== $exists) { if (!$update) { throw new Exception('Cannot add channel ' . $channel->name . ', channel already exists, use update to change'); } $checker = $this->get($channel->name); if ($channel->alias != $checker->alias) { if (file_exists($this->channelAliasFileName($checker->alias))) { @unlink($this->channelAliasFileName($checker->alias)); } } } elseif ($update) { throw new Exception('Error: channel ' . $channel->name . ' is unknown'); } if ($channel->alias != $channel->name) { if (file_exists($this->channelAliasFileName($channel->alias)) && $this->channelFromAlias($channel->alias) != $channel->name) { $channel->alias = $channel->name; } $fp = @fopen($this->channelAliasFileName($channel->alias), 'w'); if (!$fp) { throw new Exception('Cannot add/update channel ' . $channel->name . ', unable to open PEAR1 channel alias file'); } fwrite($fp, $channel->name); fclose($fp); } $fp = @fopen($this->channelFileName($channel->name), 'wb'); if (!$fp) { throw new Exception('Cannot add/update channel ' . $channel->name . ', unable to open PEAR1 channel registry file'); } $info = (string) $channel; $parser = new \Pyrus\XMLParser(); $info = $parser->parseString($info); $info = $info['channel']; if ($lastmodified) { $info['_lastmodified'] = $lastmodified; } else { $info['_lastmodified'] = date('r'); } fwrite($fp, serialize($info)); fclose($fp); return true; }
/** * 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 \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 = \Pyrus\Main::getDataPath() . '/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 = \Pyrus\Main::getDataPath() . '/customcommand-2.0.xsd'; $defaultcommands = \Pyrus\Main::getDataPath() . '/' . $type . 'commands.xml'; $parser = new \Pyrus\XMLParser(); $commands = $parser->parse($defaultcommands, $schemapath); $commands = $commands['commands']['command']; \Pyrus\PluginRegistry::addCommand($commands); }
public function listPackages($channel) { $dir = $this->_namePath($channel, ''); if (!@file_exists($dir)) { return array(); } $ret = array(); try { $parser = new \Pyrus\XMLParser(); foreach (new \DirectoryIterator($dir) as $file) { if ($file->isDot()) { continue; } try { foreach (new \DirectoryIterator($file->getPathName()) as $registries) { if ($registries->isDir()) { continue; } $a = $parser->parse($registries->getPathName()); $ret[] = $a['package']['name']; } } catch (\Exception $e) { \Pyrus\Logger::log(0, 'Warning: corrupted XML registry entry: ' . $file->getPathName() . ': ' . $e); } } } catch (\Exception $e) { throw new Exception('Could not open channel directory for ' . 'channel ' . $channel, $e); } return $ret; }
/** * save REST information for all releases of this package * * @param \Pyrus\Package $new package to save all release info for * @param bool $erase if true, the release represented by the * version of $new will be removed. * * @return void */ function saveAll(\Pyrus\Package $new, $erase = false, $is2 = false) { if ($is2) { $is2 = '2'; } else { $is2 = ''; } $reader = new \Pyrus\XMLParser(); $path = $this->getRESTPath('r', strtolower($new->name) . DIRECTORY_SEPARATOR . 'allreleases' . $is2 . '.xml'); if (file_exists($path)) { // Use the existing file, and add to it $xml = $reader->parse($path); if (isset($xml['a']['r']) && !isset($xml['a']['r'][0])) { $xml['a']['r'] = array($xml['a']['r']); } } else { // Start up a new allreleases file $xml = $this->_getProlog('a', 'allreleases' . $is2); $xml['a']['p'] = $new->name; $xml['a']['c'] = $this->chan; $xml['a']['r'] = array(); } if ($erase) { foreach ($xml['a']['r'] as $i => $release) { if ($release['v'] === $new->version['release']) { unset($xml['a']['r'][$i]); $xml['a']['r'] = array_values($xml['a']['r']); break; } } if (!count($xml['a']['r'])) { // no releases, erase all traces foreach (new DirectoryIterator($this->getRESTPath('r', strtolower($new->name))) as $name => $info) { if ($info->isDot()) { continue; } unlink($name); } } } else { $info = array('v' => $new->version['release'], 's' => $new->stability['release']); if ($is2) { $info['m'] = $new->dependencies['required']->php->min; } if (count($new->compatible)) { $info['co'] = array(); foreach ($new->compatible as $package => $cinfo) { if (strpos($package, '/')) { $c = substr($package, 0, strpos($package, '/')); $package = str_replace(array($c, '/'), '', $package); } else { $c = 'pear.php.net'; } unset($cinfo['channel']); unset($cinfo['package']); if (isset($cinfo['exclude'])) { $info['x'] = $cinfo['exclude']; unset($cinfo['exclude']); } $info['co'][] = array_merge(array('c' => $c, 'p' => $package), $cinfo); } } $test = $xml['a']['r']; if (count($test) && !isset($test[0])) { // Info exists, and there's only one release if ($test['v'] != $info['v']) { $test = array($info, $test); } } else { // There are multiple releases already in the file // Loop through them to see if this release is already present $found = false; foreach ($test as $i => $rel) { if ($rel['v'] == $info['v']) { $found = true; $test[$i] = $info; break; } } if (!$found) { array_unshift($test, $info); } } // Ok, now we have the latest release info ready if (count($test) == 1) { $test = $test[0]; } else { // Now sort the releases so we don't confuse stupid versions of PEAR & Pyrus usort($test, function ($r1, $r2) { return version_compare($r1['v'], $r2['v'], '<'); }); } $xml['a']['r'] = $test; } $this->saveReleaseREST(strtolower($new->name) . '/allreleases' . $is2 . '.xml', $xml); return $xml; }
/** * List all maintainers, or maintainers of a specific package * * @param string|null $package null to list all maintainers * * @return array */ function listMaintainers($package = null) { if ($package === null) { if (!file_exists($this->rest->getRESTPath('p', 'allpackages.xml'))) { return array(); } try { $list = $reader->parse($this->rest->getRESTPath('m', 'allmaintainers.xml')); $maint = new PEAR2_SimpleChannelServer_REST_Maintainer($this->webpath, $this->channel, $this->uri); $ret = array(); foreach ($list['m']['h'] as $info) { $inf = $maint->getInfo($info['_content']); if (!$inf) { throw new PEAR2_SimpleChannelServer_Exception('Maintainer ' . $info['_content'] . ' is listed as a maintainer, ' . 'but does not have an info file'); } $ret[] = array('user' => $info['_content'], 'name' => $inf['n']); } return $ret; } catch (Exception $e) { throw new PEAR2_SimpleChannelServer_Exception('Unable to list maintainers', $e); } } $reader = new \Pyrus\XMLParser(); $path = $this->rest->getRESTPath('r', strtolower($package) . '/maintainers2.xml'); if (!file_exists($path)) { return array(); } try { $list = $reader->parse($path); } catch (Exception $e) { throw new PEAR2_SimpleChannelServer_Exception('Unable to list maintainers for' . ' package ' . $package, $e); } $ret = array(); if (!isset($list['m']['m'][0])) { $list['m']['m'] = array($list['m']['m']); } $maint = new PEAR2_SimpleChannelServer_REST_Maintainer($this->webpath, $this->channel, $this->uri); foreach ($list['m']['m'] as $maintainer) { $info = $maint->getInfo($maintainer['h']); $inf = array('user' => $maintainer['h']); if ($info) { $inf['name'] = $info['n']; } $inf['active'] = $maintainer['a']; $ret[] = $inf; } return $ret; }
/** * get the packages in a category * * @param string $category name of category * * @return array */ public function packagesInCategory($category) { $packages = array(); $file = $this->_restDir . 'c/' . urlencode($category) . '/packages.xml'; if (file_exists($file)) { $parser = new \Pyrus\XMLParser(); try { $content = file_get_contents($file); $content = $parser->parseString($content); if (isset($content['l']['p']['_content'])) { $packages[] = $content['l']['p']['_content']; } else { foreach ($content['l']['p'] as $package) { $packages[] = $package['_content']; } } } catch (\Exception $e) { // unable to parse, assume empty. } } foreach ($this->_packages as $p => $c) { if ($c === $category && !in_array($p, $packages)) { $packages[] = $p; } } return $packages; }
/** * save REST information for all releases of this package * * @param \Pyrus\Package $new package to save all release info for * @param bool $erase if true, the release represented by the * version of $new will be removed. * * @return void */ function saveAll(\Pyrus\Package $new, $erase = false, $is2 = false) { if ($is2) { $is2 = '2'; } else { $is2 = ''; } $reader = new \Pyrus\XMLParser(); $path = $this->getRESTPath('r', strtolower($new->name) . DIRECTORY_SEPARATOR . 'allreleases' . $is2 . '.xml'); if (file_exists($path)) { $xml = $reader->parse($path); if (isset($xml['a']['r']) && !isset($xml['a']['r'][0])) { $xml['a']['r'] = array($xml['a']['r']); } } else { $xml = $this->_getProlog('a', 'allreleases' . $is2); $xml['a']['p'] = $new->name; $xml['a']['c'] = $this->chan; $xml['a']['r'] = array(); } if ($erase) { foreach ($xml['a']['r'] as $i => $release) { if ($release['v'] === $new->version['release']) { unset($xml['a']['r'][$i]); $xml['a']['r'] = array_values($xml['a']['r']); break; } } if (!count($xml['a']['r'])) { // no releases, erase all traces foreach (new DirectoryIterator($this->getRESTPath('r', strtolower($new->name))) as $name => $info) { if ($info->isDot()) { continue; } unlink($name); } } } else { $info = array('v' => $new->version['release'], 's' => $new->stability['release']); if ($is2) { $info['m'] = $new->dependencies['required']->php->min; } if (count($new->compatible)) { $info['co'] = array(); foreach ($new->compatible as $package => $cinfo) { if (strpos($package, '/')) { $c = substr($package, 0, strpos($package, '/')); $package = str_replace(array($c, '/'), '', $package); } else { $c = 'pear.php.net'; } unset($cinfo['channel']); unset($cinfo['package']); if (isset($cinfo['exclude'])) { $info['x'] = $cinfo['exclude']; unset($cinfo['exclude']); } $info['co'][] = array_merge(array('c' => $c, 'p' => $package), $cinfo); } } $test = $xml['a']['r']; if (count($test) && !isset($test[0])) { if ($test['v'] != $info['v']) { $test = array($info, $test); } } else { $found = false; foreach ($test as $i => $rel) { if ($rel['v'] == $info['v']) { $found = true; $test[$i] = $info; break; } } if (!$found) { array_unshift($test, $info); } } if (count($test) == 1) { $test = $test[0]; } $xml['a']['r'] = $test; } $this->saveReleaseREST(strtolower($new->name) . '/allreleases' . $is2 . '.xml', $xml); return $xml; }