Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Feb 25, 5:27 AM

in-portal

Index: branches/5.2.x/core/kernel/globals.php
===================================================================
--- branches/5.2.x/core/kernel/globals.php (revision 15724)
+++ branches/5.2.x/core/kernel/globals.php (revision 15725)
@@ -1,942 +1,942 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kUtil {
// const KG_TO_POUND = 2.20462262;
const POUND_TO_KG = 0.45359237;
/**
* Similar to array_merge_recursive but keyed-valued are always overwritten.
* Priority goes to the 2nd array.
*
* @param $paArray1 array
* @param $paArray2 array
* @return array
* @access public
*/
public static function array_merge_recursive($paArray1, $paArray2)
{
if (!is_array($paArray1) or !is_array($paArray2)) {
return $paArray2;
}
foreach ($paArray2 AS $sKey2 => $sValue2) {
$paArray1[$sKey2] = isset($paArray1[$sKey2]) ? self::array_merge_recursive($paArray1[$sKey2], $sValue2) : $sValue2;
}
return $paArray1;
}
/**
* Prepend a reference to an element to the beginning of an array.
* Renumbers numeric keys, so $value is always inserted to $array[0]
*
* @param $array array
* @param $value mixed
* @return int
* @access public
*/
public static function array_unshift_ref(&$array, &$value)
{
$return = array_unshift($array,'');
$array[0] =& $value;
return $return;
}
/**
* Rename key in associative array, maintaining keys order
*
* @param Array $array Associative Array
* @param mixed $old Old key name
* @param mixed $new New key name
* @access public
*/
public static function array_rename_key(&$array, $old, $new)
{
$new_array = Array ();
foreach ($array as $key => $val) {
$new_array[ $key == $old ? $new : $key] = $val;
}
$array = $new_array;
}
/**
* Same as print_r, but outputs result on screen or in debugger report (when in debug mode)
*
* @param Array $data
* @param string $label
* @param bool $on_screen
* @access public
*/
public static function print_r($data, $label = '', $on_screen = false)
{
$is_debug = false;
if ( class_exists('kApplication') && !$on_screen ) {
$application =& kApplication::Instance();
$is_debug = $application->isDebugMode();
}
if ( $is_debug && isset($application) ) {
if ( $label ) {
$application->Debugger->appendHTML('<strong>' . $label . '</strong>');
}
$application->Debugger->dumpVars($data);
}
else {
if ( $label ) {
echo '<strong>' . $label . '</strong><br/>';
}
echo '<pre>', print_r($data, true), '</pre>';
}
}
/**
* Define constant if it was not already defined before
*
* @param string $const_name
* @param string $const_value
* @access public
*/
public static function safeDefine($const_name, $const_value)
{
if ( !defined($const_name) ) {
define($const_name, $const_value);
}
}
/**
* Parses "/system/config.php" file and returns the result
*
* @param bool $parse_section
* @return Array
* @access public
*/
public static function parseConfig($parse_section = false)
{
$file = FULL_PATH . DIRECTORY_SEPARATOR . 'system' . DIRECTORY_SEPARATOR . 'config.php';
if ( !file_exists($file) ) {
return Array ();
}
if ( file_exists($file) && !is_readable($file) ) {
die('Could Not Open Ini File');
}
$contents = file($file);
if ( $contents && $contents[0] == '<' . '?' . 'php die() ?' . ">\n" ) {
// format of "config.php" file before 5.1.0 version
array_shift($contents);
return parse_ini_string(implode('', $contents), $parse_section);
}
$_CONFIG = Array ();
require($file);
if ( $parse_section ) {
if ( isset($_CONFIG['Database']['LoadBalancing']) && $_CONFIG['Database']['LoadBalancing'] ) {
require FULL_PATH . DIRECTORY_SEPARATOR . 'system' . DIRECTORY_SEPARATOR . 'db_servers.php';
}
return $_CONFIG;
}
$ret = Array ();
foreach ($_CONFIG as $section => $section_variables) {
$ret = array_merge($ret, $section_variables);
}
return $ret;
}
/**
* Returns parsed variables from "config.php" file
*
* @return Array
* @access public
*/
public static function getConfigVars()
{
static $vars = NULL;
if ( !isset($vars) ) {
$vars = self::parseConfig();
}
return $vars;
}
/**
* Same as "include_once", but also profiles file includes in debug mode and DBG_PROFILE_INCLUDES constant is set
*
* @param string $file
* @access public
*/
public static function includeOnce($file)
{
global $debugger;
if ( defined('DEBUG_MODE') && DEBUG_MODE && isset($debugger) && defined('DBG_PROFILE_INCLUDES') && DBG_PROFILE_INCLUDES ) {
if ( in_array($file, get_included_files()) ) {
return ;
}
global $debugger;
/*$debugger->IncludeLevel++;
$before_mem = memory_get_usage();*/
$debugger->ProfileStart('inc_'.crc32($file), $file);
include_once($file);
$debugger->ProfileFinish('inc_'.crc32($file));
$debugger->profilerAddTotal('includes', 'inc_'.crc32($file));
/*$used_mem = memory_get_usage() - $before_mem;
$debugger->IncludeLevel--;
$debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $file);
$debugger->IncludesData['mem'][] = $used_mem;
$debugger->IncludesData['time'][] = $used_time;
$debugger->IncludesData['level'][] = $debugger->IncludeLevel;*/
}
else {
include_once($file);
}
}
/**
* Checks if given string is a serialized array
*
* @param string $string
* @return bool
* @access public
*/
public static function IsSerialized($string)
{
if ( is_array($string) ) {
return false;
}
return preg_match('/a:([\d]+):{/', $string);
}
/**
* Generates password of given length
*
* @param int $length
* @return string
* @access public
*/
public static function generatePassword($length = 10)
{
$pass_length = $length;
$p1 = Array ('b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z');
$p2 = Array ('a','e','i','o','u');
$p3 = Array ('1','2','3','4','5','6','7','8','9');
$p4 = Array ('(','&',')',';','%'); // if you need real strong stuff
// how much elements in the array
// can be done with a array count but counting once here is faster
$s1 = 21;// this is the count of $p1
$s2 = 5; // this is the count of $p2
$s3 = 9; // this is the count of $p3
$s4 = 5; // this is the count of $p4
// possible readable combinations
$c1 = '121'; // will be like 'bab'
$c2 = '212'; // will be like 'aba'
$c3 = '12'; // will be like 'ab'
$c4 = '3'; // will be just a number '1 to 9' if you dont like number delete the 3
//$c5 = '4'; // uncomment to active the strong stuff
$comb = '4'; // the amount of combinations you made above (and did not comment out)
for ($p = 0; $p < $pass_length;) {
mt_srand((double)microtime() * 1000000);
$strpart = mt_rand(1, $comb);
// checking if the stringpart is not the same as the previous one
if ($strpart != $previous) {
$pass_structure .= ${'c' . $strpart};
// shortcutting the loop a bit
$p = $p + mb_strlen(${'c' . $strpart});
}
$previous = $strpart;
}
// generating the password from the structure defined in $pass_structure
for ($g = 0; $g < mb_strlen($pass_structure); $g++) {
mt_srand((double)microtime() * 1000000);
$sel = mb_substr($pass_structure, $g, 1);
$pass .= ${'p' . $sel}[ mt_rand(0,-1+${'s'.$sel}) ];
}
return $pass;
}
/**
* submits $url with $post as POST
*
* @param string $url
* @param mixed $data
* @param Array $headers
* @param string $request_type
* @param Array $curl_options
* @return string
* @access public
* @deprecated
*/
public static function curl_post($url, $data, $headers = NULL, $request_type = 'POST', $curl_options = NULL)
{
$application =& kApplication::Instance();
$curl_helper = $application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
if ($request_type == 'POST') {
$curl_helper->SetRequestMethod(kCurlHelper::REQUEST_METHOD_POST);
}
$curl_helper->SetRequestData($data);
if (!is_null($headers)) {
// not an associative array, so don't use kCurlHelper::SetHeaders method
$curl_helper->setOptions( Array (CURLOPT_HTTPHEADER => $headers) );
}
if (is_array($curl_options)) {
$curl_helper->setOptions($curl_options);
}
$curl_helper->followLocation = false;
$ret = $curl_helper->Send($url);
$GLOBALS['curl_errorno'] = $curl_helper->lastErrorCode;
$GLOBALS['curl_error'] = $curl_helper->lastErrorMsg;
return $ret;
}
/**
* Checks if constant is defined and has positive value
*
* @param string $const_name
* @return bool
* @access public
*/
public static function constOn($const_name)
{
return defined($const_name) && constant($const_name);
}
/**
* Converts KG to Pounds
*
* @param float $kg
* @param bool $pounds_only
* @return float
* @access public
*/
public static function Kg2Pounds($kg, $pounds_only = false)
{
$major = floor( round($kg / self::POUND_TO_KG, 3) );
$minor = abs(round(($kg - $major * self::POUND_TO_KG) / self::POUND_TO_KG * 16, 2));
if ($pounds_only) {
$major += round($minor * 0.0625, 2);
$minor = 0;
}
return array($major, $minor);
}
/**
* Converts Pounds to KG
*
* @param float $pounds
* @param float $ounces
* @return float
* @access public
*/
public static function Pounds2Kg($pounds, $ounces = 0.00)
{
return round(($pounds + ($ounces / 16)) * self::POUND_TO_KG, 5);
}
/**
* Formats file/memory size in nice way
*
* @param int $bytes
* @return string
* @access public
*/
public static function formatSize($bytes)
{
if ($bytes >= 1099511627776) {
$return = round($bytes / 1024 / 1024 / 1024 / 1024, 2);
$suffix = "TB";
} elseif ($bytes >= 1073741824) {
$return = round($bytes / 1024 / 1024 / 1024, 2);
$suffix = "GB";
} elseif ($bytes >= 1048576) {
$return = round($bytes / 1024 / 1024, 2);
$suffix = "MB";
} elseif ($bytes >= 1024) {
$return = round($bytes / 1024, 2);
$suffix = "KB";
} else {
$return = $bytes;
$suffix = "Byte";
}
$return .= ' '.$suffix;
return $return;
}
/**
* Enter description here...
*
* @param resource $filePointer the file resource to write to
* @param Array $data the data to write out
* @param string $delimiter the field separator
* @param string $enclosure symbol to enclose field data to
* @param string $recordSeparator symbols to separate records with
* @access public
*/
public static function fputcsv($filePointer, $data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n")
{
fwrite($filePointer, self::getcsvline($data, $delimiter, $enclosure, $recordSeparator));
}
/**
* Enter description here...
*
* @param Array $data the data to write out
* @param string $delimiter the field separator
* @param string $enclosure symbol to enclose field data to
* @param string $recordSeparator symbols to separate records with
* @return string
* @access public
*/
public static function getcsvline($data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n")
{
foreach($data as $field_index => $field_value) {
// replaces an enclosure with two enclosures
$data[$field_index] = str_replace($enclosure, $enclosure.$enclosure, $field_value);
}
$line = $enclosure.implode($enclosure.$delimiter.$enclosure, $data).$enclosure.$recordSeparator;
$line = preg_replace('/'.preg_quote($enclosure, '/').'([0-9\.]+)'.preg_quote($enclosure, '/').'/', '$1', $line);
return $line;
}
/**
* Allows to replace #section# within any string with current section
*
* @param string $string
* @return string
* @access public
*/
public static function replaceModuleSection($string)
{
$application =& kApplication::Instance();
$module_section = $application->RecallVar('section');
if ($module_section) {
// substitute section instead of #section# parameter in title preset name
$module_section = explode(':', $module_section);
$section = preg_replace('/(configuration|configure)_(.*)/i', '\\2', $module_section[count($module_section) == 2 ? 1 : 0]);
$string = str_replace('#section#', mb_strtolower($section), $string);
}
return $string;
}
/**
* Checks, that user IP address is within allowed range
*
* @param string $ip_list semi-column (by default) separated ip address list
* @param string $separator ip address separator (default ";")
*
* @return bool
* @access public
*/
public static function ipMatch($ip_list, $separator = ';')
{
if ( php_sapi_name() == 'cli' ) {
return false;
}
$ip_match = false;
$ip_addresses = $ip_list ? explode($separator, $ip_list) : Array ();
$application =& kApplication::Instance();
$client_ip = $application->getClientIp();
foreach ($ip_addresses as $ip_address) {
if ( self::netMatch($ip_address, $client_ip) ) {
$ip_match = true;
break;
}
}
return $ip_match;
}
/**
* Checks, that given ip belongs to given subnet
*
* @param string $network
* @param string $ip
* @return bool
* @access public
*/
public static function netMatch($network, $ip)
{
$network = trim($network);
$ip = trim($ip);
if ( preg_replace('/[\d\.\/-]/', '', $network) != '' ) {
$network = gethostbyname($network);
}
if ($network == $ip) {
// comparing two ip addresses directly
return true;
}
$d = strpos($network, '-');
if ($d !== false) {
// ip address range specified
$from = ip2long(trim(substr($network, 0, $d)));
$to = ip2long(trim(substr($network, $d + 1)));
$ip = ip2long($ip);
return ($ip >= $from && $ip <= $to);
}
elseif (strpos($network, '/') !== false) {
// single subnet specified
$ip_arr = explode('/', $network);
if (!preg_match("@\d*\.\d*\.\d*\.\d*@", $ip_arr[0], $matches)) {
$ip_arr[0] .= '.0'; // Alternate form 194.1.4/24
}
$network_long = ip2long($ip_arr[0]);
$x = ip2long($ip_arr[1]);
$mask = long2ip($x) == $ip_arr[1] ? $x : (0xffffffff << (32 - $ip_arr[1]));
$ip_long = ip2long($ip);
return ($ip_long & $mask) == ($network_long & $mask);
}
return false;
}
/**
* Returns mime type corresponding to given file
* @param string $file
* @return string
* @access public
*/
public static function mimeContentType($file)
{
$ret = self::vendorMimeContentType($file);
if ( $ret ) {
// vendor-specific mime types override any automatic detection
return $ret;
}
if ( function_exists('finfo_open') && function_exists('finfo_file') ) {
$mime_magic_resource = finfo_open(FILEINFO_MIME_TYPE);
if ( $mime_magic_resource ) {
$ret = finfo_file($mime_magic_resource, $file);
finfo_close($mime_magic_resource);
}
}
elseif ( function_exists('mime_content_type') ) {
$ret = mime_content_type($file);
}
return $ret ? $ret : self::mimeContentTypeByExtension($file);
}
/**
* Determines vendor-specific mime type from a given file
*
* @param string $file
* @return bool
* @access public
* @static
*/
public static function vendorMimeContentType($file)
{
$file_extension = mb_strtolower( pathinfo($file, PATHINFO_EXTENSION) );
$mapping = Array (
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12'
);
return isset($mapping[$file_extension]) ? $mapping[$file_extension] : false;
}
/**
* Detects mime type of the file purely based on it's extension
*
* @param string $file
* @return string
* @access public
*/
public static function mimeContentTypeByExtension($file)
{
$file_extension = mb_strtolower( pathinfo($file, PATHINFO_EXTENSION) );
$mapping = '(xls:application/excel)(hqx:application/macbinhex40)(doc,dot,wrd:application/msword)(pdf:application/pdf)
(pgp:application/pgp)(ps,eps,ai:application/postscript)(ppt:application/powerpoint)(rtf:application/rtf)
(tgz,gtar:application/x-gtar)(gz:application/x-gzip)(php,php3:application/x-httpd-php)(js:application/x-javascript)
(ppd,psd:application/x-photoshop)(swf,swc,rf:application/x-shockwave-flash)(tar:application/x-tar)(zip:application/zip)
(mid,midi,kar:audio/midi)(mp2,mp3,mpga:audio/mpeg)(ra:audio/x-realaudio)(wav:audio/wav)(bmp:image/bitmap)(bmp:image/bitmap)
(gif:image/gif)(iff:image/iff)(jb2:image/jb2)(jpg,jpe,jpeg:image/jpeg)(jpx:image/jpx)(png:image/png)(tif,tiff:image/tiff)
(wbmp:image/vnd.wap.wbmp)(xbm:image/xbm)(css:text/css)(txt:text/plain)(htm,html:text/html)(xml:text/xml)
(mpg,mpe,mpeg:video/mpeg)(qt,mov:video/quicktime)(avi:video/x-ms-video)(eml:message/rfc822)
(sxw:application/vnd.sun.xml.writer)(sxc:application/vnd.sun.xml.calc)(sxi:application/vnd.sun.xml.impress)
(sxd:application/vnd.sun.xml.draw)(sxm:application/vnd.sun.xml.math)
(odt:application/vnd.oasis.opendocument.text)(oth:application/vnd.oasis.opendocument.text-web)
(odm:application/vnd.oasis.opendocument.text-master)(odg:application/vnd.oasis.opendocument.graphics)
(odp:application/vnd.oasis.opendocument.presentation)(ods:application/vnd.oasis.opendocument.spreadsheet)
(odc:application/vnd.oasis.opendocument.chart)(odf:application/vnd.oasis.opendocument.formula)
(odi:application/vnd.oasis.opendocument.image)';
if ( preg_match('/[\(,]' . $file_extension . '[,]{0,1}.*?:(.*?)\)/s', $mapping, $regs) ) {
return $regs[1];
}
return 'application/octet-stream';
}
/**
* Return param value and removes it from params array
*
* @param string $name
* @param Array $params
* @param bool $default
* @return string
*/
public static function popParam($name, &$params, $default = false)
{
if ( isset($params[$name]) ) {
$value = $params[$name];
unset($params[$name]);
return $value;
}
return $default;
}
/**
* Generate subpath from hashed value
*
* @param string $name
* @param int $levels
* @return string
*/
public static function getHashPathForLevel($name, $levels = 2)
{
if ( $levels == 0 ) {
return '';
}
else {
$path = '';
$hash = md5($name);
for ($i = 0; $i < $levels; $i++) {
$path .= substr($hash, $i, 1) . '/';
}
return $path;
}
}
/**
* Calculates the crc32 polynomial of a string (always positive number)
*
* @param string $str
* @return int
*/
public static function crc32($str)
{
return sprintf('%u', crc32($str));
}
/**
* Returns instance of DateTime class with date set based on timestamp
*
* @static
* @param int $timestamp
* @return DateTime
* @access public
*/
public static function dateFromTimestamp($timestamp)
{
if ( version_compare(PHP_VERSION, '5.3.0', '<') ) {
$date = new DateTime('@' . $timestamp);
- $date->setTimezone(new DateTimeZone(getenv('TZ')));
+ $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
}
else {
$date = new DateTime();
$date->setTimestamp($timestamp);
}
return $date;
}
/**
* Returns timestamp from given DateTime class instance
*
* @static
* @param DateTime $date_time
* @return int|string
* @access public
*/
public static function timestampFromDate(DateTime $date_time)
{
if ( version_compare(PHP_VERSION, '5.3.0', '<') ) {
return $date_time->format('U');
}
return $date_time->getTimestamp();
}
/**
* Generates random numeric id
*
* @static
* @return string
* @access public
*/
public static function generateId()
{
list($usec, $sec) = explode(' ', microtime());
$id_part_1 = substr($usec, 4, 4);
$id_part_2 = mt_rand(1, 9);
$id_part_3 = substr($sec, 6, 4);
$digit_one = substr($id_part_1, 0, 1);
if ( $digit_one == 0 ) {
$digit_one = mt_rand(1, 9);
$id_part_1 = preg_replace('/^0/', '', $id_part_1);
$id_part_1 = $digit_one . $id_part_1;
}
return $id_part_1 . $id_part_2 . $id_part_3;
}
/**
* Changes script resource limits. Omitted argument results in limit removal.
*
* @static
* @param string|int $memory_limit
* @param int $time_limit
* @return void
* @access public
*/
public static function setResourceLimit($memory_limit = null, $time_limit = null)
{
set_time_limit(isset($time_limit) ? $time_limit : 0);
ini_set('memory_limit', isset($memory_limit) ? $memory_limit : -1);
}
}
/**
* Returns array value if key exists
* Accepts infinite number of parameters
*
* @param Array $array searchable array
* @param int $key array key
* @return string
*/
function getArrayValue(&$array, $key)
{
$ret = isset($array[$key]) ? $array[$key] : false;
if ( $ret && func_num_args() > 2 ) {
for ($i = 2; $i < func_num_args(); $i++) {
$cur_key = func_get_arg($i);
$ret = getArrayValue($ret, $cur_key);
if ( $ret === false ) {
break;
}
}
}
return $ret;
}
if ( !function_exists('parse_ini_string') ) {
/**
* Equivalent for "parse_ini_string" function available since PHP 5.3.0
*
* @param string $ini
* @param bool $process_sections
* @param int $scanner_mode
* @return Array
*/
function parse_ini_string($ini, $process_sections = false, $scanner_mode = NULL)
{
# Generate a temporary file.
$tempname = tempnam('/tmp', 'ini');
$fp = fopen($tempname, 'w');
fwrite($fp, $ini);
$ini = parse_ini_file($tempname, !empty($process_sections));
fclose($fp);
@unlink($tempname);
return $ini;
}
}
if ( !function_exists('memory_get_usage') ) {
// PHP 4.x and compiled without --enable-memory-limit option
function memory_get_usage() { return -1; }
}
if ( !function_exists('imagecreatefrombmp') ) {
// just in case if GD will add this function in future
function imagecreatefrombmp($filename)
{
//Ouverture du fichier en mode binaire
if (! $f1 = fopen($filename,"rb")) return FALSE;
//1 : Chargement des ent�tes FICHIER
$FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14));
if ($FILE['file_type'] != 19778) return FALSE;
//2 : Chargement des ent�tes BMP
$BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
'/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
'/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40));
$BMP['colors'] = pow(2,$BMP['bits_per_pixel']);
if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
$BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8;
$BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
$BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4);
$BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4);
$BMP['decal'] = 4-(4*$BMP['decal']);
if ($BMP['decal'] == 4) $BMP['decal'] = 0;
//3 : Chargement des couleurs de la palette
$PALETTE = array();
if ($BMP['colors'] < 16777216)
{
$PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));
}
//4 : Cr�ation de l'image
$IMG = fread($f1,$BMP['size_bitmap']);
$VIDE = chr(0);
$res = imagecreatetruecolor($BMP['width'],$BMP['height']);
$P = 0;
$Y = $BMP['height']-1;
while ($Y >= 0)
{
$X=0;
while ($X < $BMP['width'])
{
if ($BMP['bits_per_pixel'] == 24)
$COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
elseif ($BMP['bits_per_pixel'] == 16)
{
$COLOR = unpack("n",substr($IMG,$P,2));
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
elseif ($BMP['bits_per_pixel'] == 8)
{
$COLOR = unpack("n",$VIDE.substr($IMG,$P,1));
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
elseif ($BMP['bits_per_pixel'] == 4)
{
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F);
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
elseif ($BMP['bits_per_pixel'] == 1)
{
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
if (($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7;
elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
else
return FALSE;
imagesetpixel($res,$X,$Y,$COLOR[1]);
$X++;
$P += $BMP['bytes_per_pixel'];
}
$Y--;
$P+=$BMP['decal'];
}
//Fermeture du fichier
fclose($f1);
return $res;
}
}
\ No newline at end of file
Index: branches/5.2.x/core/install.php
===================================================================
--- branches/5.2.x/core/install.php (revision 15724)
+++ branches/5.2.x/core/install.php (revision 15725)
@@ -1,1782 +1,1782 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
ini_set('display_errors', 1);
error_reporting(E_ALL & ~E_STRICT);
define('IS_INSTALL', 1);
define('ADMIN', 1);
define('FULL_PATH', realpath(dirname(__FILE__).'/..') );
define('REL_PATH', '/core');
// run installator
$install_engine = new kInstallator();
$install_engine->Init();
$install_engine->Run();
$install_engine->Done();
class kInstallator {
/**
* Reference to kApplication class object
*
* @var kApplication
*/
var $Application = null;
/**
* Connection to database
*
* @var kDBConnection
*/
var $Conn = null;
/**
* XML file containing steps information
*
* @var string
*/
var $StepDBFile = '';
/**
* Step name, that currently being processed
*
* @var string
*/
var $currentStep = '';
/**
* Steps list (preset) to use for current installation
*
* @var string
*/
var $stepsPreset = '';
/**
* Installation steps to be done
*
* @var Array
*/
var $steps = Array (
'fresh_install' => Array ('sys_requirements', 'check_paths', 'db_config', 'select_license', /*'download_license',*/ 'select_domain', 'root_password', 'choose_modules', 'post_config', 'sys_config', 'select_theme', 'security', 'finish'),
'clean_reinstall' => Array ('install_setup', 'sys_requirements', 'check_paths', 'clean_db', 'db_config', 'select_license', /*'download_license',*/ 'select_domain', 'root_password', 'choose_modules', 'post_config', 'sys_config', 'select_theme', 'security', 'finish'),
'already_installed' => Array ('check_paths', 'install_setup'),
'upgrade' => Array ('check_paths', 'install_setup', 'sys_config', 'upgrade_modules', 'skin_upgrade', 'security', 'finish'),
'update_license' => Array ('check_paths', 'install_setup', 'select_license', /*'download_license',*/ 'select_domain', 'security', 'finish'),
'update_config' => Array ('check_paths', 'install_setup', 'sys_config', 'security', 'finish'),
'db_reconfig' => Array ('check_paths', 'install_setup', 'db_reconfig', 'security', 'finish'),
'sys_requirements' => Array ('check_paths', 'install_setup', 'sys_requirements', 'security', 'finish')
);
/**
* Steps, that doesn't required admin to be logged-in to proceed
*
* @var Array
*/
var $skipLoginSteps = Array ('sys_requirements', 'check_paths', 'select_license', /*'download_license',*/ 'select_domain', 'root_password', 'choose_modules', 'post_config', 'select_theme', 'security', 'finish', -1);
/**
* Steps, on which kApplication should not be initialized, because of missing correct db table structure
*
* @var Array
*/
var $skipApplicationSteps = Array ('sys_requirements', 'check_paths', 'clean_db', 'db_config', 'db_reconfig' /*, 'install_setup'*/); // remove install_setup when application will work separately from install
/**
* Folders that should be writeable to continue installation. $1 - main writeable folder from config.php ("/system" by default)
*
* @var Array
*/
var $writeableFolders = Array (
'$1',
'$1/.restricted',
'$1/images',
'$1/images/pending',
'$1/images/emoticons', // for "In-Bulletin"
'$1/user_files',
'$1/cache',
);
/**
* Contains last error message text
*
* @var string
*/
var $errorMessage = '';
/**
* Base path for includes in templates
*
* @var string
*/
var $baseURL = '';
/**
* Holds number of last executed query in the SQL
*
* @var int
*/
var $LastQueryNum = 0;
/**
* Dependencies, that should be used in upgrade process
*
* @var Array
*/
var $upgradeDepencies = Array ();
/**
* Log of upgrade - list of upgraded modules and their versions
*
* @var Array
*/
var $upgradeLog = Array ();
/**
* Common tools required for installation process
*
* @var kInstallToolkit
*/
var $toolkit = null;
function Init()
{
include_once(FULL_PATH . REL_PATH . '/kernel/kbase.php'); // required by kDBConnection class
include_once(FULL_PATH . REL_PATH . '/kernel/utility/multibyte.php'); // emulating multi-byte php extension
require_once(FULL_PATH . REL_PATH . '/install/install_toolkit.php'); // toolkit required for module installations to installator
$this->toolkit = new kInstallToolkit();
$this->toolkit->setInstallator($this);
$this->StepDBFile = FULL_PATH.'/'.REL_PATH.'/install/steps_db.xml';
$base_path = rtrim(preg_replace('/'.preg_quote(rtrim(REL_PATH, '/'), '/').'$/', '', str_replace('\\', '/', dirname($_SERVER['PHP_SELF']))), '/');
$this->baseURL = 'http://'.$_SERVER['HTTP_HOST'].$base_path.'/core/install/';
set_error_handler( Array(&$this, 'ErrorHandler') );
if (file_exists($this->toolkit->INIFile)) {
// if config.php found, then check his write permission too
$this->writeableFolders[] = $this->toolkit->defaultWritablePath . '/config.php';
}
if ( !$this->toolkit->getSystemConfig('Misc', 'WriteablePath') ) {
$this->toolkit->setSystemConfig('Misc', 'WriteablePath', $this->toolkit->defaultWritablePath);
}
if ( !$this->toolkit->getSystemConfig('Misc', 'RestrictedPath') ) {
$this->toolkit->setSystemConfig('Misc', 'RestrictedPath', $this->toolkit->getSystemConfig('Misc', 'WriteablePath') . DIRECTORY_SEPARATOR . '.restricted');
}
if ( !$this->toolkit->getSystemConfig('Misc', 'WebsitePath') ) {
$this->toolkit->setSystemConfig('Misc', 'WebsitePath', $base_path);
}
if ( $this->toolkit->systemConfigChanged ) {
// immediately save, because this paths will be used in kApplication class later
$this->toolkit->SaveConfig(true);
}
$this->currentStep = $this->GetVar('step');
// can't check login on steps where no application present anyways :)
$this->skipLoginSteps = array_unique(array_merge($this->skipLoginSteps, $this->skipApplicationSteps));
$this->SelectPreset();
if (!$this->currentStep) {
$this->SetFirstStep(); // sets first step of current preset
}
$this->InitStep();
}
function SetFirstStep()
{
reset($this->steps[$this->stepsPreset]);
$this->currentStep = current($this->steps[$this->stepsPreset]);
}
/**
* Selects preset to proceed based on various criteria
*
*/
function SelectPreset()
{
$preset = $this->GetVar('preset');
if ($this->toolkit->systemConfigFound()) {
// only at installation first step
$status = $this->CheckDatabase(false);
if ($status && $this->AlreadyInstalled()) {
// if already installed, then all future actions need login to work
$this->skipLoginSteps = Array ('check_paths', -1);
if (!$preset) {
$preset = 'already_installed';
$this->currentStep = '';
}
}
}
if ($preset === false) {
$preset = 'fresh_install'; // default preset
}
$this->stepsPreset = $preset;
}
/**
* Returns variable from request
*
* @param string $name
* @param mixed $default
* @return string|bool
* @access private
*/
private function GetVar($name, $default = false)
{
if ( array_key_exists($name, $_COOKIE) ) {
return $_COOKIE[$name];
}
if ( array_key_exists($name, $_POST) ) {
return $_POST[$name];
}
return array_key_exists($name, $_GET) ? $_GET[$name] : $default;
}
/**
* Sets new value for request variable
*
* @param string $name
* @param mixed $value
* @return void
* @access private
*/
private function SetVar($name, $value)
{
$_POST[$name] = $value;
}
/**
* Performs needed intialization of data, that step requires
*
*/
function InitStep()
{
$require_login = !in_array($this->currentStep, $this->skipLoginSteps);
$this->InitApplication($require_login);
if ($require_login) {
// step require login to proceed
if (!$this->Application->LoggedIn()) {
$this->stepsPreset = 'already_installed';
$this->currentStep = 'install_setup'; // manually set 2nd step, because 'check_paths' step doesn't contain login form
// $this->SetFirstStep();
}
}
switch ($this->currentStep) {
case 'sys_requirements':
$required_checks = Array (
'php_version', 'curl', 'simplexml', 'freetype', 'gd_version',
'jpeg', 'mysql', 'json', 'date.timezone', 'output_buffering',
);
$check_results = $this->toolkit->CallPrerequisitesMethod('core/', 'CheckSystemRequirements');
$required_checks = array_diff($required_checks, array_keys( array_filter($check_results) ));
if ( $required_checks ) {
// php-based checks failed - show error
$this->errorMessage = '<br/>Installation can not continue until all required environment parameters are set correctly';
}
elseif ( $this->GetVar('js_enabled') === false ) {
// can't check JS without form submit - set some fake error, so user stays on this step
$this->errorMessage = '&nbsp;';
}
elseif ( !$this->GetVar('js_enabled') || !$this->GetVar('cookies_enabled') ) {
// js/cookies disabled
$this->errorMessage = '<br/>Installation can not continue until all required environment parameters are set correctly';
}
break;
case 'check_paths':
$writeable_base = $this->toolkit->getSystemConfig('Misc', 'WriteablePath');
foreach ($this->writeableFolders as $folder_path) {
$file_path = FULL_PATH . str_replace('$1', $writeable_base, $folder_path);
if (file_exists($file_path) && !is_writable($file_path)) {
$this->errorMessage = '<br/>Installation can not continue until all required permissions are set correctly';
break;
}
}
break;
case 'clean_db':
// don't use Application, because all tables will be erased and it will crash
$sql = 'SELECT Path
FROM ' . TABLE_PREFIX . 'Modules';
$modules = $this->Conn->GetCol($sql);
foreach ($modules as $module_folder) {
$remove_file = '/' . $module_folder . 'install/remove_schema.sql';
if (file_exists(FULL_PATH . $remove_file)) {
$this->toolkit->RunSQL($remove_file);
}
}
$this->toolkit->deleteEditTables();
$this->currentStep = $this->GetNextStep();
break;
case 'db_config':
case 'db_reconfig':
$fields = Array (
'DBType', 'DBHost', 'DBName', 'DBUser',
'DBUserPassword', 'DBCollation', 'TablePrefix'
);
// set fields
foreach ($fields as $field_name) {
$submit_value = $this->GetVar($field_name);
if ($submit_value !== false) {
$this->toolkit->setSystemConfig('Database', $field_name, $submit_value);
}
/*else {
$this->toolkit->setSystemConfig('Database', $field_name, '');
}*/
}
break;
case 'download_license':
$license_source = $this->GetVar('license_source');
if ($license_source !== false && $license_source != 1) {
// previous step was "Select License" and not "Download from Intechnic" option was selected
$this->currentStep = $this->GetNextStep();
}
break;
case 'choose_modules':
// if no modules found, then proceed to next step
$modules = $this->ScanModules();
if (!$modules) {
$this->currentStep = $this->GetNextStep();
}
break;
case 'select_theme':
// put available theme list in database
$this->toolkit->rebuildThemes();
break;
case 'upgrade_modules':
// get installed modules from db and compare their versions to upgrade script
$modules = $this->GetUpgradableModules();
if (!$modules) {
$this->currentStep = $this->GetNextStep();
}
break;
case 'skin_upgrade':
if ($this->Application->RecallVar('SkinUpgradeLog') === false) {
// no errors during skin upgrade -> skip this step
$this->currentStep = $this->GetNextStep();
}
break;
case 'install_setup':
if ( $this->Application->TableFound(TABLE_PREFIX . 'UserSession', true) ) {
// update to 5.2.0 -> rename session table before using it
// don't rename any other table here, since their names could be used in upgrade script
$this->Conn->Query('RENAME TABLE ' . TABLE_PREFIX . 'UserSession TO ' . TABLE_PREFIX . 'UserSessions');
$this->Conn->Query('RENAME TABLE ' . TABLE_PREFIX . 'SessionData TO ' . TABLE_PREFIX . 'UserSessionData');
}
$next_preset = $this->Application->GetVar('next_preset');
if ($next_preset !== false) {
$user_helper = $this->Application->recallObject('UserHelper');
/* @var $user_helper UserHelper */
$username = $this->Application->GetVar('login');
$password = $this->Application->GetVar('password');
if ($username == 'root') {
// verify "root" user using configuration settings
$login_result = $user_helper->loginUser($username, $password);
if ($login_result != LoginResult::OK) {
$error_phrase = $login_result == LoginResult::NO_PERMISSION ? 'la_no_permissions' : 'la_invalid_password';
$this->errorMessage = $this->Application->Phrase($error_phrase) . '. If you don\'t know your username or password, contact Intechnic Support';
}
}
else {
// non "root" user -> verify using licensing server
$url_params = Array (
'login' => md5($username),
'password' => md5($password),
'action' => 'check',
'license_code' => base64_encode( $this->toolkit->getSystemConfig('Intechnic', 'LicenseCode') ),
'version' => '4.3.0',//$this->toolkit->GetMaxModuleVersion('core/'),
'domain' => base64_encode($_SERVER['HTTP_HOST']),
);
$curl_helper = $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$curl_helper->SetRequestData($url_params);
$file_data = $curl_helper->Send(GET_LICENSE_URL);
if ( !$curl_helper->isGoodResponseCode() ) {
$this->errorMessage = 'In-Portal servers temporarily unavailable. Please contact <a href="mailto:support@in-portal.com">In-Portal support</a> personnel directly.';
}
elseif (substr($file_data, 0, 5) == 'Error') {
$this->errorMessage = substr($file_data, 6) . ' If you don\'t know your username or password, contact Intechnic Support';
}
if ($this->errorMessage == '') {
$user_helper->loginUserById(USER_ROOT);
}
}
if ($this->errorMessage == '') {
// processed with redirect to selected step preset
if (!isset($this->steps[$next_preset])) {
$this->errorMessage = 'Preset "'.$next_preset.'" not yet implemented';
}
else {
$this->stepsPreset = $next_preset;
}
}
}
else {
// if preset was not choosen, then raise error
$this->errorMessage = 'Please select action to perform';
}
break;
case 'security':
// perform write check
if ($this->Application->GetVar('skip_security_check')) {
// administrator intensionally skips security checks
break;
}
$write_check = true;
$check_paths = Array ('/', '/index.php', $this->toolkit->defaultWritablePath . '/config.php', ADMIN_DIRECTORY . '/index.php');
foreach ($check_paths as $check_path) {
$path_check_status = $this->toolkit->checkWritePermissions(FULL_PATH . $check_path);
if (is_bool($path_check_status) && $path_check_status) {
$write_check = false;
break;
}
}
// script execute check
if (file_exists(WRITEABLE . '/install_check.php')) {
unlink(WRITEABLE . '/install_check.php');
}
$fp = fopen(WRITEABLE . '/install_check.php', 'w');
fwrite($fp, "<?php\n\techo 'OK';\n");
fclose($fp);
$curl_helper = $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$output = $curl_helper->Send($this->Application->BaseURL(WRITEBALE_BASE) . 'install_check.php');
unlink(WRITEABLE . '/install_check.php');
$execute_check = ($output !== 'OK');
$directive_check = true;
$ini_vars = Array ('register_globals' => false, 'open_basedir' => true, 'allow_url_fopen' => false);
foreach ($ini_vars as $var_name => $var_value) {
$current_value = ini_get($var_name);
if (($var_value && !$current_value) || (!$var_value && $current_value)) {
$directive_check = false;
break;
}
}
if (!$write_check || !$execute_check || !$directive_check) {
$this->errorMessage = true;
}
/*else {
$this->currentStep = $this->GetNextStep();
}*/
break;
}
$this->PerformValidation(); // returns validation status (just in case)
}
/**
* Validates data entered by user
*
* @return bool
*/
function PerformValidation()
{
if ($this->GetVar('step') != $this->currentStep) {
// just redirect from previous step, don't validate
return true;
}
$status = true;
switch ($this->currentStep) {
case 'db_config':
case 'db_reconfig':
// 1. check if required fields are filled
$section_name = 'Database';
$required_fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser', 'DBCollation');
foreach ($required_fields as $required_field) {
if (!$this->toolkit->getSystemConfig($section_name, $required_field)) {
$status = false;
$this->errorMessage = 'Please fill all required fields';
break;
}
}
if ( !$status ) {
break;
}
// 2. check permissions, that use have in this database
$status = $this->CheckDatabase(($this->currentStep == 'db_config') && !$this->GetVar('UseExistingSetup'));
break;
case 'select_license':
$license_source = $this->GetVar('license_source');
if ($license_source == 2) {
// license from file -> file must be uploaded
$upload_error = $_FILES['license_file']['error'];
if ($upload_error != UPLOAD_ERR_OK) {
$this->errorMessage = 'Missing License File';
}
}
elseif (!is_numeric($license_source)) {
$this->errorMessage = 'Please select license';
}
$status = $this->errorMessage == '';
break;
case 'root_password':
// check, that password & verify password match
$password = $this->Application->GetVar('root_password');
$password_verify = $this->Application->GetVar('root_password_verify');
if ($password != $password_verify) {
$this->errorMessage = 'Passwords does not match';
}
elseif (mb_strlen($password) < 4) {
$this->errorMessage = 'Root Password must be at least 4 characters';
}
$status = $this->errorMessage == '';
break;
case 'choose_modules':
break;
case 'upgrade_modules':
$modules = $this->Application->GetVar('modules');
if (!$modules) {
$modules = Array ();
$this->errorMessage = 'Please select module(-s) to ' . ($this->currentStep == 'choose_modules' ? 'install' : 'upgrade');
}
// check interface module
$upgrade_data = $this->GetUpgradableModules();
if (array_key_exists('core', $upgrade_data) && !in_array('core', $modules)) {
// core can be upgraded, but isn't selected
$this->errorMessage = 'Please select "Core" as interface module';
}
$status = $this->errorMessage == '';
break;
}
return $status;
}
/**
* Perform installation step actions
*
*/
function Run()
{
if ($this->errorMessage) {
// was error during data validation stage
return ;
}
switch ($this->currentStep) {
case 'db_config':
case 'db_reconfig':
// store db configuration
$sql = 'SHOW COLLATION
LIKE \''.$this->toolkit->getSystemConfig('Database', 'DBCollation').'\'';
$collation_info = $this->Conn->Query($sql);
if ($collation_info) {
$this->toolkit->setSystemConfig('Database', 'DBCharset', $collation_info[0]['Charset']);
// database is already connected, that's why set collation on the fly
$this->Conn->Query('SET NAMES \''.$this->toolkit->getSystemConfig('Database', 'DBCharset').'\' COLLATE \''.$this->toolkit->getSystemConfig('Database', 'DBCollation').'\'');
}
$this->toolkit->SaveConfig();
if ($this->currentStep == 'db_config') {
if ($this->GetVar('UseExistingSetup')) {
// abort clean install and redirect to already_installed
$this->stepsPreset = 'already_installed';
break;
}
// import base data into new database, not for db_reconfig
$this->toolkit->RunSQL('/core/install/install_schema.sql');
$this->toolkit->RunSQL('/core/install/install_data.sql');
// create category using sql, because Application is not available here
$table_name = $this->toolkit->getSystemConfig('Database', 'TablePrefix') . 'IdGenerator';
$this->Conn->Query('UPDATE ' . $table_name . ' SET lastid = lastid + 1');
$resource_id = $this->Conn->GetOne('SELECT lastid FROM ' . $table_name);
if ($resource_id === false) {
$this->Conn->Query('INSERT INTO '.$table_name.' (lastid) VALUES (2)');
$resource_id = 2;
}
// can't use USER_ROOT constant, since Application isn't available here
$fields_hash = Array (
'l1_Name' => 'Content', 'l1_MenuTitle' => 'Content', 'Filename' => 'Content',
'AutomaticFilename' => 0, 'CreatedById' => -1, 'CreatedOn' => time(),
'ResourceId' => $resource_id - 1, 'l1_Description' => 'Content', 'Status' => 4,
);
$this->Conn->doInsert($fields_hash, $this->toolkit->getSystemConfig('Database', 'TablePrefix') . 'Categories');
$this->toolkit->SetModuleRootCategory('Core', $this->Conn->getInsertID());
// set module "Core" version after install (based on upgrade scripts)
$this->toolkit->SetModuleVersion('Core', 'core/');
// for now we set "In-Portal" module version to "Core" module version (during clean install)
$this->toolkit->SetModuleVersion('In-Portal', 'core/');
}
break;
case 'select_license':
// reset memory cache, when application is first available (on fresh install and clean reinstall steps)
$this->Application->HandleEvent(new kEvent('adm:OnResetMemcache'));
$license_source = $this->GetVar('license_source');
switch ($license_source) {
case 1: // Download from Intechnic
break;
case 2: // Upload License File
$file_data = array_map('trim', file($_FILES['license_file']['tmp_name']));
if ((count($file_data) == 3) && $file_data[1]) {
$modules_helper = $this->Application->recallObject('ModulesHelper');
/* @var $modules_helper kModulesHelper */
if ($modules_helper->verifyLicense($file_data[1])) {
$this->toolkit->setSystemConfig('Intechnic', 'License', $file_data[1]);
$this->toolkit->setSystemConfig('Intechnic', 'LicenseCode', $file_data[2]);
$this->toolkit->SaveConfig();
}
else {
$this->errorMessage = 'Invalid License File';
}
}
else {
$this->errorMessage = 'Invalid License File';
}
break;
case 3: // Use Existing License
$license_hash = $this->toolkit->getSystemConfig('Intechnic', 'License');
if ($license_hash) {
$modules_helper = $this->Application->recallObject('ModulesHelper');
/* @var $modules_helper kModulesHelper */
if (!$modules_helper->verifyLicense($license_hash)) {
$this->errorMessage = 'Invalid or corrupt license detected';
}
}
else {
// happens, when browser's "Back" button is used
$this->errorMessage = 'Missing License File';
}
break;
case 4: // Skip License (Local Domain Installation)
if ($this->toolkit->sectionFound('Intechnic')) {
// remove any previous license information
$this->toolkit->setSystemConfig('Intechnic', 'License');
$this->toolkit->setSystemConfig('Intechnic', 'LicenseCode');
$this->toolkit->SaveConfig();
}
break;
}
break;
case 'download_license':
$license_login = $this->GetVar('login');
$license_password = $this->GetVar('password');
$license_id = $this->GetVar('licenses');
$curl_helper = $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
if (strlen($license_login) && strlen($license_password) && !$license_id) {
// Here we determine weather login is ok & check available licenses
$url_params = Array (
'login' => md5($license_login),
'password' => md5($license_password),
'version' => $this->toolkit->GetMaxModuleVersion('core/'),
'domain' => base64_encode($_SERVER['HTTP_HOST']),
);
$curl_helper->SetRequestData($url_params);
$file_data = $curl_helper->Send(GET_LICENSE_URL);
if (!$file_data) {
// error connecting to licensing server
$this->errorMessage = 'Unable to connect to the Intechnic server! Please try again later!';
}
else {
if (substr($file_data, 0, 5) == 'Error') {
// after processing data server returned error
$this->errorMessage = substr($file_data, 6);
}
else {
// license received
if (substr($file_data, 0, 3) == 'SEL') {
// we have more, then one license -> let user choose
$this->SetVar('license_selection', base64_encode( substr($file_data, 4) )); // we received html with radio buttons with names "licenses"
$this->errorMessage = 'Please select which license to use';
}
else {
// we have one license
$this->toolkit->processLicense($file_data);
}
}
}
}
else if (!$license_id) {
// licenses were not queried AND user/password missing
$this->errorMessage = 'Incorrect Username or Password. If you don\'t know your username or password, contact Intechnic Support';
}
else {
// Here we download license
$url_params = Array (
'license_id' => md5($license_id),
'dlog' => md5($license_login),
'dpass' => md5($license_password),
'version' => $this->toolkit->GetMaxModuleVersion('core/'),
'domain' => base64_encode($_SERVER['HTTP_HOST']),
);
$curl_helper->SetRequestData($url_params);
$file_data = $curl_helper->Send(GET_LICENSE_URL);
if (!$file_data) {
// error connecting to licensing server
$this->errorMessage = 'Unable to connect to the Intechnic server! Please try again later!';
}
else {
if (substr($file_data, 0, 5) == 'Error') {
// after processing data server returned error
$this->errorMessage = substr($file_data, 6);
}
else {
$this->toolkit->processLicense($file_data);
}
}
}
break;
case 'select_domain':
$modules_helper = $this->Application->recallObject('ModulesHelper');
/* @var $modules_helper kModulesHelper */
// get domain name as entered by user on the form
$domain = $this->GetVar('domain') == 1 ? $_SERVER['HTTP_HOST'] : str_replace(' ', '', $this->GetVar('other'));
$license_hash = $this->toolkit->getSystemConfig('Intechnic', 'License');
if ($license_hash) {
// when license present, then extract domain from it
$license_hash = base64_decode($license_hash);
list ( , , $license_keys) = $modules_helper->_ParseLicense($license_hash);
$license_domain = $license_keys[0]['domain'];
}
else {
// when license missing, then use current domain or domain entered by user
$license_domain = $domain;
}
if ($domain != '') {
if (strstr($domain, $license_domain) || $modules_helper->_IsLocalSite($domain)) {
$this->toolkit->setSystemConfig('Misc', 'Domain', $domain);
$this->toolkit->SaveConfig();
}
else {
$this->errorMessage = 'Domain name entered does not match domain name in the license!';
}
}
else {
$this->errorMessage = 'Please enter valid domain!';
}
break;
case 'sys_config':
$config_data = $this->GetVar('system_config');
foreach ($config_data as $section => $section_vars) {
foreach ($section_vars as $var_name => $var_value) {
$this->toolkit->setSystemConfig($section, $var_name, $var_value);
}
}
$this->toolkit->SaveConfig();
break;
case 'root_password':
// update root password in database
$password_formatter = $this->Application->recallObject('kPasswordFormatter');
/* @var $password_formatter kPasswordFormatter */
$config_values = Array (
'RootPass' => $password_formatter->hashPassword($this->Application->GetVar('root_password')),
'Backup_Path' => FULL_PATH . $this->toolkit->getSystemConfig('Misc', 'WriteablePath') . DIRECTORY_SEPARATOR . 'backupdata',
'DefaultEmailSender' => 'portal@' . $this->toolkit->getSystemConfig('Misc', 'Domain')
);
- $site_timezone = ini_get('date.timezone') ? ini_get('date.timezone') : getenv('TZ');
+ $site_timezone = date_default_timezone_get();
if ($site_timezone) {
$config_values['Config_Site_Time'] = $site_timezone;
}
$this->toolkit->saveConfigValues($config_values);
$user_helper = $this->Application->recallObject('UserHelper');
/* @var $user_helper UserHelper */
// login as "root", when no errors on password screen
$user_helper->loginUser('root', $this->Application->GetVar('root_password'));
// import base language for core (english)
$this->toolkit->ImportLanguage('/core/install/english');
// make sure imported language is set as active in session, created during installation
$this->Application->Session->SetField('Language', 1);
// set imported language as primary
$lang = $this->Application->recallObject('lang.-item', null, Array('skip_autoload' => true));
/* @var $lang LanguagesItem */
$lang->Load(1); // fresh install => ID=1
$lang->setPrimary(true); // for Front-End
break;
case 'choose_modules':
// run module install scripts
$modules = $this->Application->GetVar('modules');
if ($modules) {
foreach ($modules as $module) {
$install_file = MODULES_PATH.'/'.$module.'/install.php';
if (file_exists($install_file)) {
include_once($install_file);
}
}
}
// update category cache
$updater = $this->Application->makeClass('kPermCacheUpdater');
/* @var $updater kPermCacheUpdater */
$updater->OneStepRun();
break;
case 'post_config':
$this->toolkit->saveConfigValues( $this->GetVar('config') );
break;
case 'select_theme':
// 1. mark theme, that user is selected
$theme_id = $this->GetVar('theme');
$theme_table = $this->Application->getUnitOption('theme', 'TableName');
$theme_idfield = $this->Application->getUnitOption('theme', 'IDField');
$sql = 'UPDATE ' . $theme_table . '
SET Enabled = 1, PrimaryTheme = 1
WHERE ' . $theme_idfield . ' = ' . $theme_id;
$this->Conn->Query($sql);
$this->toolkit->rebuildThemes(); // rescan theme to create structure after theme is enabled !!!
// install theme dependent demo data
if ($this->Application->GetVar('install_demo_data')) {
$sql = 'SELECT Name
FROM ' . $theme_table . '
WHERE ' . $theme_idfield . ' = ' . $theme_id;
$theme_name = $this->Conn->GetOne($sql);
$site_path = $this->toolkit->getSystemConfig('Misc', 'WebsitePath') . '/';
$file_helper = $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
if ($module_name == 'In-Portal') {
continue;
}
$template_path = '/themes' . '/' . $theme_name . '/' . $module_info['TemplatePath'];
$this->toolkit->RunSQL( $template_path . '_install/install_data.sql', Array('{ThemeId}', '{SitePath}'), Array($theme_id, $site_path) );
if ( file_exists(FULL_PATH . $template_path . '_install/images') ) {
// copy theme demo images into writable path accessible by FCKEditor
$file_helper->copyFolderRecursive(FULL_PATH . $template_path . '_install/images' . DIRECTORY_SEPARATOR, WRITEABLE . '/user_files/Images');
}
}
}
break;
case 'upgrade_modules':
// get installed modules from db and compare their versions to upgrade script
$modules = $this->Application->GetVar('modules');
if ($modules) {
$upgrade_data = $this->GetUpgradableModules();
$start_from_query = $this->Application->GetVar('start_from_query');
$this->upgradeDepencies = $this->getUpgradeDependencies($modules, $upgrade_data);
if ($start_from_query !== false) {
$this->upgradeLog = unserialize( $this->Application->RecallVar('UpgradeLog') );
}
else {
$start_from_query = 0;
$this->upgradeLog = Array ('ModuleVersions' => Array ());
// remember each module version, before upgrade scripts are executed
foreach ($modules as $module_name) {
$module_info = $upgrade_data[$module_name];
$this->upgradeLog['ModuleVersions'][$module_name] = $module_info['FromVersion'];
}
$this->Application->RemoveVar('UpgradeLog');
}
// 1. perform "php before", "sql", "php after" upgrades
foreach ($modules as $module_name) {
$module_info = $upgrade_data[$module_name];
/*echo '<h2>Upgrading "' . $module_info['Name'] . '" to "' . $module_info['ToVersion'] . '"</h2>' . "\n";
flush();*/
if (!$this->RunUpgrade($module_info['Name'], $module_info['ToVersion'], $upgrade_data, $start_from_query)) {
$this->Application->StoreVar('UpgradeLog', serialize($this->upgradeLog));
$this->Done();
}
// restore upgradable module version (makes sense after sql error processing)
$upgrade_data[$module_name]['FromVersion'] = $this->upgradeLog['ModuleVersions'][$module_name];
}
// 2. import language pack, perform "languagepack" upgrade for all upgraded versions
foreach ($modules as $module_name) {
$module_info = $upgrade_data[$module_name];
$sqls =& $this->getUpgradeQueriesFromVersion($module_info['Path'], $module_info['FromVersion']);
preg_match_all('/' . VERSION_MARK . '/s', $sqls, $regs);
// import module language pack
$this->toolkit->ImportLanguage('/' . $module_info['Path'] . 'install/english', true);
// perform advanced language pack upgrade
foreach ($regs[1] as $version) {
$this->RunUpgradeScript($module_info['Path'], $version, 'languagepack');
}
}
// 3. update all theme language packs
$themes_helper = $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$themes_helper->synchronizeModule(false);
// 4. upgrade admin skin
if (in_array('core', $modules)) {
$skin_upgrade_log = $this->toolkit->upgradeSkin($upgrade_data['core']);
if ($skin_upgrade_log === true) {
$this->Application->RemoveVar('SkinUpgradeLog');
}
else {
$this->Application->StoreVar('SkinUpgradeLog', serialize($skin_upgrade_log));
}
// for now we set "In-Portal" module version to "Core" module version (during upgrade)
$this->toolkit->SetModuleVersion('In-Portal', false, $upgrade_data['core']['ToVersion']);
}
}
break;
case 'finish':
// delete cache
$this->toolkit->deleteCache();
$this->toolkit->rebuildThemes();
// compile admin skin, so it will be available in 3 frames at once
$skin_helper = $this->Application->recallObject('SkinHelper');
/* @var $skin_helper SkinHelper */
$skin = $this->Application->recallObject('skin', null, Array ('skip_autoload' => true));
/* @var $skin kDBItem */
$skin->Load(1, 'IsPrimary');
$skin_helper->compile($skin);
// set installation finished mark
if ($this->Application->ConfigValue('InstallFinished') === false) {
$fields_hash = Array (
'VariableName' => 'InstallFinished',
'VariableValue' => 1,
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'SystemSettings');
}
break;
}
if ($this->errorMessage) {
// was error during run stage
return ;
}
$this->currentStep = $this->GetNextStep();
$this->InitStep(); // init next step (that will be shown now)
$this->InitApplication();
if ($this->currentStep == -1) {
// step after last step -> redirect to admin
$user_helper = $this->Application->recallObject('UserHelper');
/* @var $user_helper UserHelper */
$user_helper->logoutUser();
$this->Application->Redirect($user_helper->event->redirect, $user_helper->event->getRedirectParams(), '', 'index.php');
}
}
function getUpgradeDependencies($modules, &$upgrade_data)
{
$dependencies = Array ();
foreach ($modules as $module_name) {
$module_info = $upgrade_data[$module_name];
$upgrade_object =& $this->getUpgradeObject($module_info['Path']);
if (!is_object($upgrade_object)) {
continue;
}
foreach ($upgrade_object->dependencies as $dependent_version => $version_dependencies) {
if (!$version_dependencies) {
// module is independent -> skip
continue;
}
list ($parent_name, $parent_version) = each($version_dependencies);
if (!array_key_exists($parent_name, $dependencies)) {
// parent module
$dependencies[$parent_name] = Array ();
}
if (!array_key_exists($parent_version, $dependencies[$parent_name])) {
// parent module versions, that are required by other module versions
$dependencies[$parent_name][$parent_version] = Array ();
}
$dependencies[$parent_name][$parent_version][] = Array ($module_info['Name'] => $dependent_version);
}
}
return $dependencies;
}
/**
* Returns database queries, that should be executed to perform upgrade from given to lastest version of given module path
*
* @param string $module_path
* @param string $from_version
* @return string
*/
function &getUpgradeQueriesFromVersion($module_path, $from_version)
{
$upgrades_file = sprintf(UPGRADES_FILE, $module_path, 'sql');
$sqls = file_get_contents($upgrades_file);
$version_mark = preg_replace('/(\(.*?\))/', $from_version, VERSION_MARK);
// get only sqls from next (relative to current) version to end of file
$start_pos = strpos($sqls, $version_mark);
$sqls = substr($sqls, $start_pos);
return $sqls;
}
function RunUpgrade($module_name, $to_version, &$upgrade_data, &$start_from_query)
{
$module_info = $upgrade_data[ strtolower($module_name) ];
$sqls =& $this->getUpgradeQueriesFromVersion($module_info['Path'], $module_info['FromVersion']);
preg_match_all('/(' . VERSION_MARK . ')/s', $sqls, $matches, PREG_SET_ORDER + PREG_OFFSET_CAPTURE);
foreach ($matches as $index => $match) {
// upgrade version
$version = $match[2][0];
if ($this->toolkit->ConvertModuleVersion($version) > $this->toolkit->ConvertModuleVersion($to_version)) {
// only upgrade to $to_version, not further
break;
}
if (!in_array($module_name . ':' . $version, $this->upgradeLog)) {
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendHTML('Upgrading "' . $module_name . '" to "' . $version . '" version: BEGIN.');
}
/*echo 'Upgrading "' . $module_name . '" to "' . $version . '".<br/>' . "\n";
flush();*/
// don't upgrade same version twice
$start_pos = $match[0][1] + strlen($match[0][0]);
$end_pos = array_key_exists($index + 1, $matches) ? $matches[$index + 1][0][1] : strlen($sqls);
$version_sqls = substr($sqls, $start_pos, $end_pos - $start_pos);
if ($start_from_query == 0) {
$this->RunUpgradeScript($module_info['Path'], $version, 'before');
}
if (!$this->toolkit->RunSQLText($version_sqls, null, null, $start_from_query)) {
$this->errorMessage .= '<input type="hidden" name="start_from_query" value="' . $this->LastQueryNum . '">';
$this->errorMessage .= '<br/>Module "' . $module_name . '" upgrade to "' . $version . '" failed.';
$this->errorMessage .= '<br/>Click Continue button below to skip this query and go further<br/>';
return false;
}
else {
// reset query counter, when all queries were processed
$start_from_query = 0;
}
$this->RunUpgradeScript($module_info['Path'], $version, 'after');
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendHTML('Upgrading "' . $module_name . '" to "' . $version . '" version: END.');
}
// remember, that we've already upgraded given version
$this->upgradeLog[] = $module_name . ':' . $version;
}
if (array_key_exists($module_name, $this->upgradeDepencies) && array_key_exists($version, $this->upgradeDepencies[$module_name])) {
foreach ($this->upgradeDepencies[$module_name][$version] as $dependency_info) {
list ($dependent_module, $dependent_version) = each($dependency_info);
if (!$this->RunUpgrade($dependent_module, $dependent_version, $upgrade_data, $start_from_query)) {
return false;
}
}
}
// only mark module as updated, when all it's dependent modules are upgraded
$this->toolkit->SetModuleVersion($module_name, false, $version);
}
return true;
}
/**
* Run upgrade PHP scripts for module with specified path
*
* @param string $module_path
* @param Array $version
* @param string $mode upgrade mode = {before,after,languagepack}
*/
function RunUpgradeScript($module_path, $version, $mode)
{
$upgrade_object =& $this->getUpgradeObject($module_path);
if (!is_object($upgrade_object)) {
return ;
}
$upgrade_method = 'Upgrade_' . str_replace(Array ('.', '-'), '_', $version);
if (method_exists($upgrade_object, $upgrade_method)) {
$upgrade_object->$upgrade_method($mode);
}
}
/**
* Returns upgrade class for given module path
*
* @param string $module_path
* @return kUpgradeHelper
*/
function &getUpgradeObject($module_path)
{
static $upgrade_classes = Array ();
$upgrades_file = sprintf(UPGRADES_FILE, $module_path, 'php');
if (!file_exists($upgrades_file)) {
$false = false;
return $false;
}
if (!isset($upgrade_classes[$module_path])) {
require_once(FULL_PATH . REL_PATH . '/install/upgrade_helper.php');
// save class name, because 2nd time (in after call)
// $upgrade_class variable will not be present
include_once $upgrades_file;
$upgrade_classes[$module_path] = $upgrade_class;
}
$upgrade_object = new $upgrade_classes[$module_path]();
/* @var $upgrade_object CoreUpgrades */
$upgrade_object->setToolkit($this->toolkit);
return $upgrade_object;
}
/**
* Initialize kApplication
*
* @param bool $force initialize in any case
*/
function InitApplication($force = false)
{
if (($force || !in_array($this->currentStep, $this->skipApplicationSteps)) && !isset($this->Application)) {
// step is allowed for application usage & it was not initialized in previous step
global $start, $debugger, $dbg_options;
include_once(FULL_PATH.'/core/kernel/startup.php');
$this->Application =& kApplication::Instance();
$this->toolkit->Application =& kApplication::Instance();
$this->includeModuleConstants();
$this->Application->Init();
$this->Conn =& $this->Application->GetADODBConnection();
$this->toolkit->Conn =& $this->Application->GetADODBConnection();
}
}
/**
* When no modules installed, then pre-include all modules contants, since they are used in unit configs
*
*/
function includeModuleConstants()
{
$modules = $this->ScanModules();
foreach ($modules as $module_path) {
$constants_file = MODULES_PATH . '/' . $module_path . '/constants.php';
if ( file_exists($constants_file) ) {
kUtil::includeOnce($constants_file);
}
}
}
/**
* Show next step screen
*
* @param string $error_message
* @return void
*/
function Done($error_message = null)
{
if ( isset($error_message) ) {
$this->errorMessage = $error_message;
}
include_once (FULL_PATH . '/' . REL_PATH . '/install/incs/install.tpl');
if ( isset($this->Application) ) {
$this->Application->Done();
}
exit;
}
function ConnectToDatabase()
{
include_once FULL_PATH . '/core/kernel/db/db_connection.php';
$required_keys = Array ('DBType', 'DBUser', 'DBName');
foreach ($required_keys as $required_key) {
if (!$this->toolkit->getSystemConfig('Database', $required_key)) {
// one of required db connection settings missing -> abort connection
return false;
}
}
$this->Conn = new kDBConnection($this->toolkit->getSystemConfig('Database', 'DBType'), Array(&$this, 'DBErrorHandler'));
$this->Conn->setup( $this->toolkit->systemConfig );
// setup toolkit too
$this->toolkit->Conn =& $this->Conn;
return !$this->Conn->hasError();
}
/**
* Checks if core is already installed
*
* @return bool
*/
function AlreadyInstalled()
{
$table_prefix = $this->toolkit->getSystemConfig('Database', 'TablePrefix');
$settings_table = $this->TableExists('ConfigurationValues') ? 'ConfigurationValues' : 'SystemSettings';
$sql = 'SELECT VariableValue
FROM ' . $table_prefix . $settings_table . '
WHERE VariableName = "InstallFinished"';
return $this->TableExists($settings_table) && $this->Conn->GetOne($sql);
}
function CheckDatabase($check_installed = true)
{
// perform various check type to database specified
// 1. user is allowed to connect to database
// 2. user has all types of permissions in database
// 3. database environment settings met minimum requirements
if (mb_strlen($this->toolkit->getSystemConfig('Database', 'TablePrefix')) > 7) {
$this->errorMessage = 'Table prefix should not be longer than 7 characters';
return false;
}
// connect to database
$status = $this->ConnectToDatabase();
if ($status) {
// if connected, then check if all sql statements work
$sql_tests[] = 'DROP TABLE IF EXISTS test_table';
$sql_tests[] = 'CREATE TABLE test_table(test_col mediumint(6))';
$sql_tests[] = 'LOCK TABLES test_table WRITE';
$sql_tests[] = 'INSERT INTO test_table(test_col) VALUES (5)';
$sql_tests[] = 'UPDATE test_table SET test_col = 12';
$sql_tests[] = 'UNLOCK TABLES';
$sql_tests[] = 'ALTER TABLE test_table ADD COLUMN new_col varchar(10)';
$sql_tests[] = 'SELECT * FROM test_table';
$sql_tests[] = 'DELETE FROM test_table';
$sql_tests[] = 'DROP TABLE IF EXISTS test_table';
foreach ($sql_tests as $sql_test) {
$this->Conn->Query($sql_test);
if ($this->Conn->getErrorCode() != 0) {
$status = false;
break;
}
}
if ($status) {
// if statements work & connection made, then check table existance
if ($check_installed && $this->AlreadyInstalled()) {
$this->errorMessage = 'An In-Portal Database already exists at this location';
return false;
}
$requirements_error = Array ();
$db_check_results = $this->toolkit->CallPrerequisitesMethod('core/', 'CheckDBRequirements');
if ( !$db_check_results['version'] ) {
$requirements_error[] = '- MySQL Version is below 5.0';
}
if ( !$db_check_results['packet_size'] ) {
$requirements_error[] = '- MySQL Packet Size is below 1 MB';
}
if ( $requirements_error ) {
$this->errorMessage = 'Connection successful, but following system requirements were not met:<br/>' . implode('<br/>', $requirements_error);
return false;
}
}
else {
// user has insufficient permissions in database specified
$this->errorMessage = 'Permission Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg();
return false;
}
}
else {
// was error while connecting
if (!$this->Conn) return false;
$this->errorMessage = 'Connection Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg();
return false;
}
return true;
}
/**
* Checks if all passed tables exists
*
* @param string $tables comma separated tables list
* @return bool
*/
function TableExists($tables)
{
$prefix = $this->toolkit->getSystemConfig('Database', 'TablePrefix');
$all_found = true;
$tables = explode(',', $tables);
foreach ($tables as $table_name) {
$sql = 'SHOW TABLES LIKE "'.$prefix.$table_name.'"';
if (count($this->Conn->Query($sql)) == 0) {
$all_found = false;
break;
}
}
return $all_found;
}
/**
* Returns modules list found in modules folder
*
* @return Array
*/
function ScanModules()
{
static $modules = null;
if ( !isset($modules) ) {
// use direct include, because it's called before kApplication::Init, that creates class factory
kUtil::includeOnce( KERNEL_PATH . kApplication::MODULE_HELPER_PATH );
$modules_helper = new kModulesHelper();
$modules = $modules_helper->getModules();
}
return $modules;
}
/**
* Virtually place module under "modules" folder or it won't be recognized during upgrade to 5.1.0 version
*
* @param string $name
* @param string $path
* @param string $version
* @return string
*/
function getModulePath($name, $path, $version)
{
if ($name == 'Core') {
// don't transform path for Core module
return $path;
}
if (!preg_match('/^modules\//', $path)) {
// upgrade from 5.0.x/1.0.x to 5.1.x/1.1.x
return 'modules/' . $path;
}
return $path;
}
/**
* Returns list of modules, that can be upgraded
*
*/
function GetUpgradableModules()
{
$ret = Array ();
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
if ($module_name == 'In-Portal') {
// don't show In-Portal, because it shares upgrade scripts with Core module
continue;
}
$module_info['Path'] = $this->getModulePath($module_name, $module_info['Path'], $module_info['Version']);
$upgrades_file = sprintf(UPGRADES_FILE, $module_info['Path'], 'sql');
if (!file_exists($upgrades_file)) {
// no upgrade file
continue;
}
$sqls = file_get_contents($upgrades_file);
$versions_found = preg_match_all('/'.VERSION_MARK.'/s', $sqls, $regs);
if (!$versions_found) {
// upgrades file doesn't contain version definitions
continue;
}
$to_version = end($regs[1]);
$this_version = $this->toolkit->ConvertModuleVersion($module_info['Version']);
if ($this->toolkit->ConvertModuleVersion($to_version) > $this_version) {
// destination version is greather then current
foreach ($regs[1] as $version) {
if ($this->toolkit->ConvertModuleVersion($version) > $this_version) {
$from_version = $version;
break;
}
}
$version_info = Array (
'FromVersion' => $from_version,
'ToVersion' => $to_version,
);
$ret[ strtolower($module_name) ] = array_merge($module_info, $version_info);
}
}
return $ret;
}
/**
* Returns content to show for current step
*
* @return string
*/
function GetStepBody()
{
$step_template = FULL_PATH.'/core/install/step_templates/'.$this->currentStep.'.tpl';
if (file_exists($step_template)) {
ob_start();
include_once ($step_template);
return ob_get_clean();
}
return '{step template "'.$this->currentStep.'" missing}';
}
/**
* Parses step information file, cache result for current step ONLY & return it
*
* @return Array
*/
function &_getStepInfo()
{
static $info = Array('help_title' => null, 'step_title' => null, 'help_body' => null, 'queried' => false);
if (!$info['queried']) {
$fdata = file_get_contents($this->StepDBFile);
$parser = xml_parser_create();
xml_parse_into_struct($parser, $fdata, $values, $index);
xml_parser_free($parser);
foreach ($index['STEP'] as $section_index) {
$step_data =& $values[$section_index];
if ($step_data['attributes']['NAME'] == $this->currentStep) {
$info['step_title'] = $step_data['attributes']['TITLE'];
if (isset($step_data['attributes']['HELP_TITLE'])) {
$info['help_title'] = $step_data['attributes']['HELP_TITLE'];
}
else {
// if help title not set, then use step title
$info['help_title'] = $step_data['attributes']['TITLE'];
}
$info['help_body'] = trim($step_data['value']);
break;
}
}
$info['queried'] = true;
}
return $info;
}
/**
* Returns particular information abou current step
*
* @param string $info_type
* @return string
*/
function GetStepInfo($info_type)
{
$step_info =& $this->_getStepInfo();
if (isset($step_info[$info_type])) {
return $step_info[$info_type];
}
return '{step "'.$this->currentStep.'"; param "'.$info_type.'" missing}';
}
/**
* Returns passed steps titles
*
* @param Array $steps
* @return Array
* @see kInstaller:PrintSteps
*/
function _getStepTitles($steps)
{
$fdata = file_get_contents($this->StepDBFile);
$parser = xml_parser_create();
xml_parse_into_struct($parser, $fdata, $values, $index);
xml_parser_free($parser);
$ret = Array ();
foreach ($index['STEP'] as $section_index) {
$step_data =& $values[$section_index];
if (in_array($step_data['attributes']['NAME'], $steps)) {
$ret[ $step_data['attributes']['NAME'] ] = $step_data['attributes']['TITLE'];
}
}
return $ret;
}
/**
* Returns current step number in active steps_preset.
* Value can't be cached, because same step can have different number in different presets
*
* @return int
*/
function GetStepNumber()
{
return array_search($this->currentStep, $this->steps[$this->stepsPreset]) + 1;
}
/**
* Returns step name to process next
*
* @return string
*/
function GetNextStep()
{
$next_index = $this->GetStepNumber();
if ($next_index > count($this->steps[$this->stepsPreset]) - 1) {
return -1;
}
return $this->steps[$this->stepsPreset][$next_index];
}
/**
* Returns step name, that was processed before this step
*
* @return string
*/
function GetPreviousStep()
{
$next_index = $this->GetStepNumber() - 1;
if ($next_index < 0) {
$next_index = 0;
}
return $this->steps[$this->stepsPreset][$next_index];
}
/**
* Prints all steps from active steps preset and highlights current step
*
* @param string $active_tpl
* @param string $passive_tpl
* @return string
*/
function PrintSteps($active_tpl, $passive_tpl)
{
$ret = '';
$step_titles = $this->_getStepTitles($this->steps[$this->stepsPreset]);
foreach ($this->steps[$this->stepsPreset] as $step_name) {
$template = $step_name == $this->currentStep ? $active_tpl : $passive_tpl;
$ret .= sprintf($template, $step_titles[$step_name]);
}
return $ret;
}
/**
* Installation error handler for sql errors
*
* @param int $code
* @param string $msg
* @param string $sql
* @return bool
* @access private
*/
function DBErrorHandler($code, $msg, $sql)
{
$this->errorMessage = 'Query: <br />'.htmlspecialchars($sql, null, 'UTF-8').'<br />execution result is error:<br />['.$code.'] '.$msg;
return true;
}
/**
* Installation error handler
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
* @param Array|string $errcontext
*/
function ErrorHandler($errno, $errstr, $errfile = '', $errline = 0, $errcontext = '')
{
if ($errno == E_USER_ERROR) {
// only react on user fatal errors
$this->Done($errstr);
}
}
/**
* Checks, that given button should be visible on current installation step
*
* @param string $name
* @return bool
*/
function buttonVisible($name)
{
$button_visibility = Array (
'continue' => $this->GetNextStep() != -1 || ($this->stepsPreset == 'already_installed'),
'refresh' => in_array($this->currentStep, Array ('sys_requirements', 'check_paths', 'security')),
'back' => in_array($this->currentStep, Array (/*'select_license',*/ 'download_license', 'select_domain')),
);
if ($name == 'any') {
foreach ($button_visibility as $button_name => $button_visible) {
if ($button_visible) {
return true;
}
}
return false;
}
return array_key_exists($name, $button_visibility) ? $button_visibility[$name] : true;
}
}

Event Timeline