📄 installer.php
字号:
* 1. Filename as listed in the filelist element from package.xml * 2. Full path to the installed file * 3. Full path from the php_dir configuration variable used in this * installation * 4. Relative path from the php_dir that this file is installed in */ function addFileOperation($type, $data) { if (!is_array($data)) { return $this->raiseError('Internal Error: $data in addFileOperation' . ' must be an array, was ' . gettype($data)); } if ($type == 'chmod') { $octmode = decoct($data[0]); $this->log(3, "adding to transaction: $type $octmode $data[1]"); } else { $this->log(3, "adding to transaction: $type " . implode(" ", $data)); } $this->file_operations[] = array($type, $data); } // }}} // {{{ startFileTransaction() function startFileTransaction($rollback_in_case = false) { if (count($this->file_operations) && $rollback_in_case) { $this->rollbackFileTransaction(); } $this->file_operations = array(); } // }}} // {{{ commitFileTransaction() function commitFileTransaction() { $n = count($this->file_operations); $this->log(2, "about to commit $n file operations"); // {{{ first, check permissions and such manually $errors = array(); foreach ($this->file_operations as $tr) { list($type, $data) = $tr; switch ($type) { case 'rename': if (!file_exists($data[0])) { $errors[] = "cannot rename file $data[0], doesn't exist"; } // check that dest dir. is writable if (!is_writable(dirname($data[1]))) { $errors[] = "permission denied ($type): $data[1]"; } break; case 'chmod': // check that file is writable if (!is_writable($data[1])) { $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); } break; case 'delete': if (!file_exists($data[0])) { $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); } // check that directory is writable if (file_exists($data[0])) { if (!is_writable(dirname($data[0]))) { $errors[] = "permission denied ($type): $data[0]"; } else { // make sure the file to be deleted can be opened for writing $fp = false; if (!is_dir($data[0]) && !($fp = @fopen($data[0], 'a'))) { $errors[] = "permission denied ($type): $data[0]"; } elseif ($fp) { fclose($fp); } } } break; } } // }}} $m = sizeof($errors); if ($m > 0) { foreach ($errors as $error) { if (!isset($this->_options['soft'])) { $this->log(1, $error); } } if (!isset($this->_options['ignore-errors'])) { return false; } } $this->_dirtree = array(); // {{{ really commit the transaction foreach ($this->file_operations as $tr) { list($type, $data) = $tr; switch ($type) { case 'backup': @copy($data[0], $data[0] . '.bak'); $this->log(3, "+ backup $data[0] to $data[0].bak"); break; case 'removebackup': @unlink($data[0] . '.bak'); $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); break; case 'rename': $test = @unlink($data[1]); if (!$test && file_exists($data[1])) { if ($data[2]) { $extra = ', this extension must be installed manually. Rename to "' . basename($data[1]) . '"'; } else { $extra = ''; } if (!isset($this->_options['soft'])) { $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . $data[0] . $extra); } if (!isset($this->_options['ignore-errors'])) { return false; } } @rename($data[0], $data[1]); $this->log(3, "+ mv $data[0] $data[1]"); break; case 'chmod': @chmod($data[1], $data[0]); $octmode = decoct($data[0]); $this->log(3, "+ chmod $octmode $data[1]"); break; case 'delete': @unlink($data[0]); $this->log(3, "+ rm $data[0]"); break; case 'rmdir': @rmdir($data[0]); $this->log(3, "+ rmdir $data[0]"); break; case 'installed_as': $this->pkginfo->setInstalledAs($data[0], $data[1]); if (!isset($this->_dirtree[dirname($data[1])])) { $this->_dirtree[dirname($data[1])] = true; $this->pkginfo->setDirtree(dirname($data[1])); while(!empty($data[3]) && $data[3] != '/' && $data[3] != '\\' && $data[3] != '.') { $this->pkginfo->setDirtree($pp = $this->_prependPath($data[3], $data[2])); $this->_dirtree[$pp] = true; $data[3] = dirname($data[3]); } } break; } } // }}} $this->log(2, "successfully committed $n file operations"); $this->file_operations = array(); return true; } // }}} // {{{ rollbackFileTransaction() function rollbackFileTransaction() { $n = count($this->file_operations); $this->log(2, "rolling back $n file operations"); foreach ($this->file_operations as $tr) { list($type, $data) = $tr; switch ($type) { case 'backup': if (file_exists($data[0] . '.bak')) { @unlink($data[0]); @copy($data[0] . '.bak', $data[0]); $this->log(3, "+ restore $data[0] from $data[0].bak"); } break; case 'rename': @unlink($data[0]); $this->log(3, "+ rm $data[0]"); break; case 'mkdir': @rmdir($data[0]); $this->log(3, "+ rmdir $data[0]"); break; case 'chmod': break; case 'delete': break; case 'installed_as': $this->pkginfo->setInstalledAs($data[0], false); break; } } $this->pkginfo->resetDirtree(); $this->file_operations = array(); } // }}} // {{{ mkDirHier($dir) function mkDirHier($dir) { $this->addFileOperation('mkdir', array($dir)); return parent::mkDirHier($dir); } // }}} // {{{ download() /** * Download any files and their dependencies, if necessary * * @param array a mixed list of package names, local files, or package.xml * @param PEAR_Config * @param array options from the command line * @param array this is the array that will be populated with packages to * install. Format of each entry: * * <code> * array('pkg' => 'package_name', 'file' => '/path/to/local/file', * 'info' => array() // parsed package.xml * ); * </code> * @param array this will be populated with any error messages * @param false private recursion variable * @param false private recursion variable * @param false private recursion variable * @deprecated in favor of PEAR_Downloader */ function download($packages, $options, &$config, &$installpackages, &$errors, $installed = false, $willinstall = false, $state = false) { // trickiness: initialize here parent::PEAR_Downloader($this->ui, $options, $config); $ret = parent::download($packages); $errors = $this->getErrorMsgs(); $installpackages = $this->getDownloadedPackages(); trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " . "in favor of PEAR_Downloader class", E_USER_WARNING); return $ret; } // }}} // {{{ _parsePackageXml() function _parsePackageXml(&$descfile, &$tmpdir) { if (substr($descfile, -4) == '.xml') { $tmpdir = false; } else { // {{{ Decompress pack in tmp dir ------------------------------------- // To allow relative package file names $descfile = realpath($descfile); if (PEAR::isError($tmpdir = System::mktemp('-d'))) { return $tmpdir; } $this->log(3, '+ tmp dir created at ' . $tmpdir); // }}} } // Parse xml file ----------------------------------------------- $pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); PEAR::staticPopErrorHandling(); if (PEAR::isError($p)) { if (is_array($p->getUserInfo())) { foreach ($p->getUserInfo() as $err) { $loglevel = $err['level'] == 'error' ? 0 : 1; if (!isset($this->_options['soft'])) { $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); } } } return $this->raiseError('Installation failed: invalid package file'); } else { $descfile = $p->getPackageFile(); } return $p; } // }}} /** * Set the list of PEAR_Downloader_Package objects to allow more sane * dependency validation * @param array */ function setDownloadedPackages(&$pkgs) { PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $err = $this->analyzeDependencies($pkgs); PEAR::popErrorHandling(); if (PEAR::isError($err)) { return $err; } $this->_downloadedPackages = &$pkgs; } /** * Set the list of PEAR_Downloader_Package objects to allow more sane * dependency validation * @param array */ function setUninstallPackages(&$pkgs) { $this->_downloadedPackages = &$pkgs; } function getInstallPackages() { return $this->_downloadedPackages; } // {{{ install()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -