Source for file Web.php
Documentation is available at Web.php
+----------------------------------------------------------------------+
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Christian Dickmann <dickmann@php.net> |
+----------------------------------------------------------------------+
$Id: Web.php,v 1.34 2005/08/08 03:13:12 cellog Exp $
require_once "PEAR/Frontend.php";
require_once "PEAR/Remote.php";
require_once "HTML/Template/IT.php";
require_once "Net/UserAgent/Detect.php";
* PEAR_Frontend_Web is a HTML based Webfrontend for the PEAR Installer
* The Webfrontend provides basic functionality of the Installer, such as
* a package list grouped by categories, a search mask, the possibility
* to install/upgrade/uninstall packages and some minor things.
* PEAR_Frontend_Web makes use of the PEAR::HTML_IT Template engine which
* provides the possibillity to skin the Installer.
* @author Christian Dickmann <dickmann@php.net>
* @package PEAR_Frontend_Web
* What type of user interface this frontend is for.
* Container, where values can be saved temporary
var $_savedOutput = array ();
var $_no_delete_pkgs = array (
var $_no_delete_chans = array (
* Flag to determine whether to treat all output as information from a post-install script
var $_installScript = false;
function PEAR_Frontend_Web ()
$GLOBALS['_PEAR_Frontend_Web_log'] = '';
$this->config = &$GLOBALS['_PEAR_Frontend_Web_config'];
function setConfig (&$config)
$this->config = &$config;
/* XXX some methods from CLI following. should be deleted in the near future */
function displayLine ($text)
function userConfirm ($prompt, $default = 'yes')
// {{{ displayStart(prompt, [default])
$tpl = $this->_initTemplate ("start.tpl.html", 'PEAR Installer');
$tpl->setVariable ('Version', '0.5');
* Initialize a TemplateObject, add a title, and icon and add JS and CSS for DHTML
* @param string $file filename of the template file
* @param string $title (optional) title of the page
* @param string $icon (optional) iconhandle for this page
* @param boolean $useDHTML (optional) add JS and CSS for DHTML-features
* @return object Object of HTML/IT - Template - Class
function _initTemplate ($file, $title = '', $icon = '', $useDHTML = true )
$tpl = new HTML_Template_IT (dirname(__FILE__ ). "/Web");
$tpl->loadTemplateFile ($file);
$tpl->setVariable ("InstallerURL", $_SERVER["PHP_SELF"]);
if ($this->config->get ('preferred_mirror') != $this->config->get ('default_channel')) {
$mirror = ' (mirror ' . $this->config->get ('preferred_mirror') . ')';
$tpl->setVariable ("_default_channel", $this->config->get ('default_channel') . $mirror);
$tpl->setVariable ("ImgPEAR", $_SERVER["PHP_SELF"]. '?img=pear');
$tpl->setVariable ("Title", $title);
$tpl->setCurrentBlock ("TitleBlock");
$tpl->setVariable ("_InstallerURL", $_SERVER["PHP_SELF"]);
$tpl->setVariable ("_Title", $title);
$tpl->setVariable ("_Icon", $icon);
$tpl->parseCurrentBlock ();
if ($useDHTML && Net_UserAgent_Detect ::getBrowser ('ie5up') == 'ie5up') {
$tpl->setVariable ("JS", 'dhtml');
$css = '<link rel="stylesheet" href="'. $_SERVER['PHP_SELF']. '?css=dhtml" />';
$tpl->setVariable ("DHTMLcss", $css);
$tpl->setVariable ("JS", 'nodhtml');
if (!isset ($_SESSION['_PEAR_Frontend_Web_js']) || $_SESSION['_PEAR_Frontend_Web_js'] == false ) {
$tpl->setCurrentBlock ('JSEnable');
$tpl->setVariable ('RedirectURL', $_SERVER['REQUEST_URI']. (!empty ($_GET) ? '&' : '?') . 'enableJS=1');
$tpl->parseCurrentBlock ();
* @param mixed $eobj PEAR_Error object or string containing the error message
* @param string $title (optional) title of the page
* @param string $img (optional) iconhandle for this page
* @param boolean $popup (optional) popuperror or normal?
* @return null does not return anything, but exit the script
function displayError ($eobj, $title = 'Error', $img = 'error', $popup = false )
if (isset ($GLOBALS['_PEAR_Frontend_Web_log']) && trim($GLOBALS['_PEAR_Frontend_Web_log'])) {
$msg = trim($GLOBALS['_PEAR_Frontend_Web_log']). "\n\n";
if (PEAR ::isError ($eobj)) {
$msg .= trim($eobj->getMessage ());
$tplfile = ($popup ? "error.popup.tpl.html" : "error.tpl.html");
$tpl = $this->_initTemplate ($tplfile, $title, $img);
$tpl->setVariable ("Error", $msg);
"uninstall" => "list-all",
if (isset ($_GET['command'])) {
if (isset ($command_map[$_GET['command']])) {
$_GET['command'] = $command_map[$_GET['command']];
$tpl->setVariable ("param", '?command='. $_GET['command']);
// {{{ displayFatalError()
* Alias for PEAR_Frontend_Web::displayError()
* @see PEAR_Frontend_Web::displayError()
function displayFatalError ($eobj, $title = 'Error', $img = 'error')
$this->displayError ($eobj, $title, $img);
function displayErrorImg ($eobj)
if (isset ($GLOBALS['_PEAR_Frontend_Web_log']) && trim($GLOBALS['_PEAR_Frontend_Web_log']))
$msg = trim($GLOBALS['_PEAR_Frontend_Web_log']). "\n\n";
$_SESSION['_PEAR_Frontend_Web_LastError'] = $eobj;
$_SESSION['_PEAR_Frontend_Web_LastError_log'] = $msg;
echo '<script language="javascript">';
printf('window.open("%s?command=show-last-error", "PEAR", "width=600, height=400");',
printf('<img src="%s?img=install_fail" border="0">', $_SERVER['PHP_SELF']);
// {{{ _outputListChannels()
function _outputListChannels ($data, $title = 'Manage Installer Channels',
$img = 'pkglist', $useDHTML = false , $paging = true )
$tpl = $this->_initTemplate ("channel.list.tpl.html", $title, $img, $useDHTML);
if (!isset ($data['data'])) {
$pageId = isset ($_GET['from']) ? $_GET['from'] : 0;
$paging_data = $this->__getData ($pageId, 5 , count($data['data']), false );
$data['data'] = array_slice($data['data'], $pageId, 5 );
$from = $paging_data['from'];
$to = $paging_data['next'];
// Generate Linkinformation to redirect to _this_ page after performing an action
$link_str = '<a href="?command=%s&from=%s" class="paging_link">%s</a>';
$command = isset ($_GET['command']) ? $_GET['command'] : 'list-channels';
if ($paging_data['from']>1 ) {
$links['back'] = sprintf($link_str, $command, $paging_data['prev'], '<<');
if ( $paging_data['next']) {
$links['next'] = sprintf($link_str, $command, $paging_data['next'], '>>');
$links['current'] = '&from=' . $paging_data['from'];
$tpl->setVariable ('Prev', $links['back']);
$tpl->setVariable ('Next', $links['next']);
$tpl->setVariable ('PagerFrom', $from);
$tpl->setVariable ('PagerTo', $to);
$tpl->setVariable ('PagerCount', $paging_data['numrows']);
$reg = &$this->config->getRegistry ();
foreach($data['data'] as $row) {
list ($channel, $summary) = $row;
$tpl->setCurrentBlock ("Row");
$tpl->setVariable ("ImgPackage", $_SERVER["PHP_SELF"]. '?img=package');
'delete' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=uninstall" width="18" height="17" border="0" alt="delete">',
'info' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=info" width="17" height="19" border="0" alt="info">',
'delete' => sprintf('%s?command=channel-delete&chan=%s%s',
$_SERVER["PHP_SELF"], urlencode($channel), $links['current']),
'info' => sprintf('%s?command=channel-info&chan=%s',
// detect whether any packages from this channel are installed
$anyinstalled = $reg->listPackages ($channel);
$id = 'id="'. $channel. '_href"';
$del = sprintf('<a href="%s" onClick="return deleteChan(\'%s\');" %s >%s</a>',
$urls['delete'], $channel, $id, $images['delete']);
$info = sprintf('<a href="%s">%s</a>', $urls['info'], $images['info']);
if (in_array($channel, $this->_no_delete_chans)) {
$tpl->setVariable ("NewChannelURL", $_SERVER['PHP_SELF']);
$tpl->setVariable ("Delete", $del);
$tpl->setVariable ("Info", $info);
$tpl->setVariable ("Channel", $channel);
$tpl->setVariable ("Summary", nl2br($summary));
$tpl->parseCurrentBlock ();
* Output a list of packages, grouped by categories. Uses Paging
* @param array $data array containing all data to display the list
* @param string $title (optional) title of the page
* @param string $img (optional) iconhandle for this page
* @param boolean $useDHTML (optional) add JS and CSS for DHTML-features
* @param boolean $paging (optional) use Paging or not
* @return boolean true (yep. i am an optimist)
function _outputListAll ($data, $title = 'Install / Upgrade / Remove PEAR Packages',
$img = 'pkglist', $useDHTML = false , $paging = true )
$tpl = $this->_initTemplate ("package.list.tpl.html", $title, $img, $useDHTML);
if (!isset ($data['data'])) {
$pageId = isset ($_GET['from']) ? $_GET['from'] : 0;
$paging_data = $this->__getData ($pageId, 5 , count($data['data']), false );
$data['data'] = array_slice($data['data'], $pageId, 5 );
$from = $paging_data['from'];
$to = $paging_data['next'];
// Generate Linkinformation to redirect to _this_ page after performing an action
$link_str = '<a href="?command=%s&from=%s&mode=%s" class="paging_link">%s</a>';
$command = isset ($_GET['command']) ? $_GET['command']: 'list-all';
$mode = isset ($_GET['mode'])? $_GET['mode']: '';
if ($paging_data['from']>1 ) {
$links['back'] = sprintf($link_str, $command, $paging_data['prev'], $mode, '<<');
if ( $paging_data['next']) {
$links['next'] = sprintf($link_str, $command, $paging_data['next'], $mode, '>>');
$links['current'] = '&from=' . $paging_data['from'] . '&mode=' . $mode;
if (isset ($_GET['command']) && $_GET['command'] == 'search') {
$links['current'] .= '&redirect=search&0='. $_REQUEST[0 ]. '&1='. $_REQUEST[1 ];
'installed' => 'list installed packages',
'' => 'list all packages',
'notinstalled' => 'list non-installed packages',
'upgrades' => 'list avail. upgrades',
foreach($modes as $mode => $text) {
$tpl->setVariable ('mode' . $i , !empty ($mode) ? '&mode='. $mode : '');
$tpl->setVariable ('mode' . $i. 'text', $text);
$tpl->setVariable ('Prev', $links['back']);
$tpl->setVariable ('Next', $links['next']);
$tpl->setVariable ('PagerFrom', $from);
$tpl->setVariable ('PagerTo', $to);
$tpl->setVariable ('PagerCount', $paging_data['numrows']);
$reg = &$this->config->getRegistry ();
foreach($data['data'] as $category => $packages) {
foreach($packages as $row) {
list ($pkgName, $pkgVersionLatest, $pkgVersionInstalled, $pkgSummary) = $row;
$parsed = $reg->parsePackageName ($pkgName, $this->config->get ('default_channel'));
$pkgChannel = $parsed['channel'];
$pkgName = $parsed['package'];
$tpl->setCurrentBlock ("Row");
$tpl->setVariable ("ImgPackage", $_SERVER["PHP_SELF"]. '?img=package');
'install' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=install" width="13" height="13" border="0" alt="install">',
'uninstall' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=uninstall" width="18" height="17" border="0" alt="uninstall">',
'upgrade' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=install" width="13" height="13" border="0" alt="upgrade">',
'info' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=info" width="17" height="19" border="0" alt="info">',
'infoExt' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=infoplus" width="18" height="19" border="0" alt="extended info">',
'install' => sprintf('%s?command=install&pkg=%s%s',
$_SERVER["PHP_SELF"], $pkgName, $links['current']),
'uninstall' => sprintf('%s?command=uninstall&pkg=%s%s',
$_SERVER["PHP_SELF"], $pkgName, $links['current']),
'upgrade' => sprintf('%s?command=upgrade&pkg=%s%s',
$_SERVER["PHP_SELF"], $pkgName, $links['current']),
'info' => sprintf('%s?command=remote-info&pkg=%s',
$_SERVER["PHP_SELF"], $pkgName),
'infoExt' => 'http://' . $this->config->get ('preferred_mirror')
$id = 'id="'. $pkgName. '_href"';
if (!$pkgVersionInstalled || $pkgVersionInstalled == "- no -") {
$inst = sprintf('<a href="%s" onClick="return perform(\'%s\');" %s>%s</a>',
$urls['install'], $pkgName, $id, $images['install']);
} else if ($compare == 1 ) {
$inst = sprintf('<a href="%s" onClick="return perform(\'%s\');" %s>%s</a>',
$urls['upgrade'], $pkgName, $id, $images['upgrade']);
$del = sprintf('<a href="%s" onClick="return deletePkg(\'%s\');" %s >%s</a>',
$urls['uninstall'], $pkgName, $id, $images['uninstall']);
$del = sprintf('<a href="%s" onClick="return deletePkg(\'%s\');" %s >%s</a>',
$urls['uninstall'], $pkgName, $id, $images['uninstall']);
$info = sprintf('<a href="%s">%s</a>', $urls['info'], $images['info']);
$infoExt = sprintf('<a href="%s">%s</a>', $urls['infoExt'], $images['infoExt']);
if ($reg->channelName ($pkgChannel) == 'pear.php.net' &&
in_array($pkgName, $this->_no_delete_pkgs)) {
$tpl->setVariable ("Latest", $pkgVersionLatest);
$tpl->setVariable ("Installed", $pkgVersionInstalled);
$tpl->setVariable ("Install", $inst);
$tpl->setVariable ("Delete", $del);
$tpl->setVariable ("Info", $info);
$tpl->setVariable ("InfoExt", $infoExt);
$tpl->setVariable ("Package", $pkgName);
$tpl->setVariable ("Channel", $pkgChannel);
$tpl->setVariable ("Summary", nl2br($pkgSummary));
$tpl->parseCurrentBlock ();
$tpl->setCurrentBlock ("Category");
$tpl->setVariable ("categoryName", $category);
$tpl->setVariable ("ImgCategory", $_SERVER["PHP_SELF"]. '?img=category');
$tpl->parseCurrentBlock ();
function _getPackageDeps ($deps)
return "<i>No dependencies registered.</i>\n";
'le' => 'version %s or older',
'ne' => 'any version but %s',
'ext' => 'PHP Extension',
'ldlib' => 'Development Library',
'rtlib' => 'Runtime Library',
'os' => 'Operating System',
'websrv' => 'Web Server',
'sapi' => 'SAPI Backend',
// Print link if it's a PEAR package
if ($row['type'] == 'pkg') {
$row['name'] = sprintf('<a class="green" href="%s?command=remote-info&pkg=%s">%s</a>',
$_SERVER['PHP_SELF'], $row['name'], $row['name']);
if (isset ($rel_trans[$row['relation']])) {
$rel = sprintf($rel_trans[$row['relation']], $row['version']);
$dep_type_desc[$row['type']], $row['name'], $rel);
$result .= sprintf("%s: %s", $dep_type_desc[$row['type']], $row['name']);
$lastversion = $row['version'];
* Output details of one package
* @param array $data array containing all information about the package
* @return boolean true (yep. i am an optimist)
function _outputPackageInfo ($data)
$tpl = $this->_initTemplate ("package.info.tpl.html", 'Package Management :: '. $data['name'], 'pkglist');
$tpl->setVariable ("PreferredMirror", $this->config->get ('preferred_mirror'));
$dl = &new PEAR_Downloader ($this, array (), $this->config);
$info = $dl->_getPackageDownloadUrl (array ('package' => $data['name'],
'channel' => $this->config->get ('default_channel'), 'version' => $data['stable']));
if (isset ($info['url'])) {
$tpl->setVariable ("DownloadURL", $info['url']);
$tpl->setVariable ("DownloadURL", $_SERVER['PHP_SELF']);
$tpl->setVariable ("Latest", $data['stable']);
$tpl->setVariable ("Installed", $data['installed']);
$tpl->setVariable ("Package", $data['name']);
$tpl->setVariable ("License", $data['license']);
$tpl->setVariable ("Category", $data['category']);
$tpl->setVariable ("Summary", nl2br($data['summary']));
$tpl->setVariable ("Description", nl2br($data['description']));
$deps = @$data['releases'][$data['stable']]['deps'];
$tpl->setVariable ("Dependencies", $this->_getPackageDeps ($deps));
'install' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=install" width="13" height="13" border="0" alt="install">',
'uninstall' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=uninstall" width="18" height="17" border="0" alt="uninstall">',
'upgrade' => '<img src="'. $_SERVER["PHP_SELF"]. '?img=install" width="13" height="13" border="0" alt="upgrade">',
if (!$data['installed'] || $data['installed'] == "- no -") {
'<a href="%s?command=install&pkg=%s&redirect=info">%s</a>',
$_SERVER["PHP_SELF"], $data['name'], $images['install']);
'<a href="%s?command=install&pkg=%s&redirect=info" class="green">Install package</a>',
$_SERVER["PHP_SELF"], $data['name']);
} else if ($compare == 1 ) {
'<a href="%s?command=upgrade&pkg=%s&redirect=info">%s</a><br>',
$_SERVER["PHP_SELF"], $data['name'], $images['upgrade']);
'<a href="%s?command=upgrade&pkg=%s&redirect=info" class="green">Upgrade package</a>',
$_SERVER["PHP_SELF"], $data['name']);
if (!in_array($data['name'], $this->_no_delete_pkgs)) {
'<a href="%s?command=uninstall&pkg=%s&redirect=info" %s>%s</a>',
$_SERVER["PHP_SELF"], $data['name'],
'onClick="return confirm(\'Do you really want to uninstall \\\''. $data['name']. '\\\'?\')"',
'<a href="%s?command=uninstall&pkg=%s&redirect=info" class="green" %s>Uninstall package</a>',
$_SERVER["PHP_SELF"], $data['name'],
'onClick="return confirm(\'Do you really want to uninstall \\\''. $data['name']. '\\\'?\')"');
if (!in_array($data['name'], $this->_no_delete_pkgs)) {
'<a href="%s?command=uninstall&pkg=%s&redirect=info" %s>%s</a>',
$_SERVER["PHP_SELF"], $data['name'],
'onClick="return confirm(\'Do you really want to uninstall \\\''. $data['name']. '\\\'?\')"',
'<a href="%s?command=uninstall&pkg=%s&redirect=info" class="green" %s>Uninstall package</a>',
$_SERVER["PHP_SELF"], $data['name'],
'onClick="return confirm(\'Do you really want to uninstall \\\''. $data['name']. '\\\'?\')"');
$tpl->setVariable ("Opt_Img_1", $opt_img[0 ]);
$tpl->setVariable ("Opt_Text_1", $opt_text[0 ]);
$tpl->setVariable ("Opt_Img_2", $opt_img[1 ]);
$tpl->setVariable ("Opt_Text_2", $opt_text[1 ]);
* Output details of one channel
* @param array $data array containing all information about the channel
* @return boolean true (yep. i am an optimist)
function _outputChannelInfo ($data)
$tpl = $this->_initTemplate ("channel.info.tpl.html",
'Channel Management :: '. $data['main']['data']['server'][1 ], 'pkglist');
$tpl->setVariable ("Channel", $data['main']['data']['server'][1 ]);
if (isset ($data['main']['data']['alias'])) {
$tpl->setVariable ("Alias", $data['main']['data']['alias'][1 ]);
$tpl->setVariable ("Alias", $data['main']['data']['server'][1 ]);
$tpl->setVariable ("Summary", $data['main']['data']['summary'][1 ]);
$tpl->setVariable ("ValidationPackage", $data['main']['data']['vpackage'][1 ]);
$tpl->setVariable ("ChannelValidationPackageVersion",
$data['main']['data']['vpackageversion'][1 ]);
if (!in_array($data['main']['data']['server'][1 ], array ('pear.php.net', '__uri'))) {
// see if the validation package is installed. If not, allow the user to install it
$reg = &$this->config->getRegistry ();
if ($reg->packageExists ($data['main']['data']['vpackage'][1 ],
$data['main']['data']['server'][1 ])) {
if ($reg->packageInfo ($data['main']['data']['vpackage'][1 ], 'version',
$data['main']['data']['server'][1 ]) ==
$data['main']['data']['vpackageversion'][1 ]) {
break; // poor man's throw
$pname = $reg->parsedPackageNameToString (array ('channel' =>
$data['main']['data']['server'][1 ],
'package' => $data['main']['data']['vpackage'][1 ],
'version' => $data['main']['data']['vpackageversion'][1 ]));
'<a href="%s?command=install&pkg=%s&redirect=info">%s</a>',
$_SERVER["PHP_SELF"], $pname
, '<img src="'. $_SERVER["PHP_SELF"]. '?img=install" width="13" height="13" border="0" alt="install">');
'<a href="%s?command=install&pkg=%s&redirect=info" class="green">Install package</a>',
$_SERVER["PHP_SELF"], $data['name']);
* Output all kinds of data depending on the command which called this method
* @param mixed $data datastructure containing the information to display
* @param string $command (optional) command from which this method was called
* @return mixed highly depends on the command
function outputData ($data, $command = '_default')
foreach($data['data'] as $group) {
foreach($group as $row) {
$prompt[$row[1 ]] = $row[0 ];
$default[$row[1 ]] = $row[2 ];
$title = 'Configuration :: '. $GLOBALS['pear_user_config'];
$GLOBALS['_PEAR_Frontend_Web_Config'] =
$this->userDialog ($command, $prompt, array (), $default, $title, 'config');
return $this->_outputListAll ($data);
return $this->_outputListChannels ($data);
return $this->_outputListAll ($data, 'Package Search :: Result', 'pkgsearch', false , false );
return $this->_outputPackageInfo ($data);
return $this->_outputChannelInfo ($data);
if ($_SERVER["REQUEST_METHOD"] != "POST")
$this->_data[$command] = $data;
$this->displayError ($data, 'Logout', 'logout');
$this->_savedOutput[] = $data;
if ($this->_installScript) {
$this->_savedOutput[] = $_SESSION['_PEAR_Frontend_Web_SavedOutput'][] = $data;
if ($this->_installScript) {
if (!isset ($_SESSION['_PEAR_Frontend_Web_SavedOutput'])) {
$_SESSION['_PEAR_Frontend_Web_SavedOutput'] = array ();
$this->_savedOutput = $_SESSION['_PEAR_Frontend_Web_SavedOutput'];
$this->_savedOutput = array ();
function finishOutput ($command, $redirectLink = false )
unset ($_SESSION['_PEAR_Frontend_Web_SavedOutput']);
$tpl = $this->_initTemplate ('info.tpl.html', " $command output" );
foreach($this->_savedOutput as $row) {
$tpl->setCurrentBlock ('Infoloop');
$tpl->setVariable ("Info", $row);
$tpl->parseCurrentBlock ();
$tpl->setCurrentBlock ('Infoloop');
$tpl->setVariable ("Info", '<a href="' . $redirectLink['link'] . '">' .
$redirectLink['text'] . '</a>');
$tpl->parseCurrentBlock ();
* @param array An array of PEAR_Task_Postinstallscript objects (or related scripts)
* @param PEAR_PackageFile_v2
function runPostinstallScripts (&$scripts, $pkg)
if (!isset ($_SESSION['_PEAR_Frontend_Web_Scripts'])) {
foreach ($scripts as $i => $task) {
$saves[$i] = (array) $task->_obj;
$_SESSION['_PEAR_Frontend_Web_Scripts'] = $saves;
foreach ($scripts as $i => $task) {
if (!isset ($_SESSION['_PEAR_Frontend_Web_ScriptIndex'])) {
$_SESSION['_PEAR_Frontend_Web_ScriptIndex'] = $i;
if ($i != $_SESSION['_PEAR_Frontend_Web_ScriptIndex']) {
// restore values from previous sessions to the install script
foreach ($_SESSION['_PEAR_Frontend_Web_Scripts'][$i] as $name => $val) {
// only public variables will be restored
$scripts[$i]->_obj ->$name = $val;
$this->_installScript = true;
$this->runInstallScript ($scripts[$i]->_params , $scripts[$i]->_obj , $pkg);
foreach ($saves as $i => $task) {
$saves[$i] = (array) $task->_obj;
$_SESSION['_PEAR_Frontend_Web_Scripts'] = $saves;
unset ($_SESSION['_PEAR_Frontend_Web_ScriptIndex']);
$this->_installScript = false;
unset ($_SESSION['_PEAR_Frontend_Web_Scripts']);
$this->finishOutput ($pkg->getPackage () . ' Install Script',
array ('link' => $GLOBALS['URL'] .
'?command=remote-info&pkg='. $pkg->getPackage (),
'text' => 'Click for ' . $pkg->getPackage () . ' Information'));
* Instruct the runInstallScript method to skip a paramgroup that matches the
* This method is useful for dynamically configuring which sections of a post-install script
* will be run based on the user's setup, which is very useful for making flexible
* post-install scripts without losing the cross-Frontend ability to retrieve user input
function skipParamgroup ($id)
$_SESSION['_PEAR_Frontend_Web_ScriptSkipSections'][$sectionName] = true;
* @param array $xml contents of postinstallscript tag
* @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) {
// only public variables will be restored
$_SESSION['_PEAR_Frontend_Web_ScriptObj'] = (array) $script;
if (!is_array($xml) || !isset ($xml['paramgroup'])) {
$script->run (array (), '_default');
if (!isset ($xml['paramgroup'][0 ])) {
$xml['paramgroup'][0 ] = array ($xml['paramgroup']);
foreach ($xml['paramgroup'] as $i => $group) {
if (isset ($_SESSION['_PEAR_Frontend_Web_ScriptSkipSections'][$group['id']])) {
if (isset ($_SESSION['_PEAR_Frontend_Web_ScriptSection'])) {
if ($i < $_SESSION['_PEAR_Frontend_Web_ScriptSection']) {
if (isset ($_SESSION['_PEAR_Frontend_Web_answers'])) {
$answers = $_SESSION['_PEAR_Frontend_Web_answers'];
if (isset ($group['name'])) {
if (isset ($answers[$group['name']])) {
switch ($group['conditiontype']) {
if ($answers[$group['name']] != $group['value']) {
if ($answers[$group['name']] == $group['value']) {
$answers[$group['name']])) {
$this->_clearScriptSession ();
$this->_clearScriptSession ();
if (!isset ($group['param'][0 ])) {
$group['param'] = array ($group['param']);
$_SESSION['_PEAR_Frontend_Web_ScriptSection'] = $i;
if (isset ($group['param'])) {
$prompts = $script->postProcessPrompts ($group['param'], $group['name']);
$this->outputData ('postinstall', 'Error: post-install script did not ' .
'return proper post-processed prompts');
$prompts = $group['param'];
foreach ($prompts as $i => $var) {
if (!is_array($var) || !isset ($var['prompt']) ||
($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'];
$this->confirmDialog ($prompts, $pkg->getPackage ()));
$this->confirmDialog ($group['param'], $pkg->getPackage ()));
array_unshift($_SESSION['_PEAR_Frontend_Web_ScriptCompletedPhases'],
if (!$script->run ($answers, $group['id'])) {
$script->run ($_SESSION['_PEAR_Frontend_Web_ScriptCompletedPhases'],
$this->_clearScriptSession ();
$script->run (array (), '_undoOnError');
$this->_clearScriptSession ();
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 ();
function _clearScriptSession ()
unset ($_SESSION['_PEAR_Frontend_Web_ScriptObj']);
unset ($_SESSION['_PEAR_Frontend_Web_answers']);
unset ($_SESSION['_PEAR_Frontend_Web_ScriptSection']);
unset ($_SESSION['_PEAR_Frontend_Web_ScriptCompletedPhases']);
unset ($_SESSION['_PEAR_Frontend_Web_ScriptSkipSections']);
* Ask for user input, confirm the answers and continue until the user is satisfied
* @param array an array of arrays, format array('name' => 'paramname', 'prompt' =>
* 'text to display', 'type' => 'string'[, default => 'default value'])
* @param string Package Name
function confirmDialog ($params, $pkg)
$prompts = $types = array ();
foreach ($params as $param) {
$prompts[$param['name']] = $param['prompt'];
$types[$param['name']] = $param['type'];
if (isset ($param['default'])) {
$answers[$param['name']] = $param['default'];
$answers[$param['name']] = '';
$_SERVER['REQUEST_METHOD'] = '';
$title = !$attempt ? $pkg . ' Install Script Input' : 'Please fill in all values';
$answers = $this->userDialog ('run-scripts', $prompts, $types, $answers, $title, '',
if ($answers === false ) {
$_SERVER['REQUEST_METHOD'] = 'POST';
* Display a formular and return the given input (yes. needs to requests)
* @param string $command command from which this method was called
* @param array $prompts associative array. keys are the inputfieldnames
* and values are the description
* @param array $types (optional) array of inputfieldtypes (text, password,
* etc.) keys have to be the same like in $prompts
* @param array $defaults (optional) array of defaultvalues. again keys have
* to be the same like in $prompts
* @param string $title (optional) title of the page
* @param string $icon (optional) iconhandle for this page
* @param array $extra (optional) extra parameters to put in the form action
* @return array input sended by the user
function userDialog ($command, $prompts, $types = array (), $defaults = array (), $title = '',
$icon = '', $extra = array ())
// If this is an POST Request, we can return the userinput
if (isset ($_GET["command"]) && $_GET["command"]== $command
&& $_SERVER["REQUEST_METHOD"] == "POST") {
if (isset ($_POST['cancel'])) {
foreach($prompts as $key => $prompt) {
$result[$key] = $_POST[$key];
// If this is an Answer GET Request , we can return the userinput
if (isset ($_GET["command"]) && $_GET["command"]== $command
&& isset ($_GET["userDialogResult"]) && $_GET["userDialogResult"]== 'get') {
foreach($prompts as $key => $prompt) {
$result[$key] = $_GET[$key];
// Assign title and icon to some commands
if ($command == 'login') {
$tpl = $this->_initTemplate ("userDialog.tpl.html", $title, $icon);
$tpl->setVariable ("Command", $command);
foreach ($extra as $name => $value) {
$tpl->setVariable ("extra", $extrap);
if (isset ($this->_data[$command])) {
$tpl->setVariable ("Headline", nl2br($this->_data[$command]));
foreach($prompts as $key => $prompt) {
if (strlen($prompt) > $maxlen) {
foreach($prompts as $key => $prompt) {
$tpl->setCurrentBlock ("InputField");
$type = (isset ($types[$key]) ? $types[$key] : 'text');
$default = (isset ($defaults[$key]) ? $defaults[$key] : '');
$tpl->setVariable ("prompt", $prompt);
$tpl->setVariable ("name", $key);
$tpl->setVariable ("default", $default);
$tpl->setVariable ("type", $type);
$tpl->setVariable ("width", 'width="275"');
$tpl->parseCurrentBlock ();
if ($command == 'run-scripts') {
$tpl->setVariable ("cancel", '<input type="submit" value="Cancel" name="cancel">');
* @param string $text message which has to written to log
$GLOBALS['_PEAR_Frontend_Web_log'] .= $text. "\n";
$this->_savedOutput[] = $text;
* Sends the required file along with Headers and exits the script
* @param string $handle handle of the requested file
* @param string $group group of the requested file
* @return null nothing, because script exits
function outputFrontendFile ($handle, $group)
"nodhtml" => "nodhtml.js",
"file" => "pkgsearch.png",
"file" => "category.jpg",
"file" => "install_wait.gif",
"file" => "install_ok.gif",
"file" => "install_fail.gif",
"file" => "infoplus.gif",
"file" => "pearsmall.gif",
"file" => "download.gif",
$file = $handles[$group][$handle];
header("Content-Type: text/css");
$filename = dirname(__FILE__ ). '/Web/'. $file['file'];
header("Content-Type: image/". $file['type']);
header("Cache-Control: public");
header("Content-Type: text/javascript");
* From DB::Pager. Removing Pager dependency.
function __getData ($from, $limit, $numrows, $maxpages = false )
if (empty ($numrows) || ($numrows < 0 )) {
$from = (empty ($from)) ? 0 : $from;
$pages = ceil($numrows/ $limit);
$data['numpages'] = $pages;
$data['lastpage'] = $pages;
$data['pages'] = array ();
for ($i=1; $i <= $pages; $i++ ) {
$offset = $limit * ($i-1 );
$data['pages'][$i] = $offset;
// $from must point to one page
// The current page we are
if (!isset ($data['current'])) {
return PEAR ::raiseError (null , 'wrong "from" param', null ,
null , null , 'DB_Error', true );
// Limit number of pages (Goole algorithm)
$radio = floor($maxpages/2 );
$minpage = $data['current'] - $radio;
$maxpage = $data['current'] + $radio - 1;
if ($maxpage > $data['numpages']) {
$maxpage = $data['numpages'];
foreach (range($minpage, $maxpage) as $page) {
$tmp[$page] = $data['pages'][$page];
$data['maxpages'] = $maxpages;
$data['maxpages'] = null;
$data['prev'] = ($prev >= 0 ) ? $prev : null;
$data['next'] = ($next < $numrows) ? $next : null;
// Results remaining in next page & Last row to fetch
if ($data['current'] == $pages) {
if ($data['current'] == ($pages - 1 )) {
$data['remain'] = $numrows - ($limit* ($pages-1 ));
$data['remain'] = $limit;
$data['to'] = $data['current'] * $limit;
$data['numrows'] = $numrows;
$data['from'] = $from + 1;
Documentation generated on Mon, 11 Mar 2019 14:37:19 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|