Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F871892
install_toolkit.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, May 8, 5:09 AM
Size
32 KB
Mime Type
text/x-php
Expires
Sat, May 10, 5:09 AM (1 d, 20 h)
Engine
blob
Format
Raw Data
Handle
617722
Attached To
rINP In-Portal
install_toolkit.php
View Options
<?php
/**
* @version $Id: install_toolkit.php 15421 2012-06-29 13:06:20Z alex $
* @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!'
);
/**
* Upgrade sqls are located using this mask
*
*/
define
(
'UPGRADES_FILE'
,
FULL_PATH
.
'/%sinstall/upgrades.%s'
);
/**
* Prerequisit check classes are located using this mask
*
*/
define
(
'PREREQUISITE_FILE'
,
FULL_PATH
.
'/%sinstall/prerequisites.php'
);
/**
* Format of version identificator in upgrade files (normal, beta, release candidate)
*
*/
define
(
'VERSION_MARK'
,
'# ===== v ([
\d
]+
\.
[
\d
]+
\.
[
\d
]+|[
\d
]+
\.
[
\d
]+
\.
[
\d
]+-B[
\d
]+|[
\d
]+
\.
[
\d
]+
\.
[
\d
]+-RC[
\d
]+) ====='
);
if
(!
defined
(
'GET_LICENSE_URL'
))
{
/**
* Url used for retrieving user licenses from Intechnic licensing server
*
*/
define
(
'GET_LICENSE_URL'
,
'http://www.in-portal.com/license.php'
);
}
/**
* Misc functions, that are required during installation, when
*
*/
class
kInstallToolkit
{
/**
* Reference to kApplication class object
*
* @var kApplication
*/
var
$Application
=
null
;
/**
* Connection to database
*
* @var kDBConnection
*/
var
$Conn
=
null
;
/**
* Path to config.php
*
* @var string
*/
var
$INIFile
=
''
;
/**
* Parsed data from config.php
*
* @var Array
*/
var
$systemConfig
=
Array
();
/**
* Tells, that system config was changed
*
* @var bool
* @access public
*/
public
$systemConfigChanged
=
false
;
/**
* Path, used by system to store data on filesystem
*
* @var string
*/
var
$defaultWritablePath
=
''
;
/**
* Installator instance
*
* @var kInstallator
*/
var
$_installator
=
null
;
function
kInstallToolkit
()
{
$this
->
defaultWritablePath
=
DIRECTORY_SEPARATOR
.
'system'
;
if
(
class_exists
(
'kApplication'
)
)
{
// auto-setup in case of separate module install
$this
->
Application
=&
kApplication
::
Instance
();
$this
->
Application
->
Init
();
// needed for standalone module install
$this
->
Conn
=&
$this
->
Application
->
GetADODBConnection
();
}
$this
->
INIFile
=
FULL_PATH
.
$this
->
defaultWritablePath
.
DIRECTORY_SEPARATOR
.
'config.php'
;
$this
->
systemConfig
=
$this
->
ParseConfig
(
true
);
}
/**
* Sets installator
*
* @param kInstallator $instance
*/
function
setInstallator
(&
$instance
)
{
$this
->
_installator
=&
$instance
;
}
/**
* Checks prerequisities before module install or upgrade
*
* @param string $module_path
* @param string $versions
* @param string $mode upgrade mode = {install, standalone, upgrade}
* @return bool
*/
function
CheckPrerequisites
(
$module_path
,
$versions
,
$mode
)
{
if
(
!
$versions
)
{
return
Array
();
}
$prerequisite_object
=&
$this
->
getPrerequisiteObject
(
$module_path
);
/* @var $prerequisite_object InPortalPrerequisites */
// some errors possible
return
is_object
(
$prerequisite_object
)
?
$prerequisite_object
->
CheckPrerequisites
(
$versions
,
$mode
)
:
Array
();
}
/**
* Call prerequisites method
*
* @param string $module_path
* @param string $method
* @return array
*/
function
CallPrerequisitesMethod
(
$module_path
,
$method
)
{
$prerequisite_object
=&
$this
->
getPrerequisiteObject
(
$module_path
);
/* @var $prerequisite_object InPortalPrerequisites */
return
is_object
(
$prerequisite_object
)
?
$prerequisite_object
->
$method
()
:
false
;
}
/**
* Returns prerequisite object to be used for checks
*
* @param string $module_path
* @return kHelper
* @access protected
*/
protected
function
&
getPrerequisiteObject
(
$module_path
)
{
static
$prerequisite_classes
=
Array
();
$prerequisites_file
=
sprintf
(
PREREQUISITE_FILE
,
$module_path
);
if
(
!
file_exists
(
$prerequisites_file
)
)
{
$false
=
false
;
return
$false
;
}
if
(
!
isset
(
$prerequisite_classes
[
$module_path
])
)
{
// save class name, because 2nd time
// (in after call $prerequisite_class variable will not be present)
include_once
$prerequisites_file
;
$prerequisite_classes
[
$module_path
]
=
$prerequisite_class
;
}
$prerequisite_object
=
new
$prerequisite_classes
[
$module_path
]();
/* @var $prerequisite_object InPortalPrerequisites */
if
(
method_exists
(
$prerequisite_object
,
'setToolkit'
)
)
{
$prerequisite_object
->
setToolkit
(
$this
);
}
return
$prerequisite_object
;
}
/**
* Processes one license, received from server
*
* @param string $file_data
*/
function
processLicense
(
$file_data
)
{
$modules_helper
=
$this
->
Application
->
recallObject
(
'ModulesHelper'
);
/* @var $modules_helper kModulesHelper */
$file_data
=
explode
(
'Code==:'
,
$file_data
);
$file_data
[
0
]
=
str_replace
(
'In-Portal License File - do not edit!'
.
"
\n
"
,
''
,
$file_data
[
0
]);
$file_data
=
array_map
(
'trim'
,
$file_data
);
if
(
$modules_helper
->
verifyLicense
(
$file_data
[
0
]))
{
$this
->
setSystemConfig
(
'Intechnic'
,
'License'
,
$file_data
[
0
]);
if
(
array_key_exists
(
1
,
$file_data
))
{
$this
->
setSystemConfig
(
'Intechnic'
,
'LicenseCode'
,
$file_data
[
1
]);
}
else
{
$this
->
setSystemConfig
(
'Intechnic'
,
'LicenseCode'
);
}
$this
->
SaveConfig
();
}
else
{
// invalid license received from licensing server
$this
->
_installator
->
errorMessage
=
'Invalid License File'
;
}
}
/**
* Saves given configuration values to database
*
* @param Array $config
*/
function
saveConfigValues
(
$config
)
{
foreach
(
$config
as
$config_var
=>
$value
)
{
$sql
=
'UPDATE '
.
TABLE_PREFIX
.
'SystemSettings
SET VariableValue = '
.
$this
->
Conn
->
qstr
(
$value
)
.
'
WHERE VariableName = '
.
$this
->
Conn
->
qstr
(
$config_var
);
$this
->
Conn
->
Query
(
$sql
);
}
}
/**
* Sets module version to passed
*
* @param string $module_name
* @param string|bool $module_path
* @param string|bool $version
*/
function
SetModuleVersion
(
$module_name
,
$module_path
=
false
,
$version
=
false
)
{
if
(
$version
===
false
)
{
if
(!
$module_path
)
{
throw
new
Exception
(
'Module path must be given to "SetModuleVersion" method to auto-detect version'
);
return
;
}
$version
=
$this
->
GetMaxModuleVersion
(
$module_path
);
}
// get table prefix from config, because application may not be available here
$table_prefix
=
$this
->
getSystemConfig
(
'Database'
,
'TablePrefix'
);
if
(
$module_name
==
'kernel'
)
{
$module_name
=
'in-portal'
;
}
// don't use "adodb_mktime" here, because it's not yet included
$sql
=
'UPDATE '
.
$table_prefix
.
'Modules
SET Version = "'
.
$version
.
'", BuildDate = '
.
time
()
.
'
WHERE LOWER(Name) = "'
.
strtolower
(
$module_name
)
.
'"'
;
$this
->
Conn
->
Query
(
$sql
);
}
/**
* Sets module root category to passed
*
* @param string $module_name
* @param int $category_id
*/
function
SetModuleRootCategory
(
$module_name
,
$category_id
=
0
)
{
// get table prefix from config, because application may not be available here
$table_prefix
=
$this
->
getSystemConfig
(
'Database'
,
'TablePrefix'
);
if
(
$module_name
==
'kernel'
)
{
$module_name
=
'in-portal'
;
}
$sql
=
'UPDATE '
.
$table_prefix
.
'Modules
SET RootCat = '
.
$category_id
.
'
WHERE LOWER(Name) = "'
.
strtolower
(
$module_name
)
.
'"'
;
$this
->
Conn
->
Query
(
$sql
);
}
/**
* Returns maximal version of given module by scanning it's upgrade scripts
*
* @param string $module_path
* @return string
*/
function
GetMaxModuleVersion
(
$module_path
)
{
$module_path
=
rtrim
(
mb_strtolower
(
$module_path
),
'/'
);
$upgrades_file
=
sprintf
(
UPGRADES_FILE
,
$module_path
.
'/'
,
'sql'
);
if
(!
file_exists
(
$upgrades_file
))
{
// no upgrade file
return
'5.0.0'
;
}
$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
return
'5.0.0'
;
}
return
end
(
$regs
[
1
]);
}
/**
* Runs SQLs from file
*
* @param string $filename
* @param mixed $replace_from
* @param mixed $replace_to
*/
function
RunSQL
(
$filename
,
$replace_from
=
null
,
$replace_to
=
null
)
{
if
(!
file_exists
(
FULL_PATH
.
$filename
))
{
return
;
}
$sqls
=
file_get_contents
(
FULL_PATH
.
$filename
);
if
(!
$this
->
RunSQLText
(
$sqls
,
$replace_from
,
$replace_to
))
{
if
(
is_object
(
$this
->
_installator
))
{
$this
->
_installator
->
Done
();
}
else
{
if
(
isset
(
$this
->
Application
))
{
$this
->
Application
->
Done
();
}
exit
;
}
}
}
/**
* Runs SQLs from string
*
* @param string $sqls
* @param mixed $replace_from
* @param mixed $replace_to
* @param int $start_from
* @return bool
*/
function
RunSQLText
(&
$sqls
,
$replace_from
=
null
,
$replace_to
=
null
,
$start_from
=
0
)
{
$table_prefix
=
$this
->
getSystemConfig
(
'Database'
,
'TablePrefix'
);
// add prefix to all tables
if
(
strlen
(
$table_prefix
)
>
0
)
{
$replacements
=
Array
(
'INSERT INTO '
,
'UPDATE '
,
'ALTER TABLE '
,
'DELETE FROM '
,
'REPLACE INTO '
);
foreach
(
$replacements
as
$replacement
)
{
$sqls
=
str_replace
(
$replacement
,
$replacement
.
$table_prefix
,
$sqls
);
}
}
$sqls
=
str_replace
(
'CREATE TABLE '
,
'CREATE TABLE IF NOT EXISTS '
.
$table_prefix
,
$sqls
);
$sqls
=
str_replace
(
'DROP TABLE '
,
'DROP TABLE IF EXISTS '
.
$table_prefix
,
$sqls
);
$sqls
=
str_replace
(
'<%TABLE_PREFIX%>'
,
$table_prefix
,
$sqls
);
$primary_language
=
is_object
(
$this
->
Application
)
?
$this
->
Application
->
GetDefaultLanguageId
()
:
1
;
$sqls
=
str_replace
(
'<%PRIMARY_LANGUAGE%>'
,
$primary_language
,
$sqls
);
if
(
isset
(
$replace_from
)
&&
isset
(
$replace_to
))
{
// replace something additionally, e.g. module root category
$sqls
=
str_replace
(
$replace_from
,
$replace_to
,
$sqls
);
}
$sqls
=
str_replace
(
"
\r\n
"
,
"
\n
"
,
$sqls
);
// convert to linux line endings
$no_comment_sqls
=
preg_replace
(
"/#
\s
([^;]*?)
\n
/is"
,
''
,
$sqls
);
// remove all comments "#" on new lines
if
(
$no_comment_sqls
===
null
)
{
// "ini.pcre.backtrack-limit" reached and error happened
$sqls
=
explode
(
";
\n
"
,
$sqls
.
"
\n
"
);
// ensures that last sql won't have ";" in it
$sqls
=
array_map
(
'trim'
,
$sqls
);
// remove all comments "#" on new lines (takes about 2 seconds for 53000 sqls)
$sqls
=
preg_replace
(
"/#
\s
([^;]*?)/"
,
''
,
$sqls
);
}
else
{
$sqls
=
explode
(
";
\n
"
,
$no_comment_sqls
.
"
\n
"
);
// ensures that last sql won't have ";" in it
$sqls
=
array_map
(
'trim'
,
$sqls
);
}
$sql_count
=
count
(
$sqls
);
$db_collation
=
$this
->
getSystemConfig
(
'Database'
,
'DBCollation'
);
for
(
$i
=
$start_from
;
$i
<
$sql_count
;
$i
++)
{
$sql
=
$sqls
[
$i
];
if
(!
$sql
||
(
substr
(
$sql
,
0
,
1
)
==
'#'
))
{
continue
;
// usually last line
}
if
(
substr
(
$sql
,
0
,
13
)
==
'CREATE TABLE '
&&
$db_collation
)
{
// it is CREATE TABLE statement -> add collation
$sql
.=
' COLLATE
\'
'
.
$db_collation
.
'
\'
'
;
}
$this
->
Conn
->
Query
(
$sql
);
if
(
$this
->
Conn
->
getErrorCode
()
!=
0
)
{
if
(
is_object
(
$this
->
_installator
))
{
$this
->
_installator
->
errorMessage
=
'Error: ('
.
$this
->
Conn
->
getErrorCode
().
') '
.
$this
->
Conn
->
getErrorMsg
().
'<br /><br />Last Database Query:<br /><textarea cols="70" rows="10" readonly>'
.
htmlspecialchars
(
$sql
).
'</textarea>'
;
$this
->
_installator
->
LastQueryNum
=
$i
+
1
;
}
return
false
;
}
}
return
true
;
}
/**
* Performs clean language import from given xml file
*
* @param string $lang_file
* @param bool $upgrade
* @todo Import for "core/install/english.lang" (322KB) takes 18 seconds to work on Windows
*/
function
ImportLanguage
(
$lang_file
,
$upgrade
=
false
)
{
$lang_file
=
FULL_PATH
.
$lang_file
.
'.lang'
;
if
(!
file_exists
(
$lang_file
))
{
return
;
}
$language_import_helper
=
$this
->
Application
->
recallObject
(
'LanguageImportHelper'
);
/* @var $language_import_helper LanguageImportHelper */
$language_import_helper
->
performImport
(
$lang_file
,
'|0|1|2|'
,
''
,
$upgrade
?
LANG_SKIP_EXISTING
:
LANG_OVERWRITE_EXISTING
);
}
/**
* Converts module version in format X.Y.Z[-BN/-RCM] to signle integer
*
* @param string $version
* @return int
*/
function
ConvertModuleVersion
(
$version
)
{
if
(
preg_match
(
'/(.*)-(B|RC)([
\d
]+)/'
,
$version
,
$regs
))
{
// -B<M> or RC-<N>
$parts
=
explode
(
'.'
,
$regs
[
1
]);
$parts
[]
=
$regs
[
2
]
==
'B'
?
1
:
2
;
// B reliases goes before RC releases
$parts
[]
=
$regs
[
3
];
}
else
{
// releases without B/RC marks go after any B/RC releases
$parts
=
explode
(
'.'
,
$version
.
'.3.100'
);
}
$bin
=
''
;
foreach
(
$parts
as
$part_index
=>
$part
)
{
if
(
$part_index
==
3
)
{
// version type only can be 1/2/3 (11 in binary form), so don't use padding at all
$pad_count
=
2
;
}
else
{
$pad_count
=
8
;
}
$bin
.=
str_pad
(
decbin
(
$part
),
$pad_count
,
'0'
,
STR_PAD_LEFT
);
}
return
bindec
(
$bin
);
}
/**
* Returns themes, found in system
*
* @param bool $rebuild
* @return int
*/
function
getThemes
(
$rebuild
=
false
)
{
if
(
$rebuild
)
{
$this
->
rebuildThemes
();
}
$id_field
=
$this
->
Application
->
getUnitOption
(
'theme'
,
'IDField'
);
$table_name
=
$this
->
Application
->
getUnitOption
(
'theme'
,
'TableName'
);
$sql
=
'SELECT Name, '
.
$id_field
.
'
FROM '
.
$table_name
.
'
ORDER BY Name ASC'
;
return
$this
->
Conn
->
GetCol
(
$sql
,
$id_field
);
}
function
ParseConfig
(
$parse_section
=
false
)
{
if
(!
file_exists
(
$this
->
INIFile
))
{
return
Array
();
}
if
(
file_exists
(
$this
->
INIFile
)
&&
!
is_readable
(
$this
->
INIFile
))
{
die
(
'Could Not Open Ini File'
);
}
$contents
=
file
(
$this
->
INIFile
);
if
(
$contents
&&
$contents
[
0
]
==
'<'
.
'?'
.
'php die() ?'
.
">
\n
"
)
{
// format of "config.php" file before 5.1.0 version
array_shift
(
$contents
);
return
$this
->
parseIniString
(
implode
(
''
,
$contents
),
$parse_section
);
}
$_CONFIG
=
Array
();
require
(
$this
->
INIFile
);
if
(
$parse_section
)
{
return
$_CONFIG
;
}
$ret
=
Array
();
foreach
(
$_CONFIG
as
$section
=>
$section_variables
)
{
$ret
=
array_merge
(
$ret
,
$section_variables
);
}
return
$ret
;
}
/**
* 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
parseIniString
(
$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
;
}
function
SaveConfig
(
$silent
=
false
)
{
if
(!
is_writable
(
$this
->
INIFile
)
&&
!
is_writable
(
dirname
(
$this
->
INIFile
)))
{
$error_msg
=
'Cannot write to "'
.
$this
->
INIFile
.
'" file'
;
if
(
$silent
)
{
trigger_error
(
$error_msg
,
E_USER_WARNING
);
}
else
{
throw
new
Exception
(
$error_msg
);
}
return
;
}
$fp
=
fopen
(
$this
->
INIFile
,
'w'
);
fwrite
(
$fp
,
'<'
.
'?'
.
'php'
.
"
\n\n
"
);
foreach
(
$this
->
systemConfig
as
$section_name
=>
$section_data
)
{
foreach
(
$section_data
as
$key
=>
$value
)
{
fwrite
(
$fp
,
'$_CONFIG[
\'
'
.
$section_name
.
'
\'
][
\'
'
.
$key
.
'
\'
] =
\'
'
.
addslashes
(
$value
)
.
'
\'
;'
.
"
\n
"
);
}
fwrite
(
$fp
,
"
\n
"
);
}
fclose
(
$fp
);
$this
->
systemConfigChanged
=
false
;
}
/**
* Sets value to system config (yet SaveConfig must be called to write it to file)
*
* @param string $section
* @param string $key
* @param string $value
*/
function
setSystemConfig
(
$section
,
$key
,
$value
=
null
)
{
$this
->
systemConfigChanged
=
true
;
if
(
isset
(
$value
))
{
if
(!
array_key_exists
(
$section
,
$this
->
systemConfig
))
{
// create section, when missing
$this
->
systemConfig
[
$section
]
=
Array
();
}
// create key in section
$this
->
systemConfig
[
$section
][
$key
]
=
$value
;
return
;
}
unset
(
$this
->
systemConfig
[
$section
][
$key
]);
}
/**
* Returns information from system config
*
* @param string $section
* @param string $key
* @param mixed $default
* @return string|bool
*/
function
getSystemConfig
(
$section
,
$key
,
$default
=
false
)
{
if
(
!
array_key_exists
(
$section
,
$this
->
systemConfig
)
)
{
return
$default
;
}
if
(
!
array_key_exists
(
$key
,
$this
->
systemConfig
[
$section
])
)
{
return
$default
;
}
return
isset
(
$this
->
systemConfig
[
$section
][
$key
])
?
$this
->
systemConfig
[
$section
][
$key
]
:
$default
;
}
/**
* Checks if system config is present and is not empty
*
* @return bool
*/
function
systemConfigFound
()
{
return
file_exists
(
$this
->
INIFile
)
&&
$this
->
systemConfig
;
}
/**
* Checks if given section is present in config
*
* @param string $section
* @return bool
*/
function
sectionFound
(
$section
)
{
return
array_key_exists
(
$section
,
$this
->
systemConfig
);
}
/**
* Returns formatted module name based on it's root folder
*
* @param string $module_folder
* @return string
*/
function
getModuleName
(
$module_folder
)
{
return
implode
(
'-'
,
array_map
(
'ucfirst'
,
explode
(
'-'
,
$module_folder
)));
}
/**
* Returns information about module (based on "install/module_info.xml" file)
*
* @param string $module_name
* @return Array
*/
function
getModuleInfo
(
$module_name
)
{
if
(
$module_name
==
'core'
)
{
$info_file
=
FULL_PATH
.
'/'
.
$module_name
.
'/install/module_info.xml'
;
}
else
{
$info_file
=
MODULES_PATH
.
'/'
.
$module_name
.
'/install/module_info.xml'
;
}
if
(
!
file_exists
(
$info_file
)
)
{
return
Array
();
}
$ret
=
Array
();
$module_info
=
simplexml_load_file
(
$info_file
);
if
(
$module_info
===
false
)
{
// non-valid xml file
return
Array
();
}
foreach
(
$module_info
as
$node
)
{
/* @var $node SimpleXMLElement */
$ret
[
strtolower
(
$node
->
getName
())]
=
trim
(
$node
);
}
return
$ret
;
}
/**
* Returns nice module string to be used on install/upgrade screens
*
* @param string $module_name
* @param string $version_string
* @return string
*/
function
getModuleString
(
$module_name
,
$version_string
)
{
// image (if exists) <description> (<name> <version>)
$ret
=
Array
();
$module_info
=
$this
->
getModuleInfo
(
$module_name
);
if
(
array_key_exists
(
'name'
,
$module_info
)
&&
$module_info
[
'name'
])
{
$module_name
=
$module_info
[
'name'
];
}
else
{
$module_name
=
$this
->
getModuleName
(
$module_name
);
}
if
(
array_key_exists
(
'image'
,
$module_info
)
&&
$module_info
[
'image'
])
{
$image_src
=
$module_info
[
'image'
];
if
(!
preg_match
(
'/^(http|https):
\/\/
/'
,
$image_src
))
{
// local image -> make absolute url
$image_src
=
$this
->
Application
->
BaseURL
()
.
$image_src
;
}
$ret
[]
=
'<img src="'
.
$image_src
.
'" alt="'
.
htmlspecialchars
(
$module_name
)
.
'" title="'
.
htmlspecialchars
(
$module_name
)
.
'" style="vertical-align:middle; margin: 3px 0 3px 5px"/>'
;
}
if
(
array_key_exists
(
'description'
,
$module_info
)
&&
$module_info
[
'description'
])
{
$ret
[]
=
$module_info
[
'description'
];
}
else
{
$ret
[]
=
$module_name
;
}
$ret
[]
=
'('
.
$module_name
.
' '
.
$version_string
.
')'
;
return
implode
(
' '
,
$ret
);
}
/**
* Creates module root category in "Home" category using given data and returns it
*
* @param string $name
* @param string $description
* @param string $category_template
* @param string $category_icon
* @return kDBItem
*/
function
&
createModuleCategory
(
$name
,
$description
,
$category_template
=
null
,
$category_icon
=
null
)
{
static
$fields
=
null
;
if
(
!
isset
(
$fields
)
)
{
$ml_formatter
=
$this
->
Application
->
recallObject
(
'kMultiLanguage'
);
/* @var $ml_formatter kMultiLanguage */
$fields
[
'name'
]
=
$ml_formatter
->
LangFieldName
(
'Name'
);
$fields
[
'description'
]
=
$ml_formatter
->
LangFieldName
(
'Description'
);
}
$category
=
$this
->
Application
->
recallObject
(
'c'
,
null
,
Array
(
'skip_autoload'
=>
true
));
/* @var $category kDBItem */
$category_fields
=
Array
(
$fields
[
'name'
]
=>
$name
,
'Filename'
=>
$name
,
'AutomaticFilename'
=>
1
,
$fields
[
'description'
]
=>
$description
,
'Status'
=>
STATUS_ACTIVE
,
'Priority'
=>
-
9999
,
// prevents empty link to module category on spearate module install
'NamedParentPath'
=>
'Content/'
.
$name
,
);
$category_fields
[
'ParentId'
]
=
$this
->
Application
->
getBaseCategory
();
if
(
isset
(
$category_template
)
)
{
$category_fields
[
'Template'
]
=
$category_template
;
$category_fields
[
'CachedTemplate'
]
=
$category_template
;
}
if
(
isset
(
$category_icon
)
)
{
$category_fields
[
'UseMenuIconUrl'
]
=
1
;
$category_fields
[
'MenuIconUrl'
]
=
$category_icon
;
}
$category
->
Clear
();
$category
->
SetDBFieldsFromHash
(
$category_fields
);
$category
->
Create
();
$priority_helper
=
$this
->
Application
->
recallObject
(
'PriorityHelper'
);
/* @var $priority_helper kPriorityHelper */
$event
=
new
kEvent
(
'c:OnListBuild'
);
// ensure, that newly created category has proper value in Priority field
$priority_helper
->
recalculatePriorities
(
$event
,
'ParentId = '
.
$category_fields
[
'ParentId'
]);
// update Priority field in object, becase "CategoriesItem::Update" method will be called
// from "kInstallToolkit::setModuleItemTemplate" and otherwise will set 0 to Priority field
$sql
=
'SELECT Priority
FROM '
.
$category
->
TableName
.
'
WHERE '
.
$category
->
IDField
.
' = '
.
$category
->
GetID
();
$category
->
SetDBField
(
'Priority'
,
$this
->
Conn
->
GetOne
(
$sql
));
return
$category
;
}
/**
* Sets category item template into custom field for given prefix
*
* @param kDBItem $category
* @param string $prefix
* @param string $item_template
*/
function
setModuleItemTemplate
(&
$category
,
$prefix
,
$item_template
)
{
$this
->
Application
->
removeObject
(
'c-cdata'
);
// recreate all fields, because custom fields are added during install script
$category
->
Configure
();
$category
->
SetDBField
(
'cust_'
.
$prefix
.
'_ItemTemplate'
,
$item_template
);
$category
->
Update
();
}
/**
* Link custom field records with search config records + create custom field columns
*
* @param string $module_folder
* @param string $prefix
* @param int $item_type
*/
function
linkCustomFields
(
$module_folder
,
$prefix
,
$item_type
)
{
$module_folder
=
strtolower
(
$module_folder
);
$module_name
=
$module_folder
;
if
(
$module_folder
==
'kernel'
)
{
$module_name
=
'in-portal'
;
$module_folder
=
'core'
;
}
$db
=&
$this
->
Application
->
GetADODBConnection
();
$sql
=
'SELECT FieldName, CustomFieldId
FROM '
.
TABLE_PREFIX
.
'CustomFields
WHERE Type = '
.
$item_type
.
' AND IsSystem = 0'
;
// config is not read here yet :( $this->Application->getUnitOption('p', 'ItemType');
$custom_fields
=
$db
->
GetCol
(
$sql
,
'CustomFieldId'
);
foreach
(
$custom_fields
as
$cf_id
=>
$cf_name
)
{
$sql
=
'UPDATE '
.
TABLE_PREFIX
.
'SearchConfig
SET CustomFieldId = '
.
$cf_id
.
'
WHERE (TableName = "CustomFields") AND (LOWER(ModuleName) = "'
.
$module_name
.
'") AND (FieldName = '
.
$db
->
qstr
(
$cf_name
)
.
')'
;
$db
->
Query
(
$sql
);
}
$this
->
Application
->
refreshModuleInfo
();
// this module configs are now processed
// because of configs was read only from installed before modules (in-portal), then reread configs
$this
->
Application
->
UnitConfigReader
->
scanModules
(
MODULES_PATH
.
DIRECTORY_SEPARATOR
.
$module_folder
);
// create correct columns in CustomData table
$ml_helper
=
$this
->
Application
->
recallObject
(
'kMultiLanguageHelper'
);
/* @var $ml_helper kMultiLanguageHelper */
$ml_helper
->
createFields
(
$prefix
.
'-cdata'
,
true
);
}
/**
* Deletes cache, useful after separate module install and installator last step
*
* @param bool $refresh_permissions
* @return void
*/
function
deleteCache
(
$refresh_permissions
=
false
)
{
$this
->
Application
->
HandleEvent
(
new
kEvent
(
'adm:OnResetMemcache'
));
// not in DB = 100% invalidate
$this
->
Application
->
HandleEvent
(
new
kEvent
(
'adm:OnResetConfigsCache'
));
$this
->
Application
->
HandleEvent
(
new
kEvent
(
'adm:OnResetSections'
));
$this
->
Application
->
HandleEvent
(
new
kEvent
(
'c:OnResetCMSMenuCache'
));
$this
->
Conn
->
Query
(
'DELETE FROM '
.
TABLE_PREFIX
.
'CachedUrls'
);
if
(
$refresh_permissions
)
{
$rebuild_mode
=
$this
->
Application
->
ConfigValue
(
'CategoryPermissionRebuildMode'
);
if
(
$rebuild_mode
==
CategoryPermissionRebuild
::
SILENT
)
{
// refresh permission without progress bar
$updater
=
$this
->
Application
->
makeClass
(
'kPermCacheUpdater'
);
/* @var $updater kPermCacheUpdater */
$updater
->
OneStepRun
();
}
elseif
(
$rebuild_mode
==
CategoryPermissionRebuild
::
AUTOMATIC
)
{
// refresh permissions with ajax progress bar (when available)
$this
->
Application
->
setDBCache
(
'ForcePermCacheUpdate'
,
1
);
}
}
}
/**
* Deletes all temp tables (from active sessions too)
*
*/
function
deleteEditTables
()
{
$table_prefix
=
$this
->
getSystemConfig
(
'Database'
,
'TablePrefix'
);
$tables
=
$this
->
Conn
->
GetCol
(
'SHOW TABLES'
);
$mask_edit_table
=
'/'
.
$table_prefix
.
'ses_(.*)_edit_(.*)/'
;
$mask_search_table
=
'/'
.
$table_prefix
.
'ses_(.*?)_(.*)/'
;
foreach
(
$tables
as
$table
)
{
if
(
preg_match
(
$mask_edit_table
,
$table
,
$rets
)
||
preg_match
(
$mask_search_table
,
$table
,
$rets
)
)
{
$this
->
Conn
->
Query
(
'DROP TABLE IF EXISTS '
.
$table
);
}
}
}
/**
* Perform redirect after separate module install
*
* @param string $module_folder
* @param bool $refresh_permissions
*/
function
finalizeModuleInstall
(
$module_folder
,
$refresh_permissions
=
false
)
{
$this
->
SetModuleVersion
(
basename
(
$module_folder
),
$module_folder
);
if
(!
$this
->
Application
->
GetVar
(
'redirect'
))
{
return
;
}
$themes_helper
=
$this
->
Application
->
recallObject
(
'ThemesHelper'
);
/* @var $themes_helper kThemesHelper */
// use direct query, since module isn't yet in kApplication::ModuleInfo array
$sql
=
'SELECT Name
FROM '
.
TABLE_PREFIX
.
'Modules
WHERE Path = '
.
$this
->
Conn
->
qstr
(
rtrim
(
$module_folder
,
'/'
)
.
'/'
);
$module_name
=
$this
->
Conn
->
GetOne
(
$sql
);
$themes_helper
->
synchronizeModule
(
$module_name
);
$ml_helper
=
$this
->
Application
->
recallObject
(
'kMultiLanguageHelper'
);
/* @var $ml_helper kMultiLanguageHelper */
$ml_helper
->
massCreateFields
();
$this
->
deleteCache
(
$refresh_permissions
);
$url_params
=
Array
(
'pass'
=>
'm'
,
'admin'
=>
1
,
'RefreshTree'
=>
1
,
'index_file'
=>
'index.php'
,
);
$this
->
Application
->
Redirect
(
'modules/modules_list'
,
$url_params
);
}
/**
* Performs rebuild of themes
*
*/
function
rebuildThemes
()
{
$this
->
Application
->
HandleEvent
(
new
kEvent
(
'adm:OnRebuildThemes'
));
}
/**
* Checks that file is writable by group or others
*
* @param string $file
* @return boolean
*/
function
checkWritePermissions
(
$file
)
{
if
(
DIRECTORY_SEPARATOR
==
'
\\
'
)
{
// windows doen't allow to check permissions (always returns null)
return
null
;
}
$permissions
=
fileperms
(
$file
);
return
$permissions
&
0x0010
||
$permissions
&
0x0002
;
}
/**
* Upgrades primary skin to the latest version
*
* @param Array $module_info
* @return string|bool
*/
function
upgradeSkin
(
$module_info
)
{
$upgrades_file
=
sprintf
(
UPGRADES_FILE
,
$module_info
[
'Path'
],
'css'
);
$data
=
file_get_contents
(
$upgrades_file
);
// get all versions with their positions in file
$versions
=
Array
();
preg_match_all
(
'/('
.
VERSION_MARK
.
')/s'
,
$data
,
$matches
,
PREG_SET_ORDER
+
PREG_OFFSET_CAPTURE
);
$from_version_int
=
$this
->
ConvertModuleVersion
(
$module_info
[
'FromVersion'
]);
foreach
(
$matches
as
$index
=>
$match
)
{
$version_int
=
$this
->
ConvertModuleVersion
(
$match
[
2
][
0
]);
if
(
$version_int
<
$from_version_int
)
{
// only process versions, that were released after currently used version
continue
;
}
$start_pos
=
$match
[
0
][
1
]
+
strlen
(
$match
[
0
][
0
]);
$end_pos
=
array_key_exists
(
$index
+
1
,
$matches
)
?
$matches
[
$index
+
1
][
0
][
1
]
:
mb_strlen
(
$data
);
$patch_data
=
str_replace
(
"
\r\n
"
,
"
\n
"
,
substr
(
$data
,
$start_pos
,
$end_pos
-
$start_pos
));
$versions
[]
=
Array
(
'Version'
=>
$match
[
2
][
0
],
// fixes trimmed leading spaces by modern text editor
'Data'
=>
ltrim
(
str_replace
(
"
\n\n
"
,
"
\n
\n
"
,
$patch_data
)
),
);
}
if
(
!
$versions
)
{
// not skin changes -> quit
return
true
;
}
$primary_skin
=
$this
->
Application
->
recallObject
(
'skin.primary'
,
null
,
Array
(
'skip_autoload'
=>
true
));
/* @var $primary_skin kDBItem */
$primary_skin
->
Load
(
1
,
'IsPrimary'
);
if
(
!
$primary_skin
->
isLoaded
()
)
{
// we always got primary skin, but just in case
return
false
;
}
$temp_handler
=
$this
->
Application
->
recallObject
(
'skin_TempHandler'
,
'kTempTablesHandler'
);
/* @var $temp_handler kTempTablesHandler */
// clone current skin
$cloned_ids
=
$temp_handler
->
CloneItems
(
'skin'
,
''
,
Array
(
$primary_skin
->
GetID
()));
if
(
!
$cloned_ids
)
{
// can't clone
return
false
;
}
$skin
=
$this
->
Application
->
recallObject
(
'skin.tmp'
,
null
,
Array
(
'skip_autoload'
=>
true
));
/* @var $skin kDBItem */
$skin
->
Load
(
$cloned_ids
[
0
]);
// save css to temp file (for patching)
$skin_file
=
tempnam
(
'/tmp'
,
'skin_css_'
);
$fp
=
fopen
(
$skin_file
,
'w'
);
fwrite
(
$fp
,
str_replace
(
"
\r\n
"
,
"
\n
"
,
$skin
->
GetDBField
(
'CSS'
)));
fclose
(
$fp
);
$output
=
Array
();
$patch_file
=
tempnam
(
'/tmp'
,
'skin_patch_'
);
foreach
(
$versions
as
$version_info
)
{
// for each left version get it's patch and apply to temp file
$fp
=
fopen
(
$patch_file
,
'w'
);
fwrite
(
$fp
,
$version_info
[
'Data'
]);
fclose
(
$fp
);
$output
[
$version_info
[
'Version'
]
]
=
shell_exec
(
'patch '
.
$skin_file
.
' '
.
$patch_file
.
' 2>&1'
)
.
"
\n
"
;
}
// place temp file content into cloned skin
$skin
->
SetDBField
(
'Name'
,
'Upgraded to '
.
$module_info
[
'ToVersion'
]);
$skin
->
SetDBField
(
'CSS'
,
file_get_contents
(
$skin_file
));
$skin
->
Update
();
unlink
(
$skin_file
);
unlink
(
$patch_file
);
$has_errors
=
false
;
foreach
(
$output
as
$version
=>
$version_output
)
{
$version_errors
=
trim
(
preg_replace
(
"/(^|
\n
)(patching file .*?|Hunk #.*?
\.
)(
\n
|$)/m"
,
''
,
$version_output
));
if
(
$version_errors
)
{
$has_errors
=
true
;
$output
[
$version
]
=
trim
(
preg_replace
(
"/(^|
\n
)(patching file .*?)(
\n
|$)/m"
,
''
,
$output
[
$version
]));
}
else
{
unset
(
$output
[
$version
]);
}
}
if
(
!
$has_errors
)
{
// copy patched css back to primary skin
$primary_skin
->
SetDBField
(
'CSS'
,
$skin
->
GetDBField
(
'CSS'
));
$primary_skin
->
Update
();
// delete temporary skin record
$temp_handler
->
DeleteItems
(
'skin'
,
''
,
Array
(
$skin
->
GetID
()));
return
true
;
}
// put clean skin from new version
$skin
->
SetDBField
(
'CSS'
,
file_get_contents
(
FULL_PATH
.
'/core/admin_templates/incs/style_template.css'
));
$skin
->
Update
();
// return output in case of errors
return
$output
;
}
/**
* Returns cache handlers, that are working
*
* @param string $current
* @return Array
*/
public
function
getWorkingCacheHandlers
(
$current
=
null
)
{
if
(
!
isset
(
$current
)
)
{
$current
=
$this
->
getSystemConfig
(
'Misc'
,
'CacheHandler'
);
}
$cache_handler
=
$this
->
Application
->
makeClass
(
'kCache'
);
$cache_handlers
=
Array
(
'Fake'
=>
'None'
,
'Memcache'
=>
'Memcached'
,
'XCache'
=>
'XCache'
,
'Apc'
=>
'Alternative PHP Cache'
);
foreach
(
$cache_handlers
AS
$class_prefix
=>
$title
)
{
$handler_class
=
$class_prefix
.
'CacheHandler'
;
if
(
!
class_exists
(
$handler_class
)
)
{
unset
(
$cache_handlers
[
$class_prefix
]);
}
else
{
$handler
=
new
$handler_class
(
$cache_handler
,
'localhost:11211'
);
/* @var $handler FakeCacheHandler */
if
(
!
$handler
->
isWorking
()
)
{
if
(
$current
==
$class_prefix
)
{
$cache_handlers
[
$class_prefix
]
.=
' (offline)'
;
}
else
{
unset
(
$cache_handlers
[
$class_prefix
]);
}
}
}
}
return
$cache_handlers
;
}
/**
* Returns compression engines, that are working
*
* @param string $current
* @return Array
*/
public
function
getWorkingCompressionEngines
(
$current
=
null
)
{
if
(
!
isset
(
$current
)
)
{
$current
=
$this
->
getSystemConfig
(
'Misc'
,
'CompressionEngine'
);
}
$output
=
shell_exec
(
'java -version 2>&1'
);
$compression_engines
=
Array
(
''
=>
'None'
,
'yui'
=>
'YUICompressor (Java)'
,
'php'
=>
'PHP-based'
);
if
(
stripos
(
$output
,
'java version'
)
===
false
)
{
if
(
$current
==
'yui'
)
{
$compression_engines
[
'yui'
]
.=
' (offline)'
;
}
else
{
unset
(
$compression_engines
[
'yui'
]);
}
}
return
$compression_engines
;
}
}
Event Timeline
Log In to Comment