/** * onUncaughtException event listener * * @param iMSCP_Exception_Event $event * @return void */ public function onUncaughtException(iMSCP_Exception_Event $event) { if (iMSCP_Registry::isRegistered('config')) { $debug = iMSCP_Registry::get('config')->DEBUG; } else { $debug = 1; } $mail = $this->prepareMail($event->getException()); if (!empty($mail)) { $footprintsCacheFile = CACHE_PATH . '/mail_body_footprints.php'; $footprints = array(); $now = time(); // Load footprints cache file if (is_readable($footprintsCacheFile)) { if (!$debug) { $footprints = (include $footprintsCacheFile); } else { iMSCP_Utility_OpcodeCache::clearAllActive($footprintsCacheFile); // Be sure to load newest version on next call @unlink($footprintsCacheFile); } if (!is_array($footprints)) { $footprints = array(); } } # Remove expired entries from the cache foreach ($footprints as $footprint => $expireTime) { if ($expireTime <= $now) { unset($footprints[$footprint]); } } // Do not send mail for identical exception in next 24 hours if (!array_key_exists($mail['footprint'], $footprints) || $footprints[$mail['footprint']] < $now) { if (@mail($mail['rcptTo'], $mail['subject'], $mail['body'], $mail['header'])) { # Add mail footprint into the cache $footprints[$mail['footprint']] = strtotime("+24 hours"); } } // Update footprints cache file if (!$debug) { $fileContent = "<?php\n"; $fileContent .= "// File automatically generated by i-MSCP. Do not edit it manually.\n"; $fileContent .= "return " . var_export($footprints, true) . ";\n"; @file_put_contents($footprintsCacheFile, $fileContent, LOCK_EX); iMSCP_Utility_OpcodeCache::clearAllActive($footprintsCacheFile); // Be sure to load newest version on next call } } }
/** * Initialize the cache properties * * @return void */ protected static function initialize() { $apcVersion = phpversion('apc'); $xcVersion = phpversion('xcache'); static::$supportedCaches = array('OPcache' => array('active' => extension_loaded('Zend OPcache') && ini_get('opcache.enable') === '1', 'version' => phpversion('Zend OPcache'), 'canReset' => true, 'canInvalidate' => function_exists('opcache_invalidate'), 'error' => false, 'clearCallback' => function ($fileAbsPath) { if ($fileAbsPath !== null && function_exists('opcache_invalidate')) { opcache_invalidate($fileAbsPath, true); } else { opcache_reset(); } }), 'APC' => array('active' => extension_loaded('apc') && !extension_loaded('apcu') && ini_get('apc.enabled') === '1', 'version' => $apcVersion, 'canReset' => true, 'canInvalidate' => self::canApcInvalidate(), 'error' => $apcVersion && version_compare($apcVersion, '3.1.7', '<'), 'clearCallback' => function ($fileAbsPath) { if ($fileAbsPath !== null && iMSCP_Utility_OpcodeCache::getCanInvalidate('APC')) { // This may output a warning like: PHP Warning: apc_delete_file(): Could not stat file // This warning isn't true, this means that apc was unable to generate the cache key // which depends on the configuration of APC. @apc_delete_file($fileAbsPath); } else { apc_clear_cache('opcode'); } }), 'XCache' => array('active' => extension_loaded('xcache'), 'version' => $xcVersion, 'canReset' => true, 'canInvalidate' => false, 'error' => false, 'clearCallback' => $xcVersion && version_compare($xcVersion, '3.0.0', '<') ? function () { if (!ini_get('xcache.admin.enable_auth')) { xcache_clear_cache(XC_TYPE_PHP, 0); } } : function () { if (!ini_get('xcache.admin.enable_auth')) { xcache_clear_cache(XC_TYPE_PHP); } }), 'eAccelerator' => array('active' => extension_loaded('eAccelerator'), 'version' => phpversion('eaccelerator'), 'canReset' => false, 'canInvalidate' => false, 'error' => false, 'clearCallback' => function () { eaccelerator_clear(); }), 'ZendOptimizerPlus' => array('active' => extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable') === '1', 'version' => phpversion('Zend Optimizer+'), 'canReset' => true, 'canInvalidate' => false, 'error' => false, 'clearCallback' => function () { accelerator_reset(); })); static::$activeCaches = array(); // Cache the active ones foreach (static::$supportedCaches as $opcodeCache => $properties) { if ($properties['active']) { static::$activeCaches[$opcodeCache] = $properties; } } }
$action = 'delete'; break; default: // Handle case where the error field is not NULL and status field is in unexpected state // Should never occurs... $pluginManager->pluginSetStatus($pluginName, 'todisable'); $action = 'disable'; } doAction($pluginManager, $pluginName, $action); } else { showBadRequestErrorPage(); } } elseif (isset($_POST['bulk_actions'])) { doBulkAction($pluginManager); } elseif (!empty($_FILES) && uploadPlugin($pluginManager)) { OpcodeCacheUtils::clearAllActive(); // Force newest files to be loaded on next run set_page_message(tr('Plugin has been successfully uploaded.'), 'success'); redirectTo('settings_plugins.php?update_plugin_list'); } redirectTo('settings_plugins.php'); } $tpl = new TemplateEngine(); $tpl->define_dynamic(array('layout' => 'shared/layouts/ui.tpl', 'page' => 'admin/settings_plugins.tpl', 'page_message' => 'layout', 'plugins_block' => 'page', 'plugin_block' => 'plugins_block', 'plugin_status_details_block' => 'plugin_block', 'plugin_activate_link' => 'plugin_block', 'plugin_deactivate_link' => 'plugin_block', 'plugin_protected_link' => 'plugin_block')); EventManager::getInstance()->registerListener(Events::onGetJsTranslations, function ($event) { /** @var $event \iMSCP_Events_Event $translations */ $event->getParam('translations')->core = array_merge($event->getParam('translations')->core, array('dataTable' => getDataTablesPluginTranslations(false), 'force_retry' => tr('Force retry'), 'close' => tr('Close'), 'error_details' => tr('Error details'))); }); $tpl->assign(array('TR_PAGE_TITLE' => tr('Admin / Settings / Plugin Management'), 'TR_BULK_ACTIONS' => tr('Bulk Actions'), 'TR_PLUGIN' => tr('Plugin'), 'TR_DESCRIPTION' => tr('Description'), 'TR_STATUS' => tr('Status'), 'TR_ACTIONS' => tr('Actions'), 'TR_INSTALL' => tr('Install'), 'TR_ACTIVATE' => tr('Activate'), 'TR_DEACTIVATE_TOOLTIP' => tr('Deactivate this plugin'), 'TR_DEACTIVATE' => tr('Deactivate'), 'TR_UNINSTALL' => tr('Uninstall'), 'TR_PROTECT' => tr('Protect'), 'TR_DELETE' => tr('Delete'), 'TR_PROTECT_TOOLTIP' => tr('Protect this plugin'), 'TR_VERSION' => tr('Version'), 'TR_BY' => tr('By'), 'TR_VISIT_PLUGIN_SITE' => tr('Visit plugin site'), 'TR_UPDATE_PLUGIN_LIST' => tr('Update Plugins'), 'TR_APPLY' => tr('Apply'), 'TR_PLUGIN_UPLOAD' => tr('Plugins Upload'), 'TR_UPLOAD' => tr('Upload'), 'TR_PLUGIN_ARCHIVE' => tr('Plugin archive'), 'TR_PLUGIN_ARCHIVE_TOOLTIP' => tr('Only tar.gz, tar.bz2 and zip archives are accepted.'), 'TR_PLUGIN_HINT' => tr('Plugins hook into i-MSCP to extend its functionality with custom features. Plugins are developed independently from the core i-MSCP application by thousands of developers all over the world. You can find new plugins to install by browsing the %s.', '<a style="text-decoration: underline" href="http://i-mscp.net/filebase/index.php/Filebase/" target="_blank">' . tr('i-MSCP plugin store') . '</a></u>'), 'TR_CLICK_FOR_MORE_DETAILS' => tr('Click here for more details'))); generateNavigation($tpl); generatePage($tpl, $pluginManager);
/** * Build languages index from machine object files. * * @throws iMSCP_Exception * @return void */ function i18n_buildLanguageIndex() { /** @var $cfg iMSCP_Config_Handler_File */ $cfg = iMSCP_Registry::get('config'); // Clear translation cache /** @var Zend_Translate $translator */ $translator = iMSCP_Registry::get('translator'); if ($translator->hasCache()) { $translator->clearCache('iMSCP'); } # Remove all cached navigation translation files if (@is_dir(CACHE_PATH . '/translations/navigation')) { if (!utils_removeDir(CACHE_PATH . '/translations/navigation')) { throw new iMSCP_Exception('Unable to remove directory for cached navigation translation files'); } } # Clear opcode cache if any iMSCP_Utility_OpcodeCache::clearAllActive(); $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($cfg->GUI_ROOT_DIR . '/i18n/locales/', FilesystemIterator::SKIP_DOTS)); $availableLanguages = array(); /** @var $item SplFileInfo */ foreach ($iterator as $item) { if (strlen($basename = $item->getBasename()) > 8) { continue; } if ($item->isReadable()) { $parser = new iMSCP_I18n_Parser_Gettext($item->getPathname()); $translationTable = $parser->getTranslationTable(); if (!empty($translationTable)) { $poRevisionDate = DateTime::createFromFormat('Y-m-d H:i O', $parser->getPotCreationDate()); $availableLanguages[$basename] = array('locale' => $parser->getLanguage(), 'revision' => $poRevisionDate->format('Y-m-d H:i'), 'translatedStrings' => $parser->getNumberOfTranslatedStrings(), 'lastTranslator' => $parser->getLastTranslator()); // Getting localized language name if (!isset($translationTable['_: Localised language'])) { $availableLanguages[$basename]['language'] = tr('Unknown'); } else { $availableLanguages[$basename]['language'] = $translationTable['_: Localised language']; } } else { set_page_message(tr('The %s translation file has been ignored: Translation table is empty.', $basename), 'warning'); } } } /** @var $dbConfig iMSCP_Config_Handler_Db */ $dbConfig = iMSCP_Registry::get('dbConfig'); sort($availableLanguages); $serializedData = serialize($availableLanguages); $dbConfig['AVAILABLE_LANGUAGES'] = $serializedData; $cfg['AVAILABLE_LANGUAGES'] = $serializedData; }
/** * Return plugin configuration from file * * @throws iMSCP_Plugin_Exception in case plugin configuration file is not readable * @return array */ public final function getConfigFromFile() { $this->isLoadedConfig = false; $pluginName = $this->getName(); $file = $this->getPluginManager()->pluginGetDirectory() . "/{$pluginName}/config.php"; $config = array(); if (@file_exists($file)) { if (@is_readable($file)) { $config = (include $file); iMSCP_Utility_OpcodeCache::clearAllActive($file); // Be sure to load newest version on next call $file = PERSISTENT_PATH . "/plugins/{$pluginName}.php"; if (@is_readable($file)) { $localConfig = (include $file); iMSCP_Utility_OpcodeCache::clearAllActive($file); // Be sure to load newest version on next call if (array_key_exists('__REMOVE__', $localConfig) && is_array($localConfig['__REMOVE__'])) { $config = utils_arrayDiffRecursive($config, $localConfig['__REMOVE__']); if (array_key_exists('__OVERRIDE__', $localConfig) && is_array($localConfig['__OVERRIDE__'])) { $config = utils_arrayMergeRecursive($config, $localConfig['__OVERRIDE__']); } } } } else { throw new iMSCP_Plugin_Exception(tr('Unable to read the plugin %s file. Please check file permissions', $file)); } } return $config; }
/** * Handle plugin protection file * * @return bool TRUE when protection file is successfully created/updated or removed FALSE otherwise */ protected function pluginUpdateProtectedFile() { $file = PERSISTENT_PATH . '/protected_plugins.php'; $lastUpdate = 'Last update: ' . date('Y-m-d H:i:s', time()) . ' by ' . $_SESSION['user_logged']; $content = "<?php\n/**\n * Protected plugin list\n * Auto-generated by i-MSCP Plugin Manager\n"; $content .= " * {$lastUpdate}\n */\n\n"; if (!empty($this->protectedPlugins)) { foreach ($this->protectedPlugins as $name) { $content .= "\$protectedPlugins[] = '{$name}';\n"; } iMSCP_Utility_OpcodeCache::clearAllActive($file); // Be sure to load newest version on next call @unlink($file); if (@file_put_contents($file, "{$content}\n", LOCK_EX) === false) { set_page_message(tr('Plugin Manager: Unable to write the %s file for protected plugins.', $file), 'error'); write_log(sprintf('Plugin Manager: Unable to write the %s file for protected plugins.', $file)); return false; } } elseif (@is_writable($file)) { iMSCP_Utility_OpcodeCache::clearAllActive($file); // Be sure to load newest version on next call if (!@unlink($file)) { write_log(sprintf('Plugin Manager: Unable to remove the %s file'), $file, E_USER_WARNING); return false; } } return true; }