diff --git a/core/Plugin/ControllerAdmin.php b/core/Plugin/ControllerAdmin.php index e503a615e65c3205e33cb0d8666fcd4a49e00dff..f24246944f62418a378044f89cbcefcbed378306 100644 --- a/core/Plugin/ControllerAdmin.php +++ b/core/Plugin/ControllerAdmin.php @@ -153,6 +153,42 @@ abstract class ControllerAdmin extends Controller Notification\Manager::notify('ControllerAdmin_EacceleratorIsUsed', $notification); } + /** + * PHP Version required by the next major Piwik version + * @return string + */ + private static function getNextRequiredMinimumPHP() + { + return '5.5.9'; + } + + private static function isUsingPhpVersionCompatibleWithNextPiwik() + { + return version_compare( PHP_VERSION, self::getNextRequiredMinimumPHP(), '>=' ); + } + + private static function notifyWhenPhpVersionIsNotCompatibleWithNextMajorPiwik() + { + if(self::isUsingPhpVersionCompatibleWithNextPiwik()) { + return; + } + + $youMustUpgradePHP = Piwik::translate('General_YouMustUpgradePhpVersionToReceiveLatestPiwik'); + $message = Piwik::translate('General_PiwikCannotBeUpgradedBecausePhpIsTooOld') + . ' ' + . sprintf(Piwik::translate('General_PleaseUpgradeYourPhpVersionSoYourPiwikDataStaysSecure'), self::getNextRequiredMinimumPHP()) + ; + + $notification = new Notification($message); + $notification->title = $youMustUpgradePHP; + $notification->priority = Notification::PRIORITY_LOW; + $notification->context = Notification::CONTEXT_WARNING; + $notification->type = Notification::TYPE_TRANSIENT; + $notification->flags = Notification::FLAG_NO_CLEAR; + NotificationManager::notify('PHPVersionTooOldForNewestPiwikCheck', $notification); + } + + private static function notifyWhenPhpVersionIsEOL() { $deprecatedMajorPhpVersion = null; @@ -167,9 +203,7 @@ abstract class ControllerAdmin extends Controller return; } - $nextRequiredMinimumPHP = '5.5'; - - $message = Piwik::translate('General_WarningPiwikWillStopSupportingPHPVersion', array($deprecatedMajorPhpVersion, $nextRequiredMinimumPHP)) + $message = Piwik::translate('General_WarningPiwikWillStopSupportingPHPVersion', array($deprecatedMajorPhpVersion, self::getNextRequiredMinimumPHP())) . "\n " . Piwik::translate('General_WarningPhpVersionXIsTooOld', $deprecatedMajorPhpVersion); @@ -243,10 +277,8 @@ abstract class ControllerAdmin extends Controller $view->isSuperUser = Piwik::hasUserSuperUserAccess(); self::notifyAnyInvalidPlugin(); - - self::checkPhpVersion($view); - self::notifyWhenPhpVersionIsEOL(); + self::notifyWhenPhpVersionIsNotCompatibleWithNextMajorPiwik(); self::notifyWhenDebugOnDemandIsEnabled('debug'); self::notifyWhenDebugOnDemandIsEnabled('debug_on_demand'); @@ -271,16 +303,6 @@ abstract class ControllerAdmin extends Controller return "Piwik " . Version::VERSION; } - /** - * Check if the current PHP version is >= 5.3. If not, a warning is displayed - * to the user. - */ - private static function checkPhpVersion($view) - { - $view->phpVersion = PHP_VERSION; - $view->phpIsNewEnough = version_compare($view->phpVersion, '5.3.0', '>='); - } - private static function isPhpVersion53() { return strpos(PHP_VERSION, '5.3') === 0; diff --git a/core/Tracker/TrackerCodeGenerator.php b/core/Tracker/TrackerCodeGenerator.php index ae1ef6d2e811c09f5919660da039df6ad0d3c23e..ffeea91b6a85ce2ff021333d102f04d445562c92 100644 --- a/core/Tracker/TrackerCodeGenerator.php +++ b/core/Tracker/TrackerCodeGenerator.php @@ -12,6 +12,7 @@ use Piwik\Common; use Piwik\Piwik; use Piwik\Plugins\CustomVariables\CustomVariables; use Piwik\Plugins\SitesManager\API as APISitesManager; +use Piwik\View; /** * Generates the Javascript code to be inserted on every page of the website to track. @@ -46,8 +47,7 @@ class TrackerCodeGenerator $disableCookies = false ) { // changes made to this code should be mirrored in plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js var generateJsCode - $jsCode = file_get_contents(PIWIK_INCLUDE_PATH . "/plugins/Morpheus/templates/javascriptCode.tpl"); - $jsCode = htmlentities($jsCode); + if (substr($piwikUrl, 0, 4) !== 'http') { $piwikUrl = 'http://' . $piwikUrl; } @@ -150,12 +150,6 @@ class TrackerCodeGenerator */ Piwik::postEvent('Piwik.getJavascriptCode', array(&$codeImpl, $parameters)); - if (!empty($codeImpl['loadAsync'])) { - $codeImpl['loadAsync'] = 'true'; - } else { - $codeImpl['loadAsync'] = 'false'; - } - $setTrackerUrl = 'var u="' . $codeImpl['protocol'] . '{$piwikUrl}/";'; if (!empty($codeImpl['httpsPiwikUrl'])) { @@ -164,6 +158,12 @@ class TrackerCodeGenerator } $codeImpl = array('setTrackerUrl' => htmlentities($setTrackerUrl)) + $codeImpl; + $view = new View('@Morpheus/javascriptCode'); + $view->disableCacheBuster(); + $view->loadAsync = $codeImpl['loadAsync']; + $jsCode = $view->render(); + $jsCode = htmlentities($jsCode); + foreach ($codeImpl as $keyToReplace => $replaceWith) { $jsCode = str_replace('{$' . $keyToReplace . '}', $replaceWith, $jsCode); } diff --git a/core/Updates/2.16.3-b3.php b/core/Updates/2.16.3-b3.php index a1175c9f4dcd0da04e69c01058cdc3cbeed2c980..4d28615f6f32af39e367589ad6bee56afb3a39c6 100644 --- a/core/Updates/2.16.3-b3.php +++ b/core/Updates/2.16.3-b3.php @@ -34,7 +34,11 @@ class Updates_2_16_3_b3 extends PiwikUpdates protected function adjustTimezoneBySite($hour, $idSite) { $timezone = Site::getTimezoneFor($idSite); - $dateTimeZone = new \DateTimeZone($timezone); + try { + $dateTimeZone = new \DateTimeZone($timezone); + } catch(\Exception $e) { + return; + } $timeZoneDifference = -ceil($dateTimeZone->getOffset(new \DateTime()) / 3600); return (24 + $hour + $timeZoneDifference) % 24; } diff --git a/core/Updates/2.16.3-rc2.php b/core/Updates/2.16.3-rc2.php new file mode 100644 index 0000000000000000000000000000000000000000..d2a394194ee4203818b5be6c7b28de9533757ec6 --- /dev/null +++ b/core/Updates/2.16.3-rc2.php @@ -0,0 +1,28 @@ +<?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\Updates; + +use Piwik\Plugins\ScheduledReports\API as ScheduledReportsAPI; +use Piwik\Plugins\ScheduledReports\Model as ScheduledReportsModel; +use Piwik\Site; +use Piwik\Updater; +use Piwik\Updates as PiwikUpdates; + +/** + * Mark the upgrade as major as the field visit_entry_idaction_url was updated in https://github.com/piwik/piwik/pull/10510 + */ +class Updates_2_16_3_rc2 extends PiwikUpdates +{ + + public static function isMajorUpdate() + { + return true; + } + +} diff --git a/core/Version.php b/core/Version.php index 9206f9e905c8d8ecf611b415842b15e718b0be57..15079e8aa718ec48d5a96bdc9d5aeb604a69054d 100644 --- a/core/Version.php +++ b/core/Version.php @@ -20,7 +20,7 @@ final class Version * The current Piwik version. * @var string */ - const VERSION = '2.16.3-rc1'; + const VERSION = '2.16.3-rc2'; public function isStableVersion($version) { diff --git a/core/View.php b/core/View.php index 0a2cbabb67a9bea507b7ca6a6dc33068227f0ef9..0c9b379a6741d8b0df095ddef48d9a25794057df 100644 --- a/core/View.php +++ b/core/View.php @@ -116,6 +116,7 @@ class View implements ViewInterface protected $templateVars = array(); private $contentType = 'text/html; charset=utf-8'; private $xFrameOptions = null; + private $enableCacheBuster = true; /** * Constructor. @@ -145,6 +146,14 @@ class View implements ViewInterface } } + /** + * Disables the cache buster (adding of ?cb=...) to JavaScript and stylesheet files + */ + public function disableCacheBuster() + { + $this->enableCacheBuster = false; + } + /** * Returns the template filename. * @@ -237,9 +246,8 @@ class View implements ViewInterface } else { $cacheBuster = UIAssetCacheBuster::getInstance()->piwikVersionBasedCacheBuster(); } - $this->cacheBuster = $cacheBuster; - + $this->loginModule = Piwik::getLoginPluginName(); $user = APIUsersManager::getInstance()->getUser($this->userLogin); @@ -260,6 +268,16 @@ class View implements ViewInterface return $this->renderTwigTemplate(); } + /** + * @internal + * @ignore + * @return Twig_Environment + */ + public function getTwig() + { + return $this->twig; + } + protected function renderTwigTemplate() { try { @@ -272,7 +290,9 @@ class View implements ViewInterface throw $ex; } - $output = $this->applyFilter_cacheBuster($output); + if ($this->enableCacheBuster) { + $output = $this->applyFilter_cacheBuster($output); + } $helper = new Theme; $output = $helper->rewriteAssetsPathToTheme($output); diff --git a/lang/en.json b/lang/en.json index a9856cc42541ffa83691da5fda6127970326bc7a..bbe45c2a774295770aa2db1ae2f5ef88ebfc5112 100644 --- a/lang/en.json +++ b/lang/en.json @@ -395,6 +395,9 @@ "Warning": "Warning", "WarningPhpVersionXIsTooOld": "The PHP version %s you are using has reached its End of Life (EOL). You are strongly urged to upgrade to a current version, as using this version may expose you to security vulnerabilities and bugs that have been fixed in more recent versions of PHP.", "WarningPiwikWillStopSupportingPHPVersion": "Piwik will stop supporting PHP %1$s in the next major version. Upgrade your PHP to at least PHP %2$s, before it's too late!", + "YouMustUpgradePhpVersionToReceiveLatestPiwik": "You must upgrade your PHP version in order to receive the latest Piwik update.", + "PiwikCannotBeUpgradedBecausePhpIsTooOld": "Piwik cannot be upgraded to the latest major version because your PHP version is too old.", + "PleaseUpgradeYourPhpVersionSoYourPiwikDataStaysSecure": "Please upgrade your PHP version to at least PHP %s so your Piwik analytics data stays secure.", "WarningFileIntegrityNoManifest": "File integrity check could not be performed due to missing manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "If you are deploying Piwik from Git, this message is normal.", "WarningFileIntegrityNoMd5file": "File integrity check could not be completed due to missing md5_file() function.", diff --git a/plugins/CoreUpdater/Commands/Update.php b/plugins/CoreUpdater/Commands/Update.php index 14865b6c333825be7e6eb33171761605c9b87c43..4340f34e3ef8169ae400a2ed718a4c68d288796a 100644 --- a/plugins/CoreUpdater/Commands/Update.php +++ b/plugins/CoreUpdater/Commands/Update.php @@ -163,6 +163,14 @@ class Update extends ConsoleCommand return; } + + if ($updater->hasMajorDbUpdate()) { + $output->writeln(array( + "", + sprintf("<comment>%s \n</comment>", Piwik::translate('CoreUpdater_MajorUpdateWarning1')) + )); + } + $output->writeln(array(" *** Note: this is a Dry Run ***", "")); foreach ($migrationQueries as $query) { diff --git a/plugins/Dashboard/Dashboard.php b/plugins/Dashboard/Dashboard.php index c25122bcea054876d7a5df890f4bf4644e265400..2eaeea105fe828714dce205c0df44b33d6d6b116 100644 --- a/plugins/Dashboard/Dashboard.php +++ b/plugins/Dashboard/Dashboard.php @@ -62,37 +62,32 @@ class Dashboard extends \Piwik\Plugin $defaultLayout = $this->getLayoutForUser('', 1); if (empty($defaultLayout)) { - $topWidget = ''; + $advertisingWidget = ''; $advertising = StaticContainer::get('Piwik\ProfessionalServices\Advertising'); if ($advertising->areAdsForProfessionalServicesEnabled() && Plugin\Manager::getInstance()->isPluginActivated('ProfessionalServices')) { - $topWidget .= '{"uniqueId":"widgetProfessionalServicespromoServices",' - . '"parameters":{"module":"ProfessionalServices","action":"promoServices"}},'; + $advertisingWidget = '{"uniqueId":"widgetProfessionalServicespromoServices","parameters":{"module":"ProfessionalServices","action":"promoServices"}},'; } if (Piwik::hasUserSuperUserAccess()) { - $topWidget .= '{"uniqueId":"widgetCoreHomegetDonateForm",' - . '"parameters":{"module":"CoreHome","action":"getDonateForm"}},'; + $piwikPromoWidget = '{"uniqueId":"widgetCoreHomegetDonateForm","parameters":{"module":"CoreHome","action":"getDonateForm"}}'; } else { - $topWidget .= '{"uniqueId":"widgetCoreHomegetPromoVideo",' - . '"parameters":{"module":"CoreHome","action":"getPromoVideo"}},'; + $piwikPromoWidget = '{"uniqueId":"widgetCoreHomegetPromoVideo","parameters":{"module":"CoreHome","action":"getPromoVideo"}}'; } $defaultLayout = '[ [ - {"uniqueId":"widgetVisitsSummarygetEvolutionGraphcolumnsArray","parameters":{"module":"VisitsSummary","action":"getEvolutionGraph","columns":"nb_visits"}}, {"uniqueId":"widgetLivewidget","parameters":{"module":"Live","action":"widget"}}, - {"uniqueId":"widgetVisitorInterestgetNumberOfVisitsPerVisitDuration","parameters":{"module":"VisitorInterest","action":"getNumberOfVisitsPerVisitDuration"}} + ' . $piwikPromoWidget . ' ], [ - ' . $topWidget . ' - {"uniqueId":"widgetReferrersgetWebsites","parameters":{"module":"Referrers","action":"getWebsites"}}, - {"uniqueId":"widgetVisitTimegetVisitInformationPerServerTime","parameters":{"module":"VisitTime","action":"getVisitInformationPerServerTime"}} + {"uniqueId":"widgetVisitsSummarygetEvolutionGraphcolumnsArray","parameters":{"module":"VisitsSummary","action":"getEvolutionGraph","columns":"nb_visits"}}, + ' . $advertisingWidget . ' + {"uniqueId":"widgetVisitsSummarygetSparklines","parameters":{"module":"VisitsSummary","action":"getSparklines"}} ], [ {"uniqueId":"widgetUserCountryMapvisitorMap","parameters":{"module":"UserCountryMap","action":"visitorMap"}}, - {"uniqueId":"widgetDevicesDetectiongetBrowsers","parameters":{"module":"DevicesDetection","action":"getBrowsers"}}, - {"uniqueId":"widgetReferrersgetSearchEngines","parameters":{"module":"Referrers","action":"getSearchEngines"}}, + {"uniqueId":"widgetReferrersgetReferrerType","parameters":{"module":"Referrers","action":"getReferrerType"}}, {"uniqueId":"widgetExampleRssWidgetrssPiwik","parameters":{"module":"ExampleRssWidget","action":"rssPiwik"}} ] ]'; diff --git a/plugins/Morpheus/templates/javascriptCode.tpl b/plugins/Morpheus/templates/javascriptCode.twig similarity index 58% rename from plugins/Morpheus/templates/javascriptCode.tpl rename to plugins/Morpheus/templates/javascriptCode.twig index 1a9ea321c18c246992e9c1c37f90e1508bc9a176..c18d850d345d988bf24a3e1731965e873f5dfeff 100644 --- a/plugins/Morpheus/templates/javascriptCode.tpl +++ b/plugins/Morpheus/templates/javascriptCode.twig @@ -7,9 +7,12 @@ {$setTrackerUrl} {$optionsBeforeTrackerUrl}_paq.push(['setTrackerUrl', u+'piwik.php']); _paq.push(['setSiteId', '{$idSite}']); - var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - g.type='text/javascript'; g.async={$loadAsync}; g.defer={$loadAsync}; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); + {% if loadAsync %}var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);{% endif %} + })(); </script> +{% if not loadAsync %}<script type='text/javascript' src="{$protocol}{$piwikUrl}/piwik.js"> +{% endif %} <noscript><p><img src="{$protocol}{$piwikUrl}/piwik.php?idsite={$idSite}" style="border:0;" alt="" /></p></noscript> <!-- End Piwik Code --> diff --git a/plugins/Referrers/Reports/GetReferrerType.php b/plugins/Referrers/Reports/GetReferrerType.php index f5656bfa7fb89efe090bb27ee493feefa59369a5..c9e9fecb351dbd49b89d31a179f271164e8a19a1 100644 --- a/plugins/Referrers/Reports/GetReferrerType.php +++ b/plugins/Referrers/Reports/GetReferrerType.php @@ -32,7 +32,7 @@ class GetReferrerType extends Base $this->constantRowsCount = true; $this->hasGoalMetrics = true; $this->order = 1; - $this->widgetTitle = 'General_Overview'; + $this->widgetTitle = 'Referrers_ReferrersOverview'; } public function getDefaultTypeViewDataTable() diff --git a/tests/PHPUnit/Integration/Tracker/TrackerCodeGeneratorTest.php b/tests/PHPUnit/Integration/Tracker/TrackerCodeGeneratorTest.php index 06f4bb5916b2e92458113c5e85536608487917be..c8bce62d517200830163f3a45c93b07a22157315 100644 --- a/tests/PHPUnit/Integration/Tracker/TrackerCodeGeneratorTest.php +++ b/tests/PHPUnit/Integration/Tracker/TrackerCodeGeneratorTest.php @@ -152,6 +152,41 @@ class TrackerCodeGeneratorTest extends IntegrationTestCase $this->assertEquals($expected, $jsTag); } + /** + * Tests the generated JS code with options before tracker url + */ + public function testJavascriptTrackingCode_loadSync() + { + $generator = new TrackerCodeGenerator(); + + Piwik::addAction('Piwik.getJavascriptCode', function (&$codeImpl) { + $codeImpl['loadAsync'] = false; + }); + + $jsTag = $generator->generate($idSite = 1, $piwikUrl = 'http://localhost/piwik', + $mergeSubdomains = true, $groupPageTitlesByDomain = true, $mergeAliasUrls = true); + + $expected = "<!-- Piwik --> +<script type="text/javascript"> + var _paq = _paq || []; + _paq.push([\"setDocumentTitle\", document.domain + \"/\" + document.title]); + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + (function() { + var u="//localhost/piwik/"; + _paq.push(['setTrackerUrl', u+'piwik.php']); + _paq.push(['setSiteId', '1']); + + })(); +</script> +<script type='text/javascript' src="//localhost/piwik/piwik.js"> +<noscript><p><img src="//localhost/piwik/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript> +<!-- End Piwik Code --> +"; + + $this->assertEquals($expected, $jsTag); + } + public function testStringsAreEscaped() { $generator = new TrackerCodeGenerator(); diff --git a/tests/UI/expected-screenshots/DashboardManager_create_new.png b/tests/UI/expected-screenshots/DashboardManager_create_new.png index e36639ec0e44a5f04041d17c03133a99d344a73b..c48621249231ff4f55b11912931e6d43877726e6 100644 Binary files a/tests/UI/expected-screenshots/DashboardManager_create_new.png and b/tests/UI/expected-screenshots/DashboardManager_create_new.png differ diff --git a/tests/UI/expected-screenshots/Dashboard_create_new.png b/tests/UI/expected-screenshots/Dashboard_create_new.png index 1e998c1c6a6ec49a4e6d530703c424644d02734d..02e4f79baa8db0f06c4902d1c9e038761a32d56f 100644 Binary files a/tests/UI/expected-screenshots/Dashboard_create_new.png and b/tests/UI/expected-screenshots/Dashboard_create_new.png differ diff --git a/tests/UI/expected-screenshots/Dashboard_reset.png b/tests/UI/expected-screenshots/Dashboard_reset.png index 0e0ada8bd5bda7da61a5a231d23a9f3f749386be..5ea8ff141a4f5a95f05ddd0b1b5438644a5a61c5 100644 Binary files a/tests/UI/expected-screenshots/Dashboard_reset.png and b/tests/UI/expected-screenshots/Dashboard_reset.png differ diff --git a/tests/UI/expected-screenshots/UIIntegrationTest_dashboard2.png b/tests/UI/expected-screenshots/UIIntegrationTest_dashboard2.png index f505ad79db1ddeebe2a5c708030678645f0bcc53..2db2e79d37c65ef09be31bd8cae4a419d8dad5b8 100644 Binary files a/tests/UI/expected-screenshots/UIIntegrationTest_dashboard2.png and b/tests/UI/expected-screenshots/UIIntegrationTest_dashboard2.png differ diff --git a/tests/UI/expected-screenshots/UIIntegrationTest_dashboard3.png b/tests/UI/expected-screenshots/UIIntegrationTest_dashboard3.png index 2bc710e9569d9d69c086dc75a2142ca5e6652636..02edab4aaa1e4a1e7542322ba78290fe965ca2e3 100644 Binary files a/tests/UI/expected-screenshots/UIIntegrationTest_dashboard3.png and b/tests/UI/expected-screenshots/UIIntegrationTest_dashboard3.png differ