_aConfig = $aConfig;
$this->_sBasePath = BX_DIRECTORY_PATH_MODULES;
$this->_sHomePath = $this->_sBasePath . $aConfig['home_dir'];
$this->_sModulePath = $this->_sBasePath . $aConfig['home_dir'];
$this->_aActions = array(
'check_script_version' => array(
'title' => _t('_adm_txt_modules_check_script_version'),
),
'check_dependencies' => array(
'title' => _t('_adm_txt_modules_check_dependencies'),
),
'show_introduction' => array(
'title' => _t('_adm_txt_modules_show_introduction'),
),
'change_permissions' => array(
'title' => _t('_adm_txt_modules_change_permissions'),
),
'execute_sql' => array(
'title' => _t('_adm_txt_modules_execute_sql'),
),
'update_languages' => array(
'title' => _t('_adm_txt_modules_update_languages'),
),
'recompile_global_paramaters' => array(
'title' => _t('_adm_txt_modules_recompile_global_paramaters'),
),
'recompile_main_menu' => array(
'title' => _t('_adm_txt_modules_recompile_main_menu'),
),
'recompile_member_menu' => array(
'title' => _t('_adm_txt_modules_recompile_member_menu'),
),
'recompile_site_stats' => array(
'title' => _t('_adm_txt_modules_recompile_site_stats'),
),
'recompile_page_builder' => array(
'title' => _t('_adm_txt_modules_recompile_page_builder'),
),
'recompile_profile_fields' => array(
'title' => _t('_adm_txt_modules_recompile_profile_fields'),
),
'recompile_comments' => array(
'title' => _t('_adm_txt_modules_recompile_comments'),
),
'recompile_member_actions' => array(
'title' => _t('_adm_txt_modules_recompile_member_actions'),
),
'recompile_tags' => array(
'title' => _t('_adm_txt_modules_recompile_tags'),
),
'recompile_votes' => array(
'title' => _t('_adm_txt_modules_recompile_votes'),
),
'recompile_categories' => array(
'title' => _t('_adm_txt_modules_recompile_categories'),
),
'recompile_search' => array(
'title' => _t('_adm_txt_modules_recompile_search'),
),
'recompile_injections' => array(
'title' => _t('_adm_txt_modules_recompile_injections'),
),
'recompile_permalinks' => array(
'title' => _t('_adm_txt_modules_recompile_permalinks'),
),
'recompile_alerts' => array(
'title' => _t('_adm_txt_modules_recompile_alerts'),
),
'clear_db_cache' => array(
'title' => _t('_adm_txt_modules_clear_db_cache'),
),
'show_conclusion' => array(
'title' => _t('_adm_txt_modules_show_conclusion'),
),
);
$this->_aNonHashable = array(
'install',
'updates'
);
}
function install($aParams)
{
$oModuleDb = new BxDolModuleDb();
$sTitle = _t('_adm_txt_modules_operation_install', $this->_aConfig['title']);
//--- Check whether the module was already installed ---//
if($oModuleDb->isModule($this->_aConfig['home_uri']))
return array(
'operation_title' => $sTitle,
'message' => _t('_adm_txt_modules_already_installed'),
'result' => false
);
//--- Check mandatory settings ---//
if($oModuleDb->isModuleParamsUsed($this->_aConfig['home_uri'], $this->_aConfig['home_dir'], $this->_aConfig['db_prefix'], $this->_aConfig['class_prefix']))
return array(
'operation_title' => $sTitle,
'message' => _t('_adm_txt_modules_params_used'),
'result' => false
);
//--- Check version compatibility ---//
$bCompatible = false;
if(isset($this->_aConfig['compatible_with']) && is_array($this->_aConfig['compatible_with']))
foreach($this->_aConfig['compatible_with'] as $iKey => $sVersion) {
$sVersion = '/^' . str_replace(array('.', 'x'), array('\.', '[0-9]+'), $sVersion) . '$/is';
$bCompatible = $bCompatible || (preg_match($sVersion, $GLOBALS['site']['ver'] . '.' . $GLOBALS['site']['build']) > 0);
}
if(!$bCompatible)
return array(
'operation_title' => $sTitle,
'message' => $this->_displayResult('check_script_version', false, '_adm_txt_modules_wrong_version_script'),
'result' => false
);
//--- Check actions ---//
$aResult = $this->_perform('install', 'Installation');
if($aResult['result']) {
$sDependencies = "";
if(isset($this->_aConfig['install']['check_dependencies']) && (int)$this->_aConfig['install']['check_dependencies'] == 1 && isset($this->_aConfig['dependencies']) && is_array($this->_aConfig['dependencies']))
$sDependencies = implode(',', array_keys($this->_aConfig['dependencies']));
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())");
$iModuleId = (int)db_last_id();
$aFiles = array();
$this->_hash($this->_sModulePath, $aFiles);
foreach($aFiles as $aFile)
db_res("INSERT IGNORE INTO `sys_modules_file_tracks`(`module_id`, `file`, `hash`) VALUES('" . $iModuleId . "', '" . $aFile['file'] . "', '" . $aFile['hash'] . "')");
$GLOBALS['MySQL']->cleanMemory('sys_modules_' . $this->_aConfig['home_uri']);
$GLOBALS['MySQL']->cleanMemory('sys_modules_' . $iModuleId);
$GLOBALS['MySQL']->cleanMemory('sys_modules');
}
$aResult['operation_title'] = $sTitle;
return $aResult;
}
function uninstall($aParams)
{
$oModuleDb = new BxDolModuleDb();
$sTitle = _t('_adm_txt_modules_operation_uninstall', $this->_aConfig['title']);
//--- Check whether the module was already installed ---//
if(!$oModuleDb->isModule($this->_aConfig['home_uri']))
return array(
'operation_title' => $sTitle,
'message' => _t('_adm_txt_modules_already_uninstalled'),
'result' => false
);
//--- Check for dependent modules ---//
$bDependent = false;
$aDependents = $oModuleDb->getDependent($this->_aConfig['home_uri']);
if(is_array($aDependents) && !empty($aDependents)) {
$bDependent = true;
$sMessage = '
-- -- ' . _t('_adm_txt_modules_has_dependents') . '
';
foreach($aDependents as $aDependent)
$sMessage .= '-- -- ' . $aDependent['title'] . '
';
}
if($bDependent)
return array(
'operation_title' => $sTitle,
'message' => $this->_displayResult('check_dependencies', false, $sMessage),
'result' => false
);
$aResult = $this->_perform('uninstall', 'Uninstallation');
if($aResult['result']) {
$iModuleId = (int)$oModuleDb->getOne("SELECT `id` FROM `sys_modules` WHERE `vendor`='" . $this->_aConfig['vendor'] . "' AND `path`='" . $this->_aConfig['home_dir'] . "' LIMIT 1");
$oModuleDb->query("DELETE FROM `sys_modules` WHERE `vendor`='" . $this->_aConfig['vendor'] . "' AND `path`='" . $this->_aConfig['home_dir'] . "' LIMIT 1");
$oModuleDb->query("DELETE FROM `sys_modules_file_tracks` WHERE `module_id`='" . $iModuleId . "'");
$GLOBALS['MySQL']->cleanMemory ('sys_modules_' . $this->_aConfig['home_uri']);
$GLOBALS['MySQL']->cleanMemory ('sys_modules_' . $iModuleId);
$GLOBALS['MySQL']->cleanMemory ('sys_modules');
}
$aResult['operation_title'] = $sTitle;
return $aResult;
}
function recompile($aParams)
{
$aResult = array('message' => '', 'result' => false);
$aLanguages = $GLOBALS['MySQL']->getAll("SELECT `ID` AS `id`, `Name` AS `name`, `Title` AS `title` FROM `sys_localization_languages` WHERE 1");
if(isAdmin() && !empty($aLanguages)) {
$this->_updateLanguage(false, current($aLanguages));
$bResult = false;
foreach($aLanguages as $aLanguage) {
$bResult = $this->_updateLanguage(true, $aLanguage) && compileLanguage($aLanguage['id']);
$aResult['message'] .= $aLanguage['title'] . ': ' . _t($bResult ? '_adm_txt_modules_process_action_success' : '_adm_txt_modules_process_action_failed') . '
';
$aResult['result'] |= $bResult;
}
}
$aResult['operation_title'] = _t('_adm_txt_modules_operation_recompile', $this->_aConfig['title']);
return $aResult;
}
function _hash($sPath, &$aFiles)
{
if(file_exists($sPath) && is_dir($sPath) && ($rSource = opendir($sPath))) {
while(($sFile = readdir($rSource)) !== false) {
if($sFile == '.' || $sFile =='..' || $sFile[0] == '.' || in_array($sFile, $this->_aNonHashable))
continue;
if(is_dir($sPath . $sFile))
$this->_hash($sPath . $sFile . '/', $aFiles);
else
$aFiles[] = $this->_info($sPath . $sFile);
}
closedir($rSource);
} else
$aFiles[] = $this->_info($sPath, $sFile);
}
function _info($sPath)
{
return array(
'file' => str_replace($this->_sModulePath, '', $sPath),
'hash' => md5(file_get_contents($sPath))
);
}
function _perform($sOperationName, $sOperationTitle)
{
if(!defined('BX_SKIP_INSTALL_CHECK') && !$GLOBALS['logged']['admin'])
return array('message' => '', 'result' => false);
$sMessage = '';
foreach($this->_aConfig[$sOperationName] as $sAction => $iEnabled) {
$sCookie = empty($this->_aConfig['name'])
? ''
: $this->_aConfig['name'] . '_' . $sAction;
$sMethod = 'action' . str_replace (' ', '', ucwords(str_replace ('_', ' ', $sAction)));
if($iEnabled == 0 || (isset($_COOKIE[$sCookie]) && (int)$_COOKIE[$sCookie] == 1) || !method_exists($this, $sMethod))
continue;
$mixedResult = $this->$sMethod($sOperationName == 'install' || $sOperationName == 'update');
//--- On Success ---//
if((is_int($mixedResult) && (int)$mixedResult == BX_DOL_INSTALLER_SUCCESS) || (isset($mixedResult['code']) && (int)$mixedResult['code'] == BX_DOL_INSTALLER_SUCCESS)) {
if($sOperationName == 'install' || $sOperationName == 'update')
setcookie($sCookie, 1, 0, '/');
else
setcookie($sCookie, 1, time() - 86400, '/');
$sMessage .= $this->_displayResult($sAction, true, isset($mixedResult['content']) ? $mixedResult['content'] : '');
continue;
}
//--- On Failed ---//
$sMethodFailed = $sMethod . 'Failed';
return array('message' => $this->_displayResult($sAction, false, method_exists($this, $sMethodFailed) ? $this->$sMethodFailed($mixedResult) : $this->actionOperationFailed($mixedResult)), 'result' => false);
}
//--- Remove all cookies ---//
foreach($this->_aConfig[$sOperationName] as $sAction => $iEnabled)
setcookie( (empty($this->_aConfig['name']) ? '' : $this->_aConfig['name']) . '_' . $sAction, 1, time() - 86400, '/');
$sMessage .= $sOperationTitle . ' finished';
return array('message' => $sMessage, 'result' => true);
}
function _displayResult($sAction, $bResult, $sResult = '')
{
$sMessage = '-- ' . $this->_aActions[$sAction]['title'] . ' ';
if(!empty($sResult) && substr($sResult, 0, 1) == '_')
$sResult = _t($sResult) . '
';
if(!$bResult)
return $sMessage . '' . $sResult . '';
if(empty($sResult))
$sResult = _t('_adm_txt_modules_process_action_success') . '
';
return $sMessage . '' . $sResult . '';
}
//--- Action Methods ---//
function actionOperationFailed($mixedResult)
{
return _t('_adm_txt_modules_process_action_failed');
}
function actionCheckDependencies($bInstall = true)
{
$sContent = '';
if($bInstall) {
if(!isset($this->_aConfig['dependencies']) || !is_array($this->_aConfig['dependencies']))
return BX_DOL_INSTALLER_SUCCESS;
$oModulesDb = new BxDolModuleDb();
foreach($this->_aConfig['dependencies'] as $sModuleUri => $sModuleTitle)
if($sModuleUri != $this->_aConfig['home_uri'] && !$oModulesDb->isModule($sModuleUri))
$sContent .= '-- -- ' . $sModuleTitle . '
';
if(!empty($sContent))
$sContent = '
-- -- ' . _t('_adm_txt_modules_wrong_dependency_install') . '
' . $sContent;
}
return empty($sContent) ? BX_DOL_INSTALLER_SUCCESS : array('code' => BX_DOL_INSTALLER_FAILED, 'content' => $sContent);
}
function actionCheckDependenciesFailed($mixedResult)
{
return $mixedResult['content'];
}
function actionShowIntroduction($bInstall = true)
{
$sFile = $this->_aConfig[($bInstall ? 'install_info' : 'uninstall_info')]['introduction'];
$sPath = $this->_sHomePath . 'install/info/' . $sFile;
return file_exists($sPath) ? array("code" => BX_DOL_INSTALLER_SUCCESS, "content" => "
" . file_get_contents($sPath) . "") : BX_DOL_INSTALLER_FAILED; } function actionShowConclusion($bInstall = true) { $sFile = $this->_aConfig[($bInstall ? 'install_info' : 'uninstall_info')]['conclusion']; $sPath = $this->_sHomePath . 'install/info/' . $sFile; return file_exists($sPath) ? array("code" => BX_DOL_INSTALLER_SUCCESS, "content" => "
" . file_get_contents($sPath) . "") : BX_DOL_INSTALLER_FAILED; } function actionChangePermissions($bInstall = true) { $aPermissions = $bInstall ? $this->_aConfig['install_permissions'] : $this->_aConfig['uninstall_permissions']; $aResult = array(); foreach($aPermissions as $sPermissions => $aFiles) { $sCheckFunction = 'is' . ucfirst($sPermissions); $sCptPermissions = _t('_adm_txt_modules_' . $sPermissions); foreach($aFiles as $sFile) if(!BxDolInstallerUtils::$sCheckFunction(bx_ltrim_str($this->_sModulePath . $sFile, BX_DIRECTORY_PATH_ROOT))) $aResult[] = array('path' => $this->_sModulePath . $sFile, 'permissions' => $sCptPermissions); } return empty($aResult) ? BX_DOL_INSTALLER_SUCCESS : array('code' => BX_DOL_INSTALLER_FAILED, 'content' => $aResult); } function actionChangePermissionsFailed($mixedResult) { $sResult = '
' . $aQuery['query'] . ''; } return $sResult; } function actionUpdateLanguages($bInstall = true) { $aLanguages = array(); $rLanguages = db_res("SELECT `ID` AS `id`, `Name` AS `name`, `Title` AS `title` FROM `sys_localization_languages`"); while($aLanguage = mysql_fetch_assoc($rLanguages)) $aLanguages[] = $aLanguage; //--- Process Language Category ---// $iCategoryId = 100; $sCategoryName = isset($this->_aConfig['language_category']) ? $this->_aConfig['language_category'] : ''; if($bInstall && !empty($sCategoryName)) { db_res("INSERT IGNORE INTO `sys_localization_categories` SET `Name`='" . $sCategoryName . "'"); if(db_affected_rows() <= 0 ) $iCategoryId = (int)db_value("SELECT `ID` FROM `sys_localization_categories` WHERE `Name`='" . $sCategoryName . "' LIMIT 1"); else $iCategoryId = db_last_id(); } else if(!$bInstall && !empty($sCategoryName)) { db_res("DELETE FROM `sys_localization_categories` WHERE `Name`='" . $sCategoryName . "'"); } //--- Process languages' key=>value pears ---// foreach($aLanguages as $aLanguage) $this->_updateLanguage($bInstall, $aLanguage, $iCategoryId); //--- Recompile all language files ---// $aResult = array(); foreach($aLanguages as $aLanguage) { $bResult = compileLanguage($aLanguage['id']); if(!$bResult) $aResult[] = $aLanguage['title']; } return empty($aResult) ? BX_DOL_INSTALLER_SUCCESS : array('code' => BX_DOL_INSTALLER_FAILED, 'content' => $aResult); } function actionUpdateLanguagesFailed($mixedResult) { $sResult = '