/** * 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 = isset($this->_pf) ? $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; }
/** * 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 if (function_exists('file_get_contents')) { $contents = file_get_contents($file); } else { $fp = fopen($file, "r"); $contents = @fread($fp, filesize($file)); fclose($fp); } 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; } }
/** * @access protected */ function validateVersion() { if ($this->_state != PEAR_VALIDATE_PACKAGING) { if (!$this->validVersion($this->_packagexml->getVersion())) { $this->_addFailure('version', 'Invalid version number "' . $this->_packagexml->getVersion() . '"'); } return false; } $version = $this->_packagexml->getVersion(); $versioncomponents = explode('.', $version); if (count($versioncomponents) != 3) { $this->_addWarning('version', 'A version number should have 3 decimals (x.y.z)'); return true; } $name = $this->_packagexml->getPackage(); // version must be based upon state switch ($this->_packagexml->getState()) { case 'snapshot': return true; case 'devel': if ($versioncomponents[0] . 'a' == '0a') { return true; } if ($versioncomponents[0] == 0) { $versioncomponents[0] = '0'; $this->_addWarning('version', 'version "' . $version . '" should be "' . implode('.', $versioncomponents) . '"'); } else { $this->_addWarning('version', 'packages with devel stability must be < version 1.0.0'); } return true; break; case 'alpha': case 'beta': // check for a package that extends a package, // like Foo and Foo2 if ($this->_state == PEAR_VALIDATE_PACKAGING) { if (substr($versioncomponents[2], 1, 2) == 'rc') { $this->_addFailure('version', 'Release Candidate versions ' . 'must have capital RC, not lower-case rc'); return false; } } if (!$this->_packagexml->getExtends()) { if ($versioncomponents[0] == '1') { if ($versioncomponents[2][0] == '0') { if ($versioncomponents[2] == '0') { // version 1.*.0000 $this->_addWarning('version', 'version 1.' . $versioncomponents[1] . '.0 probably should not be alpha or beta'); return true; } elseif (strlen($versioncomponents[2]) > 1) { // version 1.*.0RC1 or 1.*.0beta24 etc. return true; } else { // version 1.*.0 $this->_addWarning('version', 'version 1.' . $versioncomponents[1] . '.0 probably should not be alpha or beta'); return true; } } else { $this->_addWarning('version', 'bugfix versions (1.3.x where x > 0) probably should ' . 'not be alpha or beta'); return true; } } elseif ($versioncomponents[0] != '0') { $this->_addWarning('version', 'major versions greater than 1 are not allowed for packages ' . 'without an <extends> tag or an identical postfix (foo2 v2.0.0)'); return true; } if ($versioncomponents[0] . 'a' == '0a') { return true; } if ($versioncomponents[0] == 0) { $versioncomponents[0] = '0'; $this->_addWarning('version', 'version "' . $version . '" should be "' . implode('.', $versioncomponents) . '"'); } } else { $vlen = strlen($versioncomponents[0] . ''); $majver = substr($name, strlen($name) - $vlen); while ($majver && !is_numeric($majver[0])) { $majver = substr($majver, 1); } if ($versioncomponents[0] != 0 && $majver != $versioncomponents[0]) { $this->_addWarning('version', 'first version number "' . $versioncomponents[0] . '" must match the postfix of ' . 'package name "' . $name . '" (' . $majver . ')'); return true; } if ($versioncomponents[0] == $majver) { if ($versioncomponents[2][0] == '0') { if ($versioncomponents[2] == '0') { // version 2.*.0000 $this->_addWarning('version', "version {$majver}." . $versioncomponents[1] . '.0 probably should not be alpha or beta'); return false; } elseif (strlen($versioncomponents[2]) > 1) { // version 2.*.0RC1 or 2.*.0beta24 etc. return true; } else { // version 2.*.0 $this->_addWarning('version', "version {$majver}." . $versioncomponents[1] . '.0 cannot be alpha or beta'); return true; } } else { $this->_addWarning('version', "bugfix versions ({$majver}.x.y where y > 0) should " . 'not be alpha or beta'); return true; } } elseif ($versioncomponents[0] != '0') { $this->_addWarning('version', "only versions 0.x.y and {$majver}.x.y are allowed for alpha/beta releases"); return true; } if ($versioncomponents[0] . 'a' == '0a') { return true; } if ($versioncomponents[0] == 0) { $versioncomponents[0] = '0'; $this->_addWarning('version', 'version "' . $version . '" should be "' . implode('.', $versioncomponents) . '"'); } } return true; break; case 'stable': if ($versioncomponents[0] == '0') { $this->_addWarning('version', 'versions less than 1.0.0 cannot ' . 'be stable'); return true; } if (!is_numeric($versioncomponents[2])) { if (preg_match('/\\d+(rc|a|alpha|b|beta)\\d*/i', $versioncomponents[2])) { $this->_addWarning('version', 'version "' . $version . '" or any ' . 'RC/beta/alpha version cannot be stable'); return true; } } // check for a package that extends a package, // like Foo and Foo2 if ($this->_packagexml->getExtends()) { $vlen = strlen($versioncomponents[0] . ''); $majver = substr($name, strlen($name) - $vlen); while ($majver && !is_numeric($majver[0])) { $majver = substr($majver, 1); } if ($versioncomponents[0] != 0 && $majver != $versioncomponents[0]) { $this->_addWarning('version', 'first version number "' . $versioncomponents[0] . '" must match the postfix of ' . 'package name "' . $name . '" (' . $majver . ')'); return true; } } elseif ($versioncomponents[0] > 1) { $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' . '1 for any package that does not have an <extends> tag'); } return true; break; default: return false; break; } }
/** * @param array $xml contents of postinstallscript tag * example: Array ( [paramgroup] => Array ( [id] => webSetup [param] => Array ( [name] => webdirpath [prompt] => Where should... ? [default] => '/var/www/htdocs/webpear [type] => string ) ) ) * @param object $script post-installation script * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 $pkg * @param string $contents contents of the install script */ function runInstallScript($xml, &$script, &$pkg) { if (!isset($_SESSION['_PEAR_Frontend_Web_ScriptCompletedPhases'])) { $_SESSION['_PEAR_Frontend_Web_ScriptCompletedPhases'] = array(); $_SESSION['_PEAR_Frontend_Web_ScriptSkipSections'] = array(); } if (isset($_SESSION['_PEAR_Frontend_Web_ScriptObj'])) { foreach ($_SESSION['_PEAR_Frontend_Web_ScriptObj'] as $name => $val) { if ($name[0] == '_') { // only public variables will be restored continue; } $script->{$name} = $val; } } else { $_SESSION['_PEAR_Frontend_Web_ScriptObj'] = (array) $script; } if (!is_array($xml) || !isset($xml['paramgroup'])) { $script->run(array(), '_default'); } else { if (!isset($xml['paramgroup'][0])) { $xml['paramgroup'] = array($xml['paramgroup']); } foreach ($xml['paramgroup'] as $i => $group) { if (isset($_SESSION['_PEAR_Frontend_Web_ScriptSkipSections'][$group['id']])) { continue; } if (isset($_SESSION['_PEAR_Frontend_Web_ScriptSection'])) { if ($i < $_SESSION['_PEAR_Frontend_Web_ScriptSection']) { $lastgroup = $group; continue; } } if (isset($_SESSION['_PEAR_Frontend_Web_answers'])) { $answers = $_SESSION['_PEAR_Frontend_Web_answers']; } if (isset($group['name'])) { if (isset($answers)) { if (isset($answers[$group['name']])) { switch ($group['conditiontype']) { case '=': if ($answers[$group['name']] != $group['value']) { continue 2; } break; case '!=': if ($answers[$group['name']] == $group['value']) { continue 2; } break; case 'preg_match': if (!@preg_match('/' . $group['value'] . '/', $answers[$group['name']])) { continue 2; } break; default: $this->_clearScriptSession(); return; } } } else { $this->_clearScriptSession(); return; } } if (!isset($group['param'][0])) { $group['param'] = array($group['param']); } $_SESSION['_PEAR_Frontend_Web_ScriptSection'] = $i; if (!isset($answers)) { $answers = array(); } if (isset($group['param'])) { if (method_exists($script, 'postProcessPrompts')) { $prompts = $script->postProcessPrompts($group['param'], $group['name']); if (!is_array($prompts) || count($prompts) != count($group['param'])) { $this->outputData('postinstall', 'Error: post-install script did not ' . 'return proper post-processed prompts'); $prompts = $group['param']; } else { foreach ($prompts as $i => $var) { if (!is_array($var) || !isset($var['prompt']) || !isset($var['name']) || $var['name'] != $group['param'][$i]['name'] || $var['type'] != $group['param'][$i]['type']) { $this->outputData('postinstall', 'Error: post-install script ' . 'modified the variables or prompts, severe security risk. ' . 'Will instead use the defaults from the package.xml'); $prompts = $group['param']; } } } $answers = array_merge($answers, $this->confirmDialog($prompts, $pkg->getChannel() . '/' . $pkg->getPackage())); } else { $answers = array_merge($answers, $this->confirmDialog($group['param'], $pkg->getChannel() . '/' . $pkg->getPackage())); } } if ($answers) { array_unshift($_SESSION['_PEAR_Frontend_Web_ScriptCompletedPhases'], $group['id']); if (!$script->run($answers, $group['id'])) { $script->run($_SESSION['_PEAR_Frontend_Web_ScriptCompletedPhases'], '_undoOnError'); $this->_clearScriptSession(); return; } } else { $script->run(array(), '_undoOnError'); $this->_clearScriptSession(); return; } $lastgroup = $group; foreach ($group['param'] as $param) { // rename the current params to save for future tests $answers[$group['id'] . '::' . $param['name']] = $answers[$param['name']]; unset($answers[$param['name']]); } // save the script's variables and user answers for the next round $_SESSION['_PEAR_Frontend_Web_ScriptObj'] = (array) $script; $_SESSION['_PEAR_Frontend_Web_answers'] = $answers; $_SERVER['REQUEST_METHOD'] = ''; } } $this->_clearScriptSession(); }