isPluginActivated($module)) { throw new Piwik_FrontController_PluginDeactivatedException($module); } $controllerClassName = 'Piwik_' . $module . '_Controller'; // FrontController's autoloader if (!class_exists($controllerClassName, false)) { $moduleController = PIWIK_INCLUDE_PATH . '/plugins/' . $module . '/Controller.php'; if (!is_readable($moduleController)) { throw new Exception("Module controller $moduleController not found!"); } require_once $moduleController; // prefixed by PIWIK_INCLUDE_PATH } $controller = new $controllerClassName(); if ($action === false) { $action = $controller->getDefaultAction(); } if (!is_callable(array($controller, $action))) { throw new Exception("Action '$action' not found in the controller '$controllerClassName'."); } // Generic hook that plugins can use to modify any input to the function, // or even change the plugin being called $params = array($controller, $action, $parameters); Piwik_PostEvent('FrontController.dispatch', $params); try { return call_user_func_array(array($params[0], $params[1]), $params[2]); } catch (Access_NoAccessException $e) { Piwik_PostEvent('FrontController.NoAccessException', array($e), $pending = true); } catch (Exception $e) { $debugTrace = $e->getTraceAsString(); $message = Common::sanitizeInputValue($e->getMessage()); Piwik_ExitWithMessage($message, '' /* $debugTrace */, true); } } /** * Often plugins controller display stuff using echo/print. * Using this function instead of dispatch() returns the output string form the actions calls. * * @param string $controllerName * @param string $actionName * @param array $parameters * @return string */ public function fetchDispatch($controllerName = null, $actionName = null, $parameters = null) { ob_start(); $output = $this->dispatch($controllerName, $actionName, $parameters); // if nothing returned we try to load something that was printed on the screen if (empty($output)) { $output = ob_get_contents(); } ob_end_clean(); return $output; } /** * Called at the end of the page generation * */ public function __destruct() { try { Piwik::printSqlProfilingReportZend(); Piwik::printQueryCount(); Piwik::printTimer(); } catch (Exception $e) { } } // Should we show exceptions messages directly rather than display an html error page? public static function shouldRethrowException() { // If we are in no dispatch mode, eg. a script reusing Piwik libs, // then we should return the exception directly, rather than trigger the event "bad config file" // which load the HTML page of the installer with the error. // This is at least required for misc/cron/archive.php and useful to all other scripts return (defined('PIWIK_ENABLE_DISPATCH') && !PIWIK_ENABLE_DISPATCH) || Common::isPhpCliMode() || Common::isArchivePhpTriggered(); } /** * Loads the config file and assign to the global registry * This is overridden in tests to ensure test config file is used * * @return Exception */ protected function createConfigObject() { $exceptionToThrow = false; try { Config::getInstance(); } catch (Exception $e) { Piwik_PostEvent('FrontController.NoConfigurationFile', array($e), $pending = true); $exceptionToThrow = $e; } return $exceptionToThrow; } /** * Must be called before dispatch() * - checks that directories are writable, * - loads the configuration file, * - loads the plugin, * - inits the DB connection, * - etc. * * @throws Exception * @return void */ public function init() { static $initialized = false; if ($initialized) { return; } $initialized = true; try { Zend_Registry::set('timer', new Piwik_Timer); $directoriesToCheck = array( '/tmp/', '/tmp/templates_c/', '/tmp/cache/', '/tmp/assets/', '/tmp/tcpdf/' ); Piwik::dieIfDirectoriesNotWritable($directoriesToCheck); Common::assignCliParametersToRequest(); Piwik_Translate::getInstance()->loadEnglishTranslation(); $exceptionToThrow = $this->createConfigObject(); if (Piwik_Session::isFileBasedSessions()) { Piwik_Session::start(); } $this->handleMaintenanceMode(); $this->handleSSLRedirection(); $pluginsManager = PluginsManager::getInstance(); $pluginsToLoad = Config::getInstance()->Plugins['Plugins']; $pluginsManager->loadPlugins($pluginsToLoad); if ($exceptionToThrow) { throw $exceptionToThrow; } try { Piwik::createDatabaseObject(); } catch (Exception $e) { if (self::shouldRethrowException()) { throw $e; } Piwik_PostEvent('FrontController.badConfigurationFile', array($e), $pending = true); throw $e; } Piwik::createLogObject(); // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs Access::getInstance(); Piwik_PostEvent('FrontController.dispatchCoreAndPluginUpdatesScreen'); PluginsManager::getInstance()->installLoadedPlugins(); // ensure the current Piwik URL is known for later use if (method_exists('Piwik\Piwik', 'getPiwikUrl')) { $host = Piwik::getPiwikUrl(); } Piwik_PostEvent('FrontController.initAuthenticationObject'); try { $authAdapter = Zend_Registry::get('auth'); } catch (Exception $e) { throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated?
You can activate the plugin by adding:
Plugins[] = Login
under the [Plugins] section in your config/config.ini.php"); } Access::getInstance()->reloadAccess($authAdapter); // Force the auth to use the token_auth if specified, so that embed dashboard // and all other non widgetized controller methods works fine if (($token_auth = Common::getRequestVar('token_auth', false, 'string')) !== false) { Piwik_API_Request::reloadAuthUsingTokenAuth(); } Piwik::raiseMemoryLimitIfNecessary(); Piwik_Translate::getInstance()->reloadLanguage(); $pluginsManager->postLoadPlugins(); Piwik_PostEvent('FrontController.checkForUpdates'); } catch (Exception $e) { if (self::shouldRethrowException()) { throw $e; } $trace = $e->getTraceAsString(); Piwik_ExitWithMessage($e->getMessage(), false /* $debugTrace */, true); } } protected function handleMaintenanceMode() { if (Config::getInstance()->General['maintenance_mode'] == 1 && !Common::isPhpCliMode() ) { $format = Common::getRequestVar('format', ''); $message = "Piwik is in scheduled maintenance. Please come back later." . " The administrator can disable maintenance by editing the file piwik/config/config.ini.php and removing the following: " . " maintenance_mode=1 "; if (Config::getInstance()->Tracker['record_statistics'] == 0) { $message .= ' and record_statistics=0'; } $exception = new Exception($message); // extend explain how to re-enable // show error message when record stats = 0 if (empty($format)) { throw $exception; } $response = new Piwik_API_ResponseBuilder($format); echo $response->getResponseException($exception); exit; } } protected function handleSSLRedirection() { if (!Common::isPhpCliMode() && Config::getInstance()->General['force_ssl'] == 1 && !Piwik::isHttps() // Specifically disable for the opt out iframe && !(Common::getRequestVar('module', '') == 'CoreAdminHome' && Common::getRequestVar('action', '') == 'optOut') ) { $url = Piwik_Url::getCurrentUrl(); $url = str_replace("http://", "https://", $url); Piwik_Url::redirectToUrl($url); } } } /** * Exception thrown when the requested plugin is not activated in the config file * * @package Piwik * @subpackage Piwik_FrontController */ class Piwik_FrontController_PluginDeactivatedException extends Exception { public function __construct($module) { parent::__construct("The plugin $module is not enabled. You can activate the plugin on Settings > Plugins page in Piwik."); } }