Files
Froxlor/lib/classes/aps/class.ApsParser.php
2010-02-24 06:12:34 +00:00

3263 lines
95 KiB
PHP

<?php
/**
* Implementation of the Application Packaging Standard from SwSoft/Parallels
* http://apsstandard.com
*
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Florian Lippert <flo@syscp.org> (2003-2009)
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package APS
* @version $Id$
* @todo implement charset validation
* reconfigure
* patch- and versionmanagement
* use settings/userinfo array instead a copy of this vars
* remove locked packages
* replace all html code
* add https support
* multi language support (package localization)
* zip stuff in own class
* logging
* button for remove of all failed installations
* increse database counter for customer
*/
class ApsParser
{
private $userinfo = array();
private $settings = array();
private $db = false;
private $RootDir = '';
/**
* Constructor of class, setup basic variables needed by the class
*
* @param userinfo global array with the current userinfos
* @param settings global array with the current system settings
* @param db valid instance of the database class
*/
public function __construct($userinfo, $settings, $db)
{
$this->settings = $settings;
$this->userinfo = $userinfo;
$this->db = $db;
$this->RootDir = dirname(dirname(dirname(dirname(__FILE__)))) . '/';
}
/**
* function provides instance management for admins
*/
private function ManageInstances()
{
global $lng, $filename, $s, $page, $action;
$Question = false;
//dont do anything if there is no instance
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Instances = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID`');
}
else
{
$Instances = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
}
if($this->db->num_rows($Instances) == 0)
{
self::InfoBox($lng['aps']['noinstancesexisting']);
return;
}
if(isset($_POST['save']))
{
$Ids = '';
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '`');
while($Row = $this->db->fetch_array($Result))
{
//has admin clicked "yes" for question
if(isset($_POST['answer'])
&& $_POST['answer'] == $lng['panel']['yes'])
{
//instance installation stop
if(isset($_POST['stop' . $Row['ID']])
&& $_POST['stop' . $Row['ID']] == '1')
{
//remove task
$this->db->query('DELETE FROM `' . TABLE_APS_TASKS . '` WHERE `InstanceID` = ' . (int)$Row['ID']);
//remove settings
$this->db->query('DELETE FROM `' . TABLE_APS_SETTINGS . '` WHERE `InstanceID` = ' . (int)$Row['ID']);
//remove instance
$this->db->query('DELETE FROM `' . TABLE_APS_INSTANCES . '` WHERE `ID` = ' . (int)$Row['ID']);
//decrease used flag
$this->db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `aps_packages_used` = `aps_packages_used` - 1 WHERE `customerid` = ' . (int)$Row[' CustomerID']);
}
//instance uninstallation
if(isset($_POST['remove' . $Row['ID']])
&& $_POST['remove' . $Row['ID']] == '1')
{
//remove installation task if it still exists
$this->db->query('DELETE FROM `' . TABLE_APS_TASKS . '` WHERE `InstanceID` = ' . (int)$Row['ID'] . ' AND `Task` = ' . TASK_INSTALL);
//insert task for uninstallation if it doesnt exists already
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_TASKS . '` WHERE `InstanceID` = ' . (int)$Row['ID'] . ' AND `Task` = ' . TASK_REMOVE);
if($this->db->num_rows($Result2) == 0)
{
$this->db->query('INSERT INTO `' . TABLE_APS_TASKS . '` (`InstanceID`, `Task`) VALUES (' . (int)$Row['ID'] . ', ' . TASK_REMOVE . ')');
$this->db->query('UPDATE `' . TABLE_APS_INSTANCES . '` SET `Status` = ' . INSTANCE_UNINSTALL . ' WHERE `ID` = ' . (int)$Row['ID']);
$this->db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `aps_packages_used` = `aps_packages_used` - 1 WHERE `customerid` = ' . (int)$Row[' CustomerID']);
}
}
}
else
{
//backup all selected ids for yes/no question
if(isset($_POST['stop' . $Row['ID']])
&& $_POST['stop' . $Row['ID']] == '1')
{
$Ids.= '<input type="hidden" name="stop' . $Row['ID'] . '" value="1"/>';
}
if(isset($_POST['remove' . $Row['ID']])
&& $_POST['remove' . $Row['ID']] == '1')
{
$Ids.= '<input type="hidden" name="remove' . $Row['ID'] . '" value="1"/>';
}
}
}
//if there are some ids, show yes/no question
if($Ids != ''
&& !isset($_POST['answer']))
{
//show yes/no question
$Message = $lng['question']['reallydoaction'];
eval("echo \"" . getTemplate("aps/askyesno") . "\";");
$Question = true;
}
}
//create table with contents based on instance status
if($Question != true)
{
//INSTALL
$InstancesInstall = '';
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` WHERE `i`.`Status` = ' . INSTANCE_INSTALL . ' GROUP BY `Version`, `Release`');
}
else
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_INSTALL . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' GROUP BY `Version`, `Release`');
}
while($Row = $this->db->fetch_array($Result))
{
eval("\$InstancesInstall.=\"" . getTemplate("aps/manage_instances_package") . "\";");
//get instances
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` = ' . INSTANCE_INSTALL . ' AND `PackageID` = ' . $Row['PackageID']);
}
else
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_INSTALL . ' AND `i`.`PackageID` = ' . $Row['PackageID'] . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
}
while($Row2 = $this->db->fetch_array($Result2))
{
//get customer name
$Result3 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `customerid` = ' . $Row2['CustomerID']);
$Row3 = $this->db->fetch_array($Result3);
$Stop = makecheckbox('stop' . $Row2['ID'], '', '1');
eval("\$InstancesInstall.=\"" . getTemplate("aps/manage_instances_install") . "\";");
}
}
//TASK ACTIVE
$InstancesTaskActive = '';
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` WHERE `i`.`Status` = ' . INSTANCE_TASK_ACTIVE . ' GROUP BY `Version`, `Release`');
}
else
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_TASK_ACTIVE . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' GROUP BY `Version`, `Release`');
}
while($Row = $this->db->fetch_array($Result))
{
eval("\$InstancesTaskActive.=\"" . getTemplate("aps/manage_instances_package") . "\";");
//get instances
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` = ' . INSTANCE_TASK_ACTIVE . ' AND `PackageID` = ' . $Row['PackageID']);
}
else
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_TASK_ACTIVE . ' AND `i`.`PackageID` = ' . $Row['PackageID'] . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
}
while($Row2 = $this->db->fetch_array($Result2))
{
//get customer name
$Result3 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `customerid` = ' . $Row2['CustomerID']);
$Row3 = $this->db->fetch_array($Result3);
eval("\$InstancesTaskActive.=\"" . getTemplate("aps/manage_instances_taskactive") . "\";");
}
}
//SUCCESS
$InstancesSuccess = '';
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` WHERE `i`.`Status` = ' . INSTANCE_SUCCESS . ' GROUP BY `Version`, `Release`');
}
else
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_SUCCESS . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' GROUP BY `Version`, `Release`');
}
while($Row = $this->db->fetch_array($Result))
{
eval("\$InstancesSuccess.=\"" . getTemplate("aps/manage_instances_package") . "\";");
//get instances
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` = ' . INSTANCE_SUCCESS . ' AND `PackageID` = ' . $Row['PackageID']);
}
else
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_SUCCESS . ' AND `i`.`PackageID` = ' . $Row['PackageID'] . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
}
while($Row2 = $this->db->fetch_array($Result2))
{
//get customer name
$Result3 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `customerid` = ' . $Row2['CustomerID']);
$Row3 = $this->db->fetch_array($Result3);
$Remove = makecheckbox('remove' . $Row2['ID'], '', '1');
eval("\$InstancesSuccess.=\"" . getTemplate("aps/manage_instances_success") . "\";");
}
}
//ERROR
$InstancesError = '';
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` WHERE `i`.`Status` = ' . INSTANCE_ERROR . ' GROUP BY `Version`, `Release`');
}
else
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_ERROR . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' GROUP BY `Version`, `Release`');
}
while($Row = $this->db->fetch_array($Result))
{
eval("\$InstancesError.=\"" . getTemplate("aps/manage_instances_package") . "\";");
//get instances
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` = ' . INSTANCE_ERROR . ' AND `PackageID` = ' . $Row['PackageID']);
}
else
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_ERROR . ' AND `i`.`PackageID` = ' . $Row['PackageID'] . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
}
while($Row2 = $this->db->fetch_array($Result2))
{
//get customer name
$Result3 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `customerid` = ' . $Row2['CustomerID']);
$Row3 = $this->db->fetch_array($Result3);
$Remove = makecheckbox('remove' . $Row2['ID'], '', '1');
eval("\$InstancesError.=\"" . getTemplate("aps/manage_instances_error") . "\";");
}
}
//UNINSTALL
$InstancesUninstall = '';
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` WHERE `i`.`Status` = ' . INSTANCE_UNINSTALL . ' GROUP BY `Version`, `Release`');
}
else
{
$Result = $this->db->query('SELECT `p`.`Name`, `p`.`Version`, `p`.`Release`, `i`.`PackageID` FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_APS_PACKAGES . '` AS `p` ON `i`.`PackageID` = `p`.`ID` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_UNINSTALL . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' GROUP BY `Version`, `Release`');
}
while($Row = $this->db->fetch_array($Result))
{
eval("\$InstancesUninstall.=\"" . getTemplate("aps/manage_instances_package") . "\";");
//get instances
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` = ' . INSTANCE_UNINSTALL . ' AND `PackageID` = ' . $Row['PackageID']);
}
else
{
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `i`.`Status` = ' . INSTANCE_UNINSTALL . ' AND `i`.`PackageID` = ' . $Row['PackageID'] . ' AND `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
}
while($Row2 = $this->db->fetch_array($Result2))
{
//get customer name
$Result3 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `customerid` = ' . $Row2['CustomerID']);
$Row3 = $this->db->fetch_array($Result3);
eval("\$InstancesUninstall.=\"" . getTemplate("aps/manage_instances_uninstall") . "\";");
}
}
//create some statistics
$Statistics = '';
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '`');
$Statistics.= sprintf($lng['aps']['numerofinstances'], $this->db->num_rows($Result));
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` = ' . INSTANCE_SUCCESS);
$Statistics.= sprintf($lng['aps']['numerofinstancessuccess'], $this->db->num_rows($Result));
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` = ' . INSTANCE_ERROR);
$Statistics.= sprintf($lng['aps']['numerofinstanceserror'], $this->db->num_rows($Result));
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `Status` IN (' . INSTANCE_INSTALL . ', ' . INSTANCE_TASK_ACTIVE . ', ' . INSTANCE_UNINSTALL . ')');
$Statistics.= sprintf($lng['aps']['numerofinstancesaction'], $this->db->num_rows($Result));
}
else
{
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
$Statistics.= sprintf($lng['aps']['numerofinstances'], $this->db->num_rows($Result));
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' AND `Status` = ' . INSTANCE_SUCCESS);
$Statistics.= sprintf($lng['aps']['numerofinstancessuccess'], $this->db->num_rows($Result));
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' AND `Status` = ' . INSTANCE_ERROR);
$Statistics.= sprintf($lng['aps']['numerofinstanceserror'], $this->db->num_rows($Result));
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `c`.`adminid` = ' . (int)$this->userinfo['adminid'] . ' AND `Status` IN (' . INSTANCE_INSTALL . ', ' . INSTANCE_TASK_ACTIVE . ', ' . INSTANCE_UNINSTALL . ')');
$Statistics.= sprintf($lng['aps']['numerofinstancesaction'], $this->db->num_rows($Result));
}
eval("echo \"" . getTemplate("aps/manage_instances") . "\";");
}
}
/**
* unlink files recursively
*
* @param dir directory to delete recursive
*/
protected function UnlinkRecursive($Dir)
{
if(!$DirHandle = @opendir($Dir))return;
while(false !== ($Object = readdir($DirHandle)))
{
if($Object == '.'
|| $Object == '..')continue;
if(!@unlink($Dir . '/' . $Object))
{
self::UnlinkRecursive($Dir . '/' . $Object);
}
}
closedir($DirHandle);
@rmdir($Dir);
}
/**
* function provides package management for admins
*/
private function ManagePackages()
{
global $lng, $filename, $s, $page, $action;
$Question = false;
if(isset($_POST['save']))
{
if(isset($_POST['all'])
&& $_POST['all'] == 'lock')
{
//lock alle packages
$this->db->query('UPDATE `' . TABLE_APS_PACKAGES . '` SET `Status` = ' . PACKAGE_LOCKED . ' WHERE 1');
}
elseif(isset($_POST['all'])
&& $_POST['all'] == 'unlock')
{
//enable all packages
$this->db->query('UPDATE `' . TABLE_APS_PACKAGES . '` SET `Status` = ' . PACKAGE_ENABLED . ' WHERE 1');
}
elseif(isset($_POST['downloadallpackages']))
{
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_TASKS . '` WHERE `Task` = ' . TASK_SYSTEM_DOWNLOAD);
if($this->db->num_rows($Result) > 0)
{
self::InfoBox($lng['aps']['downloadtaskexists']);
}
else
{
$this->db->query('INSERT INTO `' . TABLE_APS_TASKS . '` (`Task`, `InstanceID`) VALUES (' . TASK_SYSTEM_DOWNLOAD . ', 0)');
self::InfoBox($lng['aps']['downloadtaskinserted']);
}
}
elseif(isset($_POST['updateallpackages']))
{
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_TASKS . '` WHERE `Task` = ' . TASK_SYSTEM_UPDATE);
if($this->db->num_rows($Result) > 0)
{
self::InfoBox($lng['aps']['updatetaskexists']);
}
else
{
$this->db->query('INSERT INTO `' . TABLE_APS_TASKS . '` (`Task`, `InstanceID`) VALUES (' . TASK_SYSTEM_UPDATE . ', 0)');
self::InfoBox($lng['aps']['updatetaskinserted']);
}
}
elseif(isset($_POST['enablenewest']))
{
//lock alle packages, then find newerst package and enable it
$this->db->query('UPDATE `' . TABLE_APS_PACKAGES . '` SET `Status` = ' . PACKAGE_LOCKED);
//get all packages
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` GROUP BY `Name`');
while($Row = $this->db->fetch_array($Result))
{
//get newest version of package
$NewestVersion = '';
$NewestId = '';
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Name` = "' . $this->db->escape($Row['Name']) . '"');
while($Row2 = $this->db->fetch_array($Result2))
{
if(version_compare($Row2['Version'] . '-' . $Row2['Release'], $NewestVersion) == 1)
{
$NewestVersion = $Row2['Version'] . '-' . $Row2['Release'];
$NewestId = $Row2['ID'];
}
}
//enable newest version
$this->db->query('UPDATE `' . TABLE_APS_PACKAGES . '` SET `Status` = ' . PACKAGE_ENABLED . ' WHERE `ID` = ' . $NewestId);
}
}
elseif(isset($_POST['removeunused']))
{
//remove all packages which have no dependencies (count of package instances = 0)
if(isset($_POST['answer'])
&& $_POST['answer'] == $lng['panel']['yes'])
{
//get all packages
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '`');
while($Row = $this->db->fetch_array($Result))
{
//query how often package has been installed
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `PackageID` = ' . $Row['ID']);
if($this->db->num_rows($Result2) == 0)
{
//remove package if number of package instances is 0
self::UnlinkRecursive('./packages/' . $Row['Path']);
$this->db->query('DELETE FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $Row['ID']);
}
}
}
else
{
//show yes/no question
$Message = $lng['question']['reallyremovepackages'];
$Ids = '<input type="hidden" name="removeunused" value="1"/>';
eval("echo \"" . getTemplate("aps/askyesno") . "\";");
$Question = true;
}
}
elseif(isset($_POST['all'])
&& $_POST['all'] == 'remove')
{
//remove all packages from system
if(isset($_POST['answer'])
&& $_POST['answer'] == $lng['panel']['yes'])
{
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '`');
//check for dependencies
while($Row = $this->db->fetch_array($Result))
{
//query how often package has been installed
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `PackageID` = ' . $Row['ID']);
if($this->db->num_rows($Result2) == 0)
{
//remove package if number of package instances is 0
self::UnlinkRecursive('./packages/' . $Row['Path']);
$this->db->query('DELETE FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $Row['ID']);
}
}
}
else
{
//show yes/no question
$Message = $lng['question']['reallyremovepackages'];
$Ids = '<input type="hidden" name="all" value="remove"/>';
eval("echo \"" . getTemplate("aps/askyesno") . "\";");
$Question = true;
}
}
else
{
//no special button or "all" function has been clicked
//continue to parse "single" options
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '`');
$Ids = '';
while($Row = $this->db->fetch_array($Result))
{
//set new status of package (locked)
if($Row['Status'] == PACKAGE_ENABLED
&& isset($_POST['lock' . $Row['ID']]))
{
$this->db->query('UPDATE `' . TABLE_APS_PACKAGES . '` SET `Status` = ' . PACKAGE_LOCKED . ' WHERE `ID` = ' . $this->db->escape($Row['ID']));
}
//set new status of package (enabled)
if($Row['Status'] == PACKAGE_LOCKED
&& isset($_POST['unlock' . $Row['ID']]))
{
$this->db->query('UPDATE `' . TABLE_APS_PACKAGES . '` SET `Status` = ' . PACKAGE_ENABLED . ' WHERE `ID` = ' . $this->db->escape($Row['ID']));
}
//save id of package to remove for yes/no question
if(isset($_POST['remove' . $Row['ID']]))
{
$Ids.= '<input type="hidden" name="remove' . $Row['ID'] . '" value="1"/>';
//remove package if answer is yes
if(isset($_POST['answer'])
&& $_POST['answer'] == $lng['panel']['yes'])
{
self::UnlinkRecursive('./packages/' . $Row['Path']);
$this->db->query('DELETE FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $Row['ID']);
}
}
}
//if there are some ids to remove, show yes/no box
if($Ids != ''
&& !isset($_POST['answer']))
{
//show yes/no question
$Message = $lng['question']['reallyremovepackages'];
eval("echo \"" . getTemplate("aps/askyesno") . "\";");
$Question = true;
}
}
}
//show package overview with options
if(!isset($_POST['save'])
|| $Question == false)
{
//query all packages grouped by package name
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` GROUP BY `Name` ORDER BY `Name` ASC');
$Packages = '';
while($Row = $this->db->fetch_array($Result))
{
eval("\$Packages.=\"" . getTemplate("aps/manage_packages_row") . "\";");
//get all package versions of current package
$Result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Name` = "' . $this->db->escape($Row['Name']) . '" ORDER BY `Version` DESC, `Release` DESC');
while($Row2 = $this->db->fetch_array($Result2))
{
//show package with options
$Lock = '';
$Unlock = '';
if($Row2['Status'] == PACKAGE_ENABLED)
{
$Lock = makecheckbox('lock' . $Row2['ID'], '', '1');
}
if($Row2['Status'] == PACKAGE_LOCKED)
{
$Unlock = makecheckbox('unlock' . $Row2['ID'], '', '1');
}
//query how often package has been installed
$Result3 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `PackageID` = ' . $Row2['ID']);
$Installations = $this->db->num_rows($Result3);
if($Installations == 0)$Remove = makecheckbox('remove' . $Row2['ID'], '', '1');
eval("\$Packages.=\"" . getTemplate("aps/manage_packages_detail") . "\";");
}
}
if($this->db->num_rows($Result) == 0)
{
//no packages have been installed in system
self::InfoBox($lng['aps']['nopackagesinsystem']);
eval("echo \"" . getTemplate("aps/manage_packages_download") . "\";");
}
else
{
//generate some statistics
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '`');
$Temp = $this->db->num_rows($Result);
$Statistics = sprintf($lng['aps']['numerofpackagesinstalled'], $this->db->num_rows($Result));
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED);
$Statistics.= sprintf($lng['aps']['numerofpackagesenabled'], $this->db->num_rows($Result));
$Statistics.= sprintf($lng['aps']['numerofpackageslocked'], $Temp - $this->db->num_rows($Result));
if((int)$this->userinfo['customers_see_all'] == 1)
{
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '`');
$Statistics.= sprintf($lng['aps']['numerofinstances'], $this->db->num_rows($Result));
}
else
{
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` AS `i` INNER JOIN `' . TABLE_PANEL_CUSTOMERS . '` AS `c` ON `i`.`CustomerID` = `c`.`customerid` WHERE `c`.`adminid` = ' . (int)$this->userinfo['adminid']);
$Statistics.= sprintf($lng['aps']['numerofinstances'], $this->db->num_rows($Result));
}
eval("echo \"" . getTemplate("aps/manage_packages") . "\";");
}
}
}
/**
* function provides a upload site for new packages
*/
private function UploadNewPackages()
{
global $lng, $filename, $s, $page, $action;
//define how many files can be uploaded at once
$Files = array();
//define how many upload fields will be shown
for ($i = 1;$i <= (int)$this->settings['aps']['upload_fields'];$i++)
{
$Files[] = 'file' . $i;
}
//check whether one file has been uploaded
$FilesSet = false;
foreach($Files as $File)
{
if(isset($_FILES[$File]))$FilesSet = true;
}
if($FilesSet == true)
{
//any file has been uploaded, now check for errors and parse the input
foreach($Files as $File)
{
if(isset($_FILES[$File]))
{
$Errors = array();
//check uploaded files against some things
//check for filetype
if(substr($_FILES[$File]['name'], -3) != 'zip'
&& $_FILES[$File]['error'] == 0)
{
$Errors[] = $lng['aps']['notazipfile'];
}
//check for filesize
if(($_FILES[$File]['size'] > self::PhpMemorySizeToBytes(ini_get('upload_max_filesize')) && $_FILES[$File]['error'] == 0)
|| $_FILES[$File]['error'] == 1)
{
$Errors[] = $lng['aps']['filetoobig'];
}
//check is file isnt complete
if($_FILES[$File]['error'] == 3)
{
$Errors[] = $lng['aps']['filenotcomplete'];
}
//check for other php internal errors
if($_FILES[$File]['error'] >= 6)
{
$Errors[] = $lng['aps']['phperror'] . (int)$_FILES[$File]['error'];
}
//all checks are ok, try to install the package
if(count($Errors) == 0
&& $_FILES[$File]['error'] == 0)
{
//install package in system
if(move_uploaded_file($_FILES[$File]['tmp_name'], './temp/' . basename($_FILES[$File]['name'])) == true)
{
self::InstallNewPackage('./temp/' . basename($_FILES[$File]['name']));
}
else
{
$moveproblem = str_replace('{$path}', $this->RootDir, $lng['aps']['moveproblem']);
$Errors[] = $moveproblem;
}
}
if(count($Errors) > 0)
{
//throw errors
$ErrorMessage = '';
foreach($Errors as $Error)
{
$ErrorMessage.= '<li>' . $Error . '</li>';
}
self::InfoBox(sprintf($lng['aps']['uploaderrors'], htmlspecialchars($_FILES[$File]['name']), $ErrorMessage));
}
}
}
}
//generate upload fields
$Output = '';
foreach($Files as $File)
{
$Output.= '<input size="60" name="' . $File . '" type="file" /><br/><br/>';
}
eval("echo \"" . getTemplate("aps/upload") . "\";");
}
/**
* function provides a frontend for customers to search packages
*/
private function SearchPackages()
{
global $lng, $filename, $s, $page, $action;
$Error = 0;
$Ids = array();
$ShowAll = 0;
if(isset($_GET['keyword'])
&& preg_match('/^[- _0-9a-z\.,:;]+$/i', $_GET['keyword']) != false)
{
//split all keywords
$Elements = split('[ ,;]', trim($_GET['keyword']));
if(count($Elements) == 1
&& strlen($Elements[0]) == 0)
{
//no keyword given -> show all packages
$ShowAll = 1;
}
else
{
foreach($Elements as $Key)
{
//skip empty values -> prevents that whitespaces lead to the result that all packages will be found
if($Key == '')continue;
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' AND (`Name` LIKE "%' . $this->db->escape($Key) . '%" OR `Path` LIKE "%' . $this->db->escape($Key) . '%" OR `Version` LIKE "%' . $this->db->escape($Key) . '%") ');
//check if keyword got a result
if($this->db->num_rows($result) > 0)
{
//add all package ids which match to result array
while($Temp = $this->db->fetch_array($result))
{
if(!in_array($Temp['ID'], $Ids))$Ids[] = $Temp['ID'];
}
}
}
//no matches found to given keywords
if(count($Ids) == 0)
{
$Error = 2;
}
}
}
elseif(isset($_GET['keyword'])
&& strlen($_GET['keyword']) != 0)
{
//input contains illegal characters
$Error = 1;
}
elseif(isset($_GET['keyword'])
&& strlen($_GET['keyword']) == 0)
{
//nothing has been entered - show all packages
$ShowAll = 1;
}
//show errors
if($Error == 1)
{
self::InfoBox($lng['aps']['nospecialchars']);
}
elseif($Error == 2)
{
self::InfoBox($lng['aps']['noitemsfound']);
}
//show keyword only if format is ok
$Keyword = '';
if(isset($_GET['keyword'])
&& $Error == 0)$Keyword = htmlspecialchars($_GET['keyword']);
eval("echo \"" . getTemplate("aps/search") . "\";");
//show results
if(($Error == 0 && count($Ids) > 0)
|| $ShowAll == 1)
{
//run query based on search results
if($ShowAll != 1)
{
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` IN (' . $this->db->escape(implode(',', $Ids)) . ')');
}
else
{
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED);
}
//show package infos
if($this->db->num_rows($result) > 0)
{
if($this->db->num_rows($result) == 1)
{
self::InfoBox(sprintf($lng['aps']['searchoneresult'], $this->db->num_rows($result)));
}
else
{
self::InfoBox(sprintf($lng['aps']['searchmultiresult'], $this->db->num_rows($result)));
}
while($Row = $this->db->fetch_array($result))
{
self::ShowPackageInfo($Row['ID']);
}
}
}
}
/**
* function provides a frontend for customers to show the status of installed packages
*
* @param customerid id of customer from database
*/
private function CustomerStatus($CustomerId)
{
global $lng, $filename, $s, $page, $action;
$Data = '';
$Fieldname = '';
$Fieldvalue = '';
$Groupname = '';
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId));
//customer hasnt installed any package yet
if($this->db->num_rows($result) == 0)
{
self::InfoBox($lng['aps']['nopackagesinstalled']);
return;
}
while($Row = $this->db->fetch_array($result))
{
$Data = '';
$result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $this->db->escape($Row['PackageID']));
$Row2 = $this->db->fetch_array($result2);
$Xml = self::GetXmlFromFile('./packages/' . $Row2['Path'] . '/APP-META.xml');
//skip if parse of xml has failed
if($Xml == false)continue;
$Icon = './images/default.png';
//show data and status of package
if($Xml->icon['path'])
{
$Icon = './packages/' . $Row2['Path'] . '/' . basename($Xml->icon['path']);
}
$Summary = $Xml->summary;
$Fieldname = $lng['aps']['version'];
$Fieldvalue = $Xml->version . ' (Release ' . $Xml->release . ')';
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
$Temp = '';
switch($Row['Status'])
{
case INSTANCE_INSTALL:
$Temp.= $lng['aps']['instance_install'];
break;
case INSTANCE_TASK_ACTIVE:
$Temp.= $lng['aps']['instance_task_active'];
break;
case INSTANCE_SUCCESS:
$Temp.= $lng['aps']['instance_success'];
break;
case INSTANCE_ERROR:
$Temp.= $lng['aps']['instance_error'];
break;
case INSTANCE_UNINSTALL:
$Temp.= $lng['aps']['instance_uninstall'];
break;
default:
$Temp.= $lng['aps']['unknown_status'];
break;
}
$Fieldname = $lng['aps']['currentstatus'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
$result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_TASKS . '` WHERE `InstanceID` = ' . $this->db->escape($Row['ID']));
$Temp = '';
if($this->db->num_rows($result2) > 0)
{
while($Row2 = $this->db->fetch_array($result2))
{
switch($Row2['Task'])
{
case TASK_INSTALL:
$Temp.= $lng['aps']['task_install'] . '<br/>';
break;
case TASK_REMOVE:
$Temp.= $lng['aps']['task_remove'] . '<br/>';
break;
case TASK_RECONFIGURE:
$Temp.= $lng['aps']['task_reconfigure'] . '<br/>';
break;
case TASK_UPGRADE:
$Temp.= $lng['aps']['task_upgrade'] . '<br/>';
break;
default:
$Temp.= $lng['aps']['unknown_status'] . '<br/>';
break;
}
}
}
else
{
$Temp.= $lng['aps']['no_task'];
}
$Fieldname = $lng['aps']['activetasks'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
//show entrypoints for application (important URLs within the application)
if($Row['Status'] == INSTANCE_SUCCESS)
{
$Temp = '';
//get domain to domain id
$result3 = $this->db->query('SELECT * FROM `' . TABLE_APS_SETTINGS . '` WHERE `Name` = "main_domain" AND `InstanceID` = ' . $this->db->escape($Row['ID']));
$Row3 = $this->db->fetch_array($result3);
$result4 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `customerid` = ' . $this->db->escape($CustomerId) . ' AND `id` = ' . $this->db->escape($Row3['Value']));
$Row3 = $this->db->fetch_array($result4);
$Domain = $Row3['domain'];
//get sub location for domain
$result5 = $this->db->query('SELECT * FROM `' . TABLE_APS_SETTINGS . '` WHERE `Name` = "main_location" AND `InstanceID` = ' . $this->db->escape($Row['ID']));
$Row3 = $this->db->fetch_array($result5);
$Location = $Row3['Value'];
//show main site link
if($Location == '')
{
$Temp.= '<a href="http://' . $Domain . '/" target="_blank">' . $lng['aps']['mainsite'] . '</a><br/>';
}
else
{
$Temp.= '<a href="http://' . $Domain . '/' . $Location . '/" target="_blank">' . $lng['aps']['mainsite'] . '</a><br/>';
}
//show other links from meta data
if($Xml->{'entry-points'})
{
foreach($Xml->{'entry-points'}->entry as $Entry)
{
if($Location == '')
{
$Temp.= '<a href="http://' . $Domain . $Entry->path . '" target="_blank">' . $Entry->label . '</a><br/>';
}
else
{
$Temp.= '<a href="http://' . $Domain . '/' . $Location . $Entry->path . '" target="_blank">' . $Entry->label . '</a><br/>';
}
}
}
$Fieldname = $lng['aps']['applicationlinks'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
eval("echo \"" . getTemplate("aps/package_status") . "\";");
unset($Xml);
}
}
/**
* function creates a new instance of a package based on the installer data
*
* @param packageid id of package from database
* @param customerid id of customer from database
* @return success true/error false
*/
private function CreatePackageInstance($PackageId, $CustomerId)
{
global $lng;
if(!self::IsValidPackageId($PackageId, true))return false;
//has user pressed F5/reload?
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_TEMP_SETTINGS . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId));
if($this->db->num_rows($result) == 0)
{
self::InfoBox($lng['aps']['erroronnewinstance']);
return false;
}
//get path to package xml file
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $this->db->escape($PackageId));
$Row = $this->db->fetch_array($result);
$Xml = self::GetXmlFromFile('./packages/' . $Row['Path'] . '/APP-META.xml');
//return if parse of xml file has failed
if($Xml == false)return false;
//add new instance
$this->db->query('INSERT INTO `' . TABLE_APS_INSTANCES . '` (`CustomerID`, `PackageID`, `Status`) VALUES (' . $this->db->escape($CustomerId) . ', ' . $this->db->escape($PackageId) . ', ' . INSTANCE_INSTALL . ')');
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId) . ' AND `PackageID` = ' . $this->db->escape($PackageId) . ' AND `Status` = ' . INSTANCE_INSTALL . ' ORDER BY ID DESC');
$Row = $this->db->fetch_array($result);
//copy & delete temporary data
$this->db->query('INSERT INTO `' . TABLE_APS_SETTINGS . '` (`InstanceID`, `Name`, `Value`) SELECT ' . $this->db->escape($Row['ID']) . ' AS `InstanceID`, `Name`, `Value` FROM `' . TABLE_APS_TEMP_SETTINGS . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId) . ' AND `PackageID` = ' . $this->db->escape($PackageId));
$this->db->query('DELETE FROM `' . TABLE_APS_TEMP_SETTINGS . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId) . ' AND `PackageID` = ' . $this->db->escape($PackageId));
//add task for installation
$this->db->query('INSERT INTO `' . TABLE_APS_TASKS . '` (`InstanceID`, `Task`) VALUES(' . $this->db->escape($Row['ID']) . ', ' . TASK_INSTALL . ')');
//update used counter for packages
$this->db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `aps_packages_used` = `aps_packages_used` + 1 WHERE `customerid` = ' . (int)$CustomerId);
self::InfoBox(sprintf($lng['aps']['successonnewinstance'], $Xml->name));
unset($Xml);
}
/**
* convert human readable memory sizes into bytes
*
* @param value ini_get() formated memory size
* @return memory size in bytes
*/
private function PhpMemorySizeToBytes($Value)
{
//convert memory formats from php.ini to a integer value in bytes
$Value = trim($Value);
$Last = strtolower($Value{strlen($Value) - 1});
switch($Last)
{
case 'g':
$Value*= 1024;
case 'm':
$Value*= 1024;
case 'k':
$Value*= 1024;
}
return $Value;
}
/**
* convert php.ini formated strings into true and false as a string
*
* @param value value to read from php.ini (format: safe_mode or safe-mode)
* @return (true|false) as string
*/
private function TrueFalseIniGet($Value)
{
//convert php.ini values to true and false as string
$Value = ini_get(str_replace(array('-'), array('_'), $Value));
if($Value == 0
|| $Value == false
|| $Value == 'off')
{
return 'false';
}
else
{
return 'true';
}
}
/**
* packages can fail during the validation process. this function allows to check for exceptions
*
* @param category category as string to check
* @param item item within category to check
* @return success true (value has exception) / error false (value has no exception)
*/
private function CheckException($Category, $Item, $Value)
{
global $settings;
//search for element within system settings
$Elements = explode(',', $settings['aps'][$Category . '-' . $Item]);
foreach($Elements as $Element)
{
if(strtolower($Element) == strtolower($Value))return true;
}
return false;
}
/**
* packages must be validated within the submappings of a filesystem structure
*
* @param parentmapping instance of parsed xml file, current mapping position
* @param url relative path for application specifying the current path within the mapping tree
* @return array with errors found, optional empty when no errors were found
*/
private function CheckSubmappings($ParentMapping, $Url)
{
global $lng;
$Error = array();
//check for special PHP handler extensions
$XmlPhpMapping = $ParentMapping->children('http://apstandard.com/ns/1/php');
foreach($XmlPhpMapping->handler as $Handler)
{
if(isset($Handler->extension[0])
&& strval($Handler->extension[0]) != 'php')
{
$Error[] = $lng['aps']['php_misc_handler'];
}
if(isset($Handler->disabled))
{
$Error[] = $lng['aps']['php_misc_directoryhandler'];
}
}
//check for special ASP.NET url handler within mappings
$XmlAspMapping = $ParentMapping->children('http://apstandard.com/ns/1/aspnet');
if($XmlAspMapping->handler)
{
$Error[] = $lng['aps']['asp_net'];
}
//check for special CGI url handlers within mappings
$XmlCgiMapping = $ParentMapping->children('http://apstandard.com/ns/1/cgi');
if($XmlCgiMapping->handler)
{
$Error[] = $lng['aps']['cgi'];
}
//resolve deeper mappings
foreach($ParentMapping->mapping as $Mapping)
{
$Return = array();
//recursive check of other mappings
if($Url == '/')
{
$Return = self::CheckSubmappings($Mapping, $Url . $Mapping['url']);
}
else
{
$Return = self::CheckSubmappings($Mapping, $Url . '/' . $Mapping['url']);
}
//if recursive checks found errors, attach them
if(count($Return) != 0)
{
foreach($Return as $Value)
{
if(!in_array($Value, $Error))$Error[] = $Value;
}
}
}
return $Error;
}
/**
* function validates a package against a lot of options and installs it if all conditions have succeeded
*
* @param filename path to zipfile to install
*/
private function InstallNewPackage($Filename)
{
global $lng;
if(file_exists($Filename)
&& $Xml = self::GetXmlFromZip($Filename))
{
$Error = array();
//check alot of stuff if package is supported
//php modules
$XmlPhp = $Xml->requirements->children('http://apstandard.com/ns/1/php');
if($XmlPhp->extension)
{
$ExtensionsLoaded = get_loaded_extensions();
foreach($XmlPhp->extension as $Extension)
{
if(!in_array($Extension, $ExtensionsLoaded)
&& !self::CheckException('php', 'extension', $Extension))
{
$Error[] = sprintf($lng['aps']['php_extension'], $Extension);
}
}
}
//php functions
if($XmlPhp->function)
{
foreach($XmlPhp->function as $Function)
{
if(!function_exists($Function)
&& !self::CheckException('php', 'function', $Function))
{
$Error[] = sprintf($lng['aps']['php_function'], $Function);
}
}
}
//php values
$PhpValues = array(
'short-open-tag',
'file-uploads',
'magic-quotes-gpc',
'register-globals',
'allow-url-fopen',
'safe-mode'
);
foreach($PhpValues as $Value)
{
if($XmlPhp->{$Value})
{
if(self::TrueFalseIniGet($Value) != $XmlPhp->{$Value}
&& !self::CheckException('php', 'configuration', str_replace(array('-'), array('_'), $Value)))
{
$Error[] = sprintf($lng['aps']['php_configuration'], str_replace(array('-'), array('_'), $Value));
}
}
}
if($XmlPhp->{'post-max-size'})
{
if(self::PhpMemorySizeToBytes(ini_get('post_max_size')) < intval($XmlPhp->{'post-max-size'})
&& !self::CheckException('php', 'configuration', 'post_max_size'))
{
$Error[] = $lng['aps']['php_configuration_post_max_size'];
}
}
if($XmlPhp->{'memory-limit'})
{
if(self::PhpMemorySizeToBytes(ini_get('memory_limit')) < intval($XmlPhp->{'memory-limit'})
&& !self::CheckException('php', 'configuration', 'memory_limit'))
{
$Error[] = $lng['aps']['php_configuration_memory_limit'];
}
}
if($XmlPhp->{'max-execution-time'})
{
if(ini_get('max_execution_time') < intval($XmlPhp->{'max-execution-time'})
&& !self::CheckException('php', 'configuration', 'max_execution_time'))
{
$Error[] = $lng['aps']['php_configuration_max_execution_time'];
}
}
//php version
//must be done with xpath otherwise check not possible (XML parser problem with attributes)
$Xml->registerXPathNamespace('phpversion', 'http://apstandard.com/ns/1/php');
$Result = $Xml->xpath('//phpversion:version');
if(isset($Result[0]['min']))
{
if(version_compare($Result[0]['min'], PHP_VERSION) == 1)
{
$Error[] = $lng['aps']['php_general_old'];
}
}
if(isset($Result[0]['max-not-including']))
{
if(version_compare($Result[0]['max-not-including'], PHP_VERSION) == - 1)
{
$Error[] = $lng['aps']['php_general_new'];
}
}
//database
$XmlDb = $Xml->requirements->children('http://apstandard.com/ns/1/db');
if($XmlDb->db->id)
{
if($XmlDb->db->{'server-type'} != 'mysql')
{
$Error[] = $lng['aps']['db_mysql_support'];
}
if(version_compare($XmlDb->db->{'server-min-version'}, mysql_get_server_info()) == 1)
{
$Error[] = $lng['aps']['db_mysql_version'];
}
}
//ASP.NET
$XmlAsp = $Xml->requirements->children('http://apstandard.com/ns/1/aspnet');
if($XmlAsp->handler
|| $XmlAsp->permissions
|| $XmlAsp->version)
{
$Error[] = $lng['aps']['asp_net'];
}
//CGI
$XmlCgi = $Xml->requirements->children('http://apstandard.com/ns/1/cgi');
if($XmlCgi->handler)
{
$Error[] = $lng['aps']['cgi'];
}
//webserver modules
$XmlWebserver = $Xml->requirements->children('http://apstandard.com/ns/1/apache');
if($XmlWebserver->{'required-module'})
{
if(function_exists('apache_get_modules'))
{
$ModulesLoaded = apache_get_modules();
foreach($XmlWebserver->{'required-module'} as $Module)
{
if(!in_array($Module, $ModulesLoaded)
&& !self::CheckException('webserver', 'module', $Module))
{
$Error[] = sprintf($lng['aps']['webserver_module'], $Module);
}
}
}
else
{
if(!self::CheckException('webserver', 'module', 'fcgid-any'))$Error[] = $lng['aps']['webserver_fcgid'];
}
}
//webserver .htaccess
if($XmlWebserver->htaccess
&& !self::CheckException('webserver', 'htaccess', 'htaccess'))
{
$Error[] = $lng['aps']['webserver_htaccess'];
}
//configuration script check
if($Xml->{'configuration-script-language'}
&& $Xml->{'configuration-script-language'} != 'php')
{
$Error[] = $lng['aps']['misc_configscript'];
}
//validation against a charset not possible in current version
foreach($Xml->settings->group as $Group)
{
foreach($Group->setting as $Setting)
{
if($Setting['type'] == 'string'
|| $Setting['type'] == 'password')
{
if(isset($Setting['charset']))
{
if(!in_array($lng['aps']['misc_charset'], $Error))$Error[] = $lng['aps']['misc_charset'];
}
}
}
}
//check different errors/features in submappings
$Return = self::CheckSubmappings($Xml->mapping, $Xml->mapping['url']);
if(count($Return) != 0)
{
foreach($Return as $Value)
{
if(!in_array($Value, $Error))$Error[] = $Value;
}
}
//check already installed versions
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Name` = "' . $this->db->escape($Xml->name) . '"');
$Newer = 0;
if($this->db->num_rows($result) > 0)
{
while($Row = $this->db->fetch_array($result))
{
//package is newer, install package as a update
if(version_compare($Row['Version'] . '-' . $Row['Release'], $Xml->version . '-' . $Xml->release) == - 1)
{
$Newer = 1;
}
//package is installed already with same version, cancel installation
if(version_compare($Row['Version'] . '-' . $Row['Release'], $Xml->version . '-' . $Xml->release) == 0)
{
$Error[] = $lng['aps']['misc_version_already_installed'];
break;
}
//package is older than the one which is installed already, cancel installation
if(version_compare($Row['Version'] . '-' . $Row['Release'], $Xml->version . '-' . $Xml->release) == 1)
{
$Error[] = $lng['aps']['misc_only_newer_versions'];
break;
}
}
}
if(count($Error) > 0)
{
//show errors
$Output = '';
foreach($Error as $Entry)
{
$Output.= '<li>' . $Entry . '</li>';
}
self::InfoBox(sprintf($lng['aps']['erroronscan'], $Xml->name, $Output));
return false;
}
else
{
//install package in system, all checks succeeded
$Destination = './packages/' . basename($Filename) . '/';
//create package directory
if(!file_exists($Destination))mkdir($Destination, 0777, true);
//copy xml meta data
self::GetContentFromZip($Filename, 'APP-META.xml', $Destination . 'APP-META.xml');
//copy screenshots
if($Xml->screenshot)
{
foreach($Xml->screenshot as $Screenshot)
{
self::GetContentFromZip($Filename, $Screenshot['path'], $Destination . basename($Screenshot['path']));
}
}
//copy icon
if($Xml->icon['path'])
{
self::GetContentFromZip($Filename, $Xml->icon['path'], $Destination . basename($Xml->icon['path']));
}
//copy license
if($Xml->license
&& $Xml->license->text->file)
{
self::GetContentFromZip($Filename, $Xml->license->text->file, $Destination . 'license.txt');
}
//insert package to database
$this->db->query('INSERT INTO `' . TABLE_APS_PACKAGES . '` (`Path`, `Name`, `Version`, `Release`, `Status`) VALUES ("' . $this->db->escape(basename($Filename)) . '", "' . $this->db->escape($Xml->name) . '", "' . $this->db->escape($Xml->version) . '", ' . $this->db->escape($Xml->release) . ', ' . PACKAGE_LOCKED . ')');
//copy zipfile do destination
copy($Filename, $Destination . basename($Filename));
unlink($Filename);
//show some feedback messages to admin
if($Newer == 1)
{
self::InfoBox(sprintf($lng['aps']['successpackageupdate'], $Xml->name));
}
else
{
self::InfoBox(sprintf($lng['aps']['successpackageinstall'], $Xml->name));
}
unset($Xml);
return true;
}
}
else
{
//file cannot be unzipped or parse of xml data has failed
self::InfoBox(sprintf($lng['aps']['invalidzipfile'], basename($Filename)));
return false;
}
}
/**
* main function of the class, provides all of the aps installer frontend
*/
public function MainHandler($Action)
{
global $lng, $filename, $s, $page, $action, $Id;
//check for basic functions, classes and permissions
$Error = '';
if(!class_exists('SimpleXMLElement')
|| !function_exists('zip_open'))
{
$Error.= '<li>' . $lng['aps']['class_zip_missing'] . '</li>';
}
if(!is_writable($this->RootDir.'temp/')
|| !is_writable($this->RootDir.'packages/'))
{
$dirpermission = str_replace('{$path}', $this->RootDir, $lng['aps']['dir_permissions']);
$Error.= '<li>' . $dirpermission . '</li>';
}
if($Error != '')
{
//show different error to customer and admin
if(!isset($this->userinfo['customerid']))
{
self::InfoBox(sprintf($lng['aps']['initerror'], $Error));
}
else
{
self::InfoBox($lng['aps']['initerror_customer']);
}
return;
}
if(isset($this->userinfo['customerid']))
{
$CustomerId = $this->userinfo['customerid'];
}
else
{
$CustomerId = -1;
}
$AdminId = $this->userinfo['adminid'];
$PackagesPerSite = $this->settings['aps']['items_per_page'];
//run different functions based on action
if($Action == 'install')
{
//check for valid package id
if(self::IsValidPackageId($Id, true))
{
//installation data is given
if(isset($_POST['withinput']))
{
$Errors = self::ValidatePackageData($Id, $CustomerId);
//if there are no input errors, create a new instance
if(count($Errors) == 0)
{
self::CreatePackageInstance($Id, $CustomerId);
}
else
{
self::ShowPackageInstaller($Id, $Errors, $CustomerId);
}
}
else
{
//empty array -> no errors will be shown to customer
$Errors = array();
self::ShowPackageInstaller($Id, $Errors, $CustomerId);
}
}
else
{
self::InfoBox($lng['aps']['iderror']);
}
}
elseif($Action == 'remove')
{
//check for valid instance id
if(self::IsValidInstanceId($Id, $CustomerId))
{
//customer has clicked yes to uninstall a package
if(isset($_POST['answer'])
&& $_POST['answer'] == $lng['panel']['yes'])
{
//check if there is already an task
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_TASKS . '` WHERE `InstanceID` = ' . $this->db->escape($Id) . ' AND `Task` = ' . TASK_REMOVE);
if($this->db->num_rows($result) > 0)
{
self::InfoBox($lng['aps']['removetaskexisting']);
}
else
{
//remove package, no task existing
$this->db->query('INSERT INTO `' . TABLE_APS_TASKS . '` (`InstanceID`, `Task`) VALUES (' . (int)$Id . ', ' . TASK_REMOVE . ')');
$this->db->query('UPDATE `' . TABLE_APS_INSTANCES . '` SET `Status` = ' . INSTANCE_UNINSTALL . ' WHERE `ID` = ' . (int)$Id);
$this->db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `aps_packages_used` = `aps_packages_used` - 1 WHERE `customerid` = ' . (int)$CustomerId);
self::InfoBox($lng['aps']['packagewillberemoved']);
}
}
else
{
//show yes/no question
$Message = $lng['question']['reallywanttoremove'];
$action_alt = 'customerstatus';
$Ids = '<input type="hidden" name="id" value="' . (int)$Id . '"/>';
eval("echo \"" . getTemplate("aps/askyesno") . "\";");
}
}
else
{
self::InfoBox($lng['aps']['iderror']);
}
}
elseif($Action == 'stopinstall')
{
//check for valid instance id
if(self::IsValidInstanceId($Id, $CustomerId))
{
//check if application installation runs already
$Result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `ID` = ' . $this->db->escape($Id));
$Row = $this->db->fetch_array($Result);
if($Row['Status'] == INSTANCE_TASK_ACTIVE)
{
self::InfoBox($lng['aps']['installstoperror']);
}
else
{
if(isset($_POST['answer'])
&& $_POST['answer'] == $lng['panel']['yes'])
{
//remove task
$this->db->query('DELETE FROM `' . TABLE_APS_TASKS . '` WHERE `InstanceID` = ' . $this->db->escape($Id));
//remove settings
$this->db->query('DELETE FROM `' . TABLE_APS_SETTINGS . '` WHERE `InstanceID` = ' . $this->db->escape($Id));
//remove instance
$this->db->query('DELETE FROM `' . TABLE_APS_INSTANCES . '` WHERE `ID` = ' . $this->db->escape($Id));
//update used counter
$this->db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `aps_packages_used` = `aps_packages_used` - 1 WHERE `customerid` = ' . (int)$CustomerId);
self::InfoBox($lng['aps']['installstopped']);
}
else
{
//show yes/no question
$Message = $lng['question']['reallywanttostop'];
$action_alt = 'customerstatus';
$Ids = '<input type="hidden" name="id" value="' . (int)$Id . '"/>';
eval("echo \"" . getTemplate("aps/askyesno") . "\";");
}
}
}
else
{
self::InfoBox($lng['aps']['iderror']);
}
}
elseif($Action == 'reconfigure')
{
//check for valid instance id
if(self::IsValidInstanceId($Id, $CustomerId))
{
self::InfoBox('Reconfigure function not implemented in current version!');
}
else
{
self::InfoBox($lng['aps']['iderror']);
}
}
elseif($Action == 'details')
{
//show advanced package infos if package id is valid
if(self::IsValidPackageId($Id, true))
{
self::ShowPackageInfo($Id, true);
}
else
{
self::InfoBox($lng['aps']['iderror']);
}
}
elseif($Action == 'scan'
&& !isset($this->userinfo['customerid']))
{
//find all files in temp directory
$Files = scandir('./temp/');
$Counter = 0;
foreach($Files as $File)
{
//skip invalid "files"
if(substr($File, -4) != '.zip')continue;
//install new package in system
self::InstallNewPackage('./temp/' . $File);
$Counter+= 1;
}
if($Counter == 0)
{
//throw error if no file was found
self::InfoBox($lng['aps']['nopacketsforinstallation']);
}
}
elseif($Action == 'manageinstances'
&& !isset($this->userinfo['customerid']))
{
self::ManageInstances();
}
elseif($Action == 'managepackages'
&& !isset($this->userinfo['customerid']))
{
self::ManagePackages();
}
elseif($Action == 'upload'
&& !isset($this->userinfo['customerid']))
{
self::UploadNewPackages();
}
elseif($Action == 'customerstatus')
{
self::CustomerStatus($CustomerId);
}
elseif($Action == 'search')
{
self::SearchPackages();
}
elseif($Action == 'overview')
{
// show packages with paging
if(isset($_GET['page'])
&& preg_match('/^[0-9]+$/', $_GET['page']) != - 1)
{
//check if page parameter is valid
//get all packages to find out how many pages are needed
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' ORDER BY `Name` ASC');
$Pages = intval($this->db->num_rows($result) / $PackagesPerSite);
if(($this->db->num_rows($result) / $PackagesPerSite) > $Pages)$Pages+= 1;
if($_GET['page'] >= 1
&& $_GET['page'] <= $Pages)
{
//page parameter is within available pages, now show packages for that given page
$result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' ORDER BY `Name` ASC LIMIT ' . $this->db->escape((intval($_GET['page']) - 1) * $PackagesPerSite) . ', ' . $this->db->escape($PackagesPerSite));
//show packages
while($Row3 = $this->db->fetch_array($result2))
{
self::ShowPackageInfo($Row3['ID']);
}
//show URLs for other pages
if($Pages > 1)
{
echo ('<div style="width: 90%; text-align: center;"><br/>');
for ($i = 1;$i < $Pages + 1;$i++)
{
if($i == $_GET['page'])
{
echo ('<span class="pageitem">' . $i . '</span>');
}
else
{
echo ('<span class="pageitem"><a href="' . $filename . '?s=' . $s . '&amp;action=overview&amp;page=' . $i . '">' . $i . '</a></span>');
}
}
echo ('</div><br/><br/>');
}
}
else
{
//page parameter isnt within available pages, show packages from first page
$result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' ORDER BY `Name` ASC LIMIT 0, ' . $this->db->escape($PackagesPerSite));
//show packages
while($Row3 = $this->db->fetch_array($result2))
{
self::ShowPackageInfo($Row3['ID']);
}
//fetch number of packages to calculate the number of pages
$result3 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' ORDER BY `Name` ASC');
$Pages = intval($this->db->num_rows($result3) / $PackagesPerSite);
if(($this->db->num_rows($result3) / $PackagesPerSite) > $Pages)$Pages+= 1;
//show URLs for other pages
if($Pages > 1)
{
echo ('<div style="width: 90%; text-align: center;"><br/>');
for ($i = 1;$i < $Pages + 1;$i++)
{
echo ('<span class="pageitem"><a href="' . $filename . '?s=' . $s . '&amp;action=overview&amp;page=' . $i . '">' . $i . '</a></span>');
}
echo ('</div>');
}
}
}
else
{
//page parameter isnt valid, show packages from first page
$result2 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' ORDER BY `Name` ASC LIMIT 0, ' . $this->db->escape($PackagesPerSite));
if($this->db->num_rows($result2) == 0)
{
self::InfoBox($lng['aps']['nopackagestoinstall']);
return;
}
//show packages
while($Row3 = $this->db->fetch_array($result2))
{
self::ShowPackageInfo($Row3['ID']);
}
//fetch number of packages to calculate number of pages
$result3 = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' ORDER BY `Name` ASC');
$Pages = intval($this->db->num_rows($result3) / $PackagesPerSite);
if(($this->db->num_rows($result3) / $PackagesPerSite) > $Pages)$Pages+= 1;
//show URLs for other pages
if($Pages > 1)
{
echo ('<div style="width: 90%; text-align: center;"><br/>');
for ($i = 1;$i < $Pages + 1;$i++)
{
if($i == 1)
{
echo ('<span class="pageitem">' . $i . '</span>');
}
else
{
echo ('<span class="pageitem"><a href="' . $filename . '?s=' . $s . '&amp;action=overview&amp;page=' . $i . '">' . $i . '</a></span>');
}
}
echo ('</div><br/><br/>');
}
}
}
}
/**
* function extracts resources from a zipfile to return or save them on disk
*
* @param filename zipfile to read data from
* @param file file within zip archive to read
* @param destination optional parameter where to save file from within the zip file
* @return success content of file from zip archive / error false
*/
private function GetContentFromZip($Filename, $File, $Destination = '')
{
if(!file_exists($Filename))return false;
$Content = '';
//now using the new ZipArchive class from php 5.2
$Zip = new ZipArchive;
$Resource = $Zip->open(realpath($Filename));
if($Resource === true)
{
$FileHandle = $Zip->getStream($File);
if(!$FileHandle)return false;
while(!feof($FileHandle))
{
$Content.= fread($FileHandle, 8192);
}
fclose($FileHandle);
$Zip->close();
}
else
{
//on 64 bit systems the zip functions can fail -> use safe_exec to extract the files
$ReturnLines = array();
$ReturnVal = - 1;
$ReturnLines = safe_exec('unzip -o -j -qq ' . escapeshellarg(realpath($Filename)) . ' ' . escapeshellarg($File) . ' -d ' . escapeshellarg(sys_get_temp_dir() . '/'), $ReturnVal);
if($ReturnVal == 0)
{
$Content = file_get_contents(sys_get_temp_dir() . '/' . basename($File));
unlink(sys_get_temp_dir() . '/' . basename($File));
if($Content == false)return false;
}
else
{
return false;
}
}
//return content of file from within the zipfile or save to disk
if($Content == '')
{
return false;
}
else
{
if($Destination == '')
{
return $Content;
}
else
{
//open file and save content
$File = fopen($Destination, "wb");
if($File)
{
fwrite($File, $Content);
fclose($File);
}
else
{
return false;
}
}
}
}
/**
* fetches the xml metafile from a zipfile and returns the parsed data
*
* @param filename zipfile containing the xml meta data
* @return success parsed xml content of zipfile / error false
*/
private function GetXmlFromZip($Filename)
{
if(!file_exists($Filename))return false;
//get content for xml meta data file from within the zipfile
if($XmlContent = self::GetContentFromZip($Filename, 'APP-META.xml'))
{
//parse xml content
$Xml = new SimpleXMLElement($XmlContent);
return $Xml;
}
else
{
return false;
}
}
/**
* reads the content of a xml metafile from disk and returns the parsed data
*
* @param filename xmlfile to parse
* @return success parsed xml content of file / error false
*/
private function GetXmlFromFile($Filename)
{
//read xml file from disk and return parsed data
if(!file_exists($Filename))return false;
$XmlContent = file_get_contents($Filename);
$Xml = new SimpleXMLElement($XmlContent);
return $Xml;
}
/**
* check whether a given package id is valid
*
* @param packageid id of package from database to check vor validity
* @param customer check if package can be used by customer and/or admin [true|false]
* @return success valid package id (id > 0 based on database layout) / error false
*/
private function IsValidPackageId($PackageId, $Customer)
{
if(preg_match('/^[0-9]+$/', $PackageId) != 1)return false;
if($Customer == true)
{
//customers can only see packages which are enabled
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `Status` = ' . PACKAGE_ENABLED . ' AND `ID` = ' . $this->db->escape($PackageId));
if($this->db->num_rows($result) > 0)
{
return $PackageId;
}
else
{
return false;
}
}
else
{
//admins can see all packages
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $this->db->escape($PackageId));
if($this->db->num_rows($result) > 0)
{
return $PackageId;
}
else
{
return false;
}
}
}
/**
* check whether a given instance id is valid
*
* @param packageid id of instance from database to check vor validity
* @return success valid instance id (id > 0 based on database layout) / error false
*/
private function IsValidInstanceId($InstanceId, $CustomerId)
{
if(preg_match('/^[0-9]+$/', $InstanceId) != 1)return false;
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId) . ' AND `ID` = ' . $this->db->escape($InstanceId));
if($this->db->num_rows($result) > 0)
{
return $InstanceId;
}
else
{
return false;
}
}
/**
* save installation values fetched from the installation wizard
*
* @param packageid id of package from database
* @param customerid id of customer for who the values should be saved
* @param name name of field to save
* @param value value to save for previously given name
*/
private function SetInstallationValue($PackageId, $CustomerId, $Name, $Value)
{
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_TEMP_SETTINGS . '` WHERE `PackageID` = ' . $this->db->escape($PackageId) . ' AND `CustomerID` = ' . $this->db->escape($CustomerId) . ' AND `Name` = "' . $this->db->escape($Name) . '"');
if($this->db->num_rows($result) == 0)
{
$this->db->query('INSERT INTO `' . TABLE_APS_TEMP_SETTINGS . '` (`PackageID`, `CustomerID`, `Name`, `Value`) VALUES (' . $this->db->escape($PackageId) . ', ' . $this->db->escape($CustomerId) . ', "' . $this->db->escape($Name) . '", "' . $this->db->escape($Value) . '")');
}
else
{
$Row = $this->db->fetch_array($result);
$this->db->query('UPDATE `' . TABLE_APS_TEMP_SETTINGS . '` SET `PackageID` = ' . $this->db->escape($PackageId) . ', `CustomerID` = ' . $this->db->escape($CustomerId) . ', `Name` = "' . $this->db->escape($Name) . '", `Value` ="' . $this->db->escape($Value) . '" WHERE `ID` = ' . $this->db->escape($Row['ID']));
}
}
/**
* return previously saved installation values
*
* @param packageid id of package from database
* @param customerid id of customer for who the values should be read
* @param name name of field to read
* @return success value of field from database / error false
*/
private function GetInstallationValue($PackageId, $CustomerId, $Name)
{
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_TEMP_SETTINGS . '` WHERE `PackageID` = ' . $this->db->escape($PackageId) . ' AND `CustomerID` = ' . $this->db->escape($CustomerId) . ' AND `Name` = "' . $this->db->escape($Name) . '"');
if($this->db->num_rows($result) == 0)
{
return false;
}
else
{
$Row = $this->db->fetch_array($result);
return $Row['Value'];
}
}
/**
* fix a path given by the customer
*
* @param path path which could be compromised
* @return corrected path
*/
private function MakeSecurePath($path)
{
//code based on syscp core code
$search = Array(
'#/+#',
'#\.+#',
'#\0+#',
'#\\\\+#'
);
$replace = Array(
'/',
'',
'',
'/'
);
$path = preg_replace($search, $replace, $path);
//no / at the end
if(substr($path, strlen($path) - 1, 1) == '/')$path = substr($path, 0, strlen($path) - 1);
//no / at beginning
if(substr($path, 0, 1) == '/')$path = substr($path, 1);
return $path;
}
/**
* validate the input of a customer against the xml meta descriptions
*
* @param packageid id of package from database
* @param customerid id of customer from database
* @return success/error array of errors found containing fields that were wrong
*/
private function ValidatePackageData($PackageId, $CustomerId)
{
if(!self::IsValidPackageId($PackageId, true))return false;
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $this->db->escape($PackageId));
$Row = $this->db->fetch_array($result);
$Xml = self::GetXmlFromFile('./packages/' . $Row['Path'] . '/APP-META.xml');
//return if parse of xml file has failed
if($Xml == false)return false;
//check all data fields of xml file against inut of customer
$Error = array();
foreach($Xml->settings->group as $Group)
{
foreach($Group->setting as $Setting)
{
$FieldId = strval($Setting['id']);
if($Setting['type'] == 'string'
|| $Setting['type'] == 'password')
{
if(isset($_POST[$FieldId]))
{
if(isset($Setting['min-length'])
&& strlen($_POST[$FieldId]) < $Setting['min-length'])
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(isset($Setting['max-length'])
&& strlen($_POST[$FieldId]) > $Setting['max-length'])
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(isset($Setting['regex'])
&& !preg_match("/" . $Setting['regex'] . "/", $_POST[$FieldId]))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
/*
elseif(isset($Setting['charset']))
{
//CHARSET VALIDATION FOR LATER VERSIONS
}
*/
if(!in_array($FieldId, $Error))self::SetInstallationValue($PackageId, $CustomerId, $FieldId, $_POST[$FieldId]);
}
else
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
}
else
if($Setting['type'] == 'email')
{
if(isset($_POST[$FieldId]))
{
if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/", $_POST[$FieldId]))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(!in_array($FieldId, $Error))self::SetInstallationValue($PackageId, $CustomerId, $FieldId, $_POST[$FieldId]);
}
else
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
}
elseif($Setting['type'] == 'domain-name')
{
if(isset($_POST[$FieldId]))
{
if(!preg_match("^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$", $_POST[$FieldId]))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(!in_array($FieldId, $Error))self::SetInstallationValue($PackageId, $CustomerId, $FieldId, $_POST[$FieldId]);
}
else
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
}
elseif($Setting['type'] == 'integer')
{
if(isset($_POST[$FieldId]))
{
//check if number is in the format of float
if(round($_POST[$FieldId]) != $_POST[$FieldId])
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(!is_numeric($_POST[$FieldId]))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(isset($Setting['min'])
&& intval($_POST[$FieldId]) < intval($Setting['min']))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(isset($Setting['max'])
&& intval($_POST[$FieldId]) > intval($Setting['max']))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(!in_array($FieldId, $Error))self::SetInstallationValue($PackageId, $CustomerId, $FieldId, intval($_POST[$FieldId]));
}
else
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
}
elseif($Setting['type'] == 'float')
{
if(isset($_POST[$FieldId]))
{
if(!is_numeric($_POST[$FieldId]))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(isset($Setting['min'])
&& floatval($_POST[$FieldId]) < floatval($Setting['min']))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(isset($Setting['max'])
&& floatval($_POST[$FieldId]) > floatval($Setting['max']))
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
if(!in_array($FieldId, $Error))self::SetInstallationValue($PackageId, $CustomerId, $FieldId, floatval($_POST[$FieldId]));
}
else
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
}
elseif($Setting['type'] == 'boolean')
{
if(isset($_POST[$FieldId])
&& $_POST[$FieldId] == 'true')
{
self::SetInstallationValue($PackageId, $CustomerId, $FieldId, 'true');
}
else
{
self::SetInstallationValue($PackageId, $CustomerId, $FieldId, 'false');
}
}
elseif($Setting['type'] == 'enum')
{
if(isset($_POST[$FieldId]))
{
foreach($Setting->choice as $Choice)
{
if($Choice['id'] == $_POST[$FieldId])
{
self::SetInstallationValue($PackageId, $CustomerId, $FieldId, $_POST[$FieldId]);
break;
}
}
}
else
{
if(!in_array($FieldId, $Error))$Error[] = $FieldId;
}
}
}
}
//database required?
$XmlDb = $Xml->requirements->children('http://apstandard.com/ns/1/db');
if($XmlDb->db->id)
{
if(isset($_POST['main_database_password']))
{
if(strlen($_POST['main_database_password']) < 8)
{
if(!in_array('main_database_password', $Error))$Error[] = 'main_database_password';
}
if(!in_array('main_database_password', $Error))self::SetInstallationValue($PackageId, $CustomerId, 'main_database_password', $_POST['main_database_password']);
}
else
{
if(!in_array('main_database_password', $Error))$Error[] = 'main_database_password';
}
}
//application location
if(isset($_POST['main_domain']))
{
$result2 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `customerid` = ' . $this->db->escape($CustomerId) . ' AND `id` = ' . $this->db->escape($_POST['main_domain']));
if($this->db->num_rows($result2) > 0)
{
self::SetInstallationValue($PackageId, $CustomerId, 'main_domain', $_POST['main_domain']);
}
else
{
self::SetInstallationValue($PackageId, $CustomerId, 'main_domain', '-1');
if(!in_array('main_domain', $Error))$Error[] = 'main_domain';
}
}
else
{
self::SetInstallationValue($PackageId, $CustomerId, 'main_domain', '-1');
if(!in_array('main_domain', $Error))$Error[] = 'main_domain';
}
if(isset($_POST['main_location']))
{
$Temp = $_POST['main_location'];
//call function twice for security reasons!
$Temp = self::MakeSecurePath($Temp);
$Temp = self::MakeSecurePath($Temp);
//previous instance check
$InstallPath = '';
//find real path for selected domain
$result3 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `customerid` = ' . $this->db->escape($CustomerId) . ' AND `id` = ' . $this->db->escape(self::GetInstallationValue($PackageId, $CustomerId, 'main_domain')));
if($this->db->num_rows($result3) > 0)
{
//build real path
$Row = $this->db->fetch_array($result3);
$InstallPath = $Row['documentroot'];
$InstallPath.= $Temp;
$result4 = $this->db->query('SELECT * FROM `' . TABLE_APS_INSTANCES . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId));
//get all instances from current customer
//thats needed because there cannot be installed two apps within the same directory
while($Row3 = $this->db->fetch_array($result4))
{
//get all domains linked to instances
$result5 = $this->db->query('SELECT * FROM `' . TABLE_APS_SETTINGS . '` WHERE `InstanceID` = ' . $this->db->escape($Row3['ID']) . ' AND `Name` = "main_domain"');
if($this->db->num_rows($result5) > 0)
{
$Row2 = $this->db->fetch_array($result5);
$Reserved = '';
//get real domain path
$result6 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `customerid` = ' . $this->db->escape($CustomerId) . ' AND `id` = ' . $this->db->escape($Row2['Value']));
if($this->db->num_rows($result6) > 0)
{
$Row = $this->db->fetch_array($result6);
$Reserved = $Row['documentroot'];
}
//get location under domain
$result7 = $this->db->query('SELECT * FROM `' . TABLE_APS_SETTINGS . '` WHERE `InstanceID` = ' . $this->db->escape($Row3['ID']) . ' AND `Name` = "main_location"');
if($this->db->num_rows($result7) > 0)
{
$Row = $this->db->fetch_array($result7);
$Reserved.= $Row['Value'];
}
//check whether there is another app installed already
if($Reserved == $InstallPath)
{
if(!in_array('main_location', $Error))$Error[] = 'main_location';
break;
}
}
}
}
if(!in_array('main_location', $Error))self::SetInstallationValue($PackageId, $CustomerId, 'main_location', $Temp);
}
else
{
if(!in_array('main_location', $Error))$Error[] = 'main_location';
self::SetInstallationValue($PackageId, $CustomerId, 'main_location', '');
}
if($Xml->license)
{
if($Xml->license['must-accept']
&& $Xml->license['must-accept'] == 'true')
{
if(isset($_POST['license'])
&& $_POST['license'] == 'true')
{
self::SetInstallationValue($PackageId, $CustomerId, 'license', 'true');
}
else
{
self::SetInstallationValue($PackageId, $CustomerId, 'license', 'false');
if(!in_array('license', $Error))$Error[] = 'license';
}
}
}
unset($Xml);
return $Error;
}
/**
* functions provides the frontend of the installation wizard for the customer
*
* @param packageid id of package from database
* @param wrongdata array of fields that were wrong in previous validation check
* @return error false / success none
*/
private function ShowPackageInstaller($PackageId, $WrongData, $CustomerId)
{
global $lng, $filename, $s, $page, $action;
$Data = '';
$Fieldname = '';
$Fieldvalue = '';
$Groupname = '';
if(!self::IsValidPackageId($PackageId, true))return false;
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $this->db->escape($PackageId));
$Row = $this->db->fetch_array($result);
$Xml = self::GetXmlFromFile('./packages/' . $Row['Path'] . '/APP-META.xml');
//return if parse of xml file has failed
if($Xml == false)return false;
//show notifcation if customer has reached his installation limit
if($this->userinfo['aps_packages'] != '-1'
&& (int)$this->userinfo['aps_packages_used'] >= (int)$this->userinfo['aps_packages'])
{
self::InfoBox($lng['aps']['allpackagesused']);
return false;
}
//icon for package
$Icon = './images/default.png';
if($Xml->icon['path'])
{
$Icon = './packages/' . $Row['Path'] . '/' . basename($Xml->icon['path']);
}
//show error message if some input was wrong
$ErrorMessage = 0;
if(count($WrongData) != 0)
{
$ErrorMessage = 1;
}
//remove previously entered values if new installation has been triggered
if(!isset($_POST['withinput']))
{
$this->db->query('DELETE FROM `' . TABLE_APS_TEMP_SETTINGS . '` WHERE `CustomerID` = ' . $this->db->escape($CustomerId) . ' AND `PackageID` = ' . $this->db->escape($PackageId));
}
//where to install app?
$Temp = 'http://<select size="1" name="main_domain">';
$Value = self::GetInstallationValue($PackageId, $CustomerId, 'main_domain');
$result2 = $this->db->query('SELECT * FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `customerid` = ' . $this->db->escape($CustomerId));
//if customer has no domains, app cannot be installed
//FIXME function for html code
if($this->db->num_rows($result2) > 0)
{
while($Row3 = $this->db->fetch_array($result2))
{
if($Value)
{
if($Row3['ID'] == $Value)
{
$Temp.= '<option selected="selected" value="' . $Row3['id'] . '">' . $Row3['domain'] . '</option>';
}
else
{
$Temp.= '<option value="' . $Row3['id'] . '">' . $Row3['domain'] . '</option>';
}
}
else
{
$Temp.= '<option value="' . $Row3['id'] . '">' . $Row3['domain'] . '</option>';
}
}
}
else
{
$Temp.= '<option value="-1">' . $lng['aps']['no_domains'] . '</option>';
}
$Temp.= '</select>';
$Value = self::GetInstallationValue($PackageId, $CustomerId, 'main_location');
if($Value)
{
$Temp.= '/<input type="text" name="main_location" value="' . $Value . '"/>';
}
else
{
$Temp.= '/<input type="text" name="main_location" value=""/>';
}
if(in_array('main_domain', $WrongData))
{
$Temp.= self::FieldError($lng['aps']['nodomains']);
}
if(in_array('main_location', $WrongData))
{
$Temp.= self::FieldError($lng['aps']['wrongpath']);
}
if(!in_array('main_location', $WrongData)
&& !in_array('main_domain', $WrongData))$Temp.= '<br/>';
$Temp.= '<em>' . $lng['aps']['application_location_description'] . '</em>';
$Groupname = $lng['aps']['basic_settings'];
$Fieldname = $lng['aps']['application_location'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
//database required?
$XmlDb = $Xml->requirements->children('http://apstandard.com/ns/1/db');
if($XmlDb->db->id)
{
$Temp = '<input type="password" name="main_database_password" />';
if(in_array('main_database_password', $WrongData))
{
$Temp.= self::FieldError($lng['aps']['dbpassword']);
}
if(!in_array('main_database_password', $WrongData))$Temp.= '<br/>';
$Temp.= '<em>' . $lng['aps']['database_password_description'] . '</em>';
$Groupname = '';
$Fieldname = $lng['aps']['database_password'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
foreach($Xml->settings->group as $Group)
{
$GroupPrinted = false;
foreach($Group->setting as $Setting)
{
$Temp = '';
if($Setting['type'] == 'string'
|| $Setting['type'] == 'email'
|| $Setting['type'] == 'integer'
|| $Setting['type'] == 'float'
|| $Setting['type'] == 'domain-name')
{
if(!$GroupPrinted)
{
$Groupname = $Group->name;
$GroupPrinted = true;
}
else
{
$Groupname = '';
}
$Value = self::GetInstallationValue($PackageId, $CustomerId, strval($Setting['id']));
if($Value)
{
$Temp.= '<input type="text" name="' . $Setting['id'] . '" value="' . $Value . '"/>';
}
elseif($Setting['default-value'])
{
$Temp.= '<input type="text" name="' . $Setting['id'] . '" value="' . $Setting['default-value'] . '"/>';
}
else
{
$Temp.= '<input type="text" name="' . $Setting['id'] . '" />';
}
if(in_array($Setting['id'], $WrongData))
{
if($Setting->{'error-message'})
{
$Temp.= self::FieldError($Setting->{'error-message'});
}
else
{
if($Setting['type'] == 'string')
{
$Temp.= self::FieldError($lng['aps']['error_text']);
}
elseif($Setting['type'] == 'email')
{
$Temp.= self::FieldError($lng['aps']['error_email']);
}
elseif($Setting['type'] == 'domain-name')
{
$Temp.= self::FieldError($lng['aps']['domain']);
}
elseif($Setting['type'] == 'integer')
{
$Temp.= self::FieldError($lng['aps']['error_integer']);
}
elseif($Setting['type'] == 'float')
{
$Temp.= self::FieldError($lng['aps']['error_float']);
}
}
}
}
elseif($Setting['type'] == 'password')
{
if(!$GroupPrinted)
{
$Groupname = $Group->name;
$GroupPrinted = true;
}
else
{
$Groupname = '';
}
$Temp.= '<input type="password" name="' . $Setting['id'] . '" />';
if(in_array($Setting['id'], $WrongData))
{
if($Setting->{'error-message'})
{
$Temp.= self::FieldError($Setting->{'error-message'});
}
else
{
$Temp.= self::FieldError($lng['aps']['error_password']);
}
}
}
elseif($Setting['type'] == 'boolean')
{
if(!$GroupPrinted)
{
$Groupname = $Group->name;
$GroupPrinted = true;
}
else
{
$Groupname = '';
}
$Value = self::GetInstallationValue($PackageId, $CustomerId, strval($Setting['id']));
if($Value)
{
if($Value == 'true')
{
$Temp.= '<input checked="checked" name="' . $Setting['id'] . '" type="checkbox" value="true" />';
}
else
{
$Temp.= '<input name="' . $Setting['id'] . '" type="checkbox" value="true" />';
}
}
elseif($Setting['default-value'] == 'true')
{
$Temp.= '<input checked="checked" name="' . $Setting['id'] . '" type="checkbox" value="true" />';
}
else
{
$Temp.= '<input name="' . $Setting['id'] . '" type="checkbox" value="true" />';
}
}
elseif($Setting['type'] == 'enum')
{
if(!$GroupPrinted)
{
$Groupname = $Group->name;
$GroupPrinted = true;
}
else
{
$Groupname = '';
}
$Temp.= '<select size="1" name="' . $Setting['id'] . '">';
$Value = self::GetInstallationValue($PackageId, $CustomerId, strval($Setting['id']));
foreach($Setting->choice as $Choice)
{
if($Value)
{
if(strval($Choice['id']) == $Value)
{
$Temp.= '<option selected="selected" value="' . $Choice['id'] . '">' . $Choice->name . '</option>';
}
else
{
$Temp.= '<option value="' . $Choice['id'] . '">' . $Choice->name . '</option>';
}
}
elseif(strval($Choice['id']) == strval($Setting['default-value']))
{
$Temp.= '<option selected="selected" value="' . $Choice['id'] . '">' . $Choice->name . '</option>';
}
else
{
$Temp.= '<option value="' . $Choice['id'] . '">' . $Choice->name . '</option>';
}
}
$Temp.= '</select>';
}
//default field description
if(isset($Setting->description))
{
if(!in_array(strval($Setting['id']), $WrongData))$Temp.= '<br/>';
$Temp.= '<em>' . $Setting->description . '</em>';
}
$Fieldname = $Setting->name;
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
}
if($Xml->license)
{
$Temp = '';
if($Xml->license['must-accept']
&& $Xml->license['must-accept'] == 'true')
{
if($Xml->license->text->name)$Temp.= $Xml->license->text->name . '<br/>';
if($Xml->license->text->file)
{
$Temp.= '<textarea name="text" rows="10" cols="55">';
$FileContent = file_get_contents('./packages/' . $Row['Path'] . '/license.txt');
$Temp.= htmlentities($FileContent, ENT_QUOTES, 'ISO-8859-1');
$Temp.= '</textarea>';
$Groupname = $lng['aps']['license'];
$Fieldname = $lng['aps']['license'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
else
{
$Temp.= '<a target="_blank" href="' . htmlspecialchars($Xml->license->text->url) . '">' . $lng['aps']['error_license'] . '</a>';
$Groupname = $lng['aps']['license'];
$Fieldname = $lng['aps']['license'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
$Temp = '<input name="license" type="checkbox" value="true" /> ' . $lng['aps']['error_license'];
if(in_array('license', $WrongData))
{
$Temp.= self::FieldError($lng['aps']['error_licensenoaccept']);
}
$Groupname = '';
$Fieldname = $lng['aps']['license_agreement'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
}
eval("echo \"" . getTemplate("aps/installer") . "\";");
unset($Xml);
}
/**
* show informations for a package in basic or detailed view
*
* @param packageid id of package from database
* @param mode verbosity of data to view (basic|advanced)
* @return error false / success none
*/
private function ShowPackageInfo($PackageId, $All = false)
{
global $lng, $filename, $s, $page, $action, $userinfo;
$Data = '';
$Fieldname = '';
$Fieldvalue = '';
$Groupname = '';
if(!self::IsValidPackageId($PackageId, true))return false;
$result = $this->db->query('SELECT * FROM `' . TABLE_APS_PACKAGES . '` WHERE `ID` = ' . $this->db->escape($PackageId));
$Row = $this->db->fetch_array($result);
$Xml = self::GetXmlFromFile('./packages/' . $Row['Path'] . '/APP-META.xml');
//return if parse of xml file has failed
if($Xml == false)return false;
$Icon = './images/default.png';
//show icon and basic data
if($Xml->icon['path'])
{
$Icon = './packages/' . $Row['Path'] . '/' . basename($Xml->icon['path']);
}
$Summary = htmlspecialchars($Xml->summary);
$Fieldname = $lng['aps']['version'];
$Fieldvalue = $Xml->version . ' (Release ' . $Xml->release . ')';
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
//show website
if($Xml->homepage)
{
$Fieldname = $lng['aps']['homepage'];
$Fieldvalue = '<a target="_blank" href="' . htmlspecialchars($Xml->homepage) . '">' . htmlspecialchars($Xml->homepage) . '</a>';
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
//show size after installation
if($Xml->{'installed-size'})
{
$Fieldname = $lng['aps']['installed_size'];
$Fieldvalue = 'ca. ' . number_format(intval($Xml->{'installed-size'}) / (1024 * 1024), 2) . ' MB';
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
//show categories
if($Xml->categories)
{
$Temp = '';
foreach($Xml->categories->category as $Categories)
{
$Temp.= htmlspecialchars($Categories[0]) . '<br/>';
}
$Fieldname = $lng['aps']['categories'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
//show available languages
if($Xml->languages)
{
$Temp = '';
foreach($Xml->languages->language as $Languages)
{
$Temp.= $Languages[0] . ' ';
}
$Fieldname = $lng['aps']['languages'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
//show more information
if($All == true)
{
$Fieldname = $lng['aps']['long_description'];
$Fieldvalue = htmlspecialchars($Xml->description);
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
//show config script language
if($Xml->{'configuration-script-language'})
{
$Fieldname = $lng['aps']['configscript'];
$Fieldvalue = $Xml->{'configuration-script-language'};
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
//show changelog
$Temp = '<ul>';
foreach($Xml->changelog->version as $Versions)
{
$Temp.= '<li><strong>' . $Versions['version'] . ' (Release ' . $Versions['release'] . ')</strong>';
$Temp.= '<ul>';
foreach($Versions->entry as $Entries)
{
$Temp.= '<li>' . $Entries[0] . '</li>';
}
$Temp.= '</ul></li>';
}
$Temp.= '</ul>';
$Fieldname = $lng['aps']['changelog'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
//show license
if($Xml->license)
{
if($Xml->license->text->file)
{
$Temp = '';
if($Xml->license->text->name)$Temp = $Xml->license->text->name . '<br/>';
$Temp.= '<form name="license" action="#"><textarea name="text" rows="10" cols="70">';
$FileContent = file_get_contents('./packages/' . $Row['Path'] . '/license.txt');
$Temp.= htmlentities($FileContent, ENT_QUOTES, 'ISO-8859-1');
$Temp.= '</textarea></form>';
$Fieldname = $lng['aps']['license'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
else
{
$Fieldname = $lng['aps']['license'];
$Fieldvalue = '<a target="_blank" href="' . htmlspecialchars($Xml->license->text->url) . '">' . $lng['aps']['linktolicense'] . '</a>';
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
}
//show screenshots
if($Xml->screenshot)
{
$Count = 0;
$Temp = '';
foreach($Xml->screenshot as $Screenshot)
{
$Count+= 1;
$Temp.= '<img src="./packages/' . $Row['Path'] . '/' . basename($Screenshot['path']) . '" alt="' . $Screenshot->description . '"/><br/><em>' . $Screenshot->description . '</em><br/>';
if(count($Xml->screenshot) != $Count)$Temp.= '<br/>';
}
$Fieldname = $lng['aps']['screenshots'];
$Fieldvalue = $Temp;
eval("\$Data.=\"" . getTemplate("aps/data") . "\";");
}
}
eval("echo \"" . getTemplate("aps/package") . "\";");
unset($Xml);
}
/**
* show a nice looking infobox
*
* @param message message to display in beautifull layout
*/
private function InfoBox($Message)
{
global $lng, $filename, $s, $page, $action;
//shows a box with informations
eval("echo \"" . getTemplate("aps/infobox") . "\";");
}
/**
* returns html code for nice looking boxes to show customers wrong input
*
* @param error error to display in beautifull layout
*/
private function FieldError($Error)
{
return '<div class="fielderror">' . $Error . '</div>';
}
}
?>