diff --git a/.github/workflows/matomo-tests.yml b/.github/workflows/matomo-tests.yml index 1feffdf0215..154ce2c2440 100644 --- a/.github/workflows/matomo-tests.yml +++ b/.github/workflows/matomo-tests.yml @@ -70,6 +70,7 @@ jobs: redis-service: true artifacts-pass: ${{ secrets.ARTIFACTS_PASS }} upload-artifacts: ${{ matrix.php == '7.2' }} + testomatio: ${{ secrets.TESTOMATIO_INTEGRATION }} Javascript: runs-on: ubuntu-20.04 timeout-minutes: 15 diff --git a/composer.lock b/composer.lock index 4a43beb8e99..062e31719c4 100644 --- a/composer.lock +++ b/composer.lock @@ -713,12 +713,12 @@ "source": { "type": "git", "url": "https://github.com/matomo-org/referrer-spam-list.git", - "reference": "534dd945fb63db65ef8eebe36e49f8ad30df0008" + "reference": "1e24bd1b80708505c87bc6cf4667a93bdf34c4fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matomo-org/referrer-spam-list/zipball/534dd945fb63db65ef8eebe36e49f8ad30df0008", - "reference": "534dd945fb63db65ef8eebe36e49f8ad30df0008", + "url": "https://api.github.com/repos/matomo-org/referrer-spam-list/zipball/1e24bd1b80708505c87bc6cf4667a93bdf34c4fe", + "reference": "1e24bd1b80708505c87bc6cf4667a93bdf34c4fe", "shasum": "" }, "replace": { @@ -736,7 +736,7 @@ "issues": "https://github.com/matomo-org/referrer-spam-list/issues", "source": "https://github.com/matomo-org/referrer-spam-list/tree/master" }, - "time": "2024-04-01T18:16:25+00:00" + "time": "2024-06-11T10:47:52+00:00" }, { "name": "matomo/searchengine-and-social-list", @@ -744,12 +744,12 @@ "source": { "type": "git", "url": "https://github.com/matomo-org/searchengine-and-social-list.git", - "reference": "d3bb2a65147efd02333a879ee3f0ed3490d27f66" + "reference": "c33900d90f0e2051e6e888edbf62bfdd8e34e0e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matomo-org/searchengine-and-social-list/zipball/d3bb2a65147efd02333a879ee3f0ed3490d27f66", - "reference": "d3bb2a65147efd02333a879ee3f0ed3490d27f66", + "url": "https://api.github.com/repos/matomo-org/searchengine-and-social-list/zipball/c33900d90f0e2051e6e888edbf62bfdd8e34e0e5", + "reference": "c33900d90f0e2051e6e888edbf62bfdd8e34e0e5", "shasum": "" }, "replace": { @@ -766,7 +766,7 @@ "issues": "https://github.com/matomo-org/searchengine-and-social-list/issues", "source": "https://github.com/matomo-org/searchengine-and-social-list/tree/master" }, - "time": "2024-03-06T20:51:16+00:00" + "time": "2024-06-11T09:49:14+00:00" }, { "name": "maxmind-db/reader", @@ -1714,16 +1714,16 @@ }, { "name": "symfony/console", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1" + "reference": "aa73115c0c24220b523625bfcfa655d7d73662dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f3e591c48688a0cfa1a3296205926c05e84b22b1", - "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1", + "url": "https://api.github.com/repos/symfony/console/zipball/aa73115c0c24220b523625bfcfa655d7d73662dd", + "reference": "aa73115c0c24220b523625bfcfa655d7d73662dd", "shasum": "" }, "require": { @@ -1793,7 +1793,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.39" + "source": "https://github.com/symfony/console/tree/v5.4.40" }, "funding": [ { @@ -1809,7 +1809,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1880,16 +1880,16 @@ }, { "name": "symfony/error-handler", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd" + "reference": "c6c8f965a87b22d5005a7806783c7f10ae7e58cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd", - "reference": "9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/c6c8f965a87b22d5005a7806783c7f10ae7e58cd", + "reference": "c6c8f965a87b22d5005a7806783c7f10ae7e58cd", "shasum": "" }, "require": { @@ -1931,7 +1931,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.39" + "source": "https://github.com/symfony/error-handler/tree/v5.4.40" }, "funding": [ { @@ -1947,20 +1947,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d40fae9fd85c762b6ba378152fdd1157a85d7e4f" + "reference": "a54e2a8a114065f31020d6a89ede83e34c3b27a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d40fae9fd85c762b6ba378152fdd1157a85d7e4f", - "reference": "d40fae9fd85c762b6ba378152fdd1157a85d7e4f", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a54e2a8a114065f31020d6a89ede83e34c3b27a4", + "reference": "a54e2a8a114065f31020d6a89ede83e34c3b27a4", "shasum": "" }, "require": { @@ -2016,7 +2016,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.39" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.40" }, "funding": [ { @@ -2032,7 +2032,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -2115,16 +2115,16 @@ }, { "name": "symfony/http-foundation", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3356c93efc30b0c85a37606bdfef16b813faec0e" + "reference": "cf4893ca4eca3fac4ae06da1590afdbbb4217847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3356c93efc30b0c85a37606bdfef16b813faec0e", - "reference": "3356c93efc30b0c85a37606bdfef16b813faec0e", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cf4893ca4eca3fac4ae06da1590afdbbb4217847", + "reference": "cf4893ca4eca3fac4ae06da1590afdbbb4217847", "shasum": "" }, "require": { @@ -2134,7 +2134,7 @@ "symfony/polyfill-php80": "^1.16" }, "require-dev": { - "predis/predis": "~1.0", + "predis/predis": "^1.0|^2.0", "symfony/cache": "^4.4|^5.0|^6.0", "symfony/dependency-injection": "^5.4|^6.0", "symfony/expression-language": "^4.4|^5.0|^6.0", @@ -2171,7 +2171,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.39" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.40" }, "funding": [ { @@ -2187,20 +2187,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0" + "reference": "3ad03183c6985adc2eece16f239f8cfe1c4ccbe3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0", - "reference": "1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3ad03183c6985adc2eece16f239f8cfe1c4ccbe3", + "reference": "3ad03183c6985adc2eece16f239f8cfe1c4ccbe3", "shasum": "" }, "require": { @@ -2284,7 +2284,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.39" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.40" }, "funding": [ { @@ -2300,20 +2300,20 @@ "type": "tidelift" } ], - "time": "2024-04-29T11:17:46+00:00" + "time": "2024-06-02T15:53:08+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "c61589f4ba11236cb68433123c99dd2d77ab9b43" + "reference": "ac6e0bf2a275e017c1dedd54dd0f1fbf252a9351" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/c61589f4ba11236cb68433123c99dd2d77ab9b43", - "reference": "c61589f4ba11236cb68433123c99dd2d77ab9b43", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/ac6e0bf2a275e017c1dedd54dd0f1fbf252a9351", + "reference": "ac6e0bf2a275e017c1dedd54dd0f1fbf252a9351", "shasum": "" }, "require": { @@ -2368,7 +2368,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v5.4.39" + "source": "https://github.com/symfony/monolog-bridge/tree/v5.4.40" }, "funding": [ { @@ -2384,7 +2384,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "symfony/polyfill-ctype", @@ -3025,16 +3025,16 @@ }, { "name": "symfony/string", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "495e71bae5862308051b9e63cc3e34078eed83ef" + "reference": "142877285aa974a6f7685e292ab5ba9aae86b143" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/495e71bae5862308051b9e63cc3e34078eed83ef", - "reference": "495e71bae5862308051b9e63cc3e34078eed83ef", + "url": "https://api.github.com/repos/symfony/string/zipball/142877285aa974a6f7685e292ab5ba9aae86b143", + "reference": "142877285aa974a6f7685e292ab5ba9aae86b143", "shasum": "" }, "require": { @@ -3091,7 +3091,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.39" + "source": "https://github.com/symfony/string/tree/v5.4.40" }, "funding": [ { @@ -3107,20 +3107,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e" + "reference": "af8868a6e9d6082dfca11f1a1f205ae93a8b6d93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e", - "reference": "1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/af8868a6e9d6082dfca11f1a1f205ae93a8b6d93", + "reference": "af8868a6e9d6082dfca11f1a1f205ae93a8b6d93", "shasum": "" }, "require": { @@ -3180,7 +3180,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.39" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.40" }, "funding": [ { @@ -3196,7 +3196,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "szymach/c-pchart", @@ -3703,16 +3703,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -3720,11 +3720,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -3750,7 +3751,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -3758,7 +3759,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "phar-io/manifest", @@ -5195,16 +5196,16 @@ }, { "name": "symfony/yaml", - "version": "v5.4.39", + "version": "v5.4.40", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "bc780e16879000f77a1022163c052f5323b5e640" + "reference": "81cad0ceab3d61fe14fe941ff18a230ac9c80f83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/bc780e16879000f77a1022163c052f5323b5e640", - "reference": "bc780e16879000f77a1022163c052f5323b5e640", + "url": "https://api.github.com/repos/symfony/yaml/zipball/81cad0ceab3d61fe14fe941ff18a230ac9c80f83", + "reference": "81cad0ceab3d61fe14fe941ff18a230ac9c80f83", "shasum": "" }, "require": { @@ -5250,7 +5251,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.39" + "source": "https://github.com/symfony/yaml/tree/v5.4.40" }, "funding": [ { @@ -5266,7 +5267,7 @@ "type": "tidelift" } ], - "time": "2024-04-23T11:57:27+00:00" + "time": "2024-05-31T14:33:22+00:00" }, { "name": "theseer/tokenizer", diff --git a/core/DataTable/Renderer.php b/core/DataTable/Renderer.php index be2ed44c65e..8075ba7eacc 100644 --- a/core/DataTable/Renderer.php +++ b/core/DataTable/Renderer.php @@ -194,8 +194,31 @@ public static function formatValueXml($value) } $value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8'); - $htmlentities = array(" ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", "¬", "­", "®", "¯", "°", "±", "²", "³", "´", "µ", "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ", "€"); - $xmlentities = array("¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", "¬", "­", "®", "¯", "°", "±", "²", "³", "´", "µ", "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ", "€"); + $htmlentities = array( + " ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", + "ª", "«", "¬", "­", "®", "¯", "°", "±", "²", "³", + "´", "µ", "¶", "·", "¸", "¹", "º", "»", "¼", + "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", + "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", + "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", + "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "à", + "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", + "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", + "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", + "ü", "ý", "þ", "ÿ", "€" + ); + $xmlentities = array( + "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", + "¬", "­", "®", "¯", "°", "±", "²", "³", "´", "µ", + "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", + "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", + "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó", + "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", + "Þ", "ß", "à", "á", "â", "ã", "ä", "å", "æ", "ç", + "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", + "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", + "ü", "ý", "þ", "ÿ", "€" + ); $value = str_replace($htmlentities, $xmlentities, $value); } elseif ($value === false) { $value = 0; diff --git a/core/Db/Schema.php b/core/Db/Schema.php index 08a044633f2..7211a1be468 100644 --- a/core/Db/Schema.php +++ b/core/Db/Schema.php @@ -89,6 +89,16 @@ private function getSchema(): SchemaInterface return $this->schema; } + /** + * Get the table options to use for a CREATE TABLE statement. + * + * @return string + */ + public function getTableCreateOptions(): string + { + return $this->getSchema()->getTableCreateOptions(); + } + /** * Get the SQL to create a specific Piwik table * diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php index 8d6cf008c11..6cfab7e90d2 100644 --- a/core/Db/Schema/Mysql.php +++ b/core/Db/Schema/Mysql.php @@ -39,10 +39,8 @@ class Mysql implements SchemaInterface */ public function getTablesCreateSql() { - $engine = $this->getTableEngine(); $prefixTables = $this->getTablePrefix(); - $dbSettings = new Db\Settings(); - $charset = $dbSettings->getUsedCharset(); + $tableOptions = $this->getTableCreateOptions(); $tables = array( 'user' => "CREATE TABLE {$prefixTables}user ( @@ -62,7 +60,7 @@ public function getTablesCreateSql() ts_changes_shown TIMESTAMP NULL, PRIMARY KEY(login), UNIQUE INDEX `uniq_email` (`email`) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'user_token_auth' => "CREATE TABLE {$prefixTables}user_token_auth ( idusertokenauth BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, @@ -77,7 +75,7 @@ public function getTablesCreateSql() secure_only TINYINT(2) unsigned NOT NULL DEFAULT '0', PRIMARY KEY(idusertokenauth), UNIQUE KEY uniq_password(password) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'twofactor_recovery_code' => "CREATE TABLE {$prefixTables}twofactor_recovery_code ( @@ -85,7 +83,7 @@ public function getTablesCreateSql() login VARCHAR(100) NOT NULL, recovery_code VARCHAR(40) NOT NULL, PRIMARY KEY(idrecoverycode) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'access' => "CREATE TABLE {$prefixTables}access ( @@ -95,7 +93,7 @@ public function getTablesCreateSql() access VARCHAR(50) NULL, PRIMARY KEY(idaccess), INDEX index_loginidsite (login, idsite) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'site' => "CREATE TABLE {$prefixTables}site ( @@ -119,7 +117,7 @@ public function getTablesCreateSql() keep_url_fragment TINYINT NOT NULL DEFAULT 0, creator_login VARCHAR(100) NULL, PRIMARY KEY(idsite) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'plugin_setting' => "CREATE TABLE {$prefixTables}plugin_setting ( @@ -131,7 +129,7 @@ public function getTablesCreateSql() `idplugin_setting` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (idplugin_setting), INDEX(plugin_name, user_login) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'site_setting' => "CREATE TABLE {$prefixTables}site_setting ( @@ -143,14 +141,14 @@ public function getTablesCreateSql() `idsite_setting` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (idsite_setting), INDEX(idsite, plugin_name) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'site_url' => "CREATE TABLE {$prefixTables}site_url ( idsite INTEGER(10) UNSIGNED NOT NULL, url VARCHAR(190) NOT NULL, PRIMARY KEY(idsite, url) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'goal' => "CREATE TABLE `{$prefixTables}goal` ( @@ -167,7 +165,7 @@ public function getTablesCreateSql() `deleted` tinyint(4) NOT NULL default '0', `event_value_as_revenue` tinyint(4) NOT NULL default '0', PRIMARY KEY (`idsite`,`idgoal`) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'logger_message' => "CREATE TABLE {$prefixTables}logger_message ( @@ -177,7 +175,7 @@ public function getTablesCreateSql() level VARCHAR(16) NULL, message TEXT NULL, PRIMARY KEY(idlogger_message) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'log_action' => "CREATE TABLE {$prefixTables}log_action ( @@ -188,7 +186,7 @@ public function getTablesCreateSql() url_prefix TINYINT(2) NULL, PRIMARY KEY(idaction), INDEX index_type_hash (type, hash) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'log_visit' => "CREATE TABLE {$prefixTables}log_visit ( @@ -202,7 +200,7 @@ public function getTablesCreateSql() INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time), INDEX index_idsite_datetime (idsite, visit_last_action_time), INDEX index_idsite_idvisitor_time (idsite, idvisitor, visit_last_action_time DESC) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'log_conversion_item' => "CREATE TABLE `{$prefixTables}log_conversion_item` ( @@ -223,7 +221,7 @@ public function getTablesCreateSql() deleted TINYINT(1) UNSIGNED NOT NULL, PRIMARY KEY(idvisit, idorder, idaction_sku), INDEX index_idsite_servertime ( idsite, server_time ) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'log_conversion' => "CREATE TABLE `{$prefixTables}log_conversion` ( @@ -247,7 +245,7 @@ public function getTablesCreateSql() PRIMARY KEY (idvisit, idgoal, buster), UNIQUE KEY unique_idsite_idorder (idsite, idorder), INDEX index_idsite_datetime ( idsite, server_time ) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'log_link_visit_action' => "CREATE TABLE {$prefixTables}log_link_visit_action ( @@ -261,7 +259,7 @@ public function getTablesCreateSql() pageview_position MEDIUMINT UNSIGNED DEFAULT NULL, PRIMARY KEY(idlink_va), INDEX index_idvisit(idvisit) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'log_profiling' => "CREATE TABLE {$prefixTables}log_profiling ( @@ -271,7 +269,7 @@ public function getTablesCreateSql() idprofiling BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (idprofiling), UNIQUE KEY query(query(100)) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'option' => "CREATE TABLE `{$prefixTables}option` ( @@ -280,7 +278,7 @@ public function getTablesCreateSql() autoload TINYINT NOT NULL DEFAULT '1', PRIMARY KEY ( option_name ), INDEX autoload( autoload ) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'session' => "CREATE TABLE {$prefixTables}session ( @@ -289,7 +287,7 @@ public function getTablesCreateSql() lifetime INTEGER, data MEDIUMTEXT, PRIMARY KEY ( id ) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'archive_numeric' => "CREATE TABLE {$prefixTables}archive_numeric ( @@ -304,7 +302,7 @@ public function getTablesCreateSql() PRIMARY KEY(idarchive, name), INDEX index_idsite_dates_period(idsite, date1, date2, period, name(6)), INDEX index_period_archived(period, ts_archived) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'archive_blob' => "CREATE TABLE {$prefixTables}archive_blob ( @@ -318,7 +316,7 @@ public function getTablesCreateSql() value MEDIUMBLOB NULL, PRIMARY KEY(idarchive, name), INDEX index_period_archived(period, ts_archived) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'archive_invalidations' => "CREATE TABLE `{$prefixTables}archive_invalidations` ( @@ -335,14 +333,14 @@ public function getTablesCreateSql() `report` VARCHAR(255) NULL, PRIMARY KEY(idinvalidation), INDEX index_idsite_dates_period_name(idsite, date1, period) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'sequence' => "CREATE TABLE {$prefixTables}sequence ( `name` VARCHAR(120) NOT NULL, `value` BIGINT(20) UNSIGNED NOT NULL , PRIMARY KEY(`name`) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'brute_force_log' => "CREATE TABLE {$prefixTables}brute_force_log ( @@ -352,7 +350,7 @@ public function getTablesCreateSql() `login` VARCHAR(100) NULL, INDEX index_ip_address(ip_address), PRIMARY KEY(`id_brute_force_log`) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'tracking_failure' => "CREATE TABLE {$prefixTables}tracking_failure ( @@ -361,14 +359,14 @@ public function getTablesCreateSql() `date_first_occurred` DATETIME NOT NULL , `request_url` MEDIUMTEXT NOT NULL , PRIMARY KEY(`idsite`, `idfailure`) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'locks' => "CREATE TABLE `{$prefixTables}locks` ( `key` VARCHAR(" . Lock::MAX_KEY_LEN . ") NOT NULL, `value` VARCHAR(255) NULL DEFAULT NULL, `expiry_time` BIGINT UNSIGNED DEFAULT 9999999999, PRIMARY KEY (`key`) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", 'changes' => "CREATE TABLE `{$prefixTables}changes` ( `idchange` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, @@ -381,7 +379,7 @@ public function getTablesCreateSql() `link` VARCHAR(255) NULL, PRIMARY KEY(`idchange`), UNIQUE KEY unique_plugin_version_title (`plugin_name`, `version`, `title`(100)) - ) ENGINE=$engine DEFAULT CHARSET=$charset + ) $tableOptions ", ); @@ -522,10 +520,10 @@ public function createDatabase($dbName = null) $dbName = $this->getDbName(); } + $createOptions = $this->getDatabaseCreateOptions(); $dbName = str_replace('`', '', $dbName); - $charset = DbHelper::getDefaultCharset(); - Db::exec("CREATE DATABASE IF NOT EXISTS `" . $dbName . "` DEFAULT CHARACTER SET " . $charset); + Db::exec("CREATE DATABASE IF NOT EXISTS `$dbName` $createOptions"); } /** @@ -538,16 +536,11 @@ public function createDatabase($dbName = null) */ public function createTable($nameWithoutPrefix, $createDefinition) { - $dbSettings = new Db\Settings(); - $charset = $dbSettings->getUsedCharset(); - $statement = sprintf( - "CREATE TABLE IF NOT EXISTS `%s` ( %s ) ENGINE=%s DEFAULT CHARSET=%s %s;", + "CREATE TABLE IF NOT EXISTS `%s` ( %s ) %s;", Common::prefixTable($nameWithoutPrefix), $createDefinition, - $this->getTableEngine(), - $charset, - $dbSettings->getRowFormat() + $this->getTableCreateOptions() ); try { @@ -680,16 +673,48 @@ public function getDefaultPort(): int return 3306; } - private function getTablePrefix() + public function getTableCreateOptions(): string { - return $this->getDbSettings()->getTablePrefix(); + $engine = $this->getTableEngine(); + $charset = $this->getUsedCharset(); + $rowFormat = $this->getTableRowFormat(); + + $options = "ENGINE=$engine DEFAULT CHARSET=$charset"; + + if ('' !== $rowFormat) { + $options .= " $rowFormat"; + } + + return $options; + } + + protected function getDatabaseCreateOptions(): string + { + $charset = DbHelper::getDefaultCharset(); + + return "DEFAULT CHARACTER SET $charset"; } - private function getTableEngine() + protected function getTableEngine() { return $this->getDbSettings()->getEngine(); } + protected function getTableRowFormat(): string + { + return $this->getDbSettings()->getRowFormat(); + } + + protected function getUsedCharset(): string + { + return $this->getDbSettings()->getUsedCharset(); + } + + private function getTablePrefix() + { + return $this->getDbSettings()->getTablePrefix(); + } + private function getDb() { return Db::get(); diff --git a/core/Db/Schema/Tidb.php b/core/Db/Schema/Tidb.php index 6a1f1e29a27..193750259c7 100644 --- a/core/Db/Schema/Tidb.php +++ b/core/Db/Schema/Tidb.php @@ -9,6 +9,8 @@ namespace Piwik\Db\Schema; +use Piwik\DbHelper; + /** * Mariadb schema */ @@ -29,4 +31,35 @@ public function getDefaultPort(): int { return 4000; } + + public function getTableCreateOptions(): string + { + $engine = $this->getTableEngine(); + $charset = $this->getUsedCharset(); + $rowFormat = $this->getTableRowFormat(); + + $options = "ENGINE=$engine DEFAULT CHARSET=$charset"; + + if ('utf8mb4' === $charset) { + $options .= ' COLLATE=utf8mb4_0900_ai_ci'; + } + + if ('' !== $rowFormat) { + $options .= " $rowFormat"; + } + + return $options; + } + + protected function getDatabaseCreateOptions(): string + { + $charset = DbHelper::getDefaultCharset(); + $options = "DEFAULT CHARACTER SET $charset"; + + if ('utf8mb4' === $charset) { + $options .= ' COLLATE=utf8mb4_0900_ai_ci'; + } + + return $options; + } } diff --git a/core/Db/SchemaInterface.php b/core/Db/SchemaInterface.php index 6405c1260d2..3c256bed5bf 100644 --- a/core/Db/SchemaInterface.php +++ b/core/Db/SchemaInterface.php @@ -131,4 +131,11 @@ public function supportsComplexColumnUpdates(): bool; * @return int */ public function getDefaultPort(): int; + + /** + * Return the table options to use for a CREATE TABLE statement. + * + * @return string + */ + public function getTableCreateOptions(): string; } diff --git a/core/Tracker.php b/core/Tracker.php index cfebf114941..bcef4a7851b 100644 --- a/core/Tracker.php +++ b/core/Tracker.php @@ -325,22 +325,6 @@ public static function setTestEnvironment($args = null, $requestMethod = null) } } - protected function loadTrackerPlugins() - { - try { - $pluginManager = PluginManager::getInstance(); - $pluginsTracker = $pluginManager->loadTrackerPlugins(); - - $this->logger->debug("Loading plugins: { {plugins} }", [ - 'plugins' => implode(", ", $pluginsTracker), - ]); - } catch (Exception $e) { - $this->logger->error('Error loading tracker plugins: {exception}', [ - 'exception' => $e, - ]); - } - } - private function handleFatalErrors() { register_shutdown_function(function () { diff --git a/core/Updater/Migration/Db/CreateTable.php b/core/Updater/Migration/Db/CreateTable.php index 10f211352fe..3d39c4c3919 100644 --- a/core/Updater/Migration/Db/CreateTable.php +++ b/core/Updater/Migration/Db/CreateTable.php @@ -9,7 +9,7 @@ namespace Piwik\Updater\Migration\Db; -use Piwik\Db; +use Piwik\Db\Schema; /** * @see Factory::createTable() @@ -19,12 +19,11 @@ class CreateTable extends Sql { /** * Constructor. - * @param Db\Settings $dbSettings * @param string $table Prefixed table name * @param string|string[] $columnNames array(columnName => columnValue) * @param string|string[] $primaryKey one or multiple columns that define the primary key */ - public function __construct(Db\Settings $dbSettings, $table, $columnNames, $primaryKey) + public function __construct($table, $columnNames, $primaryKey) { $columns = array(); foreach ($columnNames as $column => $type) { @@ -35,15 +34,12 @@ public function __construct(Db\Settings $dbSettings, $table, $columnNames, $prim $columns[] = sprintf('PRIMARY KEY ( `%s` )', implode('`, `', $primaryKey)); } - - $sql = rtrim(sprintf( - 'CREATE TABLE `%s` (%s) ENGINE=%s DEFAULT CHARSET=%s %s', + $sql = sprintf( + 'CREATE TABLE `%s` (%s) %s', $table, implode(', ', $columns), - $dbSettings->getEngine(), - $dbSettings->getUsedCharset(), - $dbSettings->getRowFormat() - )); + Schema::getInstance()->getTableCreateOptions() + ); parent::__construct($sql, static::ERROR_CODE_TABLE_EXISTS); } diff --git a/lang/ca.json b/lang/ca.json index 1bb20a7c1e0..fcb44624407 100644 --- a/lang/ca.json +++ b/lang/ca.json @@ -1,7 +1,7 @@ { "General": { - "12HourClock": "Rellotge 12-hores", - "24HourClock": "Rellotge 24-hores", + "12HourClock": "Rellotge 12 hores", + "24HourClock": "Rellotge 24 hores", "API": "API", "AbandonedCarts": "Cistelles abandonades", "AboutPiwikX": "Sobre Matomo %s", diff --git a/lang/fr.json b/lang/fr.json index ee8760a1daf..13999ab623d 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -120,7 +120,7 @@ "Confirm": "Confirmer", "Continue": "Continuer", "ContinueToPiwik": "Continuer sur Matomo", - "CopiedToClipboard": "Copié dans le presse-papiers", + "CopiedToClipboard": "Copié dans le presse-papier", "Copy": "Copier", "Create": "Créer", "CreatedByUser": "créé par %s", @@ -267,6 +267,7 @@ "Installed": "Installé", "InvalidDateRange": "Plage de dates invalide, veuillez recommencer", "InvalidResponse": "Les données reçues sont invalides.", + "InvalidatedPeriod": "Période invalidée", "JsTrackingTag": "Code de suivi JavaScript", "KpiMetric": "Métrique KPI", "Language": "Langue", @@ -282,6 +283,7 @@ "Locale": "fr_FR.UTF-8", "Logout": "Déconnexion", "MainMetrics": "Métriques principales", + "ManagePlugins": "Gérer les composants", "ManageSubscriptions": "Gérer les abonnements", "Matches": "Correspondances", "MatomoIsACollaborativeProjectYouCanContributeAndDonateNextRelease": "%1$sMatomo%2$s, anciennement connu sous le nom de Piwik, est un projet collaboratif porté par les membres de l'équipe %7$sMatomo%8$s ainsi que de nombreux autres contributeurs à travers le monde.
Si vous êtes un fan de Matomo, vous pouvez aider : découvrez %3$scomment participer à Matomo%4$s, ou %5$sfaites un don%6$s pour aider à financer la prochaine grande version de Matomo !", @@ -365,6 +367,7 @@ "PaginationWithoutTotal": "%1$s–%2$s", "ParameterMustIntegerBetween": "Le paramètre %1$s doit être un nombre entier compris entre %2$s et %3$s.", "Password": "Mot de passe", + "PasswordConfirmation": "Confirmation du mot de passe", "Period": "Période", "Piechart": "Camembert", "PiwikCannotBeUpgradedBecausePhpIsTooOld": "Matomo ne peut pas être mis à jour à la dernière version majeure car votre version de PHP est trop ancienne.", @@ -453,6 +456,7 @@ "Table": "Tableau", "TagCloud": "Nuage d'étiquettes", "Tax": "Taxes", + "Testing": "Tests en cours…", "ThankYouForUsingMatomo": "Merci d'utiliser Matomo", "TheMatomoTeam": "L'équipe Matomo", "TimeAgo": "il y a %s", @@ -499,7 +503,8 @@ "ViewDocumentationFor": "Consulter la documentation pour %1$s", "Visit": "Visite", "VisitConvertedGoal": "Visite convertie en au moins un objectif", - "VisitConvertedGoalId": "Visite convertie en objectif spécifique", + "VisitConvertedGoalId": "Visite convertie en ID d'objectif spécifique", + "VisitConvertedGoalName": "Visite convertie en nom d'objectif spécifique", "VisitConvertedNGoals": "La visite a converti %s objectifs", "VisitDuration": "Durée moy. des visites (en secondes)", "VisitId": "ID de la visite", diff --git a/lang/it.json b/lang/it.json index f3e4472f57c..dbadcdb8e60 100644 --- a/lang/it.json +++ b/lang/it.json @@ -14,7 +14,7 @@ "AllowPiwikArchivingToTriggerBrowser": "Archivia i report quando sono stati visti dal browser", "And": "e", "Apply": "Applica", - "ArchivingInlineHelp": "Per i siti di medio o grande traffico, è raccomandabile disabilitare l'archivazione di Matomo dal browser. Raccomandiamo piuttosto di configurare un cron job per elaborare i report di Matomo ogni ora.", + "ArchivingInlineHelp": "Per i siti di medio o grande traffico, è raccomandabile disabilitare l'archiviazione di Matomo dal browser. Raccomandiamo piuttosto di configurare un cron job per elaborare i report di Matomo ogni ora.", "ArchivingTriggerDescription": "Raccomandato per installazioni di Matomo grandi, devi %1$sconfigurare un cron job%2$s per elaborare i report automaticamente.", "ArchivingTriggerSegment": "L'utilizzo di segmenti personalizzati attiverà comunque l'elaborazione degli archivi.", "AuthenticationMethodSmtp": "Metodo di autenticazione per SMTP", @@ -29,7 +29,7 @@ "CannotUnzipFile": "Impossibile scompattare il file %1$s: %2$s", "ChangeInX": "Cambia in %1$s", "ChangePassword": "Cambio password", - "ChangeTagCloudView": "Nota che puoi vedere il report in altri modi diversi dalla tag cloud. Usa i controlli in fondo al report per fare ciò.", + "ChangeTagCloudView": "Nota che puoi vedere il report in altri modi diversi dalla tag cloud. Usa i controlli in fondo al report per farlo.", "ChooseDate": "Scegli una data, attualmente è selezionata: %s", "ChooseLanguage": "Scegli la lingua", "ChoosePeriod": "Scegli il periodo", diff --git a/phpcs.xml b/phpcs.xml index eafcbfa3e97..d6834f30744 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -26,8 +26,14 @@ + - + + + + + tests/PHPUnit/* + plugins/*/tests/* diff --git a/plugins/AnonymousPiwikUsageMeasurement b/plugins/AnonymousPiwikUsageMeasurement index d8d1e812bed..6ced5ca272e 160000 --- a/plugins/AnonymousPiwikUsageMeasurement +++ b/plugins/AnonymousPiwikUsageMeasurement @@ -1 +1 @@ -Subproject commit d8d1e812bed4ce1ce0646dd9f6a6ac0dcb5f55b4 +Subproject commit 6ced5ca272e424a930cae8f344894506512db297 diff --git a/plugins/BulkTracking/tests/Integration/TrackerTest.php b/plugins/BulkTracking/tests/Integration/TrackerTest.php index efe629d0ca7..8d6641e2a2b 100644 --- a/plugins/BulkTracking/tests/Integration/TrackerTest.php +++ b/plugins/BulkTracking/tests/Integration/TrackerTest.php @@ -17,14 +17,6 @@ use Piwik\Tracker; use Piwik\Tests\Framework\Mock\Tracker\RequestSet; -class TestIntegrationTracker extends Tracker -{ - protected function loadTrackerPlugins() - { - // if we reload the plugins we would lose the injected data :( - } -} - /** * @group TrackerTest * @group Tracker @@ -32,7 +24,7 @@ protected function loadTrackerPlugins() class TrackerTest extends BulkTrackingTestCase { /** - * @var TestIntegrationTracker + * @var Tracker */ private $tracker; @@ -40,7 +32,7 @@ public function setUp(): void { parent::setUp(); - $this->tracker = new TestIntegrationTracker(); + $this->tracker = new Tracker(); Fixture::createWebsite('2014-01-01 00:00:00'); Fixture::createWebsite('2014-01-01 00:00:00'); diff --git a/plugins/CoreConsole/Commands/GeneratePluginBase.php b/plugins/CoreConsole/Commands/GeneratePluginBase.php index 06b12d5dab4..681207e749d 100644 --- a/plugins/CoreConsole/Commands/GeneratePluginBase.php +++ b/plugins/CoreConsole/Commands/GeneratePluginBase.php @@ -194,16 +194,34 @@ protected function checkAndUpdateRequiredPiwikVersion($pluginName) $missingVersion = $dependency->getMissingVersions($piwikVersion, $requiredVersion); if (!empty($missingVersion)) { - $msg = sprintf('We cannot generate this component as the plugin "%s" requires the Piwik version "%s" in the file "%s". Generating this component requires "%s". If you know your plugin is compatible with your Piwik version remove the required Piwik version in "%s" and try to execute this command again.', $pluginName, $requiredVersion, $relativePluginJson, $newRequiredVersion, $relativePluginJson); + $msg = sprintf( + 'We cannot generate this component as the plugin "%s" requires the Piwik version "%s" in the ' . + 'file "%s". Generating this component requires "%s". If you know your plugin is compatible with your ' . + 'Piwik version remove the required Piwik version in "%s" and try to execute this command again.', + $pluginName, + $requiredVersion, + $relativePluginJson, + $newRequiredVersion, + $relativePluginJson + ); throw new \Exception($msg); } $output->writeln(''); - $output->writeln(sprintf('We have updated the required Piwik version from "%s" to "%s" in "%s".', $requiredVersion, $newRequiredVersion, $relativePluginJson)); + $output->writeln(sprintf( + 'We have updated the required Piwik version from "%s" to "%s" in "%s".', + $requiredVersion, + $newRequiredVersion, + $relativePluginJson + )); } else { $output->writeln(''); - $output->writeln(sprintf('We have updated your "%s" to require the Piwik version "%s".', $relativePluginJson, $newRequiredVersion)); + $output->writeln(sprintf( + 'We have updated your "%s" to require the Piwik version "%s".', + $relativePluginJson, + $newRequiredVersion + )); } $pluginJson['require']['matomo'] = $newRequiredVersion; @@ -299,7 +317,7 @@ protected function copyTemplateMethodToExisitingClass($sourceClassName, $methodN * @param array $whitelistFiles If not empty, only given files/directories will be copied. * For instance array('/Controller.php', '/templates', '/templates/index.twig') */ - protected function copyTemplateToPlugin($templateFolder, $pluginName, array $replace = array(), $whitelistFiles = array()) + protected function copyTemplateToPlugin($templateFolder, $pluginName, array $replace = [], $whitelistFiles = []) { $replace['PLUGINNAME'] = $pluginName; @@ -405,7 +423,9 @@ protected function throwErrorIfNotGitInstalled() { if (!SettingsPiwik::isGitDeployment()) { $url = 'https://developer.matomo.org/guides/getting-started-part-1'; - throw new NotGitInstalledException("This development feature requires Matomo to be checked out from git. For more information please visit {$url}."); + throw new NotGitInstalledException( + "This development feature requires Matomo to be checked out from git. For more information please visit {$url}." + ); } } } diff --git a/plugins/CoreHome/lang/zh-tw.json b/plugins/CoreHome/lang/zh-tw.json index 789ca4f0f9c..b2b1c1f9163 100644 --- a/plugins/CoreHome/lang/zh-tw.json +++ b/plugins/CoreHome/lang/zh-tw.json @@ -68,6 +68,7 @@ "PageDownShortcutDescription": "前往網頁最下方", "PageUpShortcutDescription": "回到網頁最上方", "PeriodHasOnlyRawData": "似乎這一時段的報表尚未處理完成。想看看現在的狀況嗎?查看%1$s訪問紀錄%2$s或選擇不同的時段,直到有生成的報告。", + "PeriodHasOnlyRawDataNoVisitsLog": "此期間的報表似乎還沒處理好,但將會在數小時內就完成。在報表生成前,可以先選擇其他日期期間的報表。", "PeriodRange": "範圍", "PivotBySubtable": "此報表尚未圖形化 %1$s 以 %2$s 圖形化", "Profilable": "可紀錄的", diff --git a/plugins/CoreHome/tests/UI/VersionInfoHeaderMessage_spec.js b/plugins/CoreHome/tests/UI/VersionInfoHeaderMessage_spec.js index f5f447a10c3..166b7f0b5a0 100644 --- a/plugins/CoreHome/tests/UI/VersionInfoHeaderMessage_spec.js +++ b/plugins/CoreHome/tests/UI/VersionInfoHeaderMessage_spec.js @@ -149,6 +149,7 @@ describe('VersionInfoHeaderMessage', function() { messageDropdown.innerHTML = messageDropdown.innerHTML.replace(matomoVersion, '5.x-uitest'); }, selectorComponent, selectorMessageDropdown); + await page.mouse.move(-10, -10); await page.hover(selectorMessage); await page.waitForSelector(selectorMessageDropdown, {visible: true, timeout: 250}); diff --git a/plugins/CorePluginsAdmin/lang/zh-tw.json b/plugins/CorePluginsAdmin/lang/zh-tw.json index 434c0c6f201..7b1e9d84c62 100644 --- a/plugins/CorePluginsAdmin/lang/zh-tw.json +++ b/plugins/CorePluginsAdmin/lang/zh-tw.json @@ -48,6 +48,7 @@ "OriginThirdParty": "第三方", "PluginActivated": "外掛已啟用", "PluginFreeTrialStarted": "%1$s你的 30 天免費試用%3$s已經開始%2$s。", + "PluginFreeTrialStartedAccountCreatedMessage": "您的許可碼已成功添加,開始30天免費試用%1$s。繼續安裝並啓動您的外掛。", "PluginFreeTrialStartedAccountCreatedTitle": "你的帳號已經建立", "PluginHomepage": "外掛首頁", "PluginNotCompatibleWith": "%1$s 個外掛和 %2$s 不相容。", diff --git a/plugins/CoreUpdater/Commands/SecurityFiles.php b/plugins/CoreUpdater/Commands/SecurityFiles.php index 3e25a4d584e..7fd64877082 100644 --- a/plugins/CoreUpdater/Commands/SecurityFiles.php +++ b/plugins/CoreUpdater/Commands/SecurityFiles.php @@ -21,13 +21,22 @@ protected function configure() { $this->setName('core:create-security-files'); - $this->setDescription('Creates some web server security files if they haven\'t existed previously. Useful when using for example Apache or IIS web server and Matomo cannot create these files automatically because of missing write permissions.'); + $this->setDescription( + 'Creates some web server security files if they haven\'t existed previously. ' . + 'Useful when using for example Apache or IIS web server and Matomo cannot create these ' . + 'files automatically because of missing write permissions.' + ); } protected function doExecute(): int { ServerFilesGenerator::createFilesForSecurity(); - $this->getOutput()->writeln('Done. To check if this worked please open the system report or run `./console diagnostics:run` and look out for the private directories check. If it doesn\'t work you may need to execute this command using a user that has write permissions or maybe you are not using Apache or IIS web server. Please note you may need to execut this command every time you update Matomo to a newer version.'); + $this->getOutput()->writeln( + 'Done. To check if this worked please open the system report or run `./console diagnostics:run` and look ' . + 'out for the private directories check. If it doesn\'t work you may need to execute this command using a ' . + 'user that has write permissions or maybe you are not using Apache or IIS web server. Please note you ' . + 'may need to execut this command every time you update Matomo to a newer version.' + ); return self::SUCCESS; } diff --git a/plugins/CustomAlerts b/plugins/CustomAlerts index 2470806b98f..098573fb4f9 160000 --- a/plugins/CustomAlerts +++ b/plugins/CustomAlerts @@ -1 +1 @@ -Subproject commit 2470806b98f9b5e6ca3d01e43a38a1fe9ba3ef1a +Subproject commit 098573fb4f96a87629d0b413b2cf078795c28405 diff --git a/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_dashboard3.png b/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_dashboard3.png index 2cca772b0a0..a3a23cb5ed0 100644 --- a/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_dashboard3.png +++ b/plugins/Dashboard/tests/UI/expected-screenshots/Dashboard_dashboard3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:16067bdeb979f3ccd6592ecd3c4ce056c0ead67ce277fb653578792b61097827 -size 1668465 +oid sha256:06f415af72a19c77e0db080fe1aa5db45be4a8afc0334b17fc0a83eef523b47b +size 1668495 diff --git a/plugins/Diagnostics/lang/fr.json b/plugins/Diagnostics/lang/fr.json index 9a10874c81a..9c0e75148cb 100644 --- a/plugins/Diagnostics/lang/fr.json +++ b/plugins/Diagnostics/lang/fr.json @@ -19,6 +19,7 @@ "EnableRequiredDirectoriesDiagnostic": "Cette vérification a été ignorée car elle est désactivée dans la configuration. Pour activer cette vérification, définissez [General] enable_required_directories_diagnostic = 1 dans le fichier \"config/config.ini.php.", "HideUnchanged": "Si vous souhaitez afficher uniquement les valeurs modifiées, vous pouvez cliquer sur %1$smasquer toutes les valeurs inchangées%2$s.", "HtaccessWarningNginx": "Pour garantir l'impossibilité d'accéder directement aux fichiers sensibles, il est recommandé de configurer votre serveur web afin de restreindre l'accès à certains répertoires. Pour plus d'informations, veuillez consulter la %1$s configuration officielle du serveur nginx %2$s", + "MariaDbNotConfigured": "Votre version de base de données indique que vous utilisez peut-être un serveur MariaDb. Si c'est le cas, veuillez vous assurer d'avoir défini [database] schema = Mariadb dans le fichier \"config/config.ini.php\", afin que toutes les fonctionnalités de la base de données fonctionnent comme prévu.", "MysqlMaxPacketSize": "Taille maximale des paquets", "MysqlMaxPacketSizeWarning": "Il est important de configurer une taille '%1$smax_allowed_packet%2$s' dans votre base de données MySQL d'au moins %3$s. %4$s configuré en ce moment.", "MysqlTemporaryTablesWarning": "L'autorisation MySQL CREATE TEMPORARY TABLES est requise pour que Matomo fonctionne correctement.", diff --git a/plugins/Goals/API.php b/plugins/Goals/API.php index 66cb3fab13c..e48219fe046 100644 --- a/plugins/Goals/API.php +++ b/plugins/Goals/API.php @@ -80,10 +80,11 @@ public function getGoal($idSite, $idGoal) * Returns all Goals for a given website, or list of websites * * @param string|array $idSite Array or Comma separated list of website IDs to request the goals for + * @param bool $orderByName * * @return array Array of Goal attributes */ - public function getGoals($idSite) + public function getGoals($idSite, bool $orderByName = false): array { $cacheId = self::getCacheId($idSite); $cache = $this->getGoalsInfoStaticCache(); @@ -94,7 +95,7 @@ public function getGoals($idSite) $idSite = Site::getIdSitesFromIdSitesString($idSite); if (empty($idSite)) { - return array(); + return []; } Piwik::checkUserHasViewAccess($idSite); @@ -109,7 +110,19 @@ public function getGoals($idSite) $cache->save($cacheId, $cleanedGoals); } - return $cache->fetch($cacheId); + $goals = $cache->fetch($cacheId); + + if ($orderByName) { + uasort($goals, function ($a, $b) { + if ($a['name'] == $b['name']) { + return $a['idgoal'] > $b['idgoal'] ? -1 : 1; + } + + return strcasecmp($a['name'], $b['name']); + }); + } + + return $goals; } private function formatGoal($goal) diff --git a/plugins/Goals/Controller.php b/plugins/Goals/Controller.php index 63267f3193e..5d12806db27 100644 --- a/plugins/Goals/Controller.php +++ b/plugins/Goals/Controller.php @@ -72,7 +72,7 @@ public function __construct(Translator $translator) $this->translator = $translator; - $this->goals = Request::processRequest('Goals.getGoals', ['idSite' => $this->idSite, 'filter_limit' => '-1'], $default = []); + $this->goals = Request::processRequest('Goals.getGoals', ['idSite' => $this->idSite, 'filter_limit' => '-1', 'orderByName' => true], $default = []); } public function manage() @@ -266,7 +266,7 @@ public function getEvolutionGraph(array $columns = array(), $idGoal = false, arr public function getSparklines() { $content = ""; - $goals = Request::processRequest('Goals.getGoals', ['idSite' => $this->idSite, 'filter_limit' => '-1'], []); + $goals = Request::processRequest('Goals.getGoals', ['idSite' => $this->idSite, 'filter_limit' => '-1', 'orderByName' => true], []); foreach ($goals as $goal) { $params = [ diff --git a/plugins/Goals/Goals.php b/plugins/Goals/Goals.php index d5de3f1b7dd..7c804811eba 100644 --- a/plugins/Goals/Goals.php +++ b/plugins/Goals/Goals.php @@ -210,7 +210,7 @@ public function addSubcategories(&$subcategories) } } - $goals = Request::processRequest('Goals.getGoals', ['idSite' => $idSite, 'filter_limit' => '-1'], $default = []); + $goals = Request::processRequest('Goals.getGoals', ['idSite' => $idSite, 'filter_limit' => '-1', 'orderByName' => true], $default = []); $order = 900; foreach ($goals as $goal) { diff --git a/plugins/Goals/Visualizations/Goals.php b/plugins/Goals/Visualizations/Goals.php index 44173149fda..ffcbc92ceed 100644 --- a/plugins/Goals/Visualizations/Goals.php +++ b/plugins/Goals/Visualizations/Goals.php @@ -327,7 +327,7 @@ protected function getGoals($idSite) } // add the site's goals (and escape all goal names) - $siteGoals = Request::processRequest('Goals.getGoals', ['idSite' => $idSite, 'filter_limit' => '-1'], $default = []); + $siteGoals = Request::processRequest('Goals.getGoals', ['idSite' => $idSite, 'filter_limit' => '-1', 'orderByName' => true], $default = []); foreach ($siteGoals as &$goal) { $goal['quoted_name'] = '"' . $goal['name'] . '"'; diff --git a/plugins/Goals/tests/UI/expected-screenshots/GoalsPages_overview.png b/plugins/Goals/tests/UI/expected-screenshots/GoalsPages_overview.png index fe5542e750f..39635a23509 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/GoalsPages_overview.png +++ b/plugins/Goals/tests/UI/expected-screenshots/GoalsPages_overview.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5cf52231de97f09b4a247b874a3e3393496e7bca2dff63ef09e76fd1eb97d0b -size 184861 +oid sha256:45a9062d3f1ad81f5cee23265e7a27c1e9cc8de14cc46952d22efa0e11bc5ac1 +size 185870 diff --git a/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_goals_table_full.png b/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_goals_table_full.png index de27534e78f..b9faa9350a0 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_goals_table_full.png +++ b/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_goals_table_full.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c16d83287396bdf394f6b24275d317a2bc0eaba956adf520d82eff1aaf36a8dd -size 85619 +oid sha256:d54b490f6076edd70b07784951936cb9f19e00e86e6bf523bad588854897a4bc +size 85833 diff --git a/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_initial.png b/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_initial.png index d9fa09f83ff..3118e65e3b6 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_initial.png +++ b/plugins/Goals/tests/UI/expected-screenshots/GoalsTable_initial.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f6baac0444a0f3d3ba78d6174ebb3e1d28dcb5577d43102c03f48d00d7a7658 -size 78237 +oid sha256:631d317dd58fc1d2dd4dc262798d4d546e5148b6cc2d44c61f046820e53c8039 +size 73676 diff --git a/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls.png b/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls.png index 6d963f7ddc1..336de19bcdc 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls.png +++ b/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b34660de1ad2648b865e1844a38f711455867887a8a99537b4485950aef90b8 -size 94371 +oid sha256:73fb0913713dbe3cb3b557617948ae0d980f73d56e48097a83a8cbba6df43fb4 +size 94200 diff --git a/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls_subtable.png b/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls_subtable.png index 16fb109f037..56a1388d644 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls_subtable.png +++ b/plugins/Goals/tests/UI/expected-screenshots/Goals_action_goals_visualization_page_urls_subtable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e6cc0a5c198cf96130c06784b7731b484727c8cef9763b37b02ee72fea002f4 -size 110597 +oid sha256:4e1eea1e26194d74921f4017f6a52c4c15b0b027552652f3cf4ebfd9649ee1d3 +size 110288 diff --git a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_page_titles.png b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_page_titles.png index 1f9e8da4522..98cd41124b9 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_page_titles.png +++ b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_page_titles.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83d36aeb3149755124e3a98c8fd585ec089e95edf075c6e31578844349d251b9 -size 21503 +oid sha256:50e07322885b87485f80629553306555c635386c2de1da149f7f85308f180f2f +size 24925 diff --git a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_pages.png b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_pages.png index 0b45cd45ad4..1d89f8f7db7 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_pages.png +++ b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_entry_pages.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d7fcfc149c351939cdb5aa38b1122809e14aac642899f1551e3a85f52d7e459 -size 23339 +oid sha256:6445dd6b68e76f997a2a25a840b6844ea1d43718a2256e906a67d37db4e8dd9a +size 26895 diff --git a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_page_titles.png b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_page_titles.png index ee0e95ee8fe..7577cc464d4 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_page_titles.png +++ b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_page_titles.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89ef28441d04ca8a5f60f1ad0718d15d63bd267d5fcdafe9708bedfad543e1d3 -size 53625 +oid sha256:d6293b84314aa351a45c0c769e6fa76d786f742bfd2240418dfd64185bc5f7a6 +size 54356 diff --git a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_pages.png b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_pages.png index 4501506f2d5..56d0a4d680d 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_pages.png +++ b/plugins/Goals/tests/UI/expected-screenshots/Goals_goals_by_pages.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e04e0c8218c84a443fc8f69ca47e18f4d129543f0f822d512c563a13e3452b88 -size 57014 +oid sha256:1ec834ce47ae5d6ec42ff613f2afea03f5f64f4dd7d2c7b657649bcad9f0178b +size 52916 diff --git a/plugins/Goals/tests/UI/expected-screenshots/Goals_overview.png b/plugins/Goals/tests/UI/expected-screenshots/Goals_overview.png index 5a136241da1..d6aa5188a8d 100644 --- a/plugins/Goals/tests/UI/expected-screenshots/Goals_overview.png +++ b/plugins/Goals/tests/UI/expected-screenshots/Goals_overview.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99e6df4f3699d6d67291934b98338fec011e27b1da2fae6b81e5a98537ab6cf2 -size 121910 +oid sha256:f1e3dcaf72058de99c461ea46601b104abb567df4af7b8b5fca8e8e0899ba15e +size 122473 diff --git a/plugins/Installation/lang/zh-tw.json b/plugins/Installation/lang/zh-tw.json index 7270d22c08f..5a1815bf7c6 100644 --- a/plugins/Installation/lang/zh-tw.json +++ b/plugins/Installation/lang/zh-tw.json @@ -16,6 +16,7 @@ "DatabaseSetup": "資料庫設定", "DatabaseSetupAdapter": "介面卡", "DatabaseSetupDatabaseName": "資料庫名稱", + "DatabaseSetupEngine": "資料庫引擎", "DatabaseSetupLogin": "資料庫帳號", "DatabaseSetupServer": "資料庫伺服器", "DatabaseSetupTablePrefix": "資料表前綴", diff --git a/plugins/Login/templates/invitation.twig b/plugins/Login/templates/invitation.twig index 6bf67483065..507a62e7eed 100644 --- a/plugins/Login/templates/invitation.twig +++ b/plugins/Login/templates/invitation.twig @@ -29,8 +29,8 @@
-
diff --git a/plugins/Login/tests/UI/Login_spec.js b/plugins/Login/tests/UI/Login_spec.js index 76fd74bdf5d..27b8e0de0c9 100644 --- a/plugins/Login/tests/UI/Login_spec.js +++ b/plugins/Login/tests/UI/Login_spec.js @@ -19,8 +19,6 @@ describe("Login", function () { testEnvironment.testUseMockAuth = 0; testEnvironment.queryParamOverride = {date: "2012-01-01", period: "year"}; testEnvironment.save(); - - await page.clearCookies(); }); beforeEach(function () { @@ -37,8 +35,6 @@ describe("Login", function () { delete testEnvironment.queryParamOverride; delete testEnvironment.configOverride.General; testEnvironment.save(); - - await page.clearCookies(); }); afterEach(function () { diff --git a/plugins/Login/tests/UI/NoAccess_spec.js b/plugins/Login/tests/UI/NoAccess_spec.js index b047e9a4234..8b8a715e772 100644 --- a/plugins/Login/tests/UI/NoAccess_spec.js +++ b/plugins/Login/tests/UI/NoAccess_spec.js @@ -14,19 +14,14 @@ describe("NoAccess", function () { testEnvironment.testUseMockAuth = 0; testEnvironment.overrideConfig('General', 'login_session_not_remembered_idle_timeout', 1) testEnvironment.save(); - - await page.clearCookies(); }); after(async function () { testEnvironment.testUseMockAuth = 1; testEnvironment.save(); - - await page.clearCookies(); }); it("should login successfully with user credentials and show error when a site without access is viewed", async function() { - await page.clearCookies(); await page.goto("?idSite=2"); await page.waitForNetworkIdle(); await page.type("#login_form_login", "oliverqueen"); diff --git a/plugins/Morpheus/Controller.php b/plugins/Morpheus/Controller.php index 05eb04461d5..837d1be4767 100644 --- a/plugins/Morpheus/Controller.php +++ b/plugins/Morpheus/Controller.php @@ -22,6 +22,7 @@ public function demo() $snippets = []; + // @phpcs:disable Generic.Files.LineLength $snippets[] = [ 'id' => 'ActivityIndicator', 'title' => 'Loading indicator', @@ -864,6 +865,7 @@ public function demo() 'plugin' ], ]; + // @phpcs:enable Generic.Files.LineLength return $this->renderTemplate('demo', [ 'snippets' => $snippets, diff --git a/plugins/MultiSites/API.php b/plugins/MultiSites/API.php index 2734474019f..1563c2baab8 100644 --- a/plugins/MultiSites/API.php +++ b/plugins/MultiSites/API.php @@ -91,18 +91,33 @@ public function getAll($period, $date, $segment = false, $_restrictSitesToLogin { Piwik::checkUserHasSomeViewAccess(); - $sites = $this->getSitesIdFromPattern($pattern, $_restrictSitesToLogin); + $idSites = $this->getSitesIdFromPattern($pattern, $_restrictSitesToLogin); + + /** + * This event can be used to manipulate the sites being displayed on all websites dashboard. + * + * **Example** + * + * Piwik::addAction('MultiSites.filterSites', function (&$idSites) { + * $idSites = array_filter($idSites, function($idSite) { + * return $idSite !== 1 + * }); + * }); + * + * @param array &$idSites List of idSites that the current user would be allowed to see in all websites dashboard. + */ + Piwik::postEvent('MultiSites.filterSites', [&$idSites]); if (!empty($showColumns) && !is_array($showColumns)) { $showColumns = explode(',', $showColumns); } - if (empty($sites)) { + if (empty($idSites)) { return new DataTable(); } return $this->buildDataTable( - $sites, + $idSites, $period, $date, $segment, @@ -159,8 +174,12 @@ private function getSitesIdFromPattern($pattern, $_restrictSitesToLogin) // Both calls above have called Site::setSitesFromArray. We now get these sites: $sitesToProblablyAdd = Site::getSites(); + $idSites = []; + foreach ($sitesToProblablyAdd as $site) { + $idSites[] = $site['idsite']; + } - return $sitesToProblablyAdd; + return $idSites; } /** @@ -180,10 +199,14 @@ public function getOne($idSite, $period, $date, $segment = false, $_restrictSite { Piwik::checkUserHasViewAccess($idSite); - $sites = $this->getSiteFromId($idSite); + $site = $this->getSiteFromId($idSite); + + if (empty($site)) { + return new DataTable(); + } return $this->buildDataTable( - $sites, + [$idSite], $period, $date, $segment, @@ -233,20 +256,11 @@ public function getAllWithGroups($period = null, $date = null, $segment = false, private function getSiteFromId($idSite) { $idSite = (int) $idSite; - $sites = array(APISitesManager::getInstance()->getSiteFromId($idSite)); - - return $sites; + return APISitesManager::getInstance()->getSiteFromId($idSite); } - private function buildDataTable($sitesToProblablyAdd, $period, $date, $segment, $_restrictSitesToLogin, $enhanced, $multipleWebsitesRequested, $showColumns) + private function buildDataTable($idSites, $period, $date, $segment, $_restrictSitesToLogin, $enhanced, $multipleWebsitesRequested, $showColumns) { - $idSites = array(); - if (!empty($sitesToProblablyAdd)) { - foreach ($sitesToProblablyAdd as $site) { - $idSites[] = $site['idsite']; - } - } - // build the archive type used to query archive data $archive = Archive::build( $idSites, diff --git a/plugins/MultiSites/tests/System/ApiTest.php b/plugins/MultiSites/tests/System/ApiTest.php index 2572226bc15..09fd8fddf4f 100644 --- a/plugins/MultiSites/tests/System/ApiTest.php +++ b/plugins/MultiSites/tests/System/ApiTest.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\MultiSites\tests\System; +use Piwik\Piwik; use Piwik\Plugins\MultiSites\tests\Fixtures\ManySitesWithVisits; use Piwik\Tests\Framework\TestCase\SystemTestCase; @@ -95,6 +96,22 @@ public function getApiForTesting() ]; } + /** + * @dataProvider getApiForTesting + */ + public function testApiFiltered($api, $params) + { + $params['testSuffix'] .= '_filtered'; + + Piwik::addAction('MultiSites.filterSites', function (&$idSites) { + $idSites = array_filter($idSites, function ($idSite) { + return $idSite != 2 && $idSite != 10; + }); + }); + + $this->runApiTests($api, $params); + } + public static function getOutputPrefix() { return ''; diff --git a/plugins/MultiSites/tests/System/expected/test__filtered__MultiSites.getAllWithGroups_day.xml b/plugins/MultiSites/tests/System/expected/test__filtered__MultiSites.getAllWithGroups_day.xml new file mode 100644 index 00000000000..36ff3cab54d --- /dev/null +++ b/plugins/MultiSites/tests/System/expected/test__filtered__MultiSites.getAllWithGroups_day.xml @@ -0,0 +1,508 @@ + + + 13 + + 6 + 4 + 10 + 2,541 + 0 + + 2013-01-22 + + + + 2 + 4 + 3 + $2,541 + 1 + 1 + 2541 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 1 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 1 + 4 + 2 + $0 + 0 + 0 + 0 + 100% + 1 + 100% + 1 + 100% + 1 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 3 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 1 + 2 + 1 + $0 + 0 + 0 + 0 + 100% + 1 + 100% + 1 + 100% + 1 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 4 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 5 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 6 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 7 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 8 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 9 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 11 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 12 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 13 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 14 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 15 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + \ No newline at end of file diff --git a/plugins/MultiSites/tests/System/expected/test_limitedWithOffset_filtered__MultiSites.getAllWithGroups_day.xml b/plugins/MultiSites/tests/System/expected/test_limitedWithOffset_filtered__MultiSites.getAllWithGroups_day.xml new file mode 100644 index 00000000000..1fccc5db64b --- /dev/null +++ b/plugins/MultiSites/tests/System/expected/test_limitedWithOffset_filtered__MultiSites.getAllWithGroups_day.xml @@ -0,0 +1,204 @@ + + + 13 + + 6 + 4 + 10 + 2,541 + 0 + + 2013-01-22 + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 6 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 7 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 8 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 9 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 11 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + \ No newline at end of file diff --git a/plugins/MultiSites/tests/System/expected/test_limitedWithPattern_filtered__MultiSites.getAllWithGroups_day.xml b/plugins/MultiSites/tests/System/expected/test_limitedWithPattern_filtered__MultiSites.getAllWithGroups_day.xml new file mode 100644 index 00000000000..264436d1437 --- /dev/null +++ b/plugins/MultiSites/tests/System/expected/test_limitedWithPattern_filtered__MultiSites.getAllWithGroups_day.xml @@ -0,0 +1,204 @@ + + + 6 + + 6 + 4 + 10 + 2,541 + 0 + + 2013-01-22 + + + + 2 + 4 + 3 + $2,541 + 1 + 1 + 2541 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 1 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 11 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 12 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 13 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 14 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + \ No newline at end of file diff --git a/plugins/MultiSites/tests/System/expected/test_limited_filtered__MultiSites.getAllWithGroups_day.xml b/plugins/MultiSites/tests/System/expected/test_limited_filtered__MultiSites.getAllWithGroups_day.xml new file mode 100644 index 00000000000..f41a063f9ad --- /dev/null +++ b/plugins/MultiSites/tests/System/expected/test_limited_filtered__MultiSites.getAllWithGroups_day.xml @@ -0,0 +1,204 @@ + + + 13 + + 6 + 4 + 10 + 2,541 + 0 + + 2013-01-22 + + + + 2 + 4 + 3 + $2,541 + 1 + 1 + 2541 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 100% + 1 + 1 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 1 + 4 + 2 + $0 + 0 + 0 + 0 + 100% + 1 + 100% + 1 + 100% + 1 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 3 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 1 + 2 + 1 + $0 + 0 + 0 + 0 + 100% + 1 + 100% + 1 + 100% + 1 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 4 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 5 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + + 0 + 0 + 0 + $0 + 0 + 0 + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 0% + 0 + 6 + 1 + $ + 0 + day + Tue, Jan 22 + 0 + 0 + 0 + 0 + 0 + 0 + + http://piwik.net + + + \ No newline at end of file diff --git a/plugins/MultiSites/tests/System/expected/test_multiplePeriods_filtered__MultiSites.getAllWithGroups_day.xml b/plugins/MultiSites/tests/System/expected/test_multiplePeriods_filtered__MultiSites.getAllWithGroups_day.xml new file mode 100644 index 00000000000..f76ae70b1cc --- /dev/null +++ b/plugins/MultiSites/tests/System/expected/test_multiplePeriods_filtered__MultiSites.getAllWithGroups_day.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/plugins/PrivacyManager/Commands/AnonymizeRawData.php b/plugins/PrivacyManager/Commands/AnonymizeRawData.php index d9368847a17..92abb9f02c9 100644 --- a/plugins/PrivacyManager/Commands/AnonymizeRawData.php +++ b/plugins/PrivacyManager/Commands/AnonymizeRawData.php @@ -22,7 +22,12 @@ protected function configure() $defaultDate = '1996-01-01,' . Date::now()->toString(); $this->setName('privacymanager:anonymize-some-raw-data'); - $this->setDescription('Anonymize some of the stored raw data (logs). The reason it only anonymizes "some" data is that personal data can be present in many various data collection points, for example some of your page URLs or page titles may include personal data and these will not be anonymized by this command as it is not possible to detect personal data for example in a URL automatically.'); + $this->setDescription( + 'Anonymize some of the stored raw data (logs). The reason it only anonymizes "some" data is that ' . + 'personal data can be present in many various data collection points, for example some of your page URLs ' . + 'or page titles may include personal data and these will not be anonymized by this command as it is not ' . + 'possible to detect personal data for example in a URL automatically.' + ); $this->addRequiredValueOption('date', null, 'Date or date range to invalidate raw data for (UTC). Either a date like "2015-01-03" or a range like "2015-01-05,2015-02-12". By default, all data including today will be anonymized.', $defaultDate); $this->addRequiredValueOption('unset-visit-columns', null, 'Comma separated list of log_visit columns that you want to unset. Each value for that column will be set to its default value. If the same column exists in "log_conversion" table as well, the column will be unset there as well. This action cannot be undone.', ''); $this->addRequiredValueOption('unset-link-visit-action-columns', null, 'Comma separated list of log_link_visit_action columns that you want to unset. Each value for that column will be set to its default value. This action cannot be undone.', ''); diff --git a/plugins/ProfessionalServices/lang/fr.json b/plugins/ProfessionalServices/lang/fr.json index 9fb9597f6b2..271ba7a3ba5 100644 --- a/plugins/ProfessionalServices/lang/fr.json +++ b/plugins/ProfessionalServices/lang/fr.json @@ -4,6 +4,7 @@ "PromoFunnels": "Entonnoirs", "PromoHeatmaps": "Cartes de chaleur", "PromoManage": "Gérer", + "PromoMediaAnalytics": "Média", "PromoOverview": "Aperçu", "WidgetPremiumServicesForPiwik": "Fonctionnalités Premium & Services pour Matomo" } diff --git a/plugins/SegmentEditor/tests/UI/SegmentSelectorEditor_spec.js b/plugins/SegmentEditor/tests/UI/SegmentSelectorEditor_spec.js index 3e7ff270250..6cff1d92e43 100644 --- a/plugins/SegmentEditor/tests/UI/SegmentSelectorEditor_spec.js +++ b/plugins/SegmentEditor/tests/UI/SegmentSelectorEditor_spec.js @@ -18,7 +18,14 @@ describe("SegmentSelectorEditorTest", function () { async function selectFieldValue(fieldName, textToSelect) { await (await page.jQuery(fieldName + ' input.select-dropdown', { waitFor: true })).click(); + + // wait for animation + await page.waitForTimeout(200); + await (await page.jQuery(fieldName + ' .dropdown-content li:contains("' + textToSelect + '"):first', { waitFor: true })).click(); + + // wait for animation + await page.waitForTimeout(300); await page.mouse.move(-10, -10); } @@ -150,7 +157,7 @@ describe("SegmentSelectorEditorTest", function () { expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('saved_details'); }); - it("should correctly should show a confirmation when changing segment definition", async function() { + it("should correctly show a confirmation when changing segment definition", async function() { await page.click('.segmentEditorPanel .editSegmentName'); await page.$eval('.segmentEditorPanel .segmentRow0 .ui-autocomplete-input', e => e.blur()); diff --git a/plugins/Tour/lang/fr.json b/plugins/Tour/lang/fr.json index edc31a72929..fe800236942 100644 --- a/plugins/Tour/lang/fr.json +++ b/plugins/Tour/lang/fr.json @@ -1,6 +1,7 @@ { "Tour": { "AddAnnotation": "Ajouter une annotation", + "AddAnotherWebsite": "Ajouter un autre site web", "AddReport": "Ajouter un rapport planifié", "AddSegment": "Ajouter un segment", "BecomeMatomoExpert": "Devenir un expert Matomo", @@ -21,6 +22,7 @@ "Engagement": "Engagement", "FlattenActions": "Aplatir un rapport de page", "FlattenActionsDescription": "Accédez à Comportement → Pages et cliquez sur l'icône en forme de rouage en bas du rapport pour l'aplatir. Cela modifie la hiérarchie d'un rapport groupé à une liste.", + "InviteUser": "Inviter un utilisateur", "MatomoBeginner": "Matomo débutant", "MatomoExpert": "Expert Matomo", "MatomoIntermediate": "Matomo intermédiaire", diff --git a/plugins/TrackingSpamPrevention b/plugins/TrackingSpamPrevention index 09d8ecfcd30..4b5cd51f8c4 160000 --- a/plugins/TrackingSpamPrevention +++ b/plugins/TrackingSpamPrevention @@ -1 +1 @@ -Subproject commit 09d8ecfcd30dda213a2feaa1400d7abe562bffbd +Subproject commit 4b5cd51f8c47a7a79ab9b9492cdfbecfba90311c diff --git a/plugins/Transitions/tests/UI/Transitions_spec.js b/plugins/Transitions/tests/UI/Transitions_spec.js index 81840847a83..1b2e2170d2f 100644 --- a/plugins/Transitions/tests/UI/Transitions_spec.js +++ b/plugins/Transitions/tests/UI/Transitions_spec.js @@ -42,14 +42,13 @@ describe("Transitions", function () { await page.goto("?" + urlBase + "#?" + generalParams + "&category=General_Actions&subcategory=General_Pages&" + "popover=RowAction$3ATransitions$3Aurl$3Ahttp$3A$2F$2Fpiwik.net$2Fdocs$2Fmanage-websites$2F"); await page.waitForNetworkIdle(); - await page.waitForTimeout(500); - // for some reason the tooltip isn't shown on the screenshot (even if the whole page is taken) - // but it seems to be placed in the HTML code so, we check for it's contents await (await page.$('.Transitions_CurveTextRight')).hover(); - await page.waitForSelector('.ui-tooltip'); - const toolTipHtml = await page.evaluate(() => $('.ui-tooltip:visible').html()); - expect(toolTipHtml).to.equal('
4 (out of 4) to internal pages
'); + await page.waitForSelector('.ui-tooltip', { visible: true }); + + // the tooltip will, in most cases, not be visible in the screenshot + // removing and re-adding a clone to the DOM seems to fix that problem + await page.evaluate(() => $('.ui-dialog').append($('.ui-tooltip').remove().clone())); expect(await page.screenshotSelector('.ui-dialog')).to.matchImage('transitions_popup_urls'); }); diff --git a/plugins/Transitions/tests/UI/expected-screenshots/Transitions_transitions_popup_urls.png b/plugins/Transitions/tests/UI/expected-screenshots/Transitions_transitions_popup_urls.png index d7df2d2c619..9e6b4caa6a7 100644 --- a/plugins/Transitions/tests/UI/expected-screenshots/Transitions_transitions_popup_urls.png +++ b/plugins/Transitions/tests/UI/expected-screenshots/Transitions_transitions_popup_urls.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b4d2628c87a41c8a24566e70f8710ee94bc1f7036851d298ab4f468706299d92 -size 78803 +oid sha256:038c3a55d2c687a2dc54b968f54d876caad7c55a221f453331e60bf9f6161343 +size 80811 diff --git a/plugins/UserCountryMap/tests/UI/VisitorMap_spec.js b/plugins/UserCountryMap/tests/UI/VisitorMap_spec.js index abb08c250cd..144c2d60af4 100644 --- a/plugins/UserCountryMap/tests/UI/VisitorMap_spec.js +++ b/plugins/UserCountryMap/tests/UI/VisitorMap_spec.js @@ -12,7 +12,7 @@ describe("VisitorMap", function () { var url = "?module=Widgetize&action=iframe&moduleToWidgetize=UserCountryMap&idSite=1&period=year&date=2012-08-09&" + "actionToWidgetize=visitorMap&viewDataTable=table&filter_limit=5&isFooterExpandedInDashboard=1", - urlWithCities = "?module=Widgetize&action=iframe&moduleToWidgetize=UserCountryMap&idSite=3&period=week&date=yesterday&" + urlWithCities = "?module=Widgetize&action=iframe&moduleToWidgetize=UserCountryMap&idSite=3&period=day&date=yesterday&" + "actionToWidgetize=visitorMap&viewDataTable=table&filter_limit=5&isFooterExpandedInDashboard=1"; it("should display the bounce rate metric correctly", async function() { diff --git a/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_cities.png b/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_cities.png index 12febce0820..11621672c9c 100644 --- a/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_cities.png +++ b/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_cities.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e78608cb6511fe12c4671ac036d74b87f8557be14edf0601661d6015b7275d9d -size 112487 +oid sha256:8ea3d772f63e11a59c1ac5ff7d0de0dc0054780ae880d1f7ee7916ce9f6a9dd6 +size 113888 diff --git a/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_regions.png b/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_regions.png index 04ec10633bc..5e2e93ec684 100644 --- a/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_regions.png +++ b/plugins/UserCountryMap/tests/UI/expected-screenshots/VisitorMap_regions.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e5ee739257dd15445f529c9c13dfcfe5e6ab6bb92df5b9a3adbb4bae4fa75a6 -size 111261 +oid sha256:816ba48277bca270848ef2e66b466d7847e8f42a9b03370099bbf25cc293d32d +size 112665 diff --git a/tests/PHPUnit/Framework/Mock/TestConfig.php b/tests/PHPUnit/Framework/Mock/TestConfig.php index 59c31127222..17fef243719 100644 --- a/tests/PHPUnit/Framework/Mock/TestConfig.php +++ b/tests/PHPUnit/Framework/Mock/TestConfig.php @@ -11,12 +11,25 @@ use Piwik\Application\Kernel\GlobalSettingsProvider; use Piwik\Config; +use Piwik\Plugin\Manager; use Piwik\Tests\Framework\TestingEnvironmentVariables; class TestConfig extends Config { - private $allowSave = false; - private $doSetTestEnvironment = false; + /** + * @var bool + */ + private $allowSave; + + /** + * @var bool + */ + private $doSetTestEnvironment; + + /** + * @var TestingEnvironmentVariables + */ + private $testingEnvironment; public function __construct(GlobalSettingsProvider $provider, TestingEnvironmentVariables $testingEnvironment, $allowSave = false, $doSetTestEnvironment = true) { @@ -24,6 +37,7 @@ public function __construct(GlobalSettingsProvider $provider, TestingEnvironment $this->allowSave = $allowSave; $this->doSetTestEnvironment = $doSetTestEnvironment; + $this->testingEnvironment = $testingEnvironment; $this->reload(); @@ -42,6 +56,24 @@ public function forceSave() if ($this->allowSave) { parent::forceSave(); } + + if (!$this->doSetTestEnvironment) { + return; + } + + $environmentPlugins = $this->testingEnvironment->configOverride['PluginsInstalled']['PluginsInstalled'] ?? []; + $installedPlugins = Manager::getInstance()->getInstalledPluginsName(); + + $onlyEnvironment = array_diff($environmentPlugins, $installedPlugins); + $onlyInstalled = array_diff($installedPlugins, $environmentPlugins); + + if ([] === $onlyEnvironment && [] === $onlyInstalled) { + // environment matches list of installed plugins + return; + } + + $this->testingEnvironment->overrideConfig('PluginsInstalled', 'PluginsInstalled', $installedPlugins); + $this->testingEnvironment->save(); } public function setTestEnvironment() diff --git a/tests/UI/config.dist.js b/tests/UI/config.dist.js index 746f2e2dbd0..bab41ad0bb6 100644 --- a/tests/UI/config.dist.js +++ b/tests/UI/config.dist.js @@ -40,7 +40,7 @@ exports.chai = 'chai-1.9.0'; /** * Mocha reporters to use (can be multiple delimited by a comma). */ -if (process.env.TESTOMATIO) { +if (process.env.TESTOMATIO && process.env.SHOULD_SEND_TO_TESTOMATIO === 'true') { exports.reporter = 'mocha-multi-reporters'; exports.reporterOptions = { reporterEnabled: 'spec, @testomatio/reporter/lib/adapter/mocha.js', diff --git a/tests/UI/expected-screenshots/Comparison_goals_table.png b/tests/UI/expected-screenshots/Comparison_goals_table.png index 33755831d57..a9e7d3c0c0e 100644 --- a/tests/UI/expected-screenshots/Comparison_goals_table.png +++ b/tests/UI/expected-screenshots/Comparison_goals_table.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c2dba1e4c53a574a256f8d8b16451a1e8b25b06f9ad8960ede2f74d4aeed6c51 -size 158863 +oid sha256:986ef94bb2d34b64ffd16759f1a30a5a77088d1b5a18c277c64c5825abe9038c +size 153252 diff --git a/tests/UI/expected-screenshots/QuickAccess_search_1.png b/tests/UI/expected-screenshots/QuickAccess_search_1.png index 33d303fe9d9..e1a37bdd2ee 100644 --- a/tests/UI/expected-screenshots/QuickAccess_search_1.png +++ b/tests/UI/expected-screenshots/QuickAccess_search_1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86e59e5c164b59b6f2c1e088879dc3673fa148faeb50bebf72ebaa221a6df621 -size 96666 +oid sha256:3d7c1869cb6b944f78431c2a37948d17ee24af6afb2025b709c69c1609c8ea8b +size 96975 diff --git a/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png b/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png index 2cbbcae7153..2ef76402131 100644 --- a/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png +++ b/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:52843b299537c1334aa42ce4a549d43280004c18aee16a105b0869c2bb9ab5b9 -size 4935154 +oid sha256:ecff30e1cf793356317a9f40c100f003411e09edf53c4f54ececc6e9cdd00923 +size 4937549 diff --git a/tests/UI/expected-screenshots/ViewDataTableTest_5_goals.png b/tests/UI/expected-screenshots/ViewDataTableTest_5_goals.png index d9fa09f83ff..3118e65e3b6 100644 --- a/tests/UI/expected-screenshots/ViewDataTableTest_5_goals.png +++ b/tests/UI/expected-screenshots/ViewDataTableTest_5_goals.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f6baac0444a0f3d3ba78d6174ebb3e1d28dcb5577d43102c03f48d00d7a7658 -size 78237 +oid sha256:631d317dd58fc1d2dd4dc262798d4d546e5148b6cc2d44c61f046820e53c8039 +size 73676 diff --git a/tests/UI/specs/OptOutIframe_spec.js b/tests/UI/specs/OptOutIframe_spec.js index abcbb20c5d4..495deba636b 100644 --- a/tests/UI/specs/OptOutIframe_spec.js +++ b/tests/UI/specs/OptOutIframe_spec.js @@ -21,9 +21,6 @@ describe("OptOutIframe", function () { }); } - after(async () => { - await page.clearCookies(); - }); after(async () => { await page.setUserAgent(page.originalUserAgent); }); diff --git a/tests/UI/specs/OptOutJS_spec.js b/tests/UI/specs/OptOutJS_spec.js index 7a71053f231..154c356eadb 100644 --- a/tests/UI/specs/OptOutJS_spec.js +++ b/tests/UI/specs/OptOutJS_spec.js @@ -12,10 +12,6 @@ describe('OptOutJS', function () { const siteUrl = '/tests/resources/overlay-test-site-real/opt-out.php?implementation=js'; - after(async () => { - await page.clearCookies(); - }); - async function expectHasConsentToBe(useTracker, expectedState) { let hasConsent; diff --git a/tests/lib/screenshot-testing/run-tests.js b/tests/lib/screenshot-testing/run-tests.js index 50423ea27bf..03ad2332d09 100644 --- a/tests/lib/screenshot-testing/run-tests.js +++ b/tests/lib/screenshot-testing/run-tests.js @@ -29,17 +29,14 @@ async function main() { } const browser = await puppeteer.launch(config.browserConfig); - const webpage = await browser.newPage(); - await webpage._client.send('Animation.setPlaybackRate', { playbackRate: 50 }); // make animations run 50 times faster, so we don't have to wait as much + const originalUserAgent = await browser.userAgent(); // assume the URI points to a folder and make sure Piwik won't cut off the last path segment if (config.phpServer.REQUEST_URI.slice(-1) !== '/') { config.phpServer.REQUEST_URI += '/'; } - const originalUserAgent = await browser.userAgent(); - - setUpGlobals(config, webpage, originalUserAgent); + setUpGlobals(config, browser, originalUserAgent); mocha = new Mocha({ ui: 'bdd', diff --git a/tests/lib/screenshot-testing/support/app.js b/tests/lib/screenshot-testing/support/app.js index fe2458f63b6..ac8f54c5d78 100644 --- a/tests/lib/screenshot-testing/support/app.js +++ b/tests/lib/screenshot-testing/support/app.js @@ -191,6 +191,10 @@ Application.prototype.loadTestModules = function () { mocha.suite.suites.forEach(function (suite) { var fixture = typeof suite.fixture === 'undefined' ? "Piwik\\Tests\\Fixtures\\UITestFixture" : suite.fixture; + suite.beforeAll(async function () { + await page.createPage(); + }); + suite.beforeAll(function (done) { this.timeout(0); // no timeout for fixture setup (this requires normal anonymous function, not fat arrow function) @@ -208,7 +212,8 @@ Application.prototype.loadTestModules = function () { }); }); - // move to before other hooks + // move in front of other beforeAll hooks (called twice as we're adding two beforeAll handlers) + suite._beforeAll.unshift(suite._beforeAll.pop()); suite._beforeAll.unshift(suite._beforeAll.pop()); suite.afterAll(function (done) { @@ -313,10 +318,6 @@ Application.prototype.doRunTests = function (mocha) { } }); - this.runner.on('suite', function() { - page.webpage.mouse.move(-10, -10); - }); - this.runner.on('test', function () { page._reset(); }); diff --git a/tests/lib/screenshot-testing/support/globals.js b/tests/lib/screenshot-testing/support/globals.js index b3b77fa3229..e5bf8cd4974 100644 --- a/tests/lib/screenshot-testing/support/globals.js +++ b/tests/lib/screenshot-testing/support/globals.js @@ -10,7 +10,7 @@ const path = require('path'); const chai = require('chai'); const { PageRenderer } = require('./page-renderer'); -module.exports = function setUpGlobals(config, page, originalUserAgent) { +module.exports = function setUpGlobals(config, browser, originalUserAgent) { global.config = config; global.PIWIK_INCLUDE_PATH = path.join(__dirname, '..', '..', '..', '..'); @@ -23,7 +23,7 @@ module.exports = function setUpGlobals(config, page, originalUserAgent) { global.testEnvironment = require('./test-environment').TestingEnvironment; global.app = require('./app').Application; global.expect = chai.expect; - global.page = new PageRenderer(config.piwikUrl + path.join("tests", "PHPUnit", "proxy"), page, originalUserAgent); + global.page = new PageRenderer(config.piwikUrl + path.join("tests", "PHPUnit", "proxy"), browser, originalUserAgent); // The following variables need to be in sync with Fixture::ADMIN_USER_LOGIN and Fixture::ADMIN_USER_PASSWORD global.superUserLogin = 'superUserLogin'; global.superUserPassword = 'pas3!"§$%&/()=?\'ㄨ<|-_#*+~>word'; diff --git a/tests/lib/screenshot-testing/support/page-renderer.js b/tests/lib/screenshot-testing/support/page-renderer.js index d40f4385706..718a656431e 100644 --- a/tests/lib/screenshot-testing/support/page-renderer.js +++ b/tests/lib/screenshot-testing/support/page-renderer.js @@ -77,8 +77,9 @@ const AUTO_WAIT_METHODS = {// TODO: remove this to keep it consistent? 'reload': true, }; -var PageRenderer = function (baseUrl, page, originalUserAgent) { - this.webpage = page; +var PageRenderer = function (baseUrl, browser, originalUserAgent) { + + this.browser = browser; this.originalUserAgent = originalUserAgent; this.selectorMarkerClass = 0; @@ -90,19 +91,6 @@ var PageRenderer = function (baseUrl, page, originalUserAgent) { if (this.baseUrl.substring(-1) !== '/') { this.baseUrl = this.baseUrl + '/'; } - - PAGE_PROPERTIES_TO_PROXY.forEach((propertyName) => { - Object.defineProperty(this, propertyName, { - value: page[propertyName], - writable: false, - }); - }); - - this.webpage.setViewport({ - width: 1350, - height: 768, - }); - this._setupWebpageEvents(); }; PageRenderer.prototype._reset = function () { @@ -113,6 +101,32 @@ PageRenderer.prototype._reset = function () { }); }; +PageRenderer.prototype.createPage = async function () { + if (this.browserContext) { + await this.browserContext.close(); + } + this.browserContext = await this.browser.createIncognitoBrowserContext(); + this.webpage = await this.browserContext.newPage(); + + PAGE_PROPERTIES_TO_PROXY.forEach((propertyName) => { + Object.defineProperty(this, propertyName, { + value: this.webpage[propertyName], + writable: true, + }); + }); + + await this.webpage._client.send('Animation.setPlaybackRate', { playbackRate: 50 }); // make animations run 50 times faster, so we don't have to wait as much + await this.webpage.setViewport({ + width: 1350, + height: 768, + }); + await this.webpage.mouse.move(0, 0); + await this.webpage.setExtraHTTPHeaders({ + 'Accept-Language': 'en-US' + }); + this._setupWebpageEvents(); +}; + /** * For BC only. Puppeteer drop support for waitFor function in Version 10 * @param selectorOrTimeoutOrFunction @@ -367,9 +381,10 @@ PageRenderer.prototype._logMessage = function (message) { this.pageLogs.push(message); }; -PageRenderer.prototype.clearCookies = function () { +PageRenderer.prototype.clearCookies = async function () { // see https://github.com/GoogleChrome/puppeteer/issues/1632#issuecomment-353086292 - return this.webpage._client.send('Network.clearBrowserCookies'); + await this.webpage._client.send('Network.clearBrowserCookies'); + await this.webpage.waitForTimeout(250); }; PageRenderer.prototype._setupWebpageEvents = function () { @@ -456,20 +471,6 @@ PageRenderer.prototype._setupWebpageEvents = function () { if (!VERBOSE) { this._logMessage('Unable to load resource (URL:' + request.url() + '): ' + errorMessage); } - - var type = ''; - if (type = request.url().match(/action=get(Css|CoreJs|NonCoreJs|UmdJs)/)) { - if (errorMessage === 'net::ERR_ABORTED' && (!response || response.status() !== 500)) { - console.log(type[1]+' request aborted.'); - } else if (request.url().indexOf('&reload=') === -1) { - console.log('Loading '+type[1]+' failed (' + errorMessage + ')... Try adding it with another tag.'); - var method = type[1] == 'Css' ? 'addStyleTag' : 'addScriptTag'; - await this.webpage[method]({url: request.url() + '&reload=' + Date.now()}); // add another get parameter to ensure browser doesn't use cache - await this.waitForNetworkIdle(); // wait for request to finish before continuing with tests - } else { - console.log('Reloading '+type[1]+' failed (' + errorMessage + ').'); - } - } }); this.webpage.on('requestfinished', async (request) => { @@ -488,26 +489,6 @@ PageRenderer.prototype._setupWebpageEvents = function () { const message = 'Response (size "' + bodyLength + '", status "' + response.status() + '"): ' + request.url() + "\n" + bodyContent.substring(0, 2000); this._logMessage(message); } - - // if response of css or js request does not start with /*, we assume it had an error and try to load it again - // Note: We can't do that in requestfailed only, as the response code might be 200 even if it throws an exception - var type = ''; - if (type = request.url().match(/action=get(Css|CoreJs|NonCoreJs)/)) { - var body = await response.buffer(); - if (body.toString().substring(0, 2) === '/*') { - return; - } - if (request.url().indexOf('&reload=') === -1) { - console.log('Loading '+type[1]+' failed... Try adding it with another tag.'); - var method = type[1] == 'Css' ? 'addStyleTag' : 'addScriptTag'; - await this.waitForNetworkIdle(); // wait for other requests to finish before trying to reload - await this.webpage[method]({url: request.url() + '&reload=' + Date.now()}); // add another get parameter to ensure browser doesn't use cache - await this.webpage.waitForTimeout(1000); - } else { - console.log('Reloading '+type[1]+' failed.'); - } - console.log('Response (size "' + body.length + '", status "' + response.status() + ', headers "' + JSON.stringify(response.headers()) + '"): ' + request.url() + "\n" + body.toString()); - } }); this.webpage.on('console', async (consoleMessage) => { diff --git a/tests/resources/OmniFixture-dump.sql b/tests/resources/OmniFixture-dump.sql index e0bcb6846e9..6e28bae6bb0 100644 --- a/tests/resources/OmniFixture-dump.sql +++ b/tests/resources/OmniFixture-dump.sql @@ -29,7 +29,7 @@ CREATE TABLE `access` ( `access` varchar(50) DEFAULT NULL, PRIMARY KEY (`idaccess`), KEY `index_loginidsite` (`login`,`idsite`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -161,7 +161,7 @@ CREATE TABLE `archive_invalidations` ( `report` varchar(255) DEFAULT NULL, PRIMARY KEY (`idinvalidation`), KEY `index_idsite_dates_period_name` (`idsite`,`date1`,`period`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -187,7 +187,7 @@ CREATE TABLE `brute_force_log` ( `login` varchar(100) DEFAULT NULL, PRIMARY KEY (`id_brute_force_log`), KEY `index_ip_address` (`ip_address`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -217,7 +217,7 @@ CREATE TABLE `changes` ( `link` varchar(255) DEFAULT NULL, PRIMARY KEY (`idchange`), UNIQUE KEY `unique_plugin_version_title` (`plugin_name`,`version`,`title`(100)) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -281,7 +281,7 @@ CREATE TABLE `goal` ( `deleted` tinyint(4) NOT NULL DEFAULT '0', `event_value_as_revenue` tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (`idsite`,`idgoal`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -306,7 +306,7 @@ CREATE TABLE `locks` ( `value` varchar(255) DEFAULT NULL, `expiry_time` bigint(20) unsigned DEFAULT '9999999999', PRIMARY KEY (`key`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -333,7 +333,7 @@ CREATE TABLE `log_action` ( `url_prefix` tinyint(2) DEFAULT NULL, PRIMARY KEY (`idaction`), KEY `index_type_hash` (`type`,`hash`) -) ENGINE=InnoDB AUTO_INCREMENT=2764 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=2764 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -406,7 +406,7 @@ CREATE TABLE `log_conversion` ( PRIMARY KEY (`idvisit`,`idgoal`,`buster`), UNIQUE KEY `unique_idsite_idorder` (`idsite`,`idorder`), KEY `index_idsite_datetime` (`idsite`,`server_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -444,7 +444,7 @@ CREATE TABLE `log_conversion_item` ( `deleted` tinyint(1) unsigned NOT NULL, PRIMARY KEY (`idvisit`,`idorder`,`idaction_sku`), KEY `index_idsite_servertime` (`idsite`,`server_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -520,7 +520,7 @@ CREATE TABLE `log_link_visit_action` ( PRIMARY KEY (`idlink_va`), KEY `index_idvisit` (`idvisit`), KEY `index_idsite_servertime` (`idsite`,`server_time`) -) ENGINE=InnoDB AUTO_INCREMENT=2833 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=2833 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -547,7 +547,7 @@ CREATE TABLE `log_profiling` ( `idprofiling` bigint(20) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`idprofiling`), UNIQUE KEY `query` (`query`(100)) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -641,7 +641,7 @@ CREATE TABLE `log_visit` ( KEY `index_idsite_config_datetime` (`idsite`,`config_id`,`visit_last_action_time`), KEY `index_idsite_datetime` (`idsite`,`visit_last_action_time`), KEY `index_idsite_idvisitor_time` (`idsite`,`idvisitor`,`visit_last_action_time`) -) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -668,7 +668,7 @@ CREATE TABLE `logger_message` ( `level` varchar(16) DEFAULT NULL, `message` text, PRIMARY KEY (`idlogger_message`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -693,7 +693,7 @@ CREATE TABLE `option` ( `autoload` tinyint(4) NOT NULL DEFAULT '1', PRIMARY KEY (`option_name`), KEY `autoload` (`autoload`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -722,7 +722,7 @@ CREATE TABLE `plugin_setting` ( `idplugin_setting` bigint(20) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`idplugin_setting`), KEY `plugin_name` (`plugin_name`,`user_login`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -904,7 +904,7 @@ CREATE TABLE `sequence` ( `name` varchar(120) NOT NULL, `value` bigint(20) unsigned NOT NULL, PRIMARY KEY (`name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -929,7 +929,7 @@ CREATE TABLE `session` ( `lifetime` int(11) DEFAULT NULL, `data` mediumtext, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -969,7 +969,7 @@ CREATE TABLE `site` ( `keep_url_fragment` tinyint(4) NOT NULL DEFAULT '0', `creator_login` varchar(100) DEFAULT NULL, PRIMARY KEY (`idsite`) -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -998,7 +998,7 @@ CREATE TABLE `site_setting` ( `idsite_setting` bigint(20) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`idsite_setting`), KEY `idsite` (`idsite`,`plugin_name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1021,7 +1021,7 @@ CREATE TABLE `site_url` ( `idsite` int(10) unsigned NOT NULL, `url` varchar(190) NOT NULL, PRIMARY KEY (`idsite`,`url`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1257,7 +1257,7 @@ CREATE TABLE `tracking_failure` ( `date_first_occurred` datetime NOT NULL, `request_url` mediumtext NOT NULL, PRIMARY KEY (`idsite`,`idfailure`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1281,7 +1281,7 @@ CREATE TABLE `twofactor_recovery_code` ( `login` varchar(100) NOT NULL, `recovery_code` varchar(40) NOT NULL, PRIMARY KEY (`idrecoverycode`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1345,7 +1345,7 @@ CREATE TABLE `user` ( `ts_changes_shown` timestamp NULL DEFAULT NULL, PRIMARY KEY (`login`), UNIQUE KEY `uniq_email` (`email`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1428,7 +1428,7 @@ CREATE TABLE `user_token_auth` ( `secure_only` tinyint(2) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`idusertokenauth`), UNIQUE KEY `uniq_password` (`password`) -) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- diff --git a/tests/resources/overlay-test-site/opt-out.php b/tests/resources/overlay-test-site/opt-out.php index 59341af2c89..0a9957a709a 100644 --- a/tests/resources/overlay-test-site/opt-out.php +++ b/tests/resources/overlay-test-site/opt-out.php @@ -30,7 +30,8 @@ $optOutArgs = [ 'divId' => $_GET['divId'] ?? 'matomo-opt-out', 'showIntro' => '1', - 'useCookiesIfNoTracker' => $loadTracker ? '0' : '1' + 'useCookiesIfNoTracker' => $loadTracker ? '0' : '1', + 'useCookiesTimeout' => $loadTracker ? '' : '1', ]; ?>