From c09983bb5079461517d86f18a2dbe1bc8b9bceb7 Mon Sep 17 00:00:00 2001
From: robocoder <anthon.pang@gmail.com>
Date: Sun, 22 May 2011 18:52:37 +0000
Subject: [PATCH] fixes #1279

git-svn-id: http://dev.piwik.org/svn/trunk@4765 59fd770c-687e-43c8-a1e3-f5a4ff64c105
---
 core/Db/Adapter/Pdo/Mysql.php    |  5 +++++
 core/FrontController.php         |  6 ++++++
 core/Session.php                 | 36 ++++++++++++++------------------
 core/testMinimumPhpVersion.php   | 13 +++++++++---
 index.php                        |  5 -----
 lang/en.php                      |  1 +
 plugins/Dashboard/Controller.php |  2 +-
 7 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/core/Db/Adapter/Pdo/Mysql.php b/core/Db/Adapter/Pdo/Mysql.php
index bab4dc7718..76b313c564 100644
--- a/core/Db/Adapter/Pdo/Mysql.php
+++ b/core/Db/Adapter/Pdo/Mysql.php
@@ -192,6 +192,11 @@ class Piwik_Db_Adapter_Pdo_Mysql extends Zend_Db_Adapter_Pdo_Mysql implements Pi
 	 */
 	public function query($sql, $bind = array())
 	{
+		if(!is_string($sql))
+		{
+			return parent::query($sql, $bind);
+		}
+
 		if(isset($this->cachePreparedStatement[$sql]))
 		{
 			if (!is_array($bind)) {
diff --git a/core/FrontController.php b/core/FrontController.php
index df7894050b..f59601c98d 100644
--- a/core/FrontController.php
+++ b/core/FrontController.php
@@ -259,8 +259,14 @@ class Piwik_FrontController
 			Piwik_Translate::getInstance()->reloadLanguage();
 
 			Piwik::raiseMemoryLimitIfNecessary();
+
 			$pluginsManager->postLoadPlugins();
 			
+			if(!defined('PIWIK_ENABLE_SESSION_START') || PIWIK_ENABLE_SESSION_START)
+			{
+				Piwik_Session::start();
+			}
+
 			Piwik_PostEvent('FrontController.checkForUpdates');
 		} catch(Exception $e) {
 			Piwik_ExitWithMessage($e->getMessage(), false, true);
diff --git a/core/Session.php b/core/Session.php
index 686a22d285..18b46f4cec 100644
--- a/core/Session.php
+++ b/core/Session.php
@@ -49,14 +49,22 @@ class Piwik_Session extends Zend_Session
 		@ini_set('session.referer_check', '');
 
 		// we consider these to be misconfigurations, in that
-		//  - user - Piwik doesn't implement user-defined session handler functions
-		// -  mm - is not recommended, not supported, not available for Windows, and has a potential concurrency issue
+		// - user  - we can't verify that user-defined session handler functions have been set via session_set_save_handler()
+		// - mm    - this handler is not recommended, unsupported, not available for Windows, and has a potential concurrency issue
+		// - files - this handler doesn't work well in load-balance environments and may have a concurrency issue with locked session files
 		$currentSaveHandler = ini_get('session.save_handler');
-		if($currentSaveHandler == 'user'
-			|| $currentSaveHandler == 'mm')
+		if(in_array($currentSaveHandler, array('user', 'mm', 'files')))
 		{
-			@ini_set('session.save_handler', 'files');
-			@ini_set('session.save_path', '');
+			$db = Zend_Registry::get('db');
+			$config = array(
+				'name' => Piwik_Common::prefixTable('session'),
+				'primary' => 'id',
+				'modifiedColumn' => 'modified',
+				'dataColumn' => 'data',
+				'lifetimeColumn' => 'lifetime',
+				'db' => Zend_Registry::get('db'),
+			);
+			self::setSaveHandler( new Zend_Session_SaveHandler_DbTable($config));
 		}
 
 		// garbage collection may disabled by default (e.g., Debian)
@@ -65,23 +73,11 @@ class Piwik_Session extends Zend_Session
 			@ini_set('session.gc_probability', 1);
 		}
 
-		// for "files", use our own folder to prevent local session file hijacking
-		if(ini_get('session.save_handler') == 'files')
-		{
-			$sessionPath = PIWIK_USER_PATH . '/tmp/sessions';
-			@ini_set('session.save_path', $sessionPath);
-
-			if(!is_dir($sessionPath))
-			{
-				Piwik_Common::mkdir($sessionPath);
-			}
-		}
-
 		try {
 			Zend_Session::start();
 		} catch(Exception $e) {
-			// This message is not translateable because translations haven't been loaded yet.
-			Piwik_ExitWithMessage('Unable to start session.  Check that session.save_path or tmp/sessions is writeable, and session.auto_start = 0.');
+			Piwik::log('Unable to start session: ' . $e->getMessage());
+			Piwik_ExitWithMessage(Piwik_Translate('General_ExceptionUnableToStartSession'));
 		}
 	}
 }
diff --git a/core/testMinimumPhpVersion.php b/core/testMinimumPhpVersion.php
index 068a75a238..2f55d8dd4d 100644
--- a/core/testMinimumPhpVersion.php
+++ b/core/testMinimumPhpVersion.php
@@ -43,16 +43,23 @@ else
 	if(!class_exists('ArrayObject'))
 	{
 		$piwik_errorMessage .= "<p><b>Piwik and Zend Framework require the SPL extension</b></p> 
-					<p>It appears your PHP was compiled with --disable-spl.
+					<p>It appears your PHP was compiled with <pre>--disable-spl</pre>.
 					To enjoy Piwik, you need PHP compiled without that configure option.</p>";
 	}
 
-	if(!function_exists('session_cache_limiter'))
+	if(!extension_loaded('session'))
 	{
 		$piwik_errorMessage .= "<p><b>Piwik and Zend_Session require the session extension</b></p> 
-					<p>It appears your PHP was compiled with --disable-session.
+					<p>It appears your PHP was compiled with <pre>--disable-session</pre>.
 					To enjoy Piwik, you need PHP compiled without that configure option.</p>";
 	}
+
+	if(!function_exists('ini_set'))
+	{
+		$piwik_errorMessage .= "<p><b>Piwik and Zend_Session require the <code>ini_set()</code> function</b></p> 
+					<p>It appears your PHP has disabled this function.
+					To enjoy Piwik, you need remove <pre>ini_set</pre> from your <pre>disable_functions</pre> directive in php.ini.</p>";
+	}
 }
 
 /**
diff --git a/index.php b/index.php
index 454ba1c910..691d1631ac 100644
--- a/index.php
+++ b/index.php
@@ -38,11 +38,6 @@ session_cache_limiter('nocache');
 @date_default_timezone_set('UTC');
 require_once PIWIK_INCLUDE_PATH .'/core/Loader.php';
 
-if(!defined('PIWIK_ENABLE_SESSION_START') || PIWIK_ENABLE_SESSION_START)
-{
-	Piwik_Session::start();
-}
-
 if(!defined('PIWIK_ENABLE_ERROR_HANDLER') || PIWIK_ENABLE_ERROR_HANDLER)
 {
 	require_once PIWIK_INCLUDE_PATH .'/core/ErrorHandler.php';
diff --git a/lang/en.php b/lang/en.php
index 840e2a9457..463ce5f1d7 100644
--- a/lang/en.php
+++ b/lang/en.php
@@ -239,6 +239,7 @@ $translations = array(
 	'General_ExceptionInvalidToken' => 'Token is not valid.',
 	'General_ExceptionInvalidDateFormat' => 'Date format must be: %s or any keyword supported by the %s function (see %s for more information)',
 	'General_ExceptionLanguageFileNotFound' => 'Language file \'%s\' not found.',
+	'General_ExceptionUnableToStartSession' => 'Unable to start session.',
 	'General_WarningFileIntegritySkipped' => 'Development environment detected. File integrity check skipped.',
 	'General_WarningFileIntegrityNoManifest' => 'File integrity check could not be performed due to missing manifest.inc.php.',
 	'General_WarningFileIntegrityNoMd5file' => 'File integrity check could not be completed due to missing md5_file() function.',
diff --git a/plugins/Dashboard/Controller.php b/plugins/Dashboard/Controller.php
index 8a247b6fe1..230e279b1f 100644
--- a/plugins/Dashboard/Controller.php
+++ b/plugins/Dashboard/Controller.php
@@ -96,7 +96,7 @@ class Piwik_Dashboard_Controller extends Piwik_Controller
 		{
 			$session = new Piwik_Session_Namespace("Piwik_Dashboard");
 			$session->dashboardLayout = $layout;
-			$session->setExpirationSeconds(7*86400);
+			$session->setExpirationSeconds(1800);
 		}
 		else
 		{
-- 
GitLab