diff options
-rw-r--r-- | core/Config.php | 9 | ||||
-rw-r--r-- | core/Db.php | 2 | ||||
-rw-r--r-- | core/Exceptions/HtmlMessageException.php | 25 | ||||
-rw-r--r-- | core/Filechecks.php | 4 | ||||
-rw-r--r-- | core/FrontController.php | 229 | ||||
-rw-r--r-- | core/Log.php | 16 | ||||
-rw-r--r-- | core/Plugin/Controller.php | 97 | ||||
-rw-r--r-- | core/Session.php | 4 | ||||
-rw-r--r-- | core/dispatch.php | 27 | ||||
-rw-r--r-- | plugins/CorePluginsAdmin/Controller.php | 8 | ||||
-rw-r--r-- | plugins/Installation/Installation.php | 3 |
11 files changed, 234 insertions, 190 deletions
diff --git a/core/Config.php b/core/Config.php index 7d0e9072e9..95f4e62e6c 100644 --- a/core/Config.php +++ b/core/Config.php @@ -314,13 +314,13 @@ class Config extends Singleton // read defaults from global.ini.php if (!is_readable($this->pathGlobal) && $reportError) { - Piwik_ExitWithMessage(Piwik::translate('General_ExceptionConfigurationFileNotFound', array($this->pathGlobal))); + throw new Exception(Piwik::translate('General_ExceptionConfigurationFileNotFound', array($this->pathGlobal))); } $this->configGlobal = _parse_ini_file($this->pathGlobal, true); if (empty($this->configGlobal) && $reportError) { - Piwik_ExitWithMessage(Piwik::translate('General_ExceptionUnreadableFileDisabledMethod', array($this->pathGlobal, "parse_ini_file()"))); + throw new Exception(Piwik::translate('General_ExceptionUnreadableFileDisabledMethod', array($this->pathGlobal, "parse_ini_file()"))); } $this->configCommon = _parse_ini_file($this->pathCommon, true); @@ -330,7 +330,7 @@ class Config extends Singleton $this->configLocal = _parse_ini_file($this->pathLocal, true); if (empty($this->configLocal) && $reportError) { - Piwik_ExitWithMessage(Piwik::translate('General_ExceptionUnreadableFileDisabledMethod', array($this->pathLocal, "parse_ini_file()"))); + throw new Exception(Piwik::translate('General_ExceptionUnreadableFileDisabledMethod', array($this->pathLocal, "parse_ini_file()"))); } } @@ -725,5 +725,4 @@ class Config extends Singleton } return $merged; } - -} +}
\ No newline at end of file diff --git a/core/Db.php b/core/Db.php index 52c454e333..556bd2ada5 100644 --- a/core/Db.php +++ b/core/Db.php @@ -81,7 +81,7 @@ class Db */ Piwik::postEvent('Db.getDatabaseConfig', array(&$dbConfig)); - $dbConfig['profiler'] = $config->Debug['enable_sql_profiler']; + $dbConfig['profiler'] = @$config->Debug['enable_sql_profiler']; return $dbConfig; } diff --git a/core/Exceptions/HtmlMessageException.php b/core/Exceptions/HtmlMessageException.php new file mode 100644 index 0000000000..fd13bfa58d --- /dev/null +++ b/core/Exceptions/HtmlMessageException.php @@ -0,0 +1,25 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Exceptions; + +use Exception; + +/** + * TODO + */ +class HtmlMessageException extends Exception +{ + /** + * TODO + */ + public function getHtmlMessage() + { + return $this->getMessage(); + } +}
\ No newline at end of file diff --git a/core/Filechecks.php b/core/Filechecks.php index 3dc6d53195..eab93fd260 100644 --- a/core/Filechecks.php +++ b/core/Filechecks.php @@ -8,6 +8,8 @@ */ namespace Piwik; +use Piwik\Exceptions\HtmlMessageException; + class Filechecks { /** @@ -102,7 +104,7 @@ class Filechecks . "<p>After applying the modifications, you can <a href='index.php'>refresh the page</a>.</p>" . "<p>If you need more help, try <a href='?module=Proxy&action=redirect&url=http://piwik.org'>Piwik.org</a>.</p>"; - Piwik_ExitWithMessage($directoryMessage, false, true); + throw new HtmlMessageException($directoryMessage); } /** diff --git a/core/FrontController.php b/core/FrontController.php index 34da03fd9f..7864ba6076 100644 --- a/core/FrontController.php +++ b/core/FrontController.php @@ -106,10 +106,6 @@ class FrontController extends Singleton * @param \Piwik\NoAccessException $exception The exception that was caught. */ Piwik::postEvent('User.isNotAuthorized', array($exception), $pending = true); - } catch (Exception $e) { - $debugTrace = $e->getTraceAsString(); - $message = Common::sanitizeInputValue($e->getMessage()); - Piwik_ExitWithMessage($message, $debugTrace, true, true); } } @@ -223,7 +219,8 @@ class FrontController extends Singleton { try { if (class_exists('Piwik\\Profiler') - && !SettingsServer::isTrackerApiRequest()) { + && !SettingsServer::isTrackerApiRequest() + ) { // in tracker mode Piwik\Tracker\Db\Pdo\Mysql does currently not implement profiling Profiler::displayDbProfileReport(); Profiler::printQueryCount(); @@ -308,152 +305,142 @@ class FrontController extends Singleton } $initialized = true; - try { - Registry::set('timer', new Timer); - - $directoriesToCheck = array( - '/tmp/', - '/tmp/assets/', - '/tmp/cache/', - '/tmp/logs/', - '/tmp/tcpdf/', - '/tmp/templates_c/', - ); + Registry::set('timer', new Timer); - Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck); + $directoriesToCheck = array( + '/tmp/', + '/tmp/assets/', + '/tmp/cache/', + '/tmp/logs/', + '/tmp/tcpdf/', + '/tmp/templates_c/', + ); - Translate::loadEnglishTranslation(); + Translate::loadEnglishTranslation(); - $exceptionToThrow = self::createConfigObject(); + Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck); - $this->handleMaintenanceMode(); - $this->handleProfiler(); - $this->handleSSLRedirection(); + $exceptionToThrow = self::createConfigObject(); - Plugin\Manager::getInstance()->loadPluginTranslations('en'); - Plugin\Manager::getInstance()->loadActivatedPlugins(); + $this->handleMaintenanceMode(); + $this->handleProfiler(); + $this->handleSSLRedirection(); - if ($exceptionToThrow) { - throw $exceptionToThrow; - } + Plugin\Manager::getInstance()->loadPluginTranslations('en'); + Plugin\Manager::getInstance()->loadActivatedPlugins(); - // try to connect to the database - try { - Db::createDatabaseObject(); - Db::fetchAll("SELECT DATABASE()"); - } catch (Exception $exception) { - if (self::shouldRethrowException()) { - throw $exception; - } - - Log::debug($exception); - - /** - * Triggered when Piwik cannot connect to the database. - * - * This event can be used to start the installation process or to display a custom error - * message. - * - * @param Exception $exception The exception thrown from creating and testing the database - * connection. - */ - Piwik::postEvent('Db.cannotConnectToDb', array($exception), $pending = true); - - throw $exception; - } - - // try to get an option (to check if data can be queried) - try { - Option::get('TestingIfDatabaseConnectionWorked'); - } catch (Exception $exception) { - if (self::shouldRethrowException()) { - throw $exception; - } - - Log::debug($exception); - - /** - * Triggered when Piwik cannot access database data. - * - * This event can be used to start the installation process or to display a custom error - * message. - * - * @param Exception $exception The exception thrown from trying to get an option value. - */ - Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true); + if ($exceptionToThrow) { + throw $exceptionToThrow; + } + // try to connect to the database + try { + Db::createDatabaseObject(); + Db::fetchAll("SELECT DATABASE()"); + } catch (Exception $exception) { + if (self::shouldRethrowException()) { throw $exception; } - // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs - Access::getInstance(); + Log::debug($exception); /** - * Triggered just after the platform is initialized and plugins are loaded. + * Triggered when Piwik cannot connect to the database. * - * This event can be used to do early initialization. + * This event can be used to start the installation process or to display a custom error + * message. * - * _Note: At this point the user is not authenticated yet._ + * @param Exception $exception The exception thrown from creating and testing the database + * connection. */ - Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen'); + Piwik::postEvent('Db.cannotConnectToDb', array($exception), $pending = true); - \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins(); + throw $exception; + } - // ensure the current Piwik URL is known for later use - if (method_exists('Piwik\SettingsPiwik', 'getPiwikUrl')) { - SettingsPiwik::getPiwikUrl(); + // try to get an option (to check if data can be queried) + try { + Option::get('TestingIfDatabaseConnectionWorked'); + } catch (Exception $exception) { + if (self::shouldRethrowException()) { + throw $exception; } + Log::debug($exception); + /** - * Triggered before the user is authenticated, when the global authentication object - * should be created. - * - * Plugins that provide their own authentication implementation should use this event - * to set the global authentication object (which must derive from {@link Piwik\Auth}). + * Triggered when Piwik cannot access database data. * - * **Example** + * This event can be used to start the installation process or to display a custom error + * message. * - * Piwik::addAction('Request.initAuthenticationObject', function() { - * Piwik\Registry::set('auth', new MyAuthImplementation()); - * }); + * @param Exception $exception The exception thrown from trying to get an option value. */ - Piwik::postEvent('Request.initAuthenticationObject'); - try { - $authAdapter = Registry::get('auth'); - } catch (Exception $e) { - throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated? - <br />You can activate the plugin by adding:<br /> - <code>Plugins[] = Login</code><br /> - under the <code>[Plugins]</code> section in your config/config.ini.php"); - } - Access::getInstance()->reloadAccess($authAdapter); + Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true); - // Force the auth to use the token_auth if specified, so that embed dashboard - // and all other non widgetized controller methods works fine - if (Common::getRequestVar('token_auth', false, 'string') !== false) { - Request::reloadAuthUsingTokenAuth(); - } - SettingsServer::raiseMemoryLimitIfNecessary(); + throw $exception; + } - Translate::reloadLanguage(); - \Piwik\Plugin\Manager::getInstance()->postLoadPlugins(); + // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs + Access::getInstance(); - /** - * Triggered after the platform is initialized and after the user has been authenticated, but - * before the platform has handled the request. - * - * Piwik uses this event to check for updates to Piwik. - */ - Piwik::postEvent('Platform.initialized'); - } catch (Exception $e) { + /** + * Triggered just after the platform is initialized and plugins are loaded. + * + * This event can be used to do early initialization. + * + * _Note: At this point the user is not authenticated yet._ + */ + Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen'); - if (self::shouldRethrowException()) { - throw $e; - } + \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins(); - $debugTrace = $e->getTraceAsString(); - Piwik_ExitWithMessage($e->getMessage(), $debugTrace, true); + // ensure the current Piwik URL is known for later use + if (method_exists('Piwik\SettingsPiwik', 'getPiwikUrl')) { + SettingsPiwik::getPiwikUrl(); } + + /** + * Triggered before the user is authenticated, when the global authentication object + * should be created. + * + * Plugins that provide their own authentication implementation should use this event + * to set the global authentication object (which must derive from {@link Piwik\Auth}). + * + * **Example** + * + * Piwik::addAction('Request.initAuthenticationObject', function() { + * Piwik\Registry::set('auth', new MyAuthImplementation()); + * }); + */ + Piwik::postEvent('Request.initAuthenticationObject'); + try { + $authAdapter = Registry::get('auth'); + } catch (Exception $e) { + throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated? + <br />You can activate the plugin by adding:<br /> + <code>Plugins[] = Login</code><br /> + under the <code>[Plugins]</code> 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 (Common::getRequestVar('token_auth', false, 'string') !== false) { + Request::reloadAuthUsingTokenAuth(); + } + SettingsServer::raiseMemoryLimitIfNecessary(); + + Translate::reloadLanguage(); + \Piwik\Plugin\Manager::getInstance()->postLoadPlugins(); + + /** + * Triggered after the platform is initialized and after the user has been authenticated, but + * before the platform has handled the request. + * + * Piwik uses this event to check for updates to Piwik. + */ + Piwik::postEvent('Platform.initialized'); } protected function prepareDispatch($module, $action, $parameters) diff --git a/core/Log.php b/core/Log.php index b3421d13e1..41fbf851b1 100644 --- a/core/Log.php +++ b/core/Log.php @@ -264,7 +264,10 @@ class Log extends Singleton private function setLogWritersFromConfig($logConfig) { // set the log writers - $logWriters = $logConfig[self::LOG_WRITERS_CONFIG_OPTION]; + $logWriters = @$logConfig[self::LOG_WRITERS_CONFIG_OPTION]; + if (empty($logWriters)) { + return; + } $logWriters = array_map('trim', $logWriters); foreach ($logWriters as $writerName) { @@ -309,7 +312,11 @@ class Log extends Singleton private function setLogFilePathFromConfig($logConfig) { - $logPath = $logConfig[self::LOGGER_FILE_PATH_CONFIG_OPTION]; + $logPath = @$logConfig[self::LOGGER_FILE_PATH_CONFIG_OPTION]; + if (empty($logPath)) { + $logPath = $this->getDefaultFileLogPath(); + } + if (!SettingsServer::isWindows() && $logPath[0] != '/' ) { @@ -322,6 +329,11 @@ class Log extends Singleton $this->logToFilePath = $logPath; } + private function getDefaultFileLogPath() + { + return 'tmp/logs/piwik.log'; + } + private function getAvailableWriters() { $writers = array(); diff --git a/core/Plugin/Controller.php b/core/Plugin/Controller.php index d4b6539639..9985c100d5 100644 --- a/core/Plugin/Controller.php +++ b/core/Plugin/Controller.php @@ -17,6 +17,7 @@ use Piwik\Config as PiwikConfig; use Piwik\Config; use Piwik\DataTable\Filter\CalculateEvolutionFilter; use Piwik\Date; +use Piwik\Exceptions\HtmlMessageException; use Piwik\FrontController; use Piwik\Menu\MenuTop; use Piwik\Menu\MenuUser; @@ -581,61 +582,56 @@ abstract class Controller { $view->date = $this->strDate; - try { - $view->idSite = $this->idSite; - $this->checkSitePermission(); - $this->setPeriodVariablesView($view); - - $rawDate = Common::getRequestVar('date'); - $periodStr = Common::getRequestVar('period'); - if ($periodStr != 'range') { - $date = Date::factory($this->strDate); - $period = Period\Factory::build($periodStr, $date); - } else { - $period = new Range($periodStr, $rawDate, $this->site->getTimezone()); - } - $view->rawDate = $rawDate; - $view->prettyDate = self::getCalendarPrettyDate($period); + $view->idSite = $this->idSite; + $this->checkSitePermission(); + $this->setPeriodVariablesView($view); - $view->siteName = $this->site->getName(); - $view->siteMainUrl = $this->site->getMainUrl(); + $rawDate = Common::getRequestVar('date'); + $periodStr = Common::getRequestVar('period'); + if ($periodStr != 'range') { + $date = Date::factory($this->strDate); + $period = Period\Factory::build($periodStr, $date); + } else { + $period = new Range($periodStr, $rawDate, $this->site->getTimezone()); + } + $view->rawDate = $rawDate; + $view->prettyDate = self::getCalendarPrettyDate($period); - $datetimeMinDate = $this->site->getCreationDate()->getDatetime(); - $minDate = Date::factory($datetimeMinDate, $this->site->getTimezone()); - $this->setMinDateView($minDate, $view); + $view->siteName = $this->site->getName(); + $view->siteMainUrl = $this->site->getMainUrl(); - $maxDate = Date::factory('now', $this->site->getTimezone()); - $this->setMaxDateView($maxDate, $view); + $datetimeMinDate = $this->site->getCreationDate()->getDatetime(); + $minDate = Date::factory($datetimeMinDate, $this->site->getTimezone()); + $this->setMinDateView($minDate, $view); - // Setting current period start & end dates, for pre-setting the calendar when "Date Range" is selected - $dateStart = $period->getDateStart(); - if ($dateStart->isEarlier($minDate)) { - $dateStart = $minDate; - } - $dateEnd = $period->getDateEnd(); - if ($dateEnd->isLater($maxDate)) { - $dateEnd = $maxDate; - } + $maxDate = Date::factory('now', $this->site->getTimezone()); + $this->setMaxDateView($maxDate, $view); - $view->startDate = $dateStart; - $view->endDate = $dateEnd; + // Setting current period start & end dates, for pre-setting the calendar when "Date Range" is selected + $dateStart = $period->getDateStart(); + if ($dateStart->isEarlier($minDate)) { + $dateStart = $minDate; + } + $dateEnd = $period->getDateEnd(); + if ($dateEnd->isLater($maxDate)) { + $dateEnd = $maxDate; + } - $language = LanguagesManager::getLanguageForSession(); - $view->language = !empty($language) ? $language : LanguagesManager::getLanguageCodeForCurrentUser(); + $view->startDate = $dateStart; + $view->endDate = $dateEnd; - $this->setBasicVariablesView($view); + $language = LanguagesManager::getLanguageForSession(); + $view->language = !empty($language) ? $language : LanguagesManager::getLanguageCodeForCurrentUser(); - $view->topMenu = MenuTop::getInstance()->getMenu(); - $view->userMenu = MenuUser::getInstance()->getMenu(); + $this->setBasicVariablesView($view); - $notifications = $view->notifications; - if (empty($notifications)) { - $view->notifications = NotificationManager::getAllNotificationsToDisplay(); - NotificationManager::cancelAllNonPersistent(); - } + $view->topMenu = MenuTop::getInstance()->getMenu(); + $view->userMenu = MenuUser::getInstance()->getMenu(); - } catch (Exception $e) { - Piwik_ExitWithMessage($e->getMessage(), $e->getTraceAsString()); + $notifications = $view->notifications; + if (empty($notifications)) { + $view->notifications = NotificationManager::getAllNotificationsToDisplay(); + NotificationManager::cancelAllNonPersistent(); } } @@ -841,15 +837,20 @@ abstract class Controller } if (Piwik::hasUserSuperUserAccess()) { - Piwik_ExitWithMessage("Error: no website was found in this Piwik installation. - <br />Check the table '" . Common::prefixTable('site') . "' in your database, it should contain your Piwik websites.", false, true); + $siteTableName = Common::prefixTable('site'); + $message = "Error: no website was found in this Piwik installation. + <br />Check the table '$siteTableName' in your database, it should contain your Piwik websites."; + + throw new HtmlMessageException($message); } if (!Piwik::isUserIsAnonymous()) { + $currentLogin = Piwik::getCurrentUserLogin(); $emails = implode(',', Piwik::getAllSuperUserAccessEmailAddresses()); $errorMessage = sprintf(Piwik::translate('CoreHome_NoPrivilegesAskPiwikAdmin'), $currentLogin, "<br/><a href='mailto:" . $emails . "?subject=Access to Piwik for user $currentLogin'>", "</a>"); $errorMessage .= "<br /><br /> <b><a href='index.php?module=" . Registry::get('auth')->getName() . "&action=logout'>› " . Piwik::translate('General_Logout') . "</a></b><br />"; - Piwik_ExitWithMessage($errorMessage, false, true); + + throw new HtmlMessageException($errorMessage); } echo FrontController::getInstance()->dispatch(Piwik::getLoginPluginName(), false); diff --git a/core/Session.php b/core/Session.php index cb08f0f697..24595cd764 100644 --- a/core/Session.php +++ b/core/Session.php @@ -9,6 +9,7 @@ namespace Piwik; use Exception; +use Piwik\Exceptions\HtmlMessageException; use Piwik\Session\SaveHandler\DbTable; use Zend_Session; @@ -38,6 +39,7 @@ class Session extends Zend_Session * * @param array|bool $options An array of configuration options; the auto-start (bool) setting is ignored * @return void + * @throws Exception if starting a session fails */ public static function start($options = false) { @@ -130,7 +132,7 @@ class Session extends Zend_Session $e->getMessage() ); - Piwik_ExitWithMessage($message, $e->getTraceAsString()); + throw new HtmlMessageException($message, $e->getCode(), $e); } } diff --git a/core/dispatch.php b/core/dispatch.php index 133f26f355..d266c0cf87 100644 --- a/core/dispatch.php +++ b/core/dispatch.php @@ -30,12 +30,25 @@ if (!defined('PIWIK_ENABLE_DISPATCH')) { if (PIWIK_ENABLE_DISPATCH) { $controller = FrontController::getInstance(); - $controller->init(); - $response = $controller->dispatch(); - if (is_array($response)) { - var_export($response); - } elseif (!is_null($response)) { - echo $response; + try { + $controller->init(); + $response = $controller->dispatch(); + + if (is_array($response)) { + var_export($response); + } elseif (!is_null($response)) { + echo $response; + } + } catch (Exception $ex) { + $debugTrace = $ex->getTraceAsString(); + + if (method_exists($ex, 'getHtmlMessage')) { + $message = $ex->getHtmlMessage(); + } else { + $message = Piwik\Common::sanitizeInputValue($ex->getMessage()); + } + + Piwik_ExitWithMessage($message, $debugTrace, true, true); } -} +}
\ No newline at end of file diff --git a/plugins/CorePluginsAdmin/Controller.php b/plugins/CorePluginsAdmin/Controller.php index 543d42338b..245a24ce11 100644 --- a/plugins/CorePluginsAdmin/Controller.php +++ b/plugins/CorePluginsAdmin/Controller.php @@ -11,6 +11,7 @@ namespace Piwik\Plugins\CorePluginsAdmin; use Exception; use Piwik\API\Request; use Piwik\Common; +use Piwik\Exceptions\HtmlMessageException; use Piwik\Filechecks; use Piwik\Filesystem; use Piwik\Nonce; @@ -361,8 +362,8 @@ class Controller extends Plugin\ControllerAdmin return $message; } - if (Common::isPhpCliMode()) { - Piwik_ExitWithMessage("Error:" . var_export($lastError, true)); + if (Common::isPhpCliMode()) { // TODO: I can't find how this will ever get called / safeMode is never set for Console + throw new Exception("Error: " . var_export($lastError, true)); } $view = new View('@CorePluginsAdmin/safemode'); @@ -445,7 +446,8 @@ class Controller extends Plugin\ControllerAdmin $pluginName); $exitMessage = $messageIntro . "<br/><br/>" . $messagePermissions; $exitMessage .= "<br> Or manually delete this directory (using FTP or SSH access)"; - Piwik_ExitWithMessage($exitMessage, $optionalTrace = false, $optionalLinks = false, $optionalLinkBack = true); + + throw new HtmlMessageException($exitMessage); } $this->redirectAfterModification($redirectAfter); diff --git a/plugins/Installation/Installation.php b/plugins/Installation/Installation.php index 63fd3149dd..8bd1a00fab 100644 --- a/plugins/Installation/Installation.php +++ b/plugins/Installation/Installation.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\Installation; use Piwik\Common; use Piwik\Config; +use Piwik\Exceptions\HtmlMessageException; use Piwik\FrontController; use Piwik\Piwik; use Piwik\Translate; @@ -42,7 +43,7 @@ class Installation extends \Piwik\Plugin $view = new PiwikView("@Installation/cannotConnectToDb"); $view->exceptionMessage = $exception->getMessage(); - Piwik_ExitWithMessage($view->render()); + throw new HtmlMessageException($view->render()); } public function dispatchIfNotInstalledYet(&$module, &$action, &$parameters) |