Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorsgiehl <stefan@piwik.org>2014-11-15 23:09:57 +0300
committersgiehl <stefan@piwik.org>2014-11-15 23:09:57 +0300
commitdff3519bc9152076062b1cd046594103756a5d42 (patch)
tree2cb1f8397b5311a26ecfa2261d2cce8a2174464a /core
parenta45c6b956f1828a1a9a209a7bd72a6816e907de7 (diff)
parentd78c73e305aa1bd8c2f0e01a0b9f17292f6b0c88 (diff)
Merge branch 'master' into deprecate_usersettings
Diffstat (limited to 'core')
-rw-r--r--core/Common.php92
-rw-r--r--core/DataArray.php5
-rw-r--r--core/Exception/AuthenticationFailedException.php13
-rw-r--r--core/Exception/Exception.php (renamed from core/Exceptions/HtmlMessageException.php)24
-rw-r--r--core/Exception/MissingFilePermissionException.php13
-rw-r--r--core/Exception/NoPrivilegesException.php13
-rw-r--r--core/Exception/NoWebsiteFoundException.php13
-rw-r--r--core/Filechecks.php9
-rw-r--r--core/FrontController.php23
-rw-r--r--core/Plugin/Controller.php15
-rw-r--r--core/Plugin/MetadataLoader.php2
-rw-r--r--core/Session.php7
-rw-r--r--core/Tracker.php29
-rw-r--r--core/Translate.php2
-rwxr-xr-xcore/Twig.php3
-rw-r--r--core/Updates/1.8.3-b1.php4
-rw-r--r--core/Version.php2
17 files changed, 204 insertions, 65 deletions
diff --git a/core/Common.php b/core/Common.php
index 6dfa2d22fa..a3e7515a24 100644
--- a/core/Common.php
+++ b/core/Common.php
@@ -34,6 +34,7 @@ class Common
/*
* Database
*/
+ const LANGUAGE_CODE_INVALID = 'xx';
/**
* Hashes a string into an integer which should be very low collision risks
@@ -461,7 +462,7 @@ class Common
// we deal w/ json differently
if ($varType == 'json') {
$value = self::undoMagicQuotes($requestArrayToUse[$varName]);
- $value = self::json_decode($value, $assoc = true);
+ $value = json_decode($value, $assoc = true);
return self::sanitizeInputValues($value, $alreadyStripslashed = true);
}
@@ -937,8 +938,8 @@ class Common
*/
public static function getCountry($lang, $enableLanguageToCountryGuess, $ip)
{
- if (empty($lang) || strlen($lang) < 2 || $lang == 'xx') {
- return 'xx';
+ if (empty($lang) || strlen($lang) < 2 || $lang == self::LANGUAGE_CODE_INVALID) {
+ return self::LANGUAGE_CODE_INVALID;
}
$validCountries = self::getCountriesList();
@@ -974,35 +975,73 @@ class Common
}
}
}
- return 'xx';
+ return self::LANGUAGE_CODE_INVALID;
}
/**
- * Returns the visitor language based only on the Browser 'accepted language' information
+ * Returns the language and region string, based only on the Browser 'accepted language' information.
+ * * The language tag is defined by ISO 639-1
*
* @param string $browserLanguage Browser's accepted langauge header
* @param array $validLanguages array of valid language codes
- * @return string 2 letter ISO 639 code
+ * @return string 2 letter ISO 639 code 'es' (Spanish)
*/
- public static function extractLanguageCodeFromBrowserLanguage($browserLanguage, $validLanguages)
+ public static function extractLanguageCodeFromBrowserLanguage($browserLanguage, $validLanguages = array())
{
- // assumes language preference is sorted;
- // does not handle language-script-region tags or language range (*)
- if (!empty($validLanguages) && preg_match_all('/(?:^|,)([a-z]{2,3})([-][a-z]{2})?/', $browserLanguage, $matches, PREG_SET_ORDER)) {
- foreach ($matches as $parts) {
- if (count($parts) == 3) {
- // match locale (language and location)
- if (in_array($parts[1] . $parts[2], $validLanguages)) {
- return $parts[1] . $parts[2];
- }
+ $validLanguages = self::checkValidLanguagesIsSet($validLanguages);
+ $languageRegionCode = self::extractLanguageAndRegionCodeFromBrowserLanguage($browserLanguage, $validLanguages);
+
+ if(strlen($languageRegionCode) == 2) {
+ $languageCode = $languageRegionCode;
+ } else {
+ $languageCode = substr($languageRegionCode, 0, 2);
+ }
+ if(in_array($languageCode, $validLanguages)) {
+ return $languageCode;
+ }
+ return self::LANGUAGE_CODE_INVALID;
+ }
+
+ /**
+ * Returns the language and region string, based only on the Browser 'accepted language' information.
+ * * The language tag is defined by ISO 639-1
+ * * The region tag is defined by ISO 3166-1
+ *
+ * @param string $browserLanguage Browser's accepted langauge header
+ * @param array $validLanguages array of valid language codes. Note that if the array includes "fr" then it will consider all regional variants of this language valid, such as "fr-ca" etc.
+ * @return string 2 letter ISO 639 code 'es' (Spanish) or if found, includes the region as well: 'es-ar'
+ */
+ public static function extractLanguageAndRegionCodeFromBrowserLanguage($browserLanguage, $validLanguages = array() )
+ {
+ $validLanguages = self::checkValidLanguagesIsSet($validLanguages);
+
+ if(!preg_match_all('/(?:^|,)([a-z]{2,3})([-][a-z]{2})?/', $browserLanguage, $matches, PREG_SET_ORDER)) {
+ return self::LANGUAGE_CODE_INVALID;
+ }
+ foreach ($matches as $parts) {
+ $langIso639 = $parts[1];
+ if(empty($langIso639)) {
+ continue;
+ }
+
+ // If a region tag is found eg. "fr-ca"
+ if (count($parts) == 3) {
+ $regionIso3166 = $parts[2]; // eg. "-ca"
+
+ if (in_array($langIso639 . $regionIso3166, $validLanguages)) {
+ return $langIso639 . $regionIso3166;
}
- // match language only (where no region provided)
- if (in_array($parts[1], $validLanguages)) {
- return $parts[1];
+
+ if (in_array($langIso639, $validLanguages)) {
+ return $langIso639 . $regionIso3166;
}
}
+ // eg. "fr" or "es"
+ if (in_array($langIso639, $validLanguages)) {
+ return $langIso639;
+ }
}
- return 'xx';
+ return self::LANGUAGE_CODE_INVALID;
}
/**
@@ -1161,4 +1200,17 @@ class Common
}
}
}
+
+ /**
+ * @param $validLanguages
+ * @return array
+ */
+ protected static function checkValidLanguagesIsSet($validLanguages)
+ {
+ if (empty($validLanguages)) {
+ $validLanguages = array_keys(Common::getLanguagesList());
+ return $validLanguages;
+ }
+ return $validLanguages;
+ }
}
diff --git a/core/DataArray.php b/core/DataArray.php
index 7515ef8699..2eab0bbab5 100644
--- a/core/DataArray.php
+++ b/core/DataArray.php
@@ -99,6 +99,11 @@ class DataArray
return;
}
+ // Edge case fail safe
+ if(!isset($oldRowToUpdate[Metrics::INDEX_NB_VISITS])) {
+ return;
+ }
+
$oldRowToUpdate[Metrics::INDEX_NB_VISITS] += $newRowToAdd[Metrics::INDEX_NB_VISITS];
$oldRowToUpdate[Metrics::INDEX_NB_ACTIONS] += $newRowToAdd[Metrics::INDEX_NB_ACTIONS];
$oldRowToUpdate[Metrics::INDEX_NB_UNIQ_VISITORS] += $newRowToAdd[Metrics::INDEX_NB_UNIQ_VISITORS];
diff --git a/core/Exception/AuthenticationFailedException.php b/core/Exception/AuthenticationFailedException.php
new file mode 100644
index 0000000000..ca3efc25c1
--- /dev/null
+++ b/core/Exception/AuthenticationFailedException.php
@@ -0,0 +1,13 @@
+<?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\Exception;
+
+class AuthenticationFailedException extends Exception
+{
+} \ No newline at end of file
diff --git a/core/Exceptions/HtmlMessageException.php b/core/Exception/Exception.php
index 243a0f1726..106034bf5a 100644
--- a/core/Exceptions/HtmlMessageException.php
+++ b/core/Exception/Exception.php
@@ -6,25 +6,25 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
-namespace Piwik\Exceptions;
+namespace Piwik\Exception;
-use Exception;
+use Exception as PhpException;
/**
* An exception whose message has HTML content. When these exceptions are caught
* the message will not be sanitized before being displayed to the user.
- *
- * @api
*/
-class HtmlMessageException extends Exception
+abstract class Exception extends PhpException
{
- /**
- * Returns the exception message.
- *
- * @return string
- */
- public function getHtmlMessage()
+ private $isHtmlMessage = false;
+
+ public function setIsHtmlMessage()
+ {
+ $this->isHtmlMessage = true;
+ }
+
+ public function isHtmlMessage()
{
- return $this->getMessage();
+ return $this->isHtmlMessage;
}
} \ No newline at end of file
diff --git a/core/Exception/MissingFilePermissionException.php b/core/Exception/MissingFilePermissionException.php
new file mode 100644
index 0000000000..268725c70b
--- /dev/null
+++ b/core/Exception/MissingFilePermissionException.php
@@ -0,0 +1,13 @@
+<?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\Exception;
+
+class MissingFilePermissionException extends Exception
+{
+} \ No newline at end of file
diff --git a/core/Exception/NoPrivilegesException.php b/core/Exception/NoPrivilegesException.php
new file mode 100644
index 0000000000..3ee8c9ce2b
--- /dev/null
+++ b/core/Exception/NoPrivilegesException.php
@@ -0,0 +1,13 @@
+<?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\Exception;
+
+class NoPrivilegesException extends Exception
+{
+} \ No newline at end of file
diff --git a/core/Exception/NoWebsiteFoundException.php b/core/Exception/NoWebsiteFoundException.php
new file mode 100644
index 0000000000..eb97cad37a
--- /dev/null
+++ b/core/Exception/NoWebsiteFoundException.php
@@ -0,0 +1,13 @@
+<?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\Exception;
+
+class NoWebsiteFoundException extends Exception
+{
+} \ No newline at end of file
diff --git a/core/Filechecks.php b/core/Filechecks.php
index eab93fd260..0c37680fc4 100644
--- a/core/Filechecks.php
+++ b/core/Filechecks.php
@@ -8,7 +8,7 @@
*/
namespace Piwik;
-use Piwik\Exceptions\HtmlMessageException;
+use Piwik\Exception\MissingFilePermissionException;
class Filechecks
{
@@ -96,7 +96,7 @@ class Filechecks
}
}
- $directoryMessage = "<p><b>Piwik couldn't write to some directories $optionalUserInfo</b>.</p>";
+ $directoryMessage = "<p><b>Piwik couldn't write to some directories $optionalUserInfo</b>.</p>";
$directoryMessage .= "<p>Try to Execute the following commands on your server, to allow Write access on these directories"
. ":</p>"
. "<blockquote>$directoryList</blockquote>"
@@ -104,7 +104,10 @@ 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>";
- throw new HtmlMessageException($directoryMessage);
+ $ex = new MissingFilePermissionException($directoryMessage);
+ $ex->setIsHtmlMessage();
+
+ throw $ex;
}
/**
diff --git a/core/FrontController.php b/core/FrontController.php
index 16d5930fe2..25e56cc4f9 100644
--- a/core/FrontController.php
+++ b/core/FrontController.php
@@ -12,7 +12,7 @@ namespace Piwik;
use Exception;
use Piwik\API\Request;
use Piwik\API\ResponseBuilder;
-use Piwik\Exceptions\HtmlMessageException;
+use Piwik\Exception\AuthenticationFailedException;
use Piwik\Http\Router;
use Piwik\Plugin\Controller;
use Piwik\Plugin\Report;
@@ -420,10 +420,15 @@ class FrontController extends Singleton
try {
$authAdapter = Registry::get('auth');
} catch (Exception $e) {
- throw new HtmlMessageException("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");
+ $message = "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";
+
+ $ex = new AuthenticationFailedException($message);
+ $ex->setIsHtmlMessage();
+
+ throw $ex;
}
Access::getInstance()->reloadAccess($authAdapter);
@@ -614,10 +619,10 @@ class FrontController extends Singleton
{
$debugTrace = $ex->getTraceAsString();
- if (method_exists($ex, 'getHtmlMessage')) {
- $message = $ex->getHtmlMessage();
- } else {
- $message = Common::sanitizeInputValue($ex->getMessage());
+ $message = $ex->getMessage();
+
+ if (!method_exists($ex, 'isHtmlMessage') || !$ex->isHtmlMessage()) {
+ $message = Common::sanitizeInputValue($message);
}
$logo = new CustomLogo();
diff --git a/core/Plugin/Controller.php b/core/Plugin/Controller.php
index 9985c100d5..4afcbf25ad 100644
--- a/core/Plugin/Controller.php
+++ b/core/Plugin/Controller.php
@@ -17,7 +17,8 @@ use Piwik\Config as PiwikConfig;
use Piwik\Config;
use Piwik\DataTable\Filter\CalculateEvolutionFilter;
use Piwik\Date;
-use Piwik\Exceptions\HtmlMessageException;
+use Piwik\Exception\NoPrivilegesException;
+use Piwik\Exception\NoWebsiteFoundException;
use Piwik\FrontController;
use Piwik\Menu\MenuTop;
use Piwik\Menu\MenuUser;
@@ -841,16 +842,22 @@ abstract class Controller
$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);
+ $ex = new NoWebsiteFoundException($message);
+ $ex->setIsHtmlMessage();
+
+ throw $ex;
}
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 = sprintf(Piwik::translate('CoreHome_NoPrivilegesAskPiwikAdmin'), $currentLogin, "<br/><a href='mailto:" . $emails . "?subject=Access to Piwik for user $currentLogin'>", "</a>");
$errorMessage .= "<br /><br />&nbsp;&nbsp;&nbsp;<b><a href='index.php?module=" . Registry::get('auth')->getName() . "&amp;action=logout'>&rsaquo; " . Piwik::translate('General_Logout') . "</a></b><br />";
- throw new HtmlMessageException($errorMessage);
+ $ex = new NoPrivilegesException($errorMessage);
+ $ex->setIsHtmlMessage();
+
+ throw $ex;
}
echo FrontController::getInstance()->dispatch(Piwik::getLoginPluginName(), false);
diff --git a/core/Plugin/MetadataLoader.php b/core/Plugin/MetadataLoader.php
index 34bb90dcdc..e75bc58338 100644
--- a/core/Plugin/MetadataLoader.php
+++ b/core/Plugin/MetadataLoader.php
@@ -95,7 +95,7 @@ class MetadataLoader
return array();
}
- $info = Common::json_decode($json, $assoc = true);
+ $info = json_decode($json, $assoc = true);
if (!is_array($info)
|| empty($info)
) {
diff --git a/core/Session.php b/core/Session.php
index d8fa47b4d2..f67b2e4caf 100644
--- a/core/Session.php
+++ b/core/Session.php
@@ -9,7 +9,7 @@
namespace Piwik;
use Exception;
-use Piwik\Exceptions\HtmlMessageException;
+use Piwik\Exception\MissingFilePermissionException;
use Piwik\Session\SaveHandler\DbTable;
use Zend_Session;
@@ -132,7 +132,10 @@ class Session extends Zend_Session
$e->getMessage()
);
- throw new HtmlMessageException($message, $e->getCode(), $e);
+ $ex = new MissingFilePermissionException($message, $e->getCode(), $e);
+ $ex->setIsHtmlMessage();
+
+ throw $ex;
}
}
diff --git a/core/Tracker.php b/core/Tracker.php
index ed911e55f6..a84afd9632 100644
--- a/core/Tracker.php
+++ b/core/Tracker.php
@@ -436,7 +436,7 @@ class Tracker
$result['message'] = $this->getMessageFromException($e);
}
Common::sendHeader('Content-Type: application/json');
- echo Common::json_encode($result);
+ echo json_encode($result);
die(1);
exit;
}
@@ -454,7 +454,7 @@ class Tracker
Common::sendHeader('Content-Type: text/html; charset=utf-8');
echo $this->getMessageFromException($e);
} else {
- $this->outputTransparentGif();
+ $this->sendResponse();
}
die(1);
exit;
@@ -496,12 +496,12 @@ class Tracker
$this->outputAccessControlHeaders();
Common::sendHeader('Content-Type: application/json');
- echo Common::json_encode($result);
+ echo json_encode($result);
exit;
}
switch ($this->getState()) {
case self::STATE_LOGGING_DISABLE:
- $this->outputTransparentGif ();
+ $this->sendResponse();
Common::printDebug("Logging disabled, display transparent logo");
break;
@@ -513,7 +513,7 @@ class Tracker
case self::STATE_NOSCRIPT_REQUEST:
case self::STATE_NOTHING_TO_NOTICE:
default:
- $this->outputTransparentGif ();
+ $this->sendResponse();
Common::printDebug("Nothing to notice => default behaviour");
break;
}
@@ -648,7 +648,7 @@ class Tracker
return $visit;
}
- protected function outputTransparentGif ()
+ private function sendResponse()
{
if (isset($GLOBALS['PIWIK_TRACKER_DEBUG'])
&& $GLOBALS['PIWIK_TRACKER_DEBUG']
@@ -660,11 +660,24 @@ class Tracker
// If there was an error during tracker, return so errors can be flushed
return;
}
- $transGifBase64 = "R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
- Common::sendHeader('Content-Type: image/gif');
$this->outputAccessControlHeaders();
+ $request = $_GET + $_POST;
+
+ if (array_key_exists('send_image', $request) && $request['send_image'] === '0') {
+ Common::sendHeader("HTTP/1.1 204 No Response");
+ return;
+ }
+
+ $this->outputTransparentGif();
+ }
+
+ protected function outputTransparentGif ()
+ {
+ $transGifBase64 = "R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
+ Common::sendHeader('Content-Type: image/gif');
+
print(base64_decode($transGifBase64));
}
diff --git a/core/Translate.php b/core/Translate.php
index 65381c0a2d..c29d0f0339 100644
--- a/core/Translate.php
+++ b/core/Translate.php
@@ -173,7 +173,7 @@ class Translate
$clientSideTranslations[$key] = $translations[$plugin][$stringName];
}
- $js = 'var translations = ' . Common::json_encode($clientSideTranslations) . ';';
+ $js = 'var translations = ' . json_encode($clientSideTranslations) . ';';
$js .= "\n" . 'if (typeof(piwik_translations) == \'undefined\') { var piwik_translations = new Object; }' .
'for(var i in translations) { piwik_translations[i] = translations[i];} ';
return $js;
diff --git a/core/Twig.php b/core/Twig.php
index 2e0ef95844..b15efe088f 100755
--- a/core/Twig.php
+++ b/core/Twig.php
@@ -10,7 +10,6 @@ namespace Piwik;
use Exception;
use Piwik\DataTable\Filter\SafeDecodeLabel;
-use Piwik\Period\Range;
use Piwik\Translate;
use Piwik\View\RenderTokenParser;
use Piwik\Visualization\Sparkline;
@@ -245,7 +244,7 @@ class Twig
protected function addFilter_prettyDate()
{
$prettyDate = new Twig_SimpleFilter('prettyDate', function ($dateString, $period) {
- return Range::factory($period, $dateString)->getLocalizedShortString();
+ return Period\Factory::build($period, $dateString)->getLocalizedShortString();
});
$this->twig->addFilter($prettyDate);
}
diff --git a/core/Updates/1.8.3-b1.php b/core/Updates/1.8.3-b1.php
index 7a00ec20b3..ee8e6c4d00 100644
--- a/core/Updates/1.8.3-b1.php
+++ b/core/Updates/1.8.3-b1.php
@@ -98,8 +98,8 @@ class Updates_1_8_3_b1 extends Updates
is_null($period) ? ScheduledReports::DEFAULT_PERIOD : $period,
ScheduledReports::EMAIL_TYPE,
is_null($format) ? ScheduledReports::DEFAULT_REPORT_FORMAT : $format,
- Common::json_encode(preg_split('/,/', $reports)),
- Common::json_encode($parameters),
+ json_encode(preg_split('/,/', $reports)),
+ json_encode($parameters),
$ts_created,
$ts_last_sent,
$deleted
diff --git a/core/Version.php b/core/Version.php
index b4545cacac..fa7f0f29b7 100644
--- a/core/Version.php
+++ b/core/Version.php
@@ -20,5 +20,5 @@ final class Version
* The current Piwik version.
* @var string
*/
- const VERSION = '2.9.0-b9';
+ const VERSION = '2.9.0';
}