14 define(
"CH_WSB_INSTALLER_SUCCESS", 0);
15 define(
"CH_WSB_INSTALLER_FAILED", 1);
49 parent::__construct();
52 $this->_sBasePath = CH_DIRECTORY_PATH_MODULES;
53 $this->_sHomePath = $this->_sBasePath .
$aConfig[
'home_dir'];
54 $this->_sModulePath = $this->_sBasePath .
$aConfig[
'home_dir'];
56 $this->_aActions = array(
57 'check_script_version' => array(
58 'title' =>
_t(
'_adm_txt_modules_check_script_version'),
60 'check_dependencies' => array(
61 'title' =>
_t(
'_adm_txt_modules_check_dependencies'),
63 'show_introduction' => array(
64 'title' =>
_t(
'_adm_txt_modules_show_introduction'),
66 'check_permissions' => array(
67 'title' =>
_t(
'_adm_txt_modules_check_permissions'),
69 'change_permissions' => array(
70 'title' =>
_t(
'_adm_txt_modules_change_permissions'),
72 'execute_sql' => array(
73 'title' =>
_t(
'_adm_txt_modules_execute_sql'),
75 'update_languages' => array(
76 'title' =>
_t(
'_adm_txt_modules_update_languages'),
78 'recompile_global_paramaters' => array(
79 'title' =>
_t(
'_adm_txt_modules_recompile_global_paramaters'),
81 'recompile_main_menu' => array(
82 'title' =>
_t(
'_adm_txt_modules_recompile_main_menu'),
84 'recompile_member_menu' => array(
85 'title' =>
_t(
'_adm_txt_modules_recompile_member_menu'),
87 'recompile_site_stats' => array(
88 'title' =>
_t(
'_adm_txt_modules_recompile_site_stats'),
90 'recompile_page_builder' => array(
91 'title' =>
_t(
'_adm_txt_modules_recompile_page_builder'),
93 'recompile_profile_fields' => array(
94 'title' =>
_t(
'_adm_txt_modules_recompile_profile_fields'),
96 'recompile_comments' => array(
97 'title' =>
_t(
'_adm_txt_modules_recompile_comments'),
99 'recompile_member_actions' => array(
100 'title' =>
_t(
'_adm_txt_modules_recompile_member_actions'),
102 'recompile_tags' => array(
103 'title' =>
_t(
'_adm_txt_modules_recompile_tags'),
105 'recompile_votes' => array(
106 'title' =>
_t(
'_adm_txt_modules_recompile_votes'),
108 'recompile_categories' => array(
109 'title' =>
_t(
'_adm_txt_modules_recompile_categories'),
111 'recompile_search' => array(
112 'title' =>
_t(
'_adm_txt_modules_recompile_search'),
114 'recompile_injections' => array(
115 'title' =>
_t(
'_adm_txt_modules_recompile_injections'),
117 'recompile_permalinks' => array(
118 'title' =>
_t(
'_adm_txt_modules_recompile_permalinks'),
120 'recompile_alerts' => array(
121 'title' =>
_t(
'_adm_txt_modules_recompile_alerts'),
123 'clear_db_cache' => array(
124 'title' =>
_t(
'_adm_txt_modules_clear_db_cache'),
126 'show_conclusion' => array(
127 'title' =>
_t(
'_adm_txt_modules_show_conclusion'),
130 $this->_aNonHashable = array(
139 $sTitle =
_t(
'_adm_txt_modules_operation_install', $this->_aConfig[
'title']);
142 if(
$oModuleDb->isModule($this->_aConfig[
'home_uri']))
145 'message' =>
_t(
'_adm_txt_modules_already_installed'),
150 if(
$oModuleDb->isModuleParamsUsed($this->_aConfig[
'home_uri'], $this->_aConfig[
'home_dir'], $this->_aConfig[
'db_prefix'], $this->_aConfig[
'class_prefix']))
153 'message' =>
_t(
'_adm_txt_modules_params_used'),
158 $bCompatible =
false;
159 if(isset($this->_aConfig[
'compatible_with']) && is_array($this->_aConfig[
'compatible_with']))
160 foreach($this->_aConfig[
'compatible_with']
as $iKey => $sVersion) {
161 $sVersion =
'/^' . str_replace(array(
'.',
'x'), array(
'\.',
'[0-9]+'), $sVersion) .
'$/is';
162 $bCompatible = $bCompatible || (preg_match($sVersion,
$GLOBALS[
'site'][
'ver'] .
'.' .
$GLOBALS[
'site'][
'build']) > 0);
167 'message' => $this->
_displayResult(
'check_script_version',
false,
'_adm_txt_modules_wrong_version_script'),
175 if(isset($this->_aConfig[
'install'][
'check_dependencies']) && (
int)$this->_aConfig[
'install'][
'check_dependencies'] == 1 && isset($this->_aConfig[
'dependencies']) && is_array($this->_aConfig[
'dependencies']))
176 $sDependencies = implode(
',', array_keys($this->_aConfig[
'dependencies']));
178 db_res(
"INSERT IGNORE INTO `sys_modules`(`title`, `vendor`, `version`, `update_url`, `path`, `uri`, `class_prefix`, `db_prefix`, `dependencies`, `date`) VALUES ('" . $this->_aConfig[
'title'] .
"', '" . $this->_aConfig[
'vendor'] .
"', '" . $this->_aConfig[
'version'] .
"', '" . $this->_aConfig[
'update_url'] .
"', '" . $this->_aConfig[
'home_dir'] .
"', '" . $this->_aConfig[
'home_uri'] .
"', '" . $this->_aConfig[
'class_prefix'] .
"', '" . $this->_aConfig[
'db_prefix'] .
"', '" . $sDependencies .
"', UNIX_TIMESTAMP())");
182 $this->
_hash($this->_sModulePath, $aFiles);
183 foreach($aFiles
as $aFile)
184 db_res(
"INSERT IGNORE INTO `sys_modules_file_tracks`(`module_id`, `file`, `hash`) VALUES('" . $iModuleId .
"', '" . $aFile[
'file'] .
"', '" . $aFile[
'hash'] .
"')");
186 $GLOBALS[
'MySQL']->cleanMemory(
'sys_modules_' . $this->_aConfig[
'home_uri']);
187 $GLOBALS[
'MySQL']->cleanMemory(
'sys_modules_' . $iModuleId);
188 $GLOBALS[
'MySQL']->cleanMemory(
'sys_modules');
191 $this->
_perform(
'uninstall',
'Uninstallation');
199 $sTitle =
_t(
'_adm_txt_modules_operation_uninstall', $this->_aConfig[
'title']);
202 if(!
$oModuleDb->isModule($this->_aConfig[
'home_uri']))
205 'message' =>
_t(
'_adm_txt_modules_already_uninstalled'),
211 $aDependents =
$oModuleDb->getDependent($this->_aConfig[
'home_uri']);
212 if(is_array($aDependents) && !
empty($aDependents)) {
215 $sMessage =
'<br />-- -- ' .
_t(
'_adm_txt_modules_has_dependents') .
'<br />';
216 foreach($aDependents
as $aDependent)
217 $sMessage .=
'-- -- ' . $aDependent[
'title'] .
'<br />';
229 $iModuleId = (int)
$oModuleDb->getOne(
"SELECT `id` FROM `sys_modules` WHERE `vendor`='" . $this->_aConfig[
'vendor'] .
"' AND `path`='" . $this->_aConfig[
'home_dir'] .
"' LIMIT 1");
230 $oModuleDb->query(
"DELETE FROM `sys_modules` WHERE `vendor`='" . $this->_aConfig[
'vendor'] .
"' AND `path`='" . $this->_aConfig[
'home_dir'] .
"' LIMIT 1");
231 $oModuleDb->query(
"DELETE FROM `sys_modules_file_tracks` WHERE `module_id`='" . $iModuleId .
"'");
233 $GLOBALS[
'MySQL']->cleanMemory (
'sys_modules_' . $this->_aConfig[
'home_uri']);
234 $GLOBALS[
'MySQL']->cleanMemory (
'sys_modules_' . $iModuleId);
235 $GLOBALS[
'MySQL']->cleanMemory (
'sys_modules');
243 $aResult = array(
'message' =>
'',
'result' =>
false);
245 $aLanguages =
$GLOBALS[
'MySQL']->getAll(
"SELECT `ID` AS `id`, `Name` AS `name`, `Title` AS `title` FROM `sys_localization_languages` WHERE 1");
250 foreach($aLanguages
as $aLanguage) {
252 $aResult[
'message'] .= $aLanguage[
'title'] .
': <span class="' . (
$bResult ?
'modules-action-success' :
'modules-action-failed') .
'">' .
_t(
$bResult ?
'_adm_txt_modules_process_action_success' :
'_adm_txt_modules_process_action_failed') .
'</span><br />';
258 $aResult[
'operation_title'] =
_t(
'_adm_txt_modules_operation_recompile', $this->_aConfig[
'title']);
263 if(file_exists($sPath) && is_dir($sPath) && ($rSource = opendir($sPath))) {
264 while((
$sFile = readdir($rSource)) !==
false) {
268 if(is_dir($sPath .
$sFile))
275 $aFiles[] = $this->
_info($sPath);
280 'file' => str_replace($this->_sModulePath,
'', $sPath),
281 'hash' => md5(file_get_contents($sPath))
284 function _perform($sOperationName, $sOperationTitle)
286 if(!defined(
'CH_SKIP_INSTALL_CHECK') && !
$GLOBALS[
'logged'][
'admin'])
287 return array(
'message' =>
'',
'result' =>
false);
290 foreach($this->_aConfig[$sOperationName]
as $sAction => $iEnabled) {
291 $sMethod =
'action' . str_replace (
' ',
'', ucwords(str_replace (
'_',
' ',
$sAction)));
292 if($iEnabled == 0 || !method_exists($this, $sMethod))
295 $mixedResult = $this->$sMethod($sOperationName ==
'install' || $sOperationName ==
'update');
304 $sMethodFailed = $sMethod .
'Failed';
308 $sMessage .= $sOperationTitle .
' finished';
309 return array(
'message' =>
$sMessage,
'result' =>
true);
319 return $sMessage .
'<span style="color:red; font-weight:bold;">' .
$sResult .
'</span>';
322 $sResult =
_t(
'_adm_txt_modules_process_action_success') .
'<br />';
323 return $sMessage .
'<span style="color:green; font-weight:bold;">' .
$sResult .
'</span>';
329 return _t(
'_adm_txt_modules_process_action_failed');
336 if(!isset($this->_aConfig[
'dependencies']) || !is_array($this->_aConfig[
'dependencies']))
340 foreach($this->_aConfig[
'dependencies']
as $sModuleUri => $sModuleTitle)
341 if($sModuleUri != $this->_aConfig[
'home_uri'] && !$oModulesDb->isModule($sModuleUri))
342 $sContent .=
'-- -- ' . $sModuleTitle .
'<br />';
345 $sContent =
'<br />-- -- ' .
_t(
'_adm_txt_modules_wrong_dependency_install') .
'<br />' .
$sContent;
352 return $mixedResult[
'content'];
356 $sFile = $this->_aConfig[($bInstall ?
'install_info' :
'uninstall_info')][
'introduction'];
357 $sPath = $this->_sHomePath .
'install/info/' .
$sFile;
359 return file_exists($sPath) ? array(
"code" =>
CH_WSB_INSTALLER_SUCCESS,
"content" =>
"<pre>" . file_get_contents($sPath) .
"</pre>") : array(
"code" =>
CH_WSB_INSTALLER_FAILED,
"content" =>
"<pre>Could not show Introduction. Does not exist.</pre>");
363 $sFile = $this->_aConfig[($bInstall ?
'install_info' :
'uninstall_info')][
'conclusion'];
364 $sPath = $this->_sHomePath .
'install/info/' .
$sFile;
366 return file_exists($sPath) ? array(
"code" =>
CH_WSB_INSTALLER_SUCCESS,
"content" =>
"<pre>" . file_get_contents($sPath) .
"</pre>") : array(
"code" =>
CH_WSB_INSTALLER_FAILED,
"content" =>
"<pre>Could not show Conclusion. Does not exist.</pre>");
370 $aPermissions = $bInstall ? $this->_aConfig[
'install_permissions'] : $this->_aConfig[
'uninstall_permissions'];
373 foreach($aPermissions
as $sPermissions => $aFiles) {
374 $sCheckFunction =
'is' . ucfirst($sPermissions);
375 $sCptPermissions =
_t(
'_adm_txt_modules_' . $sPermissions);
377 if(!ChWsbInstallerUtils::$sCheckFunction(
ch_ltrim_str($this->_sModulePath .
$sFile, CH_DIRECTORY_PATH_ROOT)))
378 $aResult[] = array(
'path' => $this->_sModulePath .
$sFile,
'permissions' => $sCptPermissions);
385 $sResult =
'<br />-- -- ' .
_t(
'_adm_txt_modules_wrong_permissions_check') .
'<br />';
386 foreach($mixedResult[
'content']
as $aFile)
387 $sResult .=
'-- -- ' .
_t(
'_adm_txt_modules_wrong_permissions_msg', $aFile[
'path'], $aFile[
'permissions']) .
'<br />';
392 $aPermissions = $bInstall ? $this->_aConfig[
'install_permissions'] : $this->_aConfig[
'uninstall_permissions'];
395 foreach($aPermissions
as $sPermissions => $aFiles) {
396 $sCheckFunction =
'is' . ucfirst($sPermissions);
399 if(ChWsbInstallerUtils::$sCheckFunction($sPath))
402 $aResult[] = array(
'path' => $this->_sModulePath .
$sFile,
'permissions' => $sPermissions);
403 $aChangeItems[] = array(
'file' =>
$sFile,
'path' => $sPath,
'permissions' => $sPermissions);
407 if(
empty($aChangeItems))
410 $sFtpHost =
getParam(
'sys_ftp_host');
412 $sFtpHost = $_SERVER[
'HTTP_HOST'];
417 if(!$oFile->connect())
418 return array(
'code' =>
CH_WSB_INSTALLER_FAILED,
'content_msg' =>
'_adm_txt_modules_wrong_permissions_change_cannot_connect_to_ftp',
'content_data' =>
$aResult);
420 if(!$oFile->isCheetah())
421 return array(
'code' =>
CH_WSB_INSTALLER_FAILED,
'content_msg' =>
'_adm_txt_modules_wrong_permissions_change_destination_not_valid',
'content_data' =>
$aResult);
424 foreach($aChangeItems
as $aChangeItem)
425 if(!$oFile->setPermissions($aChangeItem[
'path'], $aChangeItem[
'permissions']))
426 $aResult[] = array(
'path' => $this->_sModulePath . $aChangeItem[
'file'],
'permissions' => $aChangeItem[
'permissions']);
432 if(
empty($mixedResult[
'content_msg']) &&
empty($mixedResult[
'content_data']))
436 if(!
empty($mixedResult[
'content_msg']))
439 if(!
empty($mixedResult[
'content_data'])) {
440 $sResult .=
' ' .
_t(
'_adm_txt_modules_wrong_permissions_change_list') .
'<br />';
441 foreach($mixedResult[
'content_data']
as $aFile)
442 $sResult .=
'-- ' .
_t(
'_adm_txt_modules_wrong_permissions_msg', $aFile[
'path'], $aFile[
'permissions']) .
'<br />';
452 $sPath = $this->_sHomePath .
'install/sql/' . ($bInstall ?
'install' :
'uninstall') .
'.sql';
453 if(!file_exists($sPath) || !($rHandler = fopen($sPath,
"r")))
459 while(!feof($rHandler)) {
460 $sStr = trim(fgets($rHandler));
462 if(
empty($sStr) || $sStr[0] ==
"" || $sStr[0] ==
"#" || ($sStr[0] ==
"-" && $sStr[1] ==
"-"))
466 if(strpos($sStr,
"DELIMITER //") !==
false || strpos($sStr,
"DELIMITER ;") !==
false) {
467 $sDelimiter = trim(str_replace(
'DELIMITER',
'', $sStr));
474 if(substr($sStr, -strlen($sDelimiter)) != $sDelimiter)
478 $sQuery = str_replace(
"[db_prefix]", $this->_aConfig[
'db_prefix'], $sQuery);
479 if($sDelimiter !=
';')
480 $sQuery = str_replace($sDelimiter,
"", $sQuery);
483 $rResult =
db_res(trim($sQuery));
484 }
catch (Exception $e) {
485 $aResult[] = array(
'query' => $sQuery,
'error' => $e->getMessage());
497 $sResult =
'<br />-- -- ' .
_t(
'_adm_txt_modules_wrong_mysql_query') .
'<br />';
498 foreach($mixedResult[
'content']
as $aQuery) {
499 $sResult .=
'-- -- ' .
_t(
'_adm_txt_modules_wrong_mysql_query_msg', $aQuery[
'error']) .
'<br />';
500 $sResult .=
'<pre>' . $aQuery[
'query'] .
'</pre>';
506 $aLanguages = array();
507 $rLanguages =
db_res(
"SELECT `ID` AS `id`, `Name` AS `name`, `Title` AS `title` FROM `sys_localization_languages`");
508 while($aLanguage = $rLanguages->fetch())
509 $aLanguages[] = $aLanguage;
513 $sCategoryName = isset($this->_aConfig[
'language_category']) ? $this->_aConfig[
'language_category'] :
'';
514 if($bInstall && !
empty($sCategoryName)) {
515 $res =
db_res(
"INSERT IGNORE INTO `sys_localization_categories` SET `Name`= ?", [$sCategoryName]);
517 $iCategoryId = (int)
db_value(
"SELECT `ID` FROM `sys_localization_categories` WHERE `Name`='" . $sCategoryName .
"' LIMIT 1");
520 }
else if(!$bInstall && !
empty($sCategoryName)) {
521 db_res(
"DELETE FROM `sys_localization_categories` WHERE `Name`= ?", [$sCategoryName]);
525 foreach($aLanguages
as $aLanguage)
530 foreach($aLanguages
as $aLanguage) {
540 $sResult =
'<br />-- -- ' .
_t(
'_adm_txt_modules_cannot_recompile_lang') .
'<br />';
549 $bResult = $MySQL->oParams->cache();
581 $bResult = $oPVCacher -> createCache();
590 $bResult = $oChWsbPFMCacher -> createCache();
671 return $this->_aConfig[
'vendor'];
675 return $this->_aConfig[
'name'];
679 return $this->_aConfig[
'title'];
683 return $this->_aConfig[
'home_dir'];
690 if(
empty($iCategoryId))
691 $iCategoryId = (int)
db_value(
"SELECT `ID` FROM `sys_localization_categories` WHERE `Name`='" . $this->_aConfig[
'language_category'] .
"' LIMIT 1");
693 $sPath = $this->_sHomePath .
'install/langs/' . $aLanguage[
'name'] .
'.php';
694 if(!file_exists($sPath))
704 $iLangKeyId = (int)
db_value(
"SELECT `ID` FROM `sys_localization_keys` WHERE `IDCategory`='" . $iCategoryId .
"' AND `Key`='" . $sKey .
"' LIMIT 1");
705 if($iLangKeyId == 0) {
706 $res =
db_res(
"INSERT INTO `sys_localization_keys`(`IDCategory`, `Key`) VALUES('" . $iCategoryId .
"', '" . $sKey .
"')");
712 db_res(
"INSERT IGNORE INTO `sys_localization_strings`(`IDKey`, `IDLanguage`, `String`) VALUES('" . $iLangKeyId .
"', '" . $aLanguage[
'id'] .
"', '" . addslashes($sValue) .
"')");
717 db_res(
"DELETE FROM `sys_localization_keys`, `sys_localization_strings` USING `sys_localization_keys`, `sys_localization_strings` WHERE `sys_localization_keys`.`ID`=`sys_localization_strings`.`IDKey` AND `sys_localization_keys`.`Key`='" . $sKey .
"'");
729 $sLangName = $aLangInfo[
'Name'];
730 $sLangFlag = $aLangInfo[
'Flag'];
731 $sLangTitle = $aLangInfo[
'Title'];
732 $sLangDir = isset($aLangInfo[
'Direction']) && $aLangInfo[
'Direction'] ? $aLangInfo[
'Direction'] :
'LTR';
733 $sLangCountryCode = isset($aLangInfo[
'LanguageCountry']) && $aLangInfo[
'LanguageCountry'] ? $aLangInfo[
'LanguageCountry'] : $aLangInfo[
'Name'] .
'_' . strtoupper($aLangInfo[
'Flag']);
735 if (!
$oDb->res(
"INSERT INTO `sys_localization_languages` VALUES (?, ?, ?, ?, ?, ?)", [
745 $iLangKey =
$oDb->lastId();
747 foreach ($aLanguage
as $sKey => $sValue) {
751 $iExistedKey =
$oDb->getOne(
"SELECT `ID` FROM `sys_localization_keys` WHERE `Key` = ?", [$sDbKey]);
755 $iExistedKey =
$oDb->lastId();
758 $oDb->res(
"INSERT INTO `sys_localization_strings` VALUES(?, ?, ?)", [$iExistedKey, $iLangKey, $sDbValue]);
771 if (!
$oDb->res(
"DELETE FROM `sys_localization_languages` WHERE ID = {$iLangKey}"))
774 $oDb->res(
"DELETE FROM `sys_localization_strings` WHERE `IDLanguage` = {$iLangKey}");
783 $aLanguage =
$GLOBALS[
'MySQL']->getRow(
"SELECT `ID` AS `id`, `Name` AS `name`, `Title` AS `title` FROM `sys_localization_languages` WHERE `ID` = ?", [$iLangId]);
795 $bInclude = @include(CH_DIRECTORY_PATH_MODULES . $a[
'path'] .
'install/config.php');
800 $this->_sHomePath = $this->_sBasePath .
$aConfig[
'home_dir'];
801 $this->_sModulePath = $this->_sBasePath .
$aConfig[
'home_dir'];
807 $this->_aConfig = $aSave[
'config'];
808 $this->_sHomePath = $aSave[
'home_path'];
809 $this->_sModulePath = $aSave[
'module_path'];
817 $hPerms = @fileperms($sFilePath);
820 return substr( decoct( $hPerms ), -3 );