* @param mixed $data the value to test
* @param int $code if $data is an error object, return true
* only if $code is a string and
- * $obj->getMessage() == $code or
+ * $obj->getMessage() == $code or
* $code is an integer and $obj->getCode() == $code
* @access public
* @return bool true if parameter is an error
* @see PEAR::setErrorHandling
* @since PHP 4.0.5
*/
- function &raiseError($message = null,
+ function raiseError($message = null,
$code = null,
$mode = null,
$options = null,
function loadExtension($ext)
{
if (!extension_loaded($ext)) {
+ // if either returns true dl() will produce a FATAL error, stop that
+ if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
+ return false;
+ }
if (OS_WINDOWS) {
$suffix = '.dll';
} elseif (PHP_OS == 'HP-UX') {
} else {
$pstr = '';
}
+ $i = 0;
foreach ($info[$key] as $p) {
if ($debug < 2 && $p['type'] != "class") {
continue;
*
* @access public.
*/
- function writeConfigFile($file = null, $layer = 'user')
+ function writeConfigFile($file = null, $layer = 'user', $data = null)
{
if ($layer == 'both' || $layer == 'all') {
foreach ($this->files as $type => $file) {
- $err = $this->writeConfigFile($file, $type);
+ $err = $this->writeConfigFile($file, $type, $data);
if (PEAR::isError($err)) {
return $err;
}
if ($file === null) {
$file = $this->files[$layer];
}
- $data = $this->configuration[$layer];
+ $data = ($data === null) ? $this->configuration[$layer] : $data;
$this->_encodeOutput($data);
if (!@System::mkDir("-p " . dirname($file))) {
return $this->raiseError("could not create directory: " . dirname($file));
return $data;
}
+ // }}}
+ // {{{ getConfFile(layer)
+ /**
+ * Gets the file used for storing the config for a layer
+ *
+ * @param string $layer 'user' or 'system'
+ */
+
+ function getConfFile($layer)
+ {
+ return $this->files[$layer];
+ }
+
// }}}
// {{{ _encodeOutput(&data)
function removeLayer($layer)
{
if (isset($this->configuration[$layer])) {
- unset($this->configuration[$layer]);
- $this->layers = array_keys($this->configuration);
+ $this->configuration[$layer] = array();
return true;
}
return false;
*
* @access public
*/
- function store($layer = 'user')
+ function store($layer = 'user', $data = null)
{
- return $this->writeConfigFile(null, $layer);
+ return $this->writeConfigFile(null, $layer, $data);
}
// }}}
return PEAR_DEPENDENCY_BAD_DEPENDENCY;
}
+ /**
+ * Check package dependencies on uninstall
+ *
+ * @param string $error The resultant error string
+ * @param string $name Name of the package to test
+ *
+ * @return bool true if there were errors
+ */
+ function checkPackageUninstall(&$error, $package)
+ {
+ $error = null;
+ $packages = $this->registry->listPackages();
+ foreach ($packages as $pkg) {
+ if ($pkg == $package) {
+ continue;
+ }
+ $deps = $this->registry->packageInfo($pkg, 'release_deps');
+ if (empty($deps)) {
+ continue;
+ }
+ foreach ($deps as $dep) {
+ if ($dep['type'] == 'pkg' && strcasecmp($dep['name'], $package) == 0) {
+ $error .= "Package '$pkg' depends on '$package'\n";
+ }
+ }
+ }
+ return ($error) ? true : false;
+ }
+
/**
* Extension dependencies check method
*
$this->installroot = '';
}
$this->registry = &new PEAR_Registry($php_dir);
-
+ if (empty($options['nodeps'])) {
+ $depchecker = &new PEAR_Dependency($this->registry);
+ $error = $depchecker->checkPackageUninstall($errors, $package);
+ if ($error) {
+ return $this->raiseError($errors . 'uninstall failed');
+ }
+ }
// Delete the files
if (PEAR::isError($err = $this->_deletePackageFiles($package))) {
$this->rollbackFileTransaction();
// }}}
- // {{{ rebuildDepsFile()
-
- /**
- Experimental dependencies database handling functions (not yet in production)
-
- TODO:
- - test it
- - Think on the "not" dep relation. It's supposed that a package can't
- be installed if conflicts with another. The problem comes when the
- user forces the installation and later upgrades it
- **/
-
- // XXX Terrible slow, a lot of read, lock, write, unlock
- function rebuildDepsFile()
- {
- // Init the file with empty data
- $error = $this->_depWriteDepDB(array());
- if (PEAR::isError($error)) {
- return $error;
- }
- $packages = $this->listPackages();
- foreach ($packages as $package) {
- $deps = $this->packageInfo($package, 'release_deps');
- $error = $this->setPackageDep($package, $deps);
- if (PEAR::isError($error)) {
- return $error;
- }
- }
- return true;
- }
-
- function &_depGetDepDB()
- {
- if (!$fp = fopen($this->depfile, 'r')) {
- return $this->raiseError("Could not open dependencies file `".$this->depfile."'");
- }
- $data = fread($fp, filesize($this->depfile));
- fclose($fp);
- return unserialize($data);
- }
-
- function _depWriteDepDB(&$deps)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- if (!$fp = fopen($this->depfile, 'wb')) {
- $this->_unlock();
- return $this->raiseError("Could not open dependencies file `".$this->depfile."' for writting");
- }
- fwrite($fp, serialize($deps));
- fclose($fp);
- $this->_unlock();
- return true;
- }
-
- /*
- The data structure is as follows:
- $dep_db = array(
- // Other packages depends in some manner on this packages
- 'deps' => array(
- 'Package Name' => array(
- 0 => array(
- // This package depends on 'Package Name'
- 'depend' => 'Package',
- // Which version 'Package' needs of 'Package Name'
- 'version' => '1.0',
- // The requirement (version_compare() operator)
- 'rel' => 'ge'
- ),
- ),
- )
- // This packages are dependant on other packages
- 'pkgs' => array(
- 'Package Dependant' => array(
- // This is a index list with paths over the 'deps' array for quick
- // searching things like "what dependecies has this package?"
- // $dep_db['deps']['Package Name'][3]
- 'Package Name' => 3 // key in array ['deps']['Package Name']
- ),
- )
- )
-
- Note: It only supports package dependencies no other type
- */
-
- function removePackageDep($package)
- {
- $data = &$this->_depGetDepDB();
- if (PEAR::isError($data)) {
- return $data;
- }
- // Other packages depends on this package, can't be removed
- if (isset($data['deps'][$package])) {
- return $data['deps'][$package];
- }
- // The package depends on others, remove those dependencies
- if (isset($data['pkgs'][$package])) {
- foreach ($data['pkgs'][$package] as $pkg => $key) {
- // remove the dependency
- unset($data['deps'][$pkg][$key]);
- // if no more dependencies, remove the subject too
- if (!count($data['deps'][$pkg])) {
- unset($data['deps'][$pkg]);
- }
- }
- // remove the package from the index list
- unset($data['pkgs'][$package]);
- }
- return $this->_depWriteDepDB();
- }
-
- /**
- * Update or insert a the dependencies of a package, prechecking
- * that the package won't break any dependency in the process
- */
- function setPackageDep($package, $new_version, $rel_deps = array())
- {
- $data = &$this->_depGetDepDB();
- if (PEAR::isError($deps)) {
- return $deps;
- }
- // Other packages depend on this package, check deps. Mostly for
- // handling uncommon cases like:
- // <dep type='pkg' rel='lt' version='1.0'>Foo</dep> and we are trying to
- // update Foo to version 2.0
- if (isset($data['deps'][$package])) {
- foreach ($data['deps'][$package] as $dep) {
- $require = $dep['version'];
- $relation = $dep['rel'];
- // XXX (cox) Possible problem with changes in the way
- // PEAR_Dependency::checkPackage() works
- if ($relation != 'has') {
- if (!version_compare("$new_version", "$require", $relation)) {
- $fails[] = $dep;
- }
- }
- }
- if (isset($fails)) {
- return $fails;
- }
- }
-
- // This package has no dependencies
- if (!is_array($rel_deps) || !count($rel_deps)) {
- return true;
- }
-
- // The package depends on others, register that
- foreach ($rel_deps as $dep) {
- // We only support deps of type 'pkg's
- if ($dep && $dep['type'] == 'pkg' && isset($dep['name'])) {
- $write = array('depend' => $package,
- 'version' => $dep['version'],
- 'rel' => $dep['rel']);
- settype($data['deps'][$dep['name']], 'array');
-
- // The dependency already exists, update it
- if (isset($data['pkgs'][$package][$dep['name']])) {
- $key = $data['pkgs'][$package][$dep['name']];
- $data['deps'][$dep['name']][$key] = $write;
-
- // New dependency, insert it
- } else {
- $data['deps'][$dep['name']][] = $write;
- $key = key($data['deps'][$dep['name']]);
- settype($data['pkgs'][$package], 'array');
- $data['pkgs'][$package][$dep['name']] = $key;
- }
- }
- }
- return $this->_depWriteDepDB($data);
- }
-
- // }}}
}
?>
<?php
-// XXX TODO write the config file at the end as for example
-// in 'system' layer
-
/* $Id$ */
$pear_dir = dirname(__FILE__);
$new_ver = $reg->packageInfo($package, 'version');
$ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver));
}
+ if ($package == 'PEAR') {
+ if (is_file($ufile = $config->getConfFile('user'))) {
+ $ui->outputData('Warning! a PEAR user config file already exists from ' .
+ 'a previous PEAR installation at ' .
+ "'$ufile'. You may probably want to remove it.");
+ }
+ $ui->outputData('Writing PEAR system config file at: ' . $config->files['system']);
+ $ui->outputData('You may want to add: ' . $config->get('php_dir') . ' to your php.ini include_path');
+ $config->set('verbose', 1, 'default');
+ foreach ($config->getKeys() as $key) {
+ $data[$key] = $config->get($key);
+ }
+ $config->store('system', $data);
+ }
}
-
?>
</maintainer>
</maintainers>
<release>
- <version>1.2b2</version>
+ <version>1.2b3</version>
<state>beta</state>
- <date>2003-06-23</date>
+ <date>2003-07-08</date>
<notes>
* Changed license from PHP 2.02 to 3.0
* Added support for optional dependencies
* Made upgrade and uninstall package case insensitive
* pear makerpm, now works and generates a better system independant spec file
* pear install|build <pecl-package>, now exposes the compilation progress
+* Installer now checks dependencies on package uninstall
* Added new pear bundle command, which downloads and uncompress a <pecl-package>.
The main purpouse of this command is for easily adding extensions to the PHP sources
before compiling it.
<!--
- $Id: package.dtd,v 1.27.4.6 2003-07-02 10:38:07 pajoye Exp $
+ $Id: package.dtd,v 1.27.4.7 2003-07-08 20:39:45 pajoye Exp $
This is the PEAR package description, version 1.0.
It should be used with the informal public identifier: