(2003-2009) * @author Froxlor team (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 = ''; private $aps_version = '1.0'; /** * 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.= ''; } if(isset($_POST['remove' . $Row['ID']]) && $_POST['remove' . $Row['ID']] == '1') { $Ids.= ''; } } } //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 = ''; 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 = ''; 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.= ''; //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.= '
  • ' . $Error . '
  • '; } self::InfoBox(sprintf($lng['aps']['uploaderrors'], htmlspecialchars($_FILES[$File]['name']), $ErrorMessage)); } } } } //generate upload fields $Output = ''; foreach($Files as $File) { $Output.= '

    '; } 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 = preg_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'; $this->aps_version = isset($Xml->attributes()->version) ? (string)$Xml->attributes()->version : '1.0'; //show data and status of package if($this->aps_version != '1.0') { $iconpath = $Xml->presentation->icon['path']; $Summary = htmlspecialchars($Xml->presentation->summary); } else { $iconpath = $Xml->icon['path']; $Summary = htmlspecialchars($Xml->summary); } if($iconpath) { $Icon = './packages/' . $Row2['Path'] . '/' . basename($iconpath); } $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'] . '
    '; break; case TASK_REMOVE: $Temp.= $lng['aps']['task_remove'] . '
    '; break; case TASK_RECONFIGURE: $Temp.= $lng['aps']['task_reconfigure'] . '
    '; break; case TASK_UPGRADE: $Temp.= $lng['aps']['task_upgrade'] . '
    '; break; default: $Temp.= $lng['aps']['unknown_status'] . '
    '; 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.= '' . $lng['aps']['mainsite'] . '
    '; } else { $Temp.= '' . $lng['aps']['mainsite'] . '
    '; } //show other links from meta data if($Xml->{'entry-points'}) { foreach($Xml->{'entry-points'}->entry as $Entry) { if($Location == '') { $Temp.= '' . $Entry->label . '
    '; } else { $Temp.= '' . $Entry->label . '
    '; } } } $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(); $this->aps_version = isset($Xml->attributes()->version) ? (string)$Xml->attributes()->version : '1.0'; //check alot of stuff if package is supported //php modules if ($this->aps_version == '1.0') { // the good ole way $XmlPhp = $Xml->requirements->children('http://apstandard.com/ns/1/php'); } else { // since 1.1 $Xml->registerXPathNamespace('php', 'http://apstandard.com/ns/1/php'); $XmlPhp = new DynamicProperties; $XmlPhp->extension = getXPathValue($Xml, '//php:extension', false); $XmlPhp->function = getXPathValue($Xml, '//php:function', false); } if($XmlPhp->extension) { $ExtensionsLoaded = get_loaded_extensions(); foreach($XmlPhp->extension as $Extension) { if(strtolower($Extension) == 'php') { continue; } 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 ($this->aps_version != '1.0') { $XmlPhp->{$Value} = getXPathValue($Xml, '//php:'.$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 ($this->aps_version != '1.0') { $XmlPhp->{'post-max-size'} = getXPathValue($Xml, '//php:post-max-size'); } 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 ($this->aps_version != '1.0') { $XmlPhp->{'memory-limit'} = getXPathValue($Xml, '//php:memory-limit'); } 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 ($this->aps_version != '1.0') { $XmlPhp->{'max-execution-time'} = getXPathValue($Xml, '//php:max-execution-time'); } 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 if ($this->aps_version == '1.0') { // the good ole way $XmlDb = $Xml->requirements->children('http://apstandard.com/ns/1/db'); } else { // since 1.1 $Xml->registerXPathNamespace('db', 'http://apstandard.com/ns/1/db'); $XmlDb = new DynamicProperties; $XmlDb->db->id = getXPathValue($Xml, '//db:id'); $XmlDb->db->{'server-type'} = getXPathValue($Xml, '//db:server-type'); $XmlDb->db->{'server-min-version'} = getXPathValue($Xml, '//db:server-min-version'); } 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 if ($this->aps_version == '1.0') { // the good ole way $XmlAsp = $Xml->requirements->children('http://apstandard.com/ns/1/aspnet'); } else { // since 1.1 $Xml->registerXPathNamespace('aspnet', 'http://apstandard.com/ns/1/aspnet'); $XmlAsp = new DynamicProperties; $XmlAsp->handler = getXPathValue($Xml, '//aspnet:handler'); $XmlAsp->permissions = getXPathValue($Xml, '//aspnet:permissions'); $XmlAsp->version = getXPathValue($Xml, '//aspnet:version'); } if($XmlAsp->handler || $XmlAsp->permissions || $XmlAsp->version) { $Error[] = $lng['aps']['asp_net']; } //CGI if ($this->aps_version == '1.0') { // the good ole way $XmlCgi = $Xml->requirements->children('http://apstandard.com/ns/1/cgi'); } else { // since 1.1 $Xml->registerXPathNamespace('cgi', 'http://apstandard.com/ns/1/cgi'); $XmlCgi = new DynamicProperties; $XmlCgi->handler = getXPathValue($Xml, '//cgi:handler'); } if($XmlCgi->handler) { $Error[] = $lng['aps']['cgi']; } //webserver modules if ($this->aps_version == '1.0') { // the good ole way $XmlWebserver = $Xml->requirements->children('http://apstandard.com/ns/1/apache'); } else { // since 1.1 $Xml->registerXPathNamespace('apache', 'http://apstandard.com/ns/1/apache'); $XmlWebserver = new DynamicProperties; $XmlWebserver->{'required-module'} = getXPathValue($Xml, '//apache:required-module'); $XmlWebserver->htaccess = getXPathValue($Xml, '//apache:htaccess'); } 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 if ($this->aps_version == '1.0') { // the good ole way $aps_settings_array = $Xml->settings->group; } else { // since 1.1 $aps_settings_array = $Xml->{'global-settings'}->setting; if(!is_array($aps_settings_array)) { $aps_settings_array = $Xml->service->settings->group; } } foreach($aps_settings_array 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 if ($this->aps_version == '1.0') { $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.= '
  • ' . $Entry . '
  • '; } 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 ($this->aps_version != '1.0') { $xml_screenshots = $Xml->presentation->screenshot;; } else { $xml_screenshots = $Xml->screenshot; } if($xml_screenshots) { foreach($xml_screenshots as $Screenshot) { self::GetContentFromZip($Filename, $Screenshot['path'], $Destination . basename($Screenshot['path'])); } } //copy icon if ($this->aps_version != '1.0') { $xml_iconpath = $Xml->presentation->icon['path']; } else { $xml_iconpath = $Xml->icon['path']; } if($xml_iconpath) { self::GetContentFromZip($Filename, $xml_iconpath, $Destination . basename($xml_iconpath)); } //copy license if ($this->aps_version != '1.0') { $xml_license = $Xml->service->license; } else { $xml_license = $Xml->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.= '
  • ' . $lng['aps']['class_zip_missing'] . '
  • '; } if(!is_writable($this->RootDir.'temp/') || !is_writable($this->RootDir.'packages/')) { $dirpermission = str_replace('{$path}', $this->RootDir, $lng['aps']['dir_permissions']); $Error.= '
  • ' . $dirpermission . '
  • '; } 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 = ''; 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 = ''; 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 ('

    '); for ($i = 1;$i < $Pages + 1;$i++) { if($i == $_GET['page']) { echo ('' . $i . ''); } else { echo ('' . $i . ''); } } echo ('


    '); } } 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 ('

    '); for ($i = 1;$i < $Pages + 1;$i++) { echo ('' . $i . ''); } echo ('
    '); } } } 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 ('

    '); for ($i = 1;$i < $Pages + 1;$i++) { if($i == 1) { echo ('' . $i . ''); } else { echo ('' . $i . ''); } } echo ('


    '); } } } } /** * 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; $this->aps_version = isset($Xml->attributes()->version) ? (string)$Xml->attributes()->version : '1.0'; //check all data fields of xml file against inut of customer if ($this->aps_version == '1.0') { // the good ole way $aps_settings_array = $Xml->settings->group; } else { // since 1.1 $aps_settings_array = $Xml->{'global-settings'}->setting; if(!is_array($aps_settings_array)) { $aps_settings_array = $Xml->service->settings->group; } } $Error = array(); foreach($aps_settings_array 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])) { $email = strtolower($_POST[$FieldId]); if(filter_var($email, FILTER_VALIDATE_EMAIL) === false) { 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? if ($this->aps_version == '1.0') { // the good ole way $XmlDb = $Xml->requirements->children('http://apstandard.com/ns/1/db'); } else { // since 1.1 $Xml->registerXPathNamespace('db', 'http://apstandard.com/ns/1/db'); $XmlDb = new DynamicProperties; $XmlDb->db->id = getXPathValue($Xml, '//db:id'); } 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 ($this->aps_version != '1.0') { $xml_license = $Xml->service->license; } else { $xml_license = $Xml->license; } 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; $this->aps_version = isset($Xml->attributes()->version) ? (string)$Xml->attributes()->version : '1.0'; //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($this->aps_version != '1.0') { $iconpath = $Xml->presentation->icon['path']; } else { $iconpath = $Xml->icon['path']; } if($iconpath) { $Icon = './packages/' . $Row['Path'] . '/' . basename($iconpath); } //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://'; $Value = self::GetInstallationValue($PackageId, $CustomerId, 'main_location'); if($Value) { $Temp.= '/'; } else { $Temp.= '/'; } 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.= '
    '; $Temp.= '' . $lng['aps']['application_location_description'] . ''; $Groupname = $lng['aps']['basic_settings']; $Fieldname = $lng['aps']['application_location']; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); //database required? if ($this->aps_version == '1.0') { // the good ole way $XmlDb = $Xml->requirements->children('http://apstandard.com/ns/1/db'); } else { // since 1.1 $Xml->registerXPathNamespace('db', 'http://apstandard.com/ns/1/db'); $XmlDb = new DynamicProperties; $XmlDb->db->id = getXPathValue($Xml, '//db:id'); } if($XmlDb->db->id) { $Temp = ''; if(in_array('main_database_password', $WrongData)) { $Temp.= self::FieldError($lng['aps']['dbpassword']); } if(!in_array('main_database_password', $WrongData))$Temp.= '
    '; $Temp.= '' . $lng['aps']['database_password_description'] . ''; $Groupname = ''; $Fieldname = $lng['aps']['database_password']; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); } if ($this->aps_version == '1.0') { // the good ole way $aps_settings_array = $Xml->settings->group; } else { // since 1.1 $aps_settings_array = $Xml->{'global-settings'}->setting; if(!is_array($aps_settings_array)) { $aps_settings_array = $Xml->service->settings->group; } } foreach($aps_settings_array 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.= ''; } elseif($Setting['default-value']) { $Temp.= ''; } else { $Temp.= ''; } 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.= ''; 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.= ''; } else { $Temp.= ''; } } elseif($Setting['default-value'] == 'true') { $Temp.= ''; } else { $Temp.= ''; } } elseif($Setting['type'] == 'enum') { if(!$GroupPrinted) { $Groupname = $Group->name; $GroupPrinted = true; } else { $Groupname = ''; } $Temp.= ''; } //default field description if(isset($Setting->description)) { if(!in_array(strval($Setting['id']), $WrongData))$Temp.= '
    '; $Temp.= '' . $Setting->description . ''; } $Fieldname = $Setting->name; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); } } if ($this->aps_version != '1.0') { $xml_license = $Xml->service->license; } else { $xml_license = $Xml->license; } if($xml_license) { $Temp = ''; if($xml_license['must-accept'] && $xml_license['must-accept'] == 'true') { if($xml_license->text->name)$Temp.= $xml_license->text->name . '
    '; if($xml_license->text->file) { $Temp.= ''; $Groupname = $lng['aps']['license']; $Fieldname = $lng['aps']['license']; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); } else { $Temp.= '' . $lng['aps']['error_license'] . ''; $Groupname = $lng['aps']['license']; $Fieldname = $lng['aps']['license']; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); } $Temp = ' ' . $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'; $this->aps_version = isset($Xml->attributes()->version) ? (string)$Xml->attributes()->version : '1.0'; //show icon and basic data if($this->aps_version != '1.0') { $iconpath = $Xml->presentation->icon['path']; $Summary = htmlspecialchars($Xml->presentation->summary); $categories = $Xml->presentation->categories; $languages = $Xml->presentation->languages; $description = $Xml->presentation->description; $changelogs = $Xml->presentation->changelog; $license = $Xml->service->license; $screenshots = $Xml->presentation->screenshot; } else { $iconpath = $Xml->icon['path']; $Summary = htmlspecialchars($Xml->summary); $categories = $Xml->categories; $languages = $Xml->languages; $description = $Xml->description; $changelogs = $Xml->changelog; $license = $Xml->license; $screenshots = $Xml->screenshot; } if($iconpath) { $Icon = './packages/' . $Row['Path'] . '/' . basename($iconpath); } $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 = '' . htmlspecialchars($Xml->homepage) . ''; 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($categories) { $Temp = ''; foreach($categories->category as $_categories) { $Temp.= htmlspecialchars($_categories[0]) . '
    '; } $Fieldname = $lng['aps']['categories']; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); } //show available languages if($languages) { $Temp = ''; foreach($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($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 = ''; $Fieldname = $lng['aps']['changelog']; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); //show license if($license) { if($license->text->file) { $Temp = ''; if($license->text->name)$Temp = $license->text->name . '
    '; $Temp.= '
    '; $Fieldname = $lng['aps']['license']; $Fieldvalue = $Temp; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); } else { $Fieldname = $lng['aps']['license']; $Fieldvalue = '' . $lng['aps']['linktolicense'] . ''; eval("\$Data.=\"" . getTemplate("aps/data") . "\";"); } } //show screenshots if($screenshots) { $Count = 0; $Temp = ''; foreach($screenshots as $Screenshot) { $Count+= 1; $Temp.= '' . $Screenshot->description . '
    ' . $Screenshot->description . '
    '; if(count($screenshots) != $Count)$Temp.= '
    '; } $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 '
    ' . $Error . '
    '; } } ?>