diff --git a/.gitignore b/.gitignore index bbc7bd85e08077e40a007d49bd6b403236db65f2..a1cd27d0cde50dd9fc6d49bdb0c06f64b26cd5e5 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,6 @@ php_errors.log /.project /.settings /*.buildpath -/tests/javascript/enable_sqlite /tests/javascript/unittest.dbf /tests/javascript/unittest2.dbf /tests/lib/geoip-files/*.dat* diff --git a/.gitmodules b/.gitmodules index 6f50e7405e51ff1d7cdc44a0b1b3fdcf7f826365..8a6eb6137141d6b09a2268ab6b66675d5ae0b7d8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,6 +29,7 @@ [submodule "tests/UI/expected-ui-screenshots"] path = tests/UI/expected-ui-screenshots url = https://github.com/piwik/piwik-ui-tests.git + branch = master [submodule "tests/travis"] path = tests/travis url = https://github.com/piwik/travis-scripts @@ -40,9 +41,14 @@ [submodule "plugins/AnonymousPiwikUsageMeasurement"] path = plugins/AnonymousPiwikUsageMeasurement url = https://github.com/piwik/plugin-AnonymousPiwikUsageMeasurement.git + branch = master +[submodule "plugins/CustomDimensions"] + path = plugins/CustomDimensions + url = https://github.com/piwik/plugin-CustomDimensions.git + branch = master -# Add new Plugin submodule above this line ^ +# Add new Plugin submodule above this line ^^ # # Note: when you add a submodule that SHOULD be left in the packaged release such as the few submodules below, # then you MUST add these submodules names in the SUBMODULES_PACKAGED_WITH_CORE variable in: @@ -55,3 +61,6 @@ path = misc/log-analytics url = https://github.com/piwik/piwik-log-analytics.git branch = master + +# Note: do not add new plugin submodules here, but a few lines above + diff --git a/.travis.yml b/.travis.yml index 191839ee036e817120086beb0886b40f22174cde..a672f9eb38c70cc2f8e393249334a5c7e818d958 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,8 @@ language: php +group: legacy + php: - 5.6 - 5.5 @@ -17,6 +19,18 @@ php: services: - redis-server +addons: + apt: + sources: + - deadsnakes + + packages: + - python2.6 + - python2.6-dev + - nginx + - realpath + - lftp + # Separate different test suites env: matrix: @@ -25,7 +39,7 @@ env: - TEST_SUITE=IntegrationTests MYSQL_ADAPTER=PDO_MYSQL - TEST_SUITE=UnitTests MYSQL_ADAPTER=PDO_MYSQL # Javascript tests - - TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL SKIP_COMPOSER_INSTALL=1 + - TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL - TEST_SUITE=AngularJSTests MYSQL_ADAPTER=PDO_MYSQL SKIP_COMPOSER_INSTALL=1 # All tests after another - TEST_SUITE=AllTests MYSQL_ADAPTER=PDO_MYSQL @@ -78,11 +92,11 @@ matrix: env: TEST_SUITE=AllTests MYSQL_ADAPTER=MYSQLI # Javascript tests need to run only on one PHP version - php: 5.5 - env: TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL SKIP_COMPOSER_INSTALL=1 + env: TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL - php: hhvm - env: TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL SKIP_COMPOSER_INSTALL=1 + env: TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL - php: 7 - env: TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL SKIP_COMPOSER_INSTALL=1 + env: TEST_SUITE=JavascriptTests MYSQL_ADAPTER=PDO_MYSQL # AngularJS tests need to run only on one PHP version - php: 5.5 env: TEST_SUITE=AngularJSTests MYSQL_ADAPTER=PDO_MYSQL SKIP_COMPOSER_INSTALL=1 @@ -102,11 +116,6 @@ install: #- export GENERATE_TRAVIS_YML_COMMAND="php ./tests/travis/generator/main.php generate:travis-yml --core --verbose" #- '[[ "$TRAVIS_JOB_NUMBER" != *.1 || "$TRAVIS_PULL_REQUEST" != "false" ]] || ./tests/travis/autoupdate_travis_yml.sh' - - '[ ! -f ./tests/travis/install_mysql_5.6.sh ] || ./tests/travis/install_mysql_5.6.sh' - - # Make sure we use Python 2.6 - - '[ ! -f ./tests/travis/install_python_2.6.sh ] || ./tests/travis/install_python_2.6.sh' - - ./tests/travis/configure_git.sh # travis now complains about this failing 9 times out of 10, so removing it @@ -155,7 +164,7 @@ after_script: - cd $PIWIK_ROOT_DIR # output contents of files w/ debugging info to screen - - cat /var/log/nginx/error.log + - cat $PIWIK_ROOT_DIR/tests/travis/error.log - cat $PIWIK_ROOT_DIR/tmp/php-fpm.log - cat $PIWIK_ROOT_DIR/tmp/logs/piwik.log - cat $PIWIK_ROOT_DIR/config/config.ini.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d52a9162bd5841d5a9ff427f1902bbef11d6ee6..96e4d5361d123482bc81d2fdc003a9b6d43123c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,22 @@ This is a changelog for Piwik platform developers. All changes for our HTTP API' ### Internal change * Support for IE8 was dropped. This affects only the Piwik UI, not the Piwik.js Tracker. -* Required PHP version was changed from 5.3 to 5.4 +* Required PHP version was changed from 5.3 to 5.5 + +## Piwik 2.15.1 + +### New features + * New segment `actionType` lets you segment all actions of a given type, eg. `actionType==events` or `actionType==downloads`. Action types values are: `pageviews`, `contents`, `sitesearches`, `events`, `outlinks`, `downloads` + +### Internal change + * When generating a new plugin skeleton via `generate:plugin` command, plugin name must now contain only letters and numbers. + * JavaScript Tracker tests no longer require `SQLite`. The existing MySQL configuration for tests is used now. In order to run the tests make sure Piwik is installed and `[database_tests]` is configured in `config/config.ini.php`. + * The definitions for search engine and social network detection have been moved from bundled data files to a separate package (see [https://github.com/piwik/searchengine-and-social-list](https://github.com/piwik/searchengine-and-social-list)). + * In [UI screenshot tests](https://developer.piwik.org/guides/tests-ui), a test environment `configOverride` setting should be no longer overwritten. Instead new values should be added to the existing `configOverride` array in PHP or JavaScript. For example instead of `testEnvironment.configOverride = {group: {name: 1}}` use `testEnvironment.overrideConfig('group', 'name', '1')`. + +### New APIs + * Add your own SMS/Text provider by creating a new class in the `SMSProvider` directory of your plugin. The class has to extend `Piwik\Plugins\MobileMessaging\SMSProvider` and implement the required methods. + * Segments can now be composed by a union of multiple segments. To do this set an array of segments that shall be used for that segment `$segment->setUnionOfSegments(array('outlinkUrl', 'downloadUrl'))` instead of defining a SQL column. ## Piwik 2.15.0 diff --git a/composer.json b/composer.json index 2d476afbce91a4010dd95efc0292d0115cef12b6..8bcd8c8f27d739b15ac9cbeda6b614afad18badf 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,8 @@ "symfony/event-dispatcher": "~2.6.0", "pear/pear_exception": "~1.0.0", "piwik/referrer-spam-blacklist": "~1.0", - "tecnick.com/tcpdf": "~6.0" + "piwik/searchengine-and-social-list": "~1.0", + "tecnickcom/tcpdf": "~6.0" }, "require-dev": { "aws/aws-sdk-php": "2.7.1", diff --git a/composer.lock b/composer.lock index acb0776a049f0a4dac1c54fb05a45e139ec6b094..2a53020e147a5a3ff1bd452a51a6984baab18788 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "500550a2b3c6f91d0a34461f2e6f8654", + "hash": "ab862f8d87513f76161fb7aed61b226a", "packages": [ { "name": "container-interop/container-interop", @@ -303,16 +303,16 @@ }, { "name": "monolog/monolog", - "version": "1.17.1", + "version": "1.17.2", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422" + "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/0524c87587ab85bc4c2d6f5b41253ccb930a5422", - "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bee7f0dc9c3e0b69a6039697533dca1e845c8c24", + "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24", "shasum": "" }, "require": { @@ -326,10 +326,11 @@ "aws/aws-sdk-php": "^2.4.9", "doctrine/couchdb": "~1.0@dev", "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", "php-console/php-console": "^3.1.3", "phpunit/phpunit": "~4.5", "phpunit/phpunit-mock-objects": "2.3.0", - "raven/raven": "~0.11", + "raven/raven": "^0.13", "ruflin/elastica": ">=0.90 <3.0", "swiftmailer/swiftmailer": "~5.3", "videlalvaro/php-amqplib": "~2.4" @@ -375,7 +376,7 @@ "logging", "psr-3" ], - "time": "2015-08-31 09:17:37" + "time": "2015-10-14 12:51:02" }, { "name": "mustangostang/spyc", @@ -426,21 +427,21 @@ }, { "name": "pear/archive_tar", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/pear/Archive_Tar.git", - "reference": "e337c40bf467a1fcde6b770fce8ca6dc32dcc38f" + "reference": "fc2937c0e5a2a1c62a378d16394893172f970064" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/e337c40bf467a1fcde6b770fce8ca6dc32dcc38f", - "reference": "e337c40bf467a1fcde6b770fce8ca6dc32dcc38f", + "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/fc2937c0e5a2a1c62a378d16394893172f970064", + "reference": "fc2937c0e5a2a1c62a378d16394893172f970064", "shasum": "" }, "require": { - "pear/pear-core-minimal": "^1.9.5", - "php": ">=4.3.0" + "pear/pear-core-minimal": "^1.10.0alpha2", + "php": ">=5.2.0" }, "require-dev": { "phpunit/phpunit": "*" @@ -488,7 +489,7 @@ "archive", "tar" ], - "time": "2015-07-20 07:52:03" + "time": "2015-08-05 12:31:03" }, { "name": "pear/console_getopt", @@ -539,24 +540,24 @@ }, { "name": "pear/pear-core-minimal", - "version": "v1.9.5", + "version": "v1.10.1", "source": { "type": "git", "url": "https://github.com/pear/pear-core-minimal.git", - "reference": "bdfefcacb3b388a1050a58eff9ba5a8f43de2411" + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/bdfefcacb3b388a1050a58eff9ba5a8f43de2411", - "reference": "bdfefcacb3b388a1050a58eff9ba5a8f43de2411", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/cae0f1ce0cb5bddb611b0a652d322905a65a5896", + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896", "shasum": "" }, "require": { "pear/console_getopt": "~1.3", "pear/pear_exception": "~1.0" }, - "provide": { - "rsky/pear-core-min": "*" + "replace": { + "rsky/pear-core-min": "self.version" }, "type": "library", "autoload": { @@ -569,7 +570,7 @@ "src/" ], "license": [ - "New BSD" + "BSD-3-Clause" ], "authors": [ { @@ -579,7 +580,7 @@ } ], "description": "Minimal set of PEAR core files to be used as composer dependency", - "time": "2015-02-10 20:55:39" + "time": "2015-10-17 11:41:19" }, { "name": "pear/pear_exception", @@ -638,16 +639,16 @@ }, { "name": "php-di/invoker", - "version": "1.0.1", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/PHP-DI/Invoker.git", - "reference": "2eb8f3a9b44c1427865134ef585d986ca89bce36" + "reference": "9949fff87fcf14e8f2ccfbe36dac1e5921944c48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/2eb8f3a9b44c1427865134ef585d986ca89bce36", - "reference": "2eb8f3a9b44c1427865134ef585d986ca89bce36", + "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/9949fff87fcf14e8f2ccfbe36dac1e5921944c48", + "reference": "9949fff87fcf14e8f2ccfbe36dac1e5921944c48", "shasum": "" }, "require": { @@ -677,7 +678,7 @@ "invoke", "invoker" ], - "time": "2015-09-02 16:01:10" + "time": "2015-10-22 19:49:23" }, { "name": "php-di/php-di", @@ -738,16 +739,16 @@ }, { "name": "piwik/cache", - "version": "0.2.5", + "version": "0.2.6", "source": { "type": "git", "url": "https://github.com/piwik/component-cache.git", - "reference": "e97ed763c6e710734194664099edd5ee7a41d6b0" + "reference": "b8f2d18069c77726862f67d0199896d13073a831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/piwik/component-cache/zipball/e97ed763c6e710734194664099edd5ee7a41d6b0", - "reference": "e97ed763c6e710734194664099edd5ee7a41d6b0", + "url": "https://api.github.com/repos/piwik/component-cache/zipball/b8f2d18069c77726862f67d0199896d13073a831", + "reference": "b8f2d18069c77726862f67d0199896d13073a831", "shasum": "" }, "require": { @@ -781,7 +782,7 @@ "file", "redis" ], - "time": "2015-02-11 22:35:22" + "time": "2015-09-29 16:50:32" }, { "name": "piwik/decompress", @@ -957,6 +958,28 @@ "description": "Community-contributed list of referrer spammers", "time": "2015-10-07 10:17:59" }, + { + "name": "piwik/searchengine-and-social-list", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/piwik/searchengine-and-social-list.git", + "reference": "e2b97a1cd9ed2dde735de49f8ef9afc26b3df80b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/piwik/searchengine-and-social-list/zipball/e2b97a1cd9ed2dde735de49f8ef9afc26b3df80b", + "reference": "e2b97a1cd9ed2dde735de49f8ef9afc26b3df80b", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Public Domain" + ], + "description": "Search engine and social network definitions used by Piwik", + "time": "2015-11-06 21:32:51" + }, { "name": "psr/log", "version": "1.0.0", @@ -1001,12 +1024,12 @@ "target-dir": "Symfony/Component/Console", "source": { "type": "git", - "url": "https://github.com/symfony/Console.git", + "url": "https://github.com/symfony/console.git", "reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/0e5e18ae09d3f5c06367759be940e9ed3f568359", + "url": "https://api.github.com/repos/symfony/console/zipball/0e5e18ae09d3f5c06367759be940e9ed3f568359", "reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359", "shasum": "" }, @@ -1059,12 +1082,12 @@ "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", + "url": "https://github.com/symfony/event-dispatcher.git", "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02", "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02", "shasum": "" }, @@ -1118,12 +1141,12 @@ "target-dir": "Symfony/Bridge/Monolog", "source": { "type": "git", - "url": "https://github.com/symfony/MonologBridge.git", + "url": "https://github.com/symfony/monolog-bridge.git", "reference": "ba66eeabaa004e3ab70764cab59b056b182aa535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/MonologBridge/zipball/ba66eeabaa004e3ab70764cab59b056b182aa535", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/ba66eeabaa004e3ab70764cab59b056b182aa535", "reference": "ba66eeabaa004e3ab70764cab59b056b182aa535", "shasum": "" }, @@ -1172,17 +1195,17 @@ "time": "2015-06-25 11:21:15" }, { - "name": "tecnick.com/tcpdf", - "version": "6.2.11", + "name": "tecnickcom/tcpdf", + "version": "6.2.12", "source": { "type": "git", "url": "https://github.com/tecnickcom/TCPDF.git", - "reference": "354433a33946ae7497c3eab291eaaf814bccbfab" + "reference": "2f732eaa91b5665274689b1d40b285a7bacdc37f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/354433a33946ae7497c3eab291eaaf814bccbfab", - "reference": "354433a33946ae7497c3eab291eaaf814bccbfab", + "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/2f732eaa91b5665274689b1d40b285a7bacdc37f", + "reference": "2f732eaa91b5665274689b1d40b285a7bacdc37f", "shasum": "" }, "require": { @@ -1232,8 +1255,7 @@ "pdf417", "qrcode" ], - "abandoned": "tecnickcom/tcpdf", - "time": "2015-08-02 12:30:27" + "time": "2015-09-12 10:08:34" }, { "name": "tedivm/jshrink", @@ -1278,16 +1300,16 @@ }, { "name": "twig/twig", - "version": "v1.21.1", + "version": "v1.22.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ca8d3aa90b6a01c82e07909fe815d6b443e75a23" + "reference": "ebfc36b7e77b0c1175afe30459cf943010245540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ca8d3aa90b6a01c82e07909fe815d6b443e75a23", - "reference": "ca8d3aa90b6a01c82e07909fe815d6b443e75a23", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ebfc36b7e77b0c1175afe30459cf943010245540", + "reference": "ebfc36b7e77b0c1175afe30459cf943010245540", "shasum": "" }, "require": { @@ -1300,7 +1322,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.21-dev" + "dev-master": "1.22-dev" } }, "autoload": { @@ -1335,7 +1357,7 @@ "keywords": [ "templating" ], - "time": "2015-08-26 08:58:31" + "time": "2015-10-13 07:07:02" } ], "packages-dev": [ @@ -1487,7 +1509,7 @@ "performance", "profiling" ], - "time": "2015-02-26 14:37:51" + "time": "2014-08-28 17:34:52" }, { "name": "guzzle/guzzle", @@ -1793,16 +1815,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "2.2.2", + "version": "2.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c" + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c", - "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", "shasum": "" }, "require": { @@ -1851,7 +1873,7 @@ "testing", "xunit" ], - "time": "2015-08-04 03:42:39" + "time": "2015-10-06 15:47:00" }, { "name": "phpunit/php-file-iterator", @@ -1984,16 +2006,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.4.6", + "version": "1.4.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b" + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b", - "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", "shasum": "" }, "require": { @@ -2029,20 +2051,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-08-16 08:51:00" + "time": "2015-09-15 10:49:45" }, { "name": "phpunit/phpunit", - "version": "4.8.6", + "version": "4.8.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "2246830f4a1a551c67933e4171bf2126dc29d357" + "reference": "625f8c345606ed0f3a141dfb88f4116f0e22978e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2246830f4a1a551c67933e4171bf2126dc29d357", - "reference": "2246830f4a1a551c67933e4171bf2126dc29d357", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/625f8c345606ed0f3a141dfb88f4116f0e22978e", + "reference": "625f8c345606ed0f3a141dfb88f4116f0e22978e", "shasum": "" }, "require": { @@ -2101,20 +2123,20 @@ "testing", "xunit" ], - "time": "2015-08-24 04:09:38" + "time": "2015-10-23 06:48:33" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.7", + "version": "2.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "5e2645ad49d196e020b85598d7c97e482725786a" + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5e2645ad49d196e020b85598d7c97e482725786a", - "reference": "5e2645ad49d196e020b85598d7c97e482725786a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", "shasum": "" }, "require": { @@ -2157,7 +2179,7 @@ "mock", "xunit" ], - "time": "2015-08-19 09:14:08" + "time": "2015-10-02 06:51:40" }, { "name": "sebastian/comparator", @@ -2393,16 +2415,16 @@ }, { "name": "sebastian/global-state", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { @@ -2440,7 +2462,7 @@ "keywords": [ "global state" ], - "time": "2014-10-06 09:23:50" + "time": "2015-10-12 03:26:01" }, { "name": "sebastian/recursion-context", diff --git a/config/environment/ui-test.php b/config/environment/ui-test.php new file mode 100644 index 0000000000000000000000000000000000000000..b5ef0fede4f267d9ead645eb1d152582ebd0b49b --- /dev/null +++ b/config/environment/ui-test.php @@ -0,0 +1,62 @@ +<?php + +use Piwik\Container\StaticContainer; + +return array( + + // UI tests will remove the port from all URLs to the test server. if a test + // requires the ports in UI tests (eg, Overlay), add the api/controller methods + // to one of these blacklists + 'tests.ui.url_normalizer_blacklist.api' => array(), + 'tests.ui.url_normalizer_blacklist.controller' => array(), + + 'Piwik\Config' => \DI\decorate(function (\Piwik\Config $config) { + $config->General['cors_domains'][] = '*'; + $config->General['trusted_hosts'][] = $config->tests['http_host']; + $config->General['trusted_hosts'][] = $config->tests['http_host'] . ':' . $config->tests['port']; + return $config; + }), + + 'observers.global' => \DI\add(array( + + // removes port from all URLs to the test Piwik server so UI tests will pass no matter + // what port is used + array('Request.dispatch.end', function (&$result) { + $request = $_GET + $_POST; + + $apiblacklist = StaticContainer::get('tests.ui.url_normalizer_blacklist.api'); + if (!empty($request['method']) + && in_array($request['method'], $apiblacklist) + ) { + return; + } + + $controllerActionblacklist = StaticContainer::get('tests.ui.url_normalizer_blacklist.controller'); + if (!empty($request['module']) + && !empty($request['action']) + ) { + $controllerAction = $request['module'] . '.' . $request['action']; + if (in_array($controllerAction, $controllerActionblacklist)) { + return; + } + } + + $config = \Piwik\Config::getInstance(); + $host = $config->tests['http_host']; + $port = $config->tests['port']; + + if (!empty($port)) { + // remove the port from URLs if any so UI tests won't fail if the port isn't 80 + $result = str_replace($host . ':' . $port, $host, $result); + } + + // remove PIWIK_INCLUDE_PATH from result so tests don't change based on the machine used + $result = str_replace(realpath(PIWIK_INCLUDE_PATH), '', $result); + }), + + array('Controller.ExampleRssWidget.rssPiwik.end', function (&$result, $parameters) { + $result = ""; + }), + )), + +); diff --git a/config/global.ini.php b/config/global.ini.php index 7dd55d37190af4c857f4ac68efaac28f1c2d0da2..aad0fd33819af603d2863019042865ee83858ceb 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -44,6 +44,7 @@ schema = Mysql http_host = localhost remote_addr = "127.0.0.1" request_uri = "@REQUEST_URI@" +port = ; access key and secret as listed in AWS -> IAM -> Users aws_accesskey = "" @@ -248,8 +249,9 @@ default_language = en datatable_default_limit = 10 ; Each datatable report has a Row Limit selector at the bottom right. -; By default you can select from 5 to 500 rows. You may customise the values below: -datatable_row_limits = "5,10,25,50,100,250,500" +; By default you can select from 5 to 500 rows. You may customise the values below +; -1 will be displayed as 'all' and it will export all rows (filter_limit=-1) +datatable_row_limits = "5,10,25,50,100,250,500,-1" ; default number of rows returned in API responses ; this value is overwritten by the '# Rows to display' selector. diff --git a/config/global.php b/config/global.php index a54565498fcd5ffa016e08475ef5727207b2769d..36e04970aafd2838db6ebe744c8609320db061d9 100644 --- a/config/global.php +++ b/config/global.php @@ -73,9 +73,6 @@ return array( )))); }, - // contains RequestProcessor instances, currently used by Piwik\Tracker\Visit - 'tracker.request.processors' => array(), - 'Piwik\Tracker\VisitorRecognizer' => DI\object() ->constructorParameter('trustCookiesOnly', DI\get('ini.Tracker.trust_visitors_cookies')) ->constructorParameter('visitStandardLength', DI\get('ini.Tracker.visit_standard_length')) diff --git a/core/API/DataTableManipulator.php b/core/API/DataTableManipulator.php index 76c52f49586b9f98c010a4c15b38ac8ef072ab29..d084d6d15692dc85189305c168d6ac683fbbaa4b 100644 --- a/core/API/DataTableManipulator.php +++ b/core/API/DataTableManipulator.php @@ -152,7 +152,15 @@ abstract class DataTableManipulator $idSite = 'all'; } - $meta = API::getInstance()->getMetadata($idSite, $this->apiModule, $this->apiMethod); + $apiParameters = array(); + if (!empty($request['idDimension'])) { + $apiParameters['idDimension'] = $request['idDimension']; + } + if (!empty($request['idGoal'])) { + $apiParameters['idGoal'] = $request['idGoal']; + } + + $meta = API::getInstance()->getMetadata($idSite, $this->apiModule, $this->apiMethod, $apiParameters); if (empty($meta)) { throw new Exception(sprintf( diff --git a/core/API/DocumentationGenerator.php b/core/API/DocumentationGenerator.php index 64c25bf9b04f34ae312e1f9d126e5353df1bd723..60807267df303c76381a37445d9808455ea1a267 100644 --- a/core/API/DocumentationGenerator.php +++ b/core/API/DocumentationGenerator.php @@ -291,6 +291,7 @@ class DocumentationGenerator $aParameters['disable_queued_filters'] = false; $aParameters['disable_generic_filters'] = false; $aParameters['expanded'] = false; + $aParameters['idDimenson'] = false; $moduleName = Proxy::getInstance()->getModuleNameFromClassName($class); $aParameters = array_merge(array('module' => 'API', 'method' => $moduleName . '.' . $methodName), $aParameters); diff --git a/core/API/Proxy.php b/core/API/Proxy.php index 26e2ceb4cca9d2b3542ff7f5346daa7137256979..1d348e1b871aa27b804baaaf6c71a5b029fddaa8 100644 --- a/core/API/Proxy.php +++ b/core/API/Proxy.php @@ -262,7 +262,7 @@ class Proxy extends Singleton * **Example** * * // append (0 hits) to the end of row labels whose row has 0 hits for any report that has the 'nb_hits' metric - * Piwik::addAction('API.Actions.getPageUrls', function (&$returnValue, $info)) { + * Piwik::addAction('API.Actions.getPageUrls.end', function (&$returnValue, $info)) { * // don't process non-DataTable reports and reports that don't have the nb_hits column * if (!($returnValue instanceof DataTableInterface) * || in_array('nb_hits', $returnValue->getColumns()) diff --git a/core/API/Request.php b/core/API/Request.php index 834d83290eb2aa577fbfc9b8e822e8b514f80e5d..6ddb8333f504275037c5f534a44f49c67c1f03a6 100644 --- a/core/API/Request.php +++ b/core/API/Request.php @@ -36,12 +36,10 @@ use Piwik\Plugin\Manager as PluginManager; * ### Post-processing * * The return value of API methods undergo some extra processing before being returned by Request. - * To learn more about what happens to API results, read [this](/guides/piwiks-web-api#extra-report-processing). * * ### Output Formats * * The value returned by Request will be serialized to a certain format before being returned. - * To see the list of supported output formats, read [this](/guides/piwiks-web-api#output-formats). * * ### Examples * @@ -390,6 +388,7 @@ class Request { $params = array(); $params['format'] = 'original'; + $params['serialize'] = '0'; $params['module'] = 'API'; $params['method'] = $method; $params = $paramOverride + $params; diff --git a/core/Archive.php b/core/Archive.php index 80ef151f388792b03bd89454cb268c0be29d1da8..2efe23031809525dc75277f737656015cd999eb5 100644 --- a/core/Archive.php +++ b/core/Archive.php @@ -619,7 +619,7 @@ class Archive if ($isNumeric) { $row['value'] = $this->formatNumericValue($row['value']); } else { - $result->addMetadata($row['idsite'], $periodStr, 'ts_archived', $row['ts_archived']); + $result->addMetadata($row['idsite'], $periodStr, DataTable::ARCHIVED_DATE_METADATA_NAME, $row['ts_archived']); } $result->set($row['idsite'], $periodStr, $row['name'], $row['value']); diff --git a/core/Columns/Dimension.php b/core/Columns/Dimension.php index c4895371adcd9e093d6d0b50bf28b45c44477dea..c89ae637a51ada894f9ae8cc9840bed4edb9bd21 100644 --- a/core/Columns/Dimension.php +++ b/core/Columns/Dimension.php @@ -149,7 +149,7 @@ abstract class Dimension * This would only happen if the dimension is located in the wrong directory. * @api */ - final public function getId() + public function getId() { $className = get_class($this); diff --git a/core/Common.php b/core/Common.php index 7e3296bee15a0e7ace4c6991e032031d069e46ad..85120c97fa8fa30331c558cf4af6161b449b1faf 100644 --- a/core/Common.php +++ b/core/Common.php @@ -273,12 +273,6 @@ class Common return $value; } elseif (is_string($value)) { $value = self::sanitizeString($value); - - if (!$alreadyStripslashed) { - // a JSON array was already stripslashed, don't do it again for each value - - $value = self::undoMagicQuotes($value); - } } elseif (is_array($value)) { foreach (array_keys($value) as $key) { $newKey = $key; @@ -378,27 +372,6 @@ class Common } } - /** - * Undo the damage caused by magic_quotes; deprecated in php 5.3 but not removed until php 5.4 - * - * @param string - * @return string modified or not - */ - private static function undoMagicQuotes($value) - { - static $shouldUndo; - - if (!isset($shouldUndo)) { - $shouldUndo = version_compare(PHP_VERSION, '5.4', '<') && get_magic_quotes_gpc(); - } - - if ($shouldUndo) { - $value = stripslashes($value); - } - - return $value; - } - /** * @param string $value * @return string Line breaks and line carriage removed @@ -475,7 +448,7 @@ class Common // we deal w/ json differently if ($varType == 'json') { - $value = self::undoMagicQuotes($requestArrayToUse[$varName]); + $value = $requestArrayToUse[$varName]; $value = json_decode($value, $assoc = true); return self::sanitizeInputValues($value, $alreadyStripslashed = true); } @@ -815,86 +788,6 @@ class Common return $dataProvider->getLanguageToCountryList(); } - /** - * Returns list of search engines by URL - * - * @see core/DataFiles/SearchEngines.php - * - * @return array Array of ( URL => array( searchEngineName, keywordParameter, path, charset ) ) - */ - public static function getSearchEngineUrls() - { - $cacheId = 'Common.getSearchEngineUrls'; - $cache = Cache::getTransientCache(); - $searchEngines = $cache->fetch($cacheId); - - if (empty($searchEngines)) { - require_once PIWIK_INCLUDE_PATH . '/core/DataFiles/SearchEngines.php'; - - $searchEngines = $GLOBALS['Piwik_SearchEngines']; - - Piwik::postEvent('Referrer.addSearchEngineUrls', array(&$searchEngines)); - - $cache->save($cacheId, $searchEngines); - } - - return $searchEngines; - } - - /** - * Returns list of search engines by name - * - * @see core/DataFiles/SearchEngines.php - * - * @return array Array of ( searchEngineName => URL ) - */ - public static function getSearchEngineNames() - { - $cacheId = 'Common.getSearchEngineNames'; - $cache = Cache::getTransientCache(); - $nameToUrl = $cache->fetch($cacheId); - - if (empty($nameToUrl)) { - $searchEngines = self::getSearchEngineUrls(); - - $nameToUrl = array(); - foreach ($searchEngines as $url => $info) { - if (!isset($nameToUrl[$info[0]])) { - $nameToUrl[$info[0]] = $url; - } - } - $cache->save($cacheId, $nameToUrl); - } - - return $nameToUrl; - } - - /** - * Returns list of social networks by URL - * - * @see core/DataFiles/Socials.php - * - * @return array Array of ( URL => Social Network Name ) - */ - public static function getSocialUrls() - { - $cacheId = 'Common.getSocialUrls'; - $cache = Cache::getTransientCache(); - $socialUrls = $cache->fetch($cacheId); - - if (empty($socialUrls)) { - require_once PIWIK_INCLUDE_PATH . '/core/DataFiles/Socials.php'; - - $socialUrls = $GLOBALS['Piwik_socialUrl']; - - Piwik::postEvent('Referrer.addSocialUrls', array(&$socialUrls)); - - $cache->save($cacheId, $socialUrls); - } - - return $socialUrls; - } - /** * Returns list of provider names * diff --git a/core/Container/ContainerFactory.php b/core/Container/ContainerFactory.php index 75735036aaf29e9a2926c73bedf2115ce6741380..9c5eed12766f9d6195cb434d8f808fe2efe3b607 100644 --- a/core/Container/ContainerFactory.php +++ b/core/Container/ContainerFactory.php @@ -79,12 +79,7 @@ class ContainerFactory // Development config if ($this->isDevelopmentModeEnabled()) { - $builder->addDefinitions(PIWIK_USER_PATH . '/config/environment/dev.php'); - } - - // User config - if (file_exists(PIWIK_USER_PATH . '/config/config.php')) { - $builder->addDefinitions(PIWIK_USER_PATH . '/config/config.php'); + $this->addEnvironmentConfig($builder, 'dev'); } // Environment config @@ -92,6 +87,11 @@ class ContainerFactory $this->addEnvironmentConfig($builder, $environment); } + // User config + if (file_exists(PIWIK_USER_PATH . '/config/config.php')) { + $builder->addDefinitions(PIWIK_USER_PATH . '/config/config.php'); + } + if (!empty($this->definitions)) { foreach ($this->definitions as $definitionArray) { $builder->addDefinitions($definitionArray); diff --git a/core/CronArchive.php b/core/CronArchive.php index 4b9d3556d3f43413918c9e9967dd8afa12ca429f..c929f88809bd400a7dc0d303975e3132961411c4 100644 --- a/core/CronArchive.php +++ b/core/CronArchive.php @@ -367,7 +367,7 @@ class CronArchive continue; } - $shouldCheckIfArchivingIsNeeded = !$this->shouldArchiveSpecifiedSites && !$this->shouldArchiveAllSites; + $shouldCheckIfArchivingIsNeeded = !$this->shouldArchiveSpecifiedSites && !$this->shouldArchiveAllSites && !$this->dateLastForced; $hasWebsiteDayFinishedSinceLastRun = in_array($idSite, $this->websiteDayHasFinishedSinceLastRun); $isOldReportInvalidatedForWebsite = $this->isOldReportInvalidatedForWebsite($idSite); diff --git a/core/DataAccess/LogQueryBuilder.php b/core/DataAccess/LogQueryBuilder.php index 5e36b4617cc86d0a34df72f80c8f03c9410a00be..c491b934ce358cb50d9f8437dd12df90ab7a77f2 100644 --- a/core/DataAccess/LogQueryBuilder.php +++ b/core/DataAccess/LogQueryBuilder.php @@ -44,6 +44,39 @@ class LogQueryBuilder ); } + private function hasJoinedTableAlreadyManually($tableToFind, $joinToFind, $tables) + { + foreach ($tables as $index => $table) { + if (is_array($table) + && !empty($table['table']) + && $table['table'] === $tableToFind + && (!isset($table['tableAlias']) || $table['tableAlias'] === $tableToFind) + && isset($table['joinOn']) && $table['joinOn'] === $joinToFind) { + return true; + } + } + + return false; + } + + private function findIndexOfManuallyAddedTable($tableToFind, $tables) + { + foreach ($tables as $index => $table) { + if (is_array($table) + && !empty($table['table']) + && $table['table'] === $tableToFind + && (!isset($table['tableAlias']) || $table['tableAlias'] === $tableToFind)) { + return $index; + } + } + } + + private function hasTableAddedManually($tableToFind, $tables) + { + $table = $this->findIndexOfManuallyAddedTable($tableToFind, $tables); + + return isset($table); + } /** * Generate the join sql based on the needed tables @@ -51,10 +84,12 @@ class LogQueryBuilder * @throws Exception if tables can't be joined * @return array */ - private function generateJoinsString($tables) + private function generateJoinsString(&$tables) { - $knownTables = array("log_visit", "log_link_visit_action", "log_conversion", "log_conversion_item"); - $visitsAvailable = $actionsAvailable = $conversionsAvailable = $conversionItemAvailable = false; + $knownTables = array("log_action", "log_visit", "log_link_visit_action", "log_conversion", "log_conversion_item"); + $visitsAvailable = $linkVisitActionsTableAvailable = $conversionsAvailable = $conversionItemAvailable = $actionsTableAvailable = false; + $defaultLogActionJoin = "log_link_visit_action.idaction_url = log_action.idaction"; + $joinWithSubSelect = false; $sql = ''; @@ -67,7 +102,6 @@ class LogQueryBuilder $tables[$actionIndex] = "log_conversion"; $tables[$conversionIndex] = "log_link_visit_action"; } - // same as above: action before visit $actionIndex = array_search("log_link_visit_action", $tables); $visitIndex = array_search("log_visit", $tables); @@ -76,6 +110,29 @@ class LogQueryBuilder $tables[$visitIndex] = "log_link_visit_action"; } + // we need to add log_link_visit_action dynamically to join eg visit with action + $linkVisitAction = array_search("log_link_visit_action", $tables); + $actionIndex = array_search("log_action", $tables); + if ($linkVisitAction === false && $actionIndex > 0) { + $tables[] = "log_link_visit_action"; + } + + if ($actionIndex > 0 + && $this->hasTableAddedManually('log_action', $tables) + && !$this->hasJoinedTableAlreadyManually('log_action', $defaultLogActionJoin, $tables)) { + // we cannot join the same table with same alias twice, therefore we need to combine the join via AND + $tableIndex = $this->findIndexOfManuallyAddedTable('log_action', $tables); + $defaultLogActionJoin = '(' . $tables[$tableIndex]['joinOn'] . ' AND ' . $defaultLogActionJoin . ')'; + unset($tables[$tableIndex]); + } + + $linkVisitAction = array_search("log_link_visit_action", $tables); + $actionIndex = array_search("log_action", $tables); + if ($linkVisitAction > 0 && $actionIndex > 0 && $linkVisitAction > $actionIndex) { + $tables[$actionIndex] = "log_link_visit_action"; + $tables[$linkVisitAction] = "log_action"; + } + foreach ($tables as $i => $table) { if (is_array($table)) { // join condition provided @@ -96,17 +153,38 @@ class LogQueryBuilder // first table $sql .= $tableSql; } else { - if ($actionsAvailable && $table == "log_conversion") { + + if ($linkVisitActionsTableAvailable && $table === 'log_action') { + $join = $defaultLogActionJoin; + + if ($this->hasJoinedTableAlreadyManually($table, $join, $tables)) { + $actionsTableAvailable = true; + continue; + } + + } elseif ($linkVisitActionsTableAvailable && $table == "log_conversion") { // have actions, need conversions => join on idvisit $join = "log_conversion.idvisit = log_link_visit_action.idvisit"; - } elseif ($actionsAvailable && $table == "log_visit") { + } elseif ($linkVisitActionsTableAvailable && $table == "log_visit") { // have actions, need visits => join on idvisit $join = "log_visit.idvisit = log_link_visit_action.idvisit"; + + if ($this->hasJoinedTableAlreadyManually($table, $join, $tables)) { + $visitsAvailable = true; + continue; + } + } elseif ($visitsAvailable && $table == "log_link_visit_action") { // have visits, need actions => we have to use a more complex join // we don't hande this here, we just return joinWithSubSelect=true in this case $joinWithSubSelect = true; $join = "log_link_visit_action.idvisit = log_visit.idvisit"; + + if ($this->hasJoinedTableAlreadyManually($table, $join, $tables)) { + $linkVisitActionsTableAvailable = true; + continue; + } + } elseif ($conversionsAvailable && $table == "log_link_visit_action") { // have conversions, need actions => join on idvisit $join = "log_conversion.idvisit = log_link_visit_action.idvisit"; @@ -138,7 +216,8 @@ class LogQueryBuilder // remember which tables are available $visitsAvailable = ($visitsAvailable || $table == "log_visit"); - $actionsAvailable = ($actionsAvailable || $table == "log_link_visit_action"); + $linkVisitActionsTableAvailable = ($linkVisitActionsTableAvailable || $table == "log_link_visit_action"); + $actionsTableAvailable = ($actionsTableAvailable || $table == "log_action"); $conversionsAvailable = ($conversionsAvailable || $table == "log_conversion"); $conversionItemAvailable = ($conversionItemAvailable || $table == "log_conversion_item"); } diff --git a/core/DataArray.php b/core/DataArray.php index 386eae29a3123031388c96d74fdc55d7638b714f..1be1942312e668aec084c37091ce80308d70a2df 100644 --- a/core/DataArray.php +++ b/core/DataArray.php @@ -47,7 +47,7 @@ class DataArray public function sumMetricsVisits($label, $row) { if (!isset($this->data[$label])) { - $this->data[$label] = self::makeEmptyRow(); + $this->data[$label] = static::makeEmptyRow(); } $this->doSumVisitsMetrics($row, $this->data[$label]); } @@ -80,7 +80,7 @@ class DataArray * * @return void */ - protected function doSumVisitsMetrics($newRowToAdd, &$oldRowToUpdate, $onlyMetricsAvailableInActionsTable = false) + protected function doSumVisitsMetrics($newRowToAdd, &$oldRowToUpdate) { // Pre 1.2 format: string indexed rows are returned from the DB // Left here for Backward compatibility with plugins doing custom SQL queries using these metrics as string @@ -88,9 +88,6 @@ class DataArray $oldRowToUpdate[Metrics::INDEX_NB_VISITS] += $newRowToAdd['nb_visits']; $oldRowToUpdate[Metrics::INDEX_NB_ACTIONS] += $newRowToAdd['nb_actions']; $oldRowToUpdate[Metrics::INDEX_NB_UNIQ_VISITORS] += $newRowToAdd['nb_uniq_visitors']; - if ($onlyMetricsAvailableInActionsTable) { - return; - } $oldRowToUpdate[Metrics::INDEX_NB_USERS] += $newRowToAdd['nb_users']; $oldRowToUpdate[Metrics::INDEX_MAX_ACTIONS] = (float)max($newRowToAdd['max_actions'], $oldRowToUpdate[Metrics::INDEX_MAX_ACTIONS]); $oldRowToUpdate[Metrics::INDEX_SUM_VISIT_LENGTH] += $newRowToAdd['sum_visit_length']; @@ -107,9 +104,6 @@ class DataArray $oldRowToUpdate[Metrics::INDEX_NB_VISITS] += $newRowToAdd[Metrics::INDEX_NB_VISITS]; $oldRowToUpdate[Metrics::INDEX_NB_ACTIONS] += $newRowToAdd[Metrics::INDEX_NB_ACTIONS]; $oldRowToUpdate[Metrics::INDEX_NB_UNIQ_VISITORS] += $newRowToAdd[Metrics::INDEX_NB_UNIQ_VISITORS]; - if ($onlyMetricsAvailableInActionsTable) { - return; - } // In case the existing Row had no action metrics (eg. Custom Variable XYZ with "visit" scope) // but the new Row has action metrics (eg. same Custom Variable XYZ this time with a "page" scope) @@ -133,11 +127,50 @@ class DataArray $oldRowToUpdate[Metrics::INDEX_NB_VISITS_CONVERTED] += $newRowToAdd[Metrics::INDEX_NB_VISITS_CONVERTED]; } + /** + * Adds the given row $newRowToAdd to the existing $oldRowToUpdate passed by reference + * The rows are php arrays Name => value + * + * @param array $newRowToAdd + * @param array $oldRowToUpdate + * @param bool $onlyMetricsAvailableInActionsTable + * + * @return void + */ + protected function doSumActionsMetrics($newRowToAdd, &$oldRowToUpdate) + { + // Pre 1.2 format: string indexed rows are returned from the DB + // Left here for Backward compatibility with plugins doing custom SQL queries using these metrics as string + if (!isset($newRowToAdd[Metrics::INDEX_NB_VISITS])) { + $oldRowToUpdate[Metrics::INDEX_NB_VISITS] += $newRowToAdd['nb_visits']; + $oldRowToUpdate[Metrics::INDEX_NB_ACTIONS] += $newRowToAdd['nb_actions']; + $oldRowToUpdate[Metrics::INDEX_NB_UNIQ_VISITORS] += $newRowToAdd['nb_uniq_visitors']; + return; + } + + // Edge case fail safe + if (!isset($oldRowToUpdate[Metrics::INDEX_NB_VISITS])) { + return; + } + + $oldRowToUpdate[Metrics::INDEX_NB_VISITS] += $newRowToAdd[Metrics::INDEX_NB_VISITS]; + if (array_key_exists(Metrics::INDEX_NB_ACTIONS, $newRowToAdd)) { + $oldRowToUpdate[Metrics::INDEX_NB_ACTIONS] += $newRowToAdd[Metrics::INDEX_NB_ACTIONS]; + } + if (array_key_exists(Metrics::INDEX_PAGE_NB_HITS, $newRowToAdd)) { + if (!array_key_exists(Metrics::INDEX_PAGE_NB_HITS, $oldRowToUpdate)) { + $oldRowToUpdate[Metrics::INDEX_PAGE_NB_HITS] = 0; + } + $oldRowToUpdate[Metrics::INDEX_PAGE_NB_HITS] += $newRowToAdd[Metrics::INDEX_PAGE_NB_HITS]; + } + $oldRowToUpdate[Metrics::INDEX_NB_UNIQ_VISITORS] += $newRowToAdd[Metrics::INDEX_NB_UNIQ_VISITORS]; + } + public function sumMetricsGoals($label, $row) { $idGoal = $row['idgoal']; if (!isset($this->data[$label][Metrics::INDEX_GOALS][$idGoal])) { - $this->data[$label][Metrics::INDEX_GOALS][$idGoal] = self::makeEmptyGoalRow($idGoal); + $this->data[$label][Metrics::INDEX_GOALS][$idGoal] = static::makeEmptyGoalRow($idGoal); } $this->doSumGoalsMetrics($row, $this->data[$label][Metrics::INDEX_GOALS][$idGoal]); } @@ -201,9 +234,10 @@ class DataArray public function sumMetricsActions($label, $row) { if (!isset($this->data[$label])) { - $this->data[$label] = self::makeEmptyActionRow(); + $this->data[$label] = static::makeEmptyActionRow(); } - $this->doSumVisitsMetrics($row, $this->data[$label], $onlyMetricsAvailableInActionsTable = true); + + $this->doSumActionsMetrics($row, $this->data[$label]); } protected static function makeEmptyActionRow() @@ -218,7 +252,7 @@ class DataArray public function sumMetricsEvents($label, $row) { if (!isset($this->data[$label])) { - $this->data[$label] = self::makeEmptyEventRow(); + $this->data[$label] = static::makeEmptyEventRow(); } $this->doSumEventsMetrics($row, $this->data[$label], $onlyMetricsAvailableInActionsTable = true); } @@ -250,16 +284,16 @@ class DataArray $oldRowToUpdate[Metrics::INDEX_EVENT_NB_HITS] += $newRowToAdd[Metrics::INDEX_EVENT_NB_HITS]; $oldRowToUpdate[Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE] += $newRowToAdd[Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE]; - $newRowToAdd[Metrics::INDEX_EVENT_SUM_EVENT_VALUE] = round($newRowToAdd[Metrics::INDEX_EVENT_SUM_EVENT_VALUE], self::EVENT_VALUE_PRECISION); + $newRowToAdd[Metrics::INDEX_EVENT_SUM_EVENT_VALUE] = round($newRowToAdd[Metrics::INDEX_EVENT_SUM_EVENT_VALUE], static::EVENT_VALUE_PRECISION); $oldRowToUpdate[Metrics::INDEX_EVENT_SUM_EVENT_VALUE] += $newRowToAdd[Metrics::INDEX_EVENT_SUM_EVENT_VALUE]; - $oldRowToUpdate[Metrics::INDEX_EVENT_MAX_EVENT_VALUE] = round(max($newRowToAdd[Metrics::INDEX_EVENT_MAX_EVENT_VALUE], $oldRowToUpdate[Metrics::INDEX_EVENT_MAX_EVENT_VALUE]), self::EVENT_VALUE_PRECISION); + $oldRowToUpdate[Metrics::INDEX_EVENT_MAX_EVENT_VALUE] = round(max($newRowToAdd[Metrics::INDEX_EVENT_MAX_EVENT_VALUE], $oldRowToUpdate[Metrics::INDEX_EVENT_MAX_EVENT_VALUE]), static::EVENT_VALUE_PRECISION); // Update minimum only if it is set if ($newRowToAdd[Metrics::INDEX_EVENT_MIN_EVENT_VALUE] !== false) { if ($oldRowToUpdate[Metrics::INDEX_EVENT_MIN_EVENT_VALUE] === false) { - $oldRowToUpdate[Metrics::INDEX_EVENT_MIN_EVENT_VALUE] = round($newRowToAdd[Metrics::INDEX_EVENT_MIN_EVENT_VALUE], self::EVENT_VALUE_PRECISION); + $oldRowToUpdate[Metrics::INDEX_EVENT_MIN_EVENT_VALUE] = round($newRowToAdd[Metrics::INDEX_EVENT_MIN_EVENT_VALUE], static::EVENT_VALUE_PRECISION); } else { - $oldRowToUpdate[Metrics::INDEX_EVENT_MIN_EVENT_VALUE] = round(min($newRowToAdd[Metrics::INDEX_EVENT_MIN_EVENT_VALUE], $oldRowToUpdate[Metrics::INDEX_EVENT_MIN_EVENT_VALUE]), self::EVENT_VALUE_PRECISION); + $oldRowToUpdate[Metrics::INDEX_EVENT_MIN_EVENT_VALUE] = round(min($newRowToAdd[Metrics::INDEX_EVENT_MIN_EVENT_VALUE], $oldRowToUpdate[Metrics::INDEX_EVENT_MIN_EVENT_VALUE]), static::EVENT_VALUE_PRECISION); } } } @@ -290,7 +324,7 @@ class DataArray public function sumMetricsVisitsPivot($parentLabel, $label, $row) { if (!isset($this->dataTwoLevels[$parentLabel][$label])) { - $this->dataTwoLevels[$parentLabel][$label] = self::makeEmptyRow(); + $this->dataTwoLevels[$parentLabel][$label] = static::makeEmptyRow(); } $this->doSumVisitsMetrics($row, $this->dataTwoLevels[$parentLabel][$label]); } @@ -299,7 +333,7 @@ class DataArray { $idGoal = $row['idgoal']; if (!isset($this->dataTwoLevels[$parentLabel][$label][Metrics::INDEX_GOALS][$idGoal])) { - $this->dataTwoLevels[$parentLabel][$label][Metrics::INDEX_GOALS][$idGoal] = self::makeEmptyGoalRow($idGoal); + $this->dataTwoLevels[$parentLabel][$label][Metrics::INDEX_GOALS][$idGoal] = static::makeEmptyGoalRow($idGoal); } $this->doSumGoalsMetrics($row, $this->dataTwoLevels[$parentLabel][$label][Metrics::INDEX_GOALS][$idGoal]); } @@ -309,7 +343,7 @@ class DataArray if (!isset($this->dataTwoLevels[$parentLabel][$label])) { $this->dataTwoLevels[$parentLabel][$label] = $this->makeEmptyActionRow(); } - $this->doSumVisitsMetrics($row, $this->dataTwoLevels[$parentLabel][$label], $onlyMetricsAvailableInActionsTable = true); + $this->doSumActionsMetrics($row, $this->dataTwoLevels[$parentLabel][$label]); } public function sumMetricsEventsPivot($parentLabel, $label, $row) @@ -382,7 +416,7 @@ class DataArray */ public static function isRowActions($row) { - return (count($row) == count(self::makeEmptyActionRow())) && isset($row[Metrics::INDEX_NB_ACTIONS]); + return (count($row) == count(static::makeEmptyActionRow())) && isset($row[Metrics::INDEX_NB_ACTIONS]); } /** diff --git a/core/DataFiles/SearchEngines.php b/core/DataFiles/SearchEngines.php deleted file mode 100644 index 52b59713f6c7a196f4964f5271ed28eb14a10da2..0000000000000000000000000000000000000000 --- a/core/DataFiles/SearchEngines.php +++ /dev/null @@ -1,1140 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ - -/** - * Search Engine database - * - * ====================================== - * HOW TO ADD A SEARCH ENGINE TO THE LIST - * ====================================== - * If you want to add a new entry, please email us the information + icon at - * hello at piwik.org - * - * See also: http://piwik.org/faq/general/#faq_39 - * - * Detail of a line: - * Url => array( SearchEngineName, KeywordParameter, [path containing the keyword], [charset used by the search engine]) - * - * The main search engine URL has to be at the top of the list for the given - * search Engine. This serves as the master record so additional URLs - * don't have to duplicate all the information, but can override when needed. - * - * The URL, "example.com", will match "example.com", "m.example.com", - * "www.example.com", and "search.example.com". - * - * For region-specific search engines, the URL, "{}.example.com" will match - * any ISO3166-1 alpha2 country code against "{}". Similarly, "example.{}" - * will match against valid country TLDs, but should be used sparingly to - * avoid false positives. - * - * The charset should be an encoding supported by mbstring. If unspecified, - * we'll assume it's UTF-8. - * Reference: http://www.php.net/manual/en/mbstring.encodings.php - * - * You can add new search engines icons by adding the icon in the - * plugins/Referrers/images/searchEngines directory using the format - * 'mainSearchEngineUrl.png'. Example: www.google.com.png - * - * To help Piwik link directly the search engine result page for the keyword, - * specify the third entry in the array using the macro {k} that will - * automatically be replaced by the keyword. - * - * A simple example is: - * 'www.google.com' => array('Google', 'q', 'search?q={k}'), - * - * A more complicated example, with an array of possible variable names, and a custom charset: - * 'www.baidu.com' => array('Baidu', array('wd', 'word', 'kw'), 's?wd={k}', 'gb2312'), - * - * Another example using a regular expression to parse the path for keywords: - * 'infospace.com' => array('InfoSpace', array('/dir1\/(pattern)\/dir2/'), '/dir1/{k}/dir2/stuff/'), - */ -if (!isset($GLOBALS['Piwik_SearchEngines'])) { - $GLOBALS['Piwik_SearchEngines'] = array( - // 1 - '1.cz' => array('1.cz', array('/s\/([^\/]+)/', 'q'), 's/{k}', 'iso-8859-2'), - - // 123people - 'www.123people.com' => array('123people', array('/s\/([^\/]+)/', 'search_term'), 's/{k}'), - '123people.{}' => array('123people'), - - // 360search - 'so.360.cn' => array('360search', 'q', 's?q={k}', array('UTF-8', 'gb2312')), - 'www.so.com' => array('360search', 'q', 's?q={k}', array('UTF-8', 'gb2312')), - - // Abacho - 'www.abacho.de' => array('Abacho', 'q', 'suche?q={k}'), - 'www.abacho.com' => array('Abacho'), - 'www.abacho.co.uk' => array('Abacho'), - 'www.se.abacho.com' => array('Abacho'), - 'www.tr.abacho.com' => array('Abacho'), - 'www.abacho.at' => array('Abacho'), - 'www.abacho.fr' => array('Abacho'), - 'www.abacho.es' => array('Abacho'), - 'www.abacho.ch' => array('Abacho'), - 'www.abacho.it' => array('Abacho'), - - // ABCsøk - 'abcsok.no' => array('ABCsøk', 'q', '?q={k}'), - 'verden.abcsok.no' => array('ABCsøk'), - - // Acoon - 'www.acoon.de' => array('Acoon', 'begriff', 'cgi-bin/search.exe?begriff={k}'), - - // Aguea - 'chercherfr.aguea.com' => array('Aguea', 'q', 's.py?q={k}'), - - // Alexa - 'alexa.com' => array('Alexa', 'q', 'search?q={k}'), - 'search.toolbars.alexa.com' => array('Alexa'), - - // Alice Adsl - 'rechercher.aliceadsl.fr' => array('Alice Adsl', 'qs', 'google.pl?qs={k}'), - - // Allesklar - 'www.allesklar.de' => array('Allesklar', 'words', '?words={k}'), - 'www.allesklar.at' => array('Allesklar'), - 'www.allesklar.ch' => array('Allesklar'), - - // AllTheWeb - 'www.alltheweb.com' => array('AllTheWeb', 'q', 'search?q={k}'), - - // all.by - 'all.by' => array('All.by', 'query', 'cgi-bin/search.cgi?mode=by&query={k}'), - - // Altavista - 'www.altavista.com' => array('AltaVista', 'q', 'web/results?q={k}'), - 'search.altavista.com' => array('AltaVista'), - 'listings.altavista.com' => array('AltaVista'), - 'altavista.de' => array('AltaVista'), - 'altavista.fr' => array('AltaVista'), - '{}.altavista.com' => array('AltaVista'), - 'be-nl.altavista.com' => array('AltaVista'), - 'be-fr.altavista.com' => array('AltaVista'), - - // Apollo Latvia - 'apollo.lv/portal/search/' => array('Apollo lv', 'q', '?cof=FORID%3A11&q={k}&search_where=www'), - - // APOLLO7 - 'apollo7.de' => array('Apollo7', 'query', 'a7db/index.php?query={k}&de_sharelook=true&de_bing=true&de_witch=true&de_google=true&de_yahoo=true&de_lycos=true'), - - // AOL - 'search.aol.com' => array('AOL', array('query', 'q'), 'aol/search?q={k}'), - 'search.aol.it' => array('AOL'), - 'aolsearch.aol.com' => array('AOL'), - 'www.aolrecherche.aol.fr' => array('AOL'), - 'www.aolrecherches.aol.fr' => array('AOL'), - 'www.aolimages.aol.fr' => array('AOL'), - 'aim.search.aol.com' => array('AOL'), - 'www.recherche.aol.fr' => array('AOL'), - 'recherche.aol.fr' => array('AOL'), - 'find.web.aol.com' => array('AOL'), - 'recherche.aol.ca' => array('AOL'), - 'aolsearch.aol.co.uk' => array('AOL'), - 'search.aol.co.uk' => array('AOL'), - 'aolrecherche.aol.fr' => array('AOL'), - 'sucheaol.aol.de' => array('AOL'), - 'suche.aol.de' => array('AOL'), - 'o2suche.aol.de' => array('AOL'), - 'suche.aolsvc.de' => array('AOL'), - 'aolbusqueda.aol.com.mx' => array('AOL'), - 'alicesuche.aol.de' => array('AOL'), - 'alicesuchet.aol.de' => array('AOL'), - 'suchet2.aol.de' => array('AOL'), - 'search.hp.my.aol.com.au' => array('AOL'), - 'search.hp.my.aol.de' => array('AOL'), - 'search.hp.my.aol.it' => array('AOL'), - 'search-intl.netscape.com' => array('AOL'), - 'de.aolsearch.com' => array('AOL', 'q', 'search?q={k}'), - - // Aport - 'sm.aport.ru' => array('Aport', 'r', 'search?r={k}'), - - // arama - 'arama.com' => array('Arama', 'q', 'search.php3?q={k}'), - - // Arcor - 'www.arcor.de' => array('Arcor', 'Keywords', 'content/searchresult.jsp?Keywords={k}'), - - // Arianna (Libero.it) - 'arianna.libero.it' => array('Arianna', 'query', 'search/abin/integrata.cgi?query={k}'), - 'www.arianna.com' => array('Arianna'), - - // Ask (IAC Search & Media) - 'ask.com' => array('Ask', array('ask', 'q', 'searchfor'), 'web?q={k}'), - 'web.ask.com' => array('Ask'), - 'int.ask.com' => array('Ask'), - 'mws.ask.com' => array('Ask'), - 'images.ask.com' => array('Ask'), - 'images.{}.ask.com' => array('Ask'), - 'ask.reference.com' => array('Ask'), - 'www.askkids.com' => array('Ask'), - 'iwon.ask.com' => array('Ask'), - 'www.ask.co.uk' => array('Ask'), - '{}.ask.com' => array('Ask'), - 'www.qbyrd.com' => array('Ask'), - '{}.qbyrd.com' => array('Ask'), - 'www.search-results.com' => array('Ask'), - 'www1.search-results.com' => array('Ask'), - 'int.search-results.com' => array('Ask'), - '{}.search-results.com' => array('Ask'), - 'search.ask.com' => array('Ask'), - '{}.search.ask.com' => array('Ask'), - 'avira-int.ask.com' => array('Ask'), - 'searchqu.com' => array('Ask'), - 'search.tb.ask.com' => array('Ask'), - 'nortonsafe.search.ask.com' => array('Ask'), - 'safesearch.avira.com' => array('Ask'), - 'avira.search.ask.com' => array('Ask'), - 'int.search.tb.ask.com' => array('Ask'), - - // Atlas - 'searchatlas.centrum.cz' => array('Atlas', 'q', '?q={k}'), - - // auone - 'search.auone.jp' => array('auone', 'q', '?q={k}'), - 'sp-search.auone.jp' => array('auone'), - 'sp-image.search.auone.jp' => array('auone Images', 'q', '?q={k}'), - - // Austronaut - 'www2.austronaut.at' => array('Austronaut', 'q'), - 'www1.austronaut.at' => array('Austronaut'), - - // Babylon (Enhanced by Google), - 'search.babylon.com' => array('Babylon', array('q', '/\/web\/(.*)/'), '?q={k}'), - 'searchassist.babylon.com' => array('Babylon'), - - // Baidu - 'www.baidu.com' => array('Baidu', array('wd', 'word', 'kw'), 's?wd={k}', array('UTF-8', 'gb2312')), - 'www1.baidu.com' => array('Baidu'), - 'm.baidu.com' => array('Baidu'), - 'www.baidu.co.th' => array('Baidu'), - 'zhidao.baidu.com' => array('Baidu'), - 'tieba.baidu.com' => array('Baidu'), - 'news.baidu.com' => array('Baidu'), - 'web.gougou.com' => array('Baidu', 'search', 'search?search={k}'), // uses baidu search - - // Biglobe - 'cgi.search.biglobe.ne.jp' => array('Biglobe', 'q', 'cgi-bin/search-st?q={k}'), - 'images.search.biglobe.ne.jp' => array('Biglobe Images', 'q', 'cgi-bin/search-st?q={k}'), - - // Bing - 'bing.com' => array('Bing', array('q', 'Q'), 'search?q={k}'), - '{}.bing.com' => array('Bing'), - 'msnbc.msn.com' => array('Bing'), - 'dizionario.it.msn.com' => array('Bing'), - 'enciclopedia.it.msn.com' => array('Bing'), - - // Bing Cache - 'cc.bingj.com' => array('Bing'), - - // Bing Images - 'bing.com/images/search' => array('Bing Images', array('q', 'Q'), '?q={k}'), - '{}.bing.com/images/search' => array('Bing Images'), - - // blekko - 'blekko.com' => array('blekko', array('q', '/\/ws\/(.*)/'), 'ws/{k}'), - - // Blogdigger - 'www.blogdigger.com' => array('Blogdigger', 'q'), - - // Blogpulse - 'www.blogpulse.com' => array('Blogpulse', 'query', 'search?query={k}'), - - // Bluewin - 'search.bluewin.ch' => array('Bluewin', array('searchTerm', 'q'), 'v2/index.php?q={k}'), - - // canoe.ca - 'web.canoe.ca' => array('Canoe.ca', 'q', 'search?q={k}'), - - // Centrum - 'search.centrum.cz' => array('Centrum', 'q', '?q={k}'), - 'morfeo.centrum.cz' => array('Centrum'), - - // Charter - 'www.charter.net' => array('Charter', 'q', 'search/index.php?q={k}'), - - // Claro Search - 'claro-search.com' => array('Claro Search', 'q', '?q={k}'), - - // Clix (Enhanced by Google) - 'pesquisa.clix.pt' => array('Clix', 'question', 'resultado.html?in=Mundial&question={k}'), - - // Conduit - 'search.conduit.com' => array('Conduit.com', 'q', 'Results.aspx?q={k}'), - 'images.search.conduit.com' => array('Conduit.com'), - - // Comcast - 'search.comcast.net' => array('Comcast', 'q', '?q={k}'), - - // Crawler - 'www.crawler.com' => array('Crawler', 'q', 'search/results1.aspx?q={k}'), - - // Compuserve - 'websearch.cs.com' => array('Compuserve.com (Enhanced by Google)', 'query', 'cs/search?query={k}'), - - // Cuil - 'www.cuil.com' => array('Cuil', 'q', 'search?q={k}'), - - // Daemon search - 'daemon-search.com' => array('Daemon search', 'q', 'explore/web?q={k}'), - 'my.daemon-search.com' => array('Daemon search'), - - // DasOertliche - 'www.dasoertliche.de' => array('DasOertliche', 'kw'), - 'www2.dasoertliche.de' => array('DasOertliche', array('ph', 'kw')), - - // DasTelefonbuch - 'www1.dastelefonbuch.de' => array('DasTelefonbuch', 'kw'), - - // Daum - 'search.daum.net' => array('Daum', 'q', 'search?q={k}'), - - // Delfi Latvia - 'smart.delfi.lv' => array('Delfi lv', 'q', 'find?q={k}'), - - // Delfi - 'otsing.delfi.ee' => array('Delfi EE', 'q', 'find?q={k}'), - - // Digg - 'digg.com' => array('Digg', 's', 'search?s={k}'), - - // dir.com - 'fr.dir.com' => array('dir.com', 'req'), - - // dmoz - 'dmoz.org' => array('dmoz', 'search'), - 'editors.dmoz.org' => array('dmoz'), - - // DuckDuckGo - 'duckduckgo.com' => array('DuckDuckGo', 'q', '?q={k}'), - 'r.duckduckgo.com' => array('DuckDuckGo'), - - // earthlink - 'search.earthlink.net' => array('Earthlink', 'q', 'search?q={k}'), - - // Ecosia (powered by Bing) - 'ecosia.org' => array('Ecosia', 'q', 'search.php?q={k}'), - - // Eniro - 'www.eniro.se' => array('Eniro', array('q', 'search_word'), 'query?q={k}'), - - // Eurip - 'www.eurip.com' => array('Eurip', 'q', 'search/?q={k}'), - - // Euroseek - 'www.euroseek.com' => array('Euroseek', 'string', 'system/search.cgi?string={k}'), - - // Everyclick - 'www.everyclick.com' => array('Everyclick', 'keyword'), - - // Excite - 'search.excite.it' => array('Excite', 'q', 'web/?q={k}'), - 'search.excite.fr' => array('Excite'), - 'search.excite.de' => array('Excite'), - 'search.excite.co.uk' => array('Excite'), - 'search.excite.es' => array('Excite'), - 'search.excite.nl' => array('Excite'), - 'msxml.excite.com' => array('Excite', '/\/[^\/]+\/ws\/results\/[^\/]+\/([^\/]+)/'), - 'www.excite.co.jp' => array('Excite', 'search', 'search.gw?search={k}', 'SHIFT_JIS'), - - // Exalead - 'www.exalead.fr' => array('Exalead', 'q', 'search/results?q={k}'), - 'www.exalead.com' => array('Exalead'), - - // eo - 'eo.st' => array('eo', 'x_query', 'cgi-bin/eolost.cgi?x_query={k}'), - - // Facebook - 'www.facebook.com' => array('Facebook', 'q', 'search/?q={k}'), - - // Fast Browser Search - 'www.fastbrowsersearch.com' => array('Fast Browser Search', 'q', 'results/results.aspx?q={k}'), - - // Francite - 'recherche.francite.com' => array('Francite', 'name'), - - // Findhurtig - 'www.findhurtig.dk' => array('Findhurtig', 'q', 'web?q={k}'), - - // Fireball - 'www.fireball.de' => array('Fireball', 'q', 'ajax.asp?q={k}'), - - // Firstfind - 'www.firstsfind.com' => array('Firstsfind', 'qry'), - - // Fixsuche - 'www.fixsuche.de' => array('Fixsuche', 'q'), - - // Flix - 'www.flix.de' => array('Flix.de', 'keyword'), - - // Fooooo - 'search.fooooo.com' => array('Fooooo', 'q', 'web/?q={k}'), - - // Forestle - 'forestle.org' => array('Forestle', 'q', 'search.php?q={k}'), - '{}.forestle.org' => array('Forestle'), - 'forestle.mobi' => array('Forestle'), - - // Free - 'search.free.fr' => array('Free', array('q', 'qs')), - 'search1-2.free.fr' => array('Free'), - 'search1-1.free.fr' => array('Free'), - - // Freecause - 'search.freecause.com' => array('FreeCause', 'p', '?p={k}'), - - // Freenet - 'suche.freenet.de' => array('Freenet', array('query', 'Keywords'), 'suche/?query={k}'), - - // FriendFeed - 'friendfeed.com' => array('FriendFeed', 'q', 'search?q={k}'), - - // GAIS - 'gais.cs.ccu.edu.tw' => array('GAIS', 'q', 'search.php?q={k}'), - - // Genieo - 'search.genieo.com' => array('Genieo', 'q', '&q={k}'), - - // Geona - 'geona.net' => array('Geona', 'q', 'search?q={k}'), - - // Gigablast - 'www.gigablast.com' => array('Gigablast', 'q', 'search?q={k}'), - 'dir.gigablast.com' => array('Gigablast (Directory)', 'q'), - - // Gnadenmeer - 'www.gnadenmeer.de' => array('Gnadenmeer', 'keyword'), - - // Gomeo - 'www.gomeo.com' => array('Gomeo', array('Keywords', '/\/search\/([^\/]+)/'), '/search/{k}'), - - // goo - 'search.goo.ne.jp' => array('goo', 'MT', 'web.jsp?MT={k}'), - 'ocnsearch.goo.ne.jp' => array('goo'), - - // Google - 'google.com' => array('Google', 'q', 'search?q={k}'), - 'google.{}' => array('Google'), - 'www2.google.com' => array('Google'), - 'ipv6.google.com' => array('Google'), - 'go.google.com' => array('Google'), - - // Google vs typo squatters - 'wwwgoogle.com' => array('Google'), - 'wwwgoogle.{}' => array('Google'), - 'gogole.com' => array('Google'), - 'gogole.{}' => array('Google'), - 'gppgle.com' => array('Google'), - 'gppgle.{}' => array('Google'), - 'googel.com' => array('Google'), - 'googel.{}' => array('Google'), - - // Powered by Google - 'search.avg.com' => array('Google'), - 'isearch.avg.com' => array('Google'), - 'search.chedot.com' => array('Google', 'text'), - 'www.cnn.com' => array('Google', 'query'), - 'darkoogle.com' => array('Google'), - 'search.darkoogle.com' => array('Google'), - 'search.foxtab.com' => array('Google'), - 'www.gooofullsearch.com' => array('Google', 'Keywords'), - 'search.hiyo.com' => array('Google'), - 'search.incredimail.com' => array('Google'), - 'search1.incredimail.com' => array('Google'), - 'search2.incredimail.com' => array('Google'), - 'search3.incredimail.com' => array('Google'), - 'search4.incredimail.com' => array('Google'), - 'search.sweetim.com' => array('Google'), - 'www.fastweb.it' => array('Google'), - 'search.juno.com' => array('Google', 'query'), - 'find.tdc.dk' => array('Google'), - 'it.luna.tv' => array('Google'), - 'searchresults.verizon.com' => array('Google'), - 'search.walla.co.il' => array('Google'), - 'search.alot.com' => array('Google'), - 'suche.gmx.net' => array('Google', 'q', 'web?q={k}'), - 'search.incredibar.com' => array('Google', 'q', 'search.php?q={k}'), - 'www.delta-search.com' => array('Google', 'q'), - 'www1.delta-search.com' => array('Google', 'q'), - 'search.1und1.de' => array('Google', 'q', 'web?q={k}'), - 'suche.1und1.de' => array('Google', 'q', 'web?q={k}'), - 'search.zonealarm.com' => array('Google'), - 'start.lenovo.com' => array('Google', 'q', 'search/index.php?q={k}'), - 'wow.com' => array('Google'), - '{}.wow.com' => array('Google'), - 'search.leonardo.it' => array('Google'), - 'www.optuszoo.com.au' => array('Google'), - 'search.dolphin-browser.jp' => array('Google'), - 'netlavis.azione.jp' => array('Google'), - 'search.nan.so' => array('Google'), - 'cgi2.nintendo.co.jp' => array('Google', 'gsc.q'), - 'search.smt.docomo.ne.jp' => array('Google', 'MT'), - 'image.search.smt.docomo.ne.jp' => array('Google', 'MT'), - 'gfsoso.com' => array('Google', 'q'), - 'searches.safehomepage.com' => array('Google', 'q'), - 'searches.f-secure.com' => array('Google', 'query', 'search?query={k}'), - - // Google Cache - 'webcache.googleusercontent.com' => array('Google', '/\/search\?q=cache:[A-Za-z0-9]+:[^+]+([^&]+)/', 'search?q={k}'), - - // Google SSL - 'encrypted.google.com' => array('Google SSL', 'q', 'search?q={k}'), - - // Google Blogsearch - 'blogsearch.google.com' => array('Google Blogsearch', 'q', 'blogsearch?q={k}'), - 'blogsearch.google.{}' => array('Google Blogsearch'), - - // Google Custom Search - 'google.com/cse' => array('Google Custom Search', array('q', 'query')), - 'google.{}/cse' => array('Google Custom Search'), - 'google.com/custom' => array('Google Custom Search'), - 'google.{}/custom' => array('Google Custom Search'), - - // Google Translation - 'translate.google.com' => array('Google Translations', 'q'), - - // Google Images - 'images.google.com' => array('Google Images', 'q', 'images?q={k}'), - 'images.google.{}' => array('Google Images'), - - // Google Maps - 'maps.google.com' => array('Google Maps', 'q', 'maps?q={k}'), - 'maps.google.{}' => array('Google Maps'), - - // Google News - 'news.google.com' => array('Google News', 'q'), - 'news.google.{}' => array('Google News'), - - // Google Shopping - 'google.com/products' => array('Google Shopping', 'q', '?q={k}&tbm=shop'), - 'google.{}/products' => array('Google Shopping'), - - // Google syndicated search - 'googlesyndicatedsearch.com' => array('Google syndicated search', 'q'), - - // Google Video - 'video.google.com' => array('Google Video', 'q', 'search?q={k}&tbm=vid'), - - // Google Scholar - 'scholar.google.com' => array('Google Scholar', 'q', 'scholar?q={k}'), - 'scholar.google.{}' => array('Google Scholar'), - - // Google Wireless Transcoder - // - does not appear to execute JavaScript -// 'google.com/gwt/n' => array('Google Wireless Transcoder'), - - // Goyellow.de - 'www.goyellow.de' => array('GoYellow.de', 'MDN'), - - // Gule Sider - 'www.gulesider.no' => array('Gule Sider', 'q'), - - // Haosou - 'www.haosou.com' => array('Haosou', 'q', 's?q={k}'), - - // HighBeam - 'www.highbeam.com' => array('HighBeam', 'q', 'Search.aspx?q={k}'), - - // Hit-Parade - 'req.hit-parade.com' => array('Hit-Parade', 'p7', 'general/recherche.asp?p7={k}'), - 'class.hit-parade.com' => array('Hit-Parade'), - 'www.hit-parade.com' => array('Hit-Parade'), - - // Holmes.ge - 'holmes.ge' => array('Holmes', 'q', 'search.htm?q={k}'), - - // Hooseek.com - 'www.hooseek.com' => array('Hooseek', 'recherche', 'web?recherche={k}'), - - // Hotbot - 'www.hotbot.com' => array('Hotbot', 'query'), - - // Icerocket - 'blogs.icerocket.com' => array('Icerocket', 'q', 'search?q={k}'), - - // ICQ - 'www.icq.com' => array('ICQ', 'q', 'search/results.php?q={k}'), - 'search.icq.com' => array('ICQ'), - - // Ilse - 'www.ilse.nl' => array('Ilse NL', 'search_for', '?search_for={k}'), - - // iMesh - 'search.imesh.com' => array('iMesh', array('q', 'si'), 'web?q={k}'), - - // Inbox.com - 'www2.inbox.com' => array('Inbox', 'q', 'search/results1.aspx?q={k}'), - - // InfoSpace (and related web properties) - 'infospace.com' => array('InfoSpace', 'q', '/search/web?q={k}'), - 'dogpile.com' => array('InfoSpace'), - 'tattoodle.com' => array('InfoSpace'), - 'metacrawler.com' => array('InfoSpace'), - 'webfetch.com' => array('InfoSpace'), - 'webcrawler.com' => array('InfoSpace'), - 'search.kiwee.com' => array('InfoSpace'), - 'searches.vi-view.com' => array('InfoSpace'), - 'search.webssearches.com' => array('InfoSpace'), - 'search.fbdownloader.com' => array('InfoSpace'), - 'searches3.globososo.com' => array('InfoSpace'), - - // old infospace system - 'wsdsold.infospace.com' => array('InfoSpace', '/\/[^\/]+\/ws\/results\/[^\/]+\/([^\/]+)/', 'pemonitorhosted/ws/results/Web/{k}/1/417/TopNavigation/Source/'), - - // Powered by InfoSpace - 'isearch.babylon.com' => array('InfoSpace', 'q'), - 'start.facemoods.com' => array('InfoSpace', 's'), - 'start.funmoods.com' => array('InfoSpace', 'q'), - 'search.magentic.com' => array('InfoSpace', 'q'), - 'search.searchcompletion.com' => array('InfoSpace', 'q'), - 'www.searchmobileonline.com' => array('InfoSpace', 'q'), - 'isearch.glarysoft.com' => array('InfoSpace', 'q'), - 'search.chatzum.com' => array('InfoSpace', 'q'), - 'home.speedbit.com' => array('InfoSpace', 'q'), - 'search.b1.org' => array('InfoSpace', 'q'), - 'searchya.com' => array('InfoSpace', 'q'), - 'search.handycafe.com' => array('InfoSpace', 'q'), - 'search.v9.com' => array('InfoSpace', 'q'), - 'search.iminent.com' => array('InfoSpace', 'q'), - 'utorrent.inspsearch.com' => array('InfoSpace', 'q'), - - /* - * Other InfoSpace powered metasearches are handled in Common::extractSearchEngineInformationFromUrl() - * - * This includes sites such as: - * - search.nation.com - * - ws.copernic.com - * - result.iminent.com - */ - - // Interia - 'www.google.interia.pl' => array('Interia', 'q', 'szukaj?q={k}'), - - // I-play - 'start.iplay.com' => array('I-play', 'q', 'searchresults.aspx?q={k}'), - - // Ixquick - 'ixquick.com' => array('Ixquick', 'query'), - 'www.eu.ixquick.com' => array('Ixquick'), - 'ixquick.de' => array('Ixquick'), - 'www.ixquick.de' => array('Ixquick'), - 'us.ixquick.com' => array('Ixquick'), - 's1.us.ixquick.com' => array('Ixquick'), - 's2.us.ixquick.com' => array('Ixquick'), - 's3.us.ixquick.com' => array('Ixquick'), - 's4.us.ixquick.com' => array('Ixquick'), - 's5.us.ixquick.com' => array('Ixquick'), - 'eu.ixquick.com' => array('Ixquick'), - 's8-eu.ixquick.com' => array('Ixquick'), - 's1-eu.ixquick.de' => array('Ixquick'), - 's2-eu4.ixquick.com' => array('Ixquick'), - 's5-eu4.ixquick.com' => array('Ixquick'), - - // Jyxo - 'jyxo.1188.cz' => array('Jyxo', 'q', 's?q={k}'), - - // Jungle Spider - 'www.jungle-spider.de' => array('Jungle Spider', 'q'), - - // Jungle key - 'junglekey.com' => array('Jungle Key', 'query', 'search.php?query={k}&type=web&lang=en'), - 'junglekey.fr' => array('Jungle Key'), - - // K9 Safe Search - 'k9safesearch.com' => array('K9 Safe Search', 'q', 'search.jsp?q={k}'), - - // Kataweb - 'www.kataweb.it' => array('Kataweb', 'q'), - - // Kensaq - 'www.kensaq.com' => array('Kensaq', 'q', 'web?q={k}'), - - // Kvasir - 'www.kvasir.no' => array('Kvasir', 'q', 'alle?q={k}'), - - // 묻지마 검색 - 'kwzf.net' => array('묻지마 검색', 'search', '#search={k}'), - - // Latne - 'www.latne.lv' => array('Latne', 'q', 'siets.php?q={k}'), - - // La Toile Du Québec via Google - 'www.toile.com' => array('La Toile Du Québec (Google)', 'q', 'search?q={k}'), - 'web.toile.com' => array('La Toile Du Québec (Google)'), - - // LookAny - 'www.lookany.com' => array('LookAny', '/(?:search|images|videos)\/([^\/]+)/'), - - // Looksmart - 'www.looksmart.com' => array('Looksmart', 'key'), - - // Lo.st (Enhanced by Google) - 'lo.st' => array('Lo.st', 'x_query', 'cgi-bin/eolost.cgi?x_query={k}'), - - // Lycos - 'search.lycos.com' => array('Lycos', 'query', '?query={k}'), - 'lycos.{}' => array('Lycos'), - - // maailm.com - 'www.maailm.com' => array('maailm.com', 'tekst'), - - // Mail.ru - 'go.mail.ru' => array('Mailru', 'q', 'search?rch=e&q={k}', array('UTF-8', 'windows-1251')), - - // Mamma - 'www.mamma.com' => array('Mamma', 'query', 'result.php?q={k}'), - 'mamma75.mamma.com' => array('Mamma'), - - // Meta - 'meta.ua' => array('Meta.ua', 'q', 'search.asp?q={k}'), - - // MetaCrawler.de - 's1.metacrawler.de' => array('MetaCrawler DE', 'qry', '?qry={k}'), - 's2.metacrawler.de' => array('MetaCrawler DE'), - 's3.metacrawler.de' => array('MetaCrawler DE'), - - // Metager - 'meta.rrzn.uni-hannover.de' => array('Metager', 'eingabe', 'meta/cgi-bin/meta.ger1?eingabe={k}'), - 'www.metager.de' => array('Metager'), - 'metager.de' => array('Metager'), - - // Metager2 - 'metager2.de' => array('Metager2', 'q', 'search/index.php?q={k}'), - - // Meinestadt - 'www.meinestadt.de' => array('Meinestadt.de', 'words'), - - // Mister Wong - 'www.mister-wong.com' => array('Mister Wong', 'keywords', 'search/?keywords={k}'), - 'www.mister-wong.de' => array('Mister Wong'), - - // Monstercrawler - 'www.monstercrawler.com' => array('Monstercrawler', 'qry'), - - // Mozbot - 'www.mozbot.fr' => array('mozbot', 'q', 'results.php?q={k}'), - 'www.mozbot.co.uk' => array('mozbot'), - 'www.mozbot.com' => array('mozbot'), - - // El Mundo - 'ariadna.elmundo.es' => array('El Mundo', 'q'), - - // MySpace - 'searchservice.myspace.com' => array('MySpace', 'qry', 'index.cfm?fuseaction=sitesearch.results&type=Web&qry={k}'), - - // MySearch / MyWay / MyWebSearch (default: powered by Ask.com) - 'www.mysearch.com' => array('MyWebSearch', array('searchfor', 'searchFor'), 'search/Ajmain.jhtml?searchfor={k}'), - 'ms114.mysearch.com' => array('MyWebSearch'), - 'ms146.mysearch.com' => array('MyWebSearch'), - 'kf.mysearch.myway.com' => array('MyWebSearch'), - 'ki.mysearch.myway.com' => array('MyWebSearch'), - 'search.myway.com' => array('MyWebSearch'), - 'search.mywebsearch.com' => array('MyWebSearch'), - - // Najdi - 'www.najdi.si' => array('Najdi.si', 'q', 'search.jsp?q={k}'), - - // Nate - 'search.nate.com' => array('Nate', 'q', 'search/all.html?q={k}', 'EUC-KR'), - - // Naver - 'search.naver.com' => array('Naver', 'query', 'search.naver?query={k}'), - - // Needtofind - 'ko.search.need2find.com' => array('Needtofind', 'searchfor', 'search/AJmain.jhtml?searchfor={k}'), - - // Neti - 'www.neti.ee' => array('Neti', 'query', 'cgi-bin/otsing?query={k}', 'iso-8859-1'), - - // Nifty - 'search.nifty.com' => array('Nifty', array('q', 'Text'), 'websearch/search?q={k}'), - 'search.azby.fmworld.net' => array('Nifty'), - 'videosearch.nifty.com' => array('Nifty Videos', 'kw', 'search?kw={k}'), - - // Nigma - 'nigma.ru' => array('Nigma', 's', 'index.php?s={k}'), - - // Onet - 'szukaj.onet.pl' => array('Onet.pl', 'qt', 'query.html?qt={k}'), - - // Online.no - 'online.no' => array('Online.no', 'q', 'google/index.jsp?q={k}'), - - // Opplysningen 1881 - 'www.1881.no' => array('Opplysningen 1881', 'Query', 'Multi/?Query={k}'), - - // Orange - 'busca.orange.es' => array('Orange', 'q', 'search?q={k}'), - 'lemoteur.ke.voila.fr' => array('Orange', 'kw', '?kw={k}'), - - // Paperball - 'www.paperball.de' => array('Paperball', 'q', 'suche/s/?q={k}'), - - // PeoplePC - 'search.peoplepc.com' => array('PeoplePC', 'q', 'search?q={k}'), - - // PeopleCheck - 'extern.peoplecheck.de' => array('PeopleCheck', 'q', 'link.php?q={k}'), - - // Picsearch - 'www.picsearch.com' => array('Picsearch', 'q', 'index.cgi?q={k}'), - - // Plazoo - 'www.plazoo.com' => array('Plazoo', 'q'), - - // PlusNetwork - 'plusnetwork.com' => array('PlusNetwork', 'q', '?q={k}'), - - // Poisk.Ru - 'poisk.ru' => array('Poisk.Ru', 'text', 'cgi-bin/poisk?text={k}', 'windows-1251'), - - // qip - 'search.qip.ru' => array('qip.ru', 'query', 'search?query={k}'), - - // Qualigo - 'www.qualigo.at' => array('Qualigo', 'q'), - 'www.qualigo.ch' => array('Qualigo'), - 'www.qualigo.de' => array('Qualigo'), - 'www.qualigo.nl' => array('Qualigo'), - - // Qwant - 'www.qwant.com' => array('Qwant', 'q'), - - // Rakuten - 'websearch.rakuten.co.jp' => array('Rakuten', 'qt', 'WebIS?qt={k}'), - - // Rambler - 'nova.rambler.ru' => array('Rambler', array('query', 'words'), 'search?query={k}'), - - // RPMFind - 'rpmfind.net' => array('rpmfind', 'query', 'linux/rpm2html/search.php?query={k}'), - 'fr2.rpmfind.net' => array('rpmfind'), - - // Road Runner Search - 'search.rr.com' => array('Road Runner', 'q', '?q={k}'), - - // Sapo - 'pesquisa.sapo.pt' => array('Sapo', 'q', '?q={k}'), - - // scour.com - 'scour.com' => array('Scour.com', '/search\/[^\/]+\/(.*)/', 'search/web/{k}'), - - // Search.com - 'www.search.com' => array('Search.com', 'q', 'search?q={k}'), - - // Search.ch - 'www.search.ch' => array('Search.ch', 'q', '?q={k}'), - - // Searchalot - 'searchalot.com' => array('Searchalot', 'q', '?q={k}'), - - // SearchCanvas - 'www.searchcanvas.com' => array('SearchCanvas', 'q', 'web?q={k}'), - - // Searchy - 'www.searchy.co.uk' => array('Searchy', 'q', 'index.html?q={k}'), - - // Setooz - // 2010-09-13: the mismatches are because subdomains are language codes - // (not country codes) - 'bg.setooz.com' => array('Setooz', 'query', 'search?query={k}'), - 'da.setooz.com' => array('Setooz'), - 'el.setooz.com' => array('Setooz'), - 'fa.setooz.com' => array('Setooz'), - 'ur.setooz.com' => array('Setooz'), - '{}.setooz.com' => array('Setooz'), - - // Seznam - 'search.seznam.cz' => array('Seznam', 'q', '?q={k}'), - - // Seznam Videa (Video) - 'videa.seznam.cz' => array('Seznam Videa', 'q', '?q={k}'), - - // Sharelook - 'www.sharelook.fr' => array('Sharelook', 'keyword'), - - // Skynet - 'www.skynet.be' => array('Skynet', 'q', 'services/recherche/google?q={k}'), - - // sm.cn - 'm.sm.cn' => array('sm.cn', 'q', 's?q={k}'), - 'm.sp.sm.cn' => array('sm.cn'), - - // sm.de - 'www.sm.de' => array('sm.de', 'q', '?q={k}'), - - // SmartAdressbar - 'search.smartaddressbar.com' => array('SmartAddressbar', 's', '?s={k}'), - - // Snap.do - 'search.snap.do' => array('Snap.do', 'q', '?q={k}'), - - // SeeSaa - 'search.seesaa.jp' => array('SeeSaa', '/\/([^\/]+)\/index\.html/', '{k}/index.html'), - - // So-net - 'www.so-net.ne.jp' => array('So-net', 'query', 'search/web/?query={k}'), - 'video.so-net.ne.jp' => array('So-net Videos', 'kw', 'search/?kw={k}'), - - // Sogou - 'www.sogou.com' => array('Sogou', 'query', 'web?query={k}', 'gb2312'), - 'm.sogou.com' => array('Sogou', 'keyword'), - - // Softonic - 'search.softonic.com' => array('Softonic', 'q', 'default/default?q={k}'), - - // soso.com - 'www.soso.com' => array('Soso', 'w', 'q?w={k}', 'gb2312'), - - // sputnik.ru - 'www.sputnik.ru' => array('Sputnik', 'q', 'search?q={k}'), - - // Startpagina - 'startgoogle.startpagina.nl' => array('Startpagina (Google)', 'q', '?q={k}'), - - // Startsiden - 'www.startsiden.no' => array('Startsiden', 'q', 'sok/index.html?q={k}'), - - // suche.info - 'suche.info' => array('Suche.info', 'Keywords', 'suche.php?Keywords={k}'), - - // Suchmaschine.com - 'www.suchmaschine.com' => array('Suchmaschine.com', 'suchstr', 'cgi-bin/wo.cgi?suchstr={k}'), - - // Suchnase - 'www.suchnase.de' => array('Suchnase', 'q'), - - // Surf Canyon - 'surfcanyon.com' => array('Surf Canyon', 'q'), - - // talimba - 'www.talimba.com' => array('talimba', 'search', 'index.php?page=search/web&search={k}'), - - // TalkTalk - 'www.talktalk.co.uk' => array('TalkTalk', 'query', 'search/results.html?query={k}'), - - // Technorati - 'technorati.com' => array('Technorati', 'q', 'search?return=sites&authority=all&q={k}'), - - // Teoma - 'www.teoma.com' => array('Teoma', 'q', 'web?q={k}'), - - // Terra -- referrer does not contain search phrase (keywords) - 'buscador.terra.es' => array('Terra', 'query', 'Default.aspx?source=Search&query={k}'), - 'buscador.terra.cl' => array('Terra'), - 'buscador.terra.com.br' => array('Terra'), - - // Tiscali - 'search.tiscali.it' => array('Tiscali', array('q', 'key'), '?q={k}'), - 'search-dyn.tiscali.it' => array('Tiscali'), - 'hledani.tiscali.cz' => array('Tiscali', 'query'), - - // Tixuma - 'www.tixuma.de' => array('Tixuma', 'sc', 'index.php?mp=search&stp=&sc={k}&tg=0'), - - // T-Online - 'suche.t-online.de' => array('T-Online', 'q', 'fast-cgi/tsc?mandant=toi&context=internet-tab&q={k}'), - 'brisbane.t-online.de' => array('T-Online'), - 'navigationshilfe.t-online.de' => array('T-Online', 'q', 'dtag/dns/results?mode=search_top&q={k}'), - - // Toolbarhome - 'www.toolbarhome.com' => array('Toolbarhome', 'q', 'search.aspx?q={k}'), - 'vshare.toolbarhome.com' => array('Toolbarhome'), - - // Toppreise.ch - 'www.toppreise.ch' => array('Toppreise.ch', 'search', 'index.php?search={k}', 'ISO-8859-1'), - 'toppreise.ch' => array('Toppreise.ch', null, null, 'ISO-8859-1'), - 'fr.toppreise.ch' => array('Toppreise.ch', null, null, 'ISO-8859-1'), - 'de.toppreise.ch' => array('Toppreise.ch', null, null, 'ISO-8859-1'), - 'en.toppreise.ch' => array('Toppreise.ch', null, null, 'ISO-8859-1'), - - // Trouvez.com - 'www.trouvez.com' => array('Trouvez.com', 'query'), - - // TrovaRapido - 'www.trovarapido.com' => array('TrovaRapido', 'q', 'result.php?q={k}'), - - // Trusted-Search - 'www.trusted-search.com' => array('Trusted Search', 'w', 'search?w={k}'), - - // Twingly - 'www.twingly.com' => array('Twingly', 'q', 'search?q={k}'), - - // uol.com.br - 'busca.uol.com.br' => array('uol.com.br', 'q', '/web/?q={k}'), - - // URL.ORGanzier - 'www.url.org' => array('URL.ORGanzier', 'q', '?l=de&q={k}'), - - // Vinden - 'www.vinden.nl' => array('Vinden', 'q', '?q={k}'), - - // Vindex - 'www.vindex.nl' => array('Vindex', 'search_for', '/web?search_for={k}'), - 'search.vindex.nl' => array('Vindex'), - - // Virgilio - 'ricerca.virgilio.it' => array('Virgilio', 'qs', 'ricerca?qs={k}'), - 'ricercaimmagini.virgilio.it' => array('Virgilio'), - 'ricercavideo.virgilio.it' => array('Virgilio'), - 'ricercanews.virgilio.it' => array('Virgilio'), - 'mobile.virgilio.it' => array('Virgilio', 'qrs'), - - // Voila - 'search.ke.voila.fr' => array('Voila', 'rdata', 'S/voila?rdata={k}'), - 'www.lemoteur.fr' => array('Voila'), // uses voila search - - // Volny - 'web.volny.cz' => array('Volny', 'search', 'fulltext/?search={k}', 'windows-1250'), - - // Walhello - 'www.walhello.info' => array('Walhello', 'key', 'search?key={k}'), - 'www.walhello.com' => array('Walhello'), - 'www.walhello.de' => array('Walhello'), - 'www.walhello.nl' => array('Walhello'), - - // Web.de - 'suche.web.de' => array('Web.de', array('su', 'q'), 'search/web/?su={k}'), - 'm.suche.web.de' => array('Web.de'), - - // Web.nl - 'www.web.nl' => array('Web.nl', 'zoekwoord'), - - // Weborama - 'www.weborama.fr' => array('weborama', 'QUERY'), - - // WebSearch - 'www.websearch.com' => array('WebSearch', array('qkw', 'q'), 'search/results2.aspx?q={k}'), - - // Wedoo - // 2011-02-15 - keyword no longer appears to be in Referrer URL; candidate for removal? - 'fr.wedoo.com' => array('Wedoo', 'keyword'), - 'en.wedoo.com' => array('Wedoo'), - 'es.wedoo.com' => array('Wedoo'), - - // Winamp (Enhanced by Google) - 'search.winamp.com' => array('Winamp', 'q', 'search/search?q={k}'), - - // Witch - 'www.witch.de' => array('Witch', 'search', 'search-result.php?cn=0&search={k}'), - - // Wirtualna Polska - 'szukaj.wp.pl' => array('Wirtualna Polska', 'szukaj', 'http://szukaj.wp.pl/szukaj.html?szukaj={k}'), - - // Woopie - 'www.woopie.jp' => array('Woopie', 'kw', 'search?kw={k}'), - - // WWW - 'search.www.ee' => array('www värav', 'query'), - - // X-recherche - 'www.x-recherche.com' => array('X-Recherche', 'MOTS', 'cgi-bin/websearch?MOTS={k}'), - - // Yahoo! Japan - 'search.yahoo.co.jp' => array('Yahoo! Japan', array('p', 'vp'), 'search?p={k}'), - 'jp.hao123.com' => array('Yahoo! Japan', 'query'), - 'home.kingsoft.jp' => array('Yahoo! Japan', 'keyword'), - 'video.search.yahoo.co.jp' => array('Yahoo! Japan Videos', 'p', 'search?p={k}'), - 'image.search.yahoo.co.jp' => array('Yahoo! Japan Images', 'p', 'search?p={k}'), - - // Yahoo - 'search.yahoo.com' => array('Yahoo!', array('p', 'q'), 'search?p={k}'), -// '*.search.yahoo.com' => array('Yahoo!'), // see built-in helper in Common.php - 'yahoo.com' => array('Yahoo!'), - 'yahoo.{}' => array('Yahoo!'), - '{}.yahoo.com' => array('Yahoo!'), - 'cade.yahoo.com' => array('Yahoo!'), - 'espanol.yahoo.com' => array('Yahoo!'), - 'qc.yahoo.com' => array('Yahoo!'), - 'one.cn.yahoo.com' => array('Yahoo!'), - - // Powered by Yahoo APIs - 'www.cercato.it' => array('Yahoo!', 'q'), - 'search.offerbox.com' => array('Yahoo!', 'q'), - 'www.benefind.de' => array('Yahoo!', 'q'), - - // Powered by Yahoo! Search Marketing (Overture) - 'ys.mirostart.com' => array('Yahoo!', 'q'), - - // Yahoo! Directory - 'search.yahoo.com/search/dir' => array('Yahoo! Directory', 'p', '?p={k}'), -// '{}.dir.yahoo.com' => array('Yahoo! Directory'), - - // Yahoo! Images - 'images.search.yahoo.com' => array('Yahoo! Images', array('p', 'va'), 'search/images?p={k}'), -// '*.images.search.yahoo.com'=> array('Yahoo! Images'), // see built-in helper in Common.php - '{}.images.yahoo.com' => array('Yahoo! Images'), - 'cade.images.yahoo.com' => array('Yahoo! Images'), - 'espanol.images.yahoo.com' => array('Yahoo! Images'), - 'qc.images.yahoo.com' => array('Yahoo! Images'), - - // Yam - 'search.yam.com' => array('Yam', 'k', 'Search/Web/?SearchType=web&k={k}'), - - // Yandex - 'yandex.ru' => array('Yandex', 'text', 'yandsearch?text={k}'), - 'yandex.com' => array('Yandex'), - 'yandex.{}' => array('Yandex'), - - // Yandex Images - 'images.yandex.ru' => array('Yandex Images', 'text', 'yandsearch?text={k}'), - 'images.yandex.com' => array('Yandex Images'), - 'images.yandex.{}' => array('Yandex Images'), - - // Yasni - 'www.yasni.de' => array('Yasni', 'query'), - 'www.yasni.com' => array('Yasni'), - 'www.yasni.co.uk' => array('Yasni'), - 'www.yasni.ch' => array('Yasni'), - 'www.yasni.at' => array('Yasni'), - - // Yatedo - 'www.yatedo.com' => array('Yatedo', 'q', 'search/profil?q={k}'), - 'www.yatedo.fr' => array('Yatedo'), - - // Yellowmap - 'yellowmap.de' => array('Yellowmap', ' '), - - // Yippy - 'search.yippy.com' => array('Yippy', 'query', 'search?query={k}'), - - // YouGoo - 'www.yougoo.fr' => array('YouGoo', 'q', '?cx=search&q={k}'), - - // Zapmeta - 'www.zapmeta.com' => array('Zapmeta', array('q', 'query'), '?q={k}'), - 'zapmeta.{}' => array('Zapmeta'), - 'uk.zapmeta.com' => array('Zapmeta'), - 'ar.zapmeta.com' => array('Zapmeta'), - 'au.zapmeta.com' => array('Zapmeta'), - 'ca.zapmeta.com' => array('Zapmeta'), - 'fi.zapmeta.com' => array('Zapmeta'), - 'no.zapmeta.com' => array('Zapmeta'), - 'tr.zapmeta.com' => array('Zapmeta'), - - // Zoek - 'www3.zoek.nl' => array('Zoek', 'q'), - - // Zhongsou - 'p.zhongsou.com' => array('Zhongsou', 'w', 'p?w={k}'), - - // Zoeken - 'www.zoeken.nl' => array('Zoeken', 'q', '?q={k}'), - - // Zoohoo - 'zoohoo.cz' => array('Zoohoo', 'q', '?q={k}', 'windows-1250'), - - // Zoznam - 'www.zoznam.sk' => array('Zoznam', 's', 'hladaj.fcgi?s={k}&co=svet'), - - // Zxuso - 'www.zxuso.com' => array('Zxuso', 'wd', 'ri/?wd={k}'), - ); -} diff --git a/core/DataFiles/Socials.php b/core/DataFiles/Socials.php deleted file mode 100755 index 92b131b49654eb4be3ad1293a9c60a610c9e9a70..0000000000000000000000000000000000000000 --- a/core/DataFiles/Socials.php +++ /dev/null @@ -1,230 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ - -if (!isset($GLOBALS['Piwik_socialUrl'])) { - // Note: the key of the array should have max 3 elements eg. sub.domain.ext - $GLOBALS['Piwik_socialUrl'] = array( - - // Facebook - 'facebook.com' => 'Facebook', - 'fb.me' => 'Facebook', - - // Ozone - 'qzone.qq.com' => 'Qzone', - - // Haboo - 'habbo.com' => 'Haboo', - - // Twitter - 'twitter.com' => 'Twitter', - 't.co' => 'Twitter', - - // Renren - 'renren.com' => 'Renren', - - // Windows Live Spaces - 'login.live.com' => 'Windows Live Spaces', - - // LinkedIn - 'linkedin.com' => 'LinkedIn', - - // Bebo - 'bebo.com' => 'Bebo', - - // Vkontakte - 'vk.com' => 'Vkontakte', - 'vkontakte.ru' => 'Vkontakte', - - // Tagged - 'login.tagged.com' => 'Tagged', - - // Orkut - 'orkut.com' => 'Orkut', - - // Myspace - 'myspace.com' => 'Myspace', - - // Frinedster - 'friendster.com' => 'Friendster', - - // Badoo - 'badoo.com' => 'Badoo', - - // hi5 - 'hi5.com' => 'hi5', - - // Netlog - 'netlog.com' => 'Netlog', - - // Flixster - 'flixster.com' => 'Flixster', - - // MyLife - 'mylife.ru' => 'MyLife', - - // Classmates.com - 'classmates.com' => 'Classmates.com', - - // Github - 'github.com' => 'Github', - - // Google+ - 'plus.google.com' => 'Google%2B', - 'url.google.com' => 'Google%2B', - - // douban - 'douban.com' => 'douban', - - // dribbble - 'dribbble.com' => 'dribbble', - - // Odnoklassniki - 'odnoklassniki.ru' => 'Odnoklassniki', - - // Viadeo - 'viadeo.com' => 'Viadeo', - - // Flickr - 'flickr.com' => 'Flickr', - - // WeeWorld - 'weeworld.com' => 'WeeWorld', - - // Last.fm - 'last.fm' => 'Last.fm', - 'lastfm.ru' => 'Last.fm', - 'lastfm.de' => 'Last.fm', - 'lastfm.es' => 'Last.fm', - 'lastfm.fr' => 'Last.fm', - 'lastfm.it' => 'Last.fm', - 'lastfm.jp' => 'Last.fm', - 'lastfm.pl' => 'Last.fm', - 'lastfm.com.br' => 'Last.fm', - 'lastfm.se' => 'Last.fm', - 'lastfm.com.tr' => 'Last.fm', - - // MyHeritage - 'myheritage.com' => 'MyHeritage', - - // Xanga - 'xanga.com' => 'Xanga', - - // Mixi - 'mixi.jp' => 'Mixi', - - // Cyworld - 'global.cyworld.com' => 'Cyworld', - - // Gaia Online - 'gaiaonline.com' => 'Gaia Online', - - // Skyrock - 'skyrock.com' => 'Skyrock', - - // BlackPlanet - 'blackplanet.com' => 'BlackPlanet', - - // myYearbook - 'myyearbook.com' => 'myYearbook', - - // Fotolog - 'fotolog.com' => 'Fotolog', - - // Friends Reunited - 'friendsreunited.com' => 'Friends Reunited', - - // LiveJournal - 'livejournal.ru' => 'LiveJournal', - 'livejournal.com' => 'LiveJournal', - - // StudiVZ/MeinVZ - 'studivz.net' => 'StudiVZ', - 'meinvz.net' => 'MeinVZ', - - // StackOverflow - 'stackoverflow.com' => 'StackOverflow', - - // Sonico.com - 'sonico.com' => 'Sonico.com', - - // Pinterest - 'pinterest.com' => 'Pinterest', - - // Plaxo - 'plaxo.com' => 'Plaxo', - - // Geni.com - 'geni.com' => 'Geni.com', - - // Tuenti - 'tuenti.com' => 'Tuenti', - - // XING - 'xing.com' => 'XING', - - // Taringa! - 'taringa.net' => 'Taringa!', - - // Nasza-klasa.pl - 'nk.pl' => 'Nasza-klasa.pl', - - // StumbleUpon - 'stumbleupon.com' => 'StumbleUpon', - - // Sourceforge - 'sourceforge.net' => 'SourceForge', - - // Hyves - 'hyves.nl' => 'Hyves', - - // WAYN - 'wayn.com' => 'WAYN', - - // Buzznet - 'buzznet.com' => 'Buzznet', - - // Multiply - 'multiply.com' => 'Multiply', - - // Foursquare - 'foursquare.com' => 'Foursquare', - - // vkrugudruzei.ru - 'vkrugudruzei.ru' => 'vkrugudruzei.ru', - - // my.mail.ru - 'my.mail.ru' => 'my.mail.ru', - - //MoiKrug.ru - 'moikrug.ru' => 'moikrug.ru', - - // Reddit - 'reddit.com' => 'reddit', - - // HackerNews - 'news.ycombinator.com' => 'Hacker News', - - // Identi.ca - 'identi.ca' => 'identi.ca', - - // Weibo - 'weibo.com' => 'Weibo', - 't.cn' => 'Weibo', - - // YouTube - 'youtube.com' => 'YouTube', - 'youtu.be' => 'YouTube', - - // Vimeo - 'vimeo.com' => 'Vimeo', - - //tumblr - 'tumblr.com' => 'tumblr', - ); -} diff --git a/core/DataTable.php b/core/DataTable.php index a297b6c70b2a44f098194dbea65642a6f7cecf35..326f25fc6f838ce888378c0b16027f7c7ee1f8f0 100644 --- a/core/DataTable.php +++ b/core/DataTable.php @@ -170,7 +170,7 @@ class DataTable implements DataTableInterface, \IteratorAggregate, \ArrayAccess const MAX_DEPTH_DEFAULT = 15; /** Name for metadata that describes when a report was archived. */ - const ARCHIVED_DATE_METADATA_NAME = 'archived_date'; + const ARCHIVED_DATE_METADATA_NAME = 'ts_archived'; /** Name for metadata that describes which columns are empty and should not be shown. */ const EMPTY_COLUMNS_METADATA_NAME = 'empty_column'; diff --git a/core/DataTable/Renderer/Csv.php b/core/DataTable/Renderer/Csv.php index 4eee1949b7a96b9dd5ef289ec8c9aa13eef442f6..c3fb08b15ae99b716de4045849a79b6179dbd626 100644 --- a/core/DataTable/Renderer/Csv.php +++ b/core/DataTable/Renderer/Csv.php @@ -70,6 +70,8 @@ class Csv extends Renderer */ const NO_DATA_AVAILABLE = 'No data available'; + private $unsupportedColumns = array(); + /** * Computes the dataTable output and returns the string/binary * @@ -213,6 +215,12 @@ class Csv extends Renderer */ private function getHeaderLine($columnMetrics) { + foreach ($columnMetrics as $index => $value) { + if (in_array($value, $this->unsupportedColumns)) { + unset($columnMetrics[$index]); + } + } + if ($this->translateColumnNames) { $columnMetrics = $this->translateColumnNames($columnMetrics); } @@ -391,12 +399,23 @@ class Csv extends Renderer $name = 'metadata_' . $name; } - $csvRow[$name] = $value; + if (is_array($value)) { + if (!in_array($name, $this->unsupportedColumns)) { + $this->unsupportedColumns[] = $name; + } + } else { + $csvRow[$name] = $value; + } + } } foreach ($csvRow as $name => $value) { - $allColumns[$name] = true; + if (in_array($name, $this->unsupportedColumns)) { + unset($allColumns[$name]); + } else { + $allColumns[$name] = true; + } } if ($this->exportIdSubtable) { @@ -410,6 +429,15 @@ class Csv extends Renderer $csv[] = $csvRow; } + + if (!empty($this->unsupportedColumns)) { + foreach ($this->unsupportedColumns as $unsupportedColumn) { + foreach ($csv as $index => $row) { + unset($row[$index][$unsupportedColumn]); + } + } + } + return $csv; } diff --git a/core/DataTable/Row.php b/core/DataTable/Row.php index 70ef662710d772371d3abebea20ffaecebddedf1..3bd3b023d8619c9b7e5c1b7eada8780f26ba0054 100644 --- a/core/DataTable/Row.php +++ b/core/DataTable/Row.php @@ -480,7 +480,7 @@ class Row extends \ArrayObject } if ($enableCopyMetadata) { - $this->sumRowMetadata($rowToSum); + $this->sumRowMetadata($rowToSum, $aggregationOperations); } } @@ -507,6 +507,19 @@ class Row extends \ArrayObject case 'sum': $newValue = $this->sumRowArray($thisColumnValue, $columnToSumValue); break; + case 'uniquearraymerge': + if (is_array($thisColumnValue) && is_array($columnToSumValue)) { + foreach ($columnToSumValue as $columnSum) { + if (!in_array($columnSum, $thisColumnValue)) { + $thisColumnValue[] = $columnSum; + } + } + } elseif (!is_array($thisColumnValue) && is_array($columnToSumValue)) { + $thisColumnValue = $columnToSumValue; + } + + $newValue = $thisColumnValue; + break; default: throw new Exception("Unknown operation '$operation'."); } @@ -517,12 +530,29 @@ class Row extends \ArrayObject * Sums the metadata in `$rowToSum` with the metadata in `$this` row. * * @param Row $rowToSum + * @param array $aggregationOperations */ - public function sumRowMetadata($rowToSum) + public function sumRowMetadata($rowToSum, $aggregationOperations = array()) { if (!empty($rowToSum->metadata) && !$this->isSummaryRow() ) { + $aggregatedMetadata = array(); + + if (is_array($aggregationOperations)) { + // we need to aggregate value before value is overwritten by maybe another row + foreach ($aggregationOperations as $columnn => $operation) { + $thisMetadata = $this->getMetadata($columnn); + $sumMetadata = $rowToSum->getMetadata($columnn); + + if ($thisMetadata === false && $sumMetadata === false) { + continue; + } + + $aggregatedMetadata[$columnn] = $this->getColumnValuesMerged($operation, $thisMetadata, $sumMetadata); + } + } + // We shall update metadata, and keep the metadata with the _most visits or pageviews_, rather than first or last seen $visits = max($rowToSum->getColumn(Metrics::INDEX_PAGE_NB_HITS) || $rowToSum->getColumn(Metrics::INDEX_NB_VISITS), // Old format pre-1.2, @see also method doSumVisitsMetrics() @@ -533,6 +563,11 @@ class Row extends \ArrayObject $this->maxVisitsSummed = $visits; $this->metadata = $rowToSum->metadata; } + + foreach ($aggregatedMetadata as $column => $value) { + // we need to make sure aggregated value is used, and not metadata from $rowToSum + $this->setMetadata($column, $value); + } } } diff --git a/core/Date.php b/core/Date.php index bac8ce7db237e3c7c32fb080303b319394b5e97f..cbbe8667080c37f11877af618303ddd8effcb0df 100644 --- a/core/Date.php +++ b/core/Date.php @@ -11,6 +11,8 @@ namespace Piwik; use Exception; use Piwik\Container\StaticContainer; +use Piwik\Intl\Data\Provider\DateTimeFormatProvider; +use Piwik\Plugins\LanguagesManager\LanguagesManager; /** * Utility class that wraps date/time related PHP functions. Using this class can @@ -41,15 +43,15 @@ class Date /** The default date time string format. */ const DATE_TIME_FORMAT = 'Y-m-d H:i:s'; - const DATETIME_FORMAT_LONG = 'Intl_Format_DateTime_Long'; - const DATETIME_FORMAT_SHORT = 'Intl_Format_DateTime_Short'; - const DATE_FORMAT_LONG = 'Intl_Format_Date_Long'; - const DATE_FORMAT_DAY_MONTH = 'Intl_Format_Date_Day_Month'; - const DATE_FORMAT_SHORT = 'Intl_Format_Date_Short'; - const DATE_FORMAT_MONTH_SHORT = 'Intl_Format_Month_Short'; - const DATE_FORMAT_MONTH_LONG = 'Intl_Format_Month_Long'; - const DATE_FORMAT_YEAR = 'Intl_Format_Year'; - const TIME_FORMAT = 'Intl_Format_Time'; + const DATETIME_FORMAT_LONG = DateTimeFormatProvider::DATE_FORMAT_LONG; + const DATETIME_FORMAT_SHORT = DateTimeFormatProvider::DATETIME_FORMAT_SHORT; + const DATE_FORMAT_LONG = DateTimeFormatProvider::DATE_FORMAT_LONG; + const DATE_FORMAT_DAY_MONTH = DateTimeFormatProvider::DATE_FORMAT_DAY_MONTH; + const DATE_FORMAT_SHORT = DateTimeFormatProvider::DATE_FORMAT_SHORT; + const DATE_FORMAT_MONTH_SHORT = DateTimeFormatProvider::DATE_FORMAT_MONTH_SHORT; + const DATE_FORMAT_MONTH_LONG = DateTimeFormatProvider::DATE_FORMAT_MONTH_LONG; + const DATE_FORMAT_YEAR = DateTimeFormatProvider::DATE_FORMAT_YEAR; + const TIME_FORMAT = DateTimeFormatProvider::TIME_FORMAT; /** * Max days for months (non-leap-year). See {@link addPeriod()} implementation. @@ -622,10 +624,9 @@ class Date { $template = $this->replaceLegacyPlaceholders($template); - if (substr($template, 0, 5) == 'Intl_') { - $translator = StaticContainer::get('Piwik\Translation\Translator'); - $template = $translator->translate($template); - } + $dateTimeFormatProvider = StaticContainer::get('Piwik\Intl\Data\Provider\DateTimeFormatProvider'); + + $template = $dateTimeFormatProvider->getFormatPattern($template); $tokens = self::parseFormat($template); diff --git a/core/Db.php b/core/Db.php index 12798d2ff5215da72b360c7e0febe1f6a5945ca4..f7eae8c8b26e16a5d6153c95ab4c18417d3bf828 100644 --- a/core/Db.php +++ b/core/Db.php @@ -33,7 +33,7 @@ use Piwik\Db\Adapter; */ class Db { - const SQL_MODE = 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE'; + const SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO'; private static $connection = null; diff --git a/core/Db/Adapter/Pdo/Mysql.php b/core/Db/Adapter/Pdo/Mysql.php index aaf93e1b6b8a649e039ad2a580a2f6a2804fb740..9e26fb7a2bb0d11ec5fc4b03e8d8989092de1d92 100644 --- a/core/Db/Adapter/Pdo/Mysql.php +++ b/core/Db/Adapter/Pdo/Mysql.php @@ -246,4 +246,19 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface $this->cachePreparedStatement[$sql] = $stmt; return $stmt; } + + /** + * Override _dsn() to ensure host and port to not be passed along + * if unix_socket is set since setting both causes unexpected behaviour + * @see http://php.net/manual/en/ref.pdo-mysql.connection.php + */ + protected function _dsn() + { + if (!empty($this->_config['unix_socket'])) { + unset($this->_config['host']); + unset($this->_config['port']); + } + + return parent::_dsn(); + } } diff --git a/core/Filesystem.php b/core/Filesystem.php index 7549192a2c567826afe1f8b2a5c49885e64d8da3..c22a4d0b2106a9b809b5352f265fe307bb3bedfa 100644 --- a/core/Filesystem.php +++ b/core/Filesystem.php @@ -135,9 +135,8 @@ class Filesystem $output = @shell_exec($command); if ($output) { - $output = explode("\n", trim($output)); - $commandFailed = (false !== strpos($output, "no file systems processed")); + $output = explode("\n", trim($output)); if (!$commandFailed && count($output) > 1) { // check if filesystem is NFS diff --git a/core/FrontController.php b/core/FrontController.php index 4b47d9024ba319bfb1952a66b08faf40e823ccde..e276ed53e7bf9845f4339a0cf828818e87d830ee 100644 --- a/core/FrontController.php +++ b/core/FrontController.php @@ -65,6 +65,11 @@ class FrontController extends Singleton */ public static $enableDispatch = true; + /** + * @var bool + */ + private $initialized = false; + /** * Executes the requested plugin controller method. * @@ -197,11 +202,11 @@ class FrontController extends Singleton */ public function init() { - static $initialized = false; - if ($initialized) { + if ($this->initialized) { return; } - $initialized = true; + + $this->initialized = true; $tmpPath = StaticContainer::get('path.tmp'); diff --git a/core/IP.php b/core/IP.php index 6e27832e4817f76f069560cd7de658db566b67df..670c674544d1ca761748dcbb9a4788bd0cda7d4d 100644 --- a/core/IP.php +++ b/core/IP.php @@ -101,7 +101,7 @@ class IP * * @param string $csv Comma separated list of elements. * @param array $excludedIps Optional list of excluded IP addresses (or IP address ranges). - * @return string Last (non-excluded) IP address in the list. + * @return string Last (non-excluded) IP address in the list or an empty string if all given IPs are excluded. */ public static function getLastIpFromList($csv, $excludedIps = null) { @@ -115,6 +115,8 @@ class IP return $element; } } + + return ''; } return trim(Common::sanitizeInputValue($csv)); } diff --git a/core/Intl/Data/Provider/DateTimeFormatProvider.php b/core/Intl/Data/Provider/DateTimeFormatProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..90ffad609ff75ac42b5ccb62e6ce8e3716d87b4f --- /dev/null +++ b/core/Intl/Data/Provider/DateTimeFormatProvider.php @@ -0,0 +1,83 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Intl\Data\Provider; + +/** + * Provides date and time formats. + */ +class DateTimeFormatProvider +{ + const DATETIME_FORMAT_LONG = 1; + const DATETIME_FORMAT_SHORT = 2; + const DATE_FORMAT_LONG = 10; + const DATE_FORMAT_DAY_MONTH = 11; + const DATE_FORMAT_SHORT = 12; + const DATE_FORMAT_MONTH_SHORT = 13; + const DATE_FORMAT_MONTH_LONG = 14; + const DATE_FORMAT_YEAR = 15; + const TIME_FORMAT = 20; + + /** + * Returns the format pattern for the given format type + * + * @param int $format one of the format constants + * + * @return string + */ + public function getFormatPattern($format) + { + switch ($format) { + case self::DATETIME_FORMAT_LONG: + return 'EEEE, MMMM d, y HH:mm:ss'; + + case self::DATETIME_FORMAT_SHORT: + return 'MMM d, y HH:mm:ss'; + + case self::DATE_FORMAT_LONG: + return 'EEEE, MMMM d, y'; + + case self::DATE_FORMAT_DAY_MONTH: + return 'E, MMM d'; + + case self::DATE_FORMAT_SHORT: + return 'MMM d, y'; + + case self::DATE_FORMAT_MONTH_SHORT: + return 'MMM y'; + + case self::DATE_FORMAT_MONTH_LONG: + return 'MMMM y'; + + case self::DATE_FORMAT_YEAR: + return 'y'; + + case self::TIME_FORMAT: + return 'HH:mm:ss'; + } + + return $format; + } + + /** + * Returns interval format pattern for the given format type + * + * @param bool $short whether to return short or long format pattern + * @param string $maxDifference maximal difference in interval dates (Y, M or D) + * + * @return string + */ + public function getRangeFormatPattern($short=false, $maxDifference='Y') + { + if ($short) { + return 'MMM d, y – MMM d, y'; + } + + return 'MMMM d, y – MMMM d, y'; + } +} diff --git a/core/Metrics/Formatter.php b/core/Metrics/Formatter.php index 077646ba00186d3ca2e5dd41ec16ed6c5e43c42d..d62db65f31cf5a7f3f570f586bab0e3b97deab45 100644 --- a/core/Metrics/Formatter.php +++ b/core/Metrics/Formatter.php @@ -72,10 +72,15 @@ class Formatter // Display 01:45:17 time format if ($displayTimeAsSentence === false) { - $hours = floor($numberOfSeconds / 3600); - $minutes = floor(($reminder = ($numberOfSeconds - $hours * 3600)) / 60); + $days = floor($numberOfSeconds / 86400); + $hours = floor(($reminder = ($numberOfSeconds - $days * 86400)) / 3600); + $minutes = floor(($reminder = ($reminder - $hours * 3600)) / 60); $seconds = floor($reminder - $minutes * 60); - $time = sprintf("%02s", $hours) . ':' . sprintf("%02s", $minutes) . ':' . sprintf("%02s", $seconds); + if ($days == 0) { + $time = sprintf("%02s", $hours) . ':' . sprintf("%02s", $minutes) . ':' . sprintf("%02s", $seconds); + } else { + $time = sprintf(Piwik::translate('Intl_NDays'), $days) . " " . sprintf("%02s", $hours) . ':' . sprintf("%02s", $minutes) . ':' . sprintf("%02s", $seconds); + } $centiSeconds = ($numberOfSeconds * 100) % 100; if ($centiSeconds) { $time .= '.' . sprintf("%02s", $centiSeconds); diff --git a/core/Period.php b/core/Period.php index 70a47d29055c8fdb8bc2eacea58780f98fee4da3..aecf6362bf5d06de2a5153e050b5029923cdd204 100644 --- a/core/Period.php +++ b/core/Period.php @@ -371,12 +371,9 @@ abstract class Period $maxDifference = 'M'; } - return $this->translator->translate( - sprintf( - 'Intl_Format_Interval_%s_%s', - $short ? 'Short' : 'Long', - $maxDifference - )); + $dateTimeFormatProvider = StaticContainer::get('Piwik\Intl\Data\Provider\DateTimeFormatProvider'); + + return $dateTimeFormatProvider->getRangeFormatPattern($short, $maxDifference); } /** diff --git a/core/Plugin/ControllerAdmin.php b/core/Plugin/ControllerAdmin.php index 44357955bee0bcbd22399eb5606450f0280f2951..1ee1b33ad71c01c70fb5719bb44af6632f7931f2 100644 --- a/core/Plugin/ControllerAdmin.php +++ b/core/Plugin/ControllerAdmin.php @@ -124,12 +124,13 @@ abstract class ControllerAdmin extends Controller private static function notifyWhenPhpVersionIsEOL() { - $notifyPhpIsEOL = Piwik::hasUserSuperUserAccess() && self::isPhpVersion54(); + return; // no supported version (5.5+) has currently ended support + $notifyPhpIsEOL = Piwik::hasUserSuperUserAccess() && self::isPhpVersionAtLeast55(); if (!$notifyPhpIsEOL) { return; } - $message = Piwik::translate('General_WarningPhpVersionXIsTooOld', '5.4'); + $message = Piwik::translate('General_WarningPhpVersionXIsTooOld', '5.5'); $notification = new Notification($message); $notification->title = Piwik::translate('General_Warning'); $notification->priority = Notification::PRIORITY_LOW; @@ -234,11 +235,11 @@ abstract class ControllerAdmin extends Controller private static function checkPhpVersion($view) { $view->phpVersion = PHP_VERSION; - $view->phpIsNewEnough = version_compare($view->phpVersion, '5.4.0', '>='); + $view->phpIsNewEnough = self::isPhpVersionAtLeast55(); } - private static function isPhpVersion54() + private static function isPhpVersionAtLeast55() { - return strpos(PHP_VERSION, '5.4') === 0; + return version_compare(PHP_VERSION, '5.5', '>='); } } diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php index 77b058b11384245812cd3d6e3b56abdbecc1f1d9..c3974937a0df2c4dc53bd650094f1eb49707d9bb 100644 --- a/core/Plugin/Manager.php +++ b/core/Plugin/Manager.php @@ -440,16 +440,10 @@ class Manager public function installLoadedPlugins() { Log::debug("Loaded plugins: " . implode(", ", array_keys($this->getLoadedPlugins()))); - $messages = array(); + foreach ($this->getLoadedPlugins() as $plugin) { - try { - $this->installPluginIfNecessary($plugin); - } catch (\Exception $e) { - $messages[] = $e->getMessage(); - } + $this->installPluginIfNecessary($plugin); } - - return $messages; } /** @@ -499,7 +493,7 @@ class Manager { $existingPlugins = $this->readPluginsDirectory(); $isPluginInFilesystem = array_search($pluginName, $existingPlugins) !== false; - return Filesystem::isValidFilename($pluginName) + return $this->isValidPluginName($pluginName) && $isPluginInFilesystem; } @@ -896,6 +890,11 @@ class Manager return $newPlugin; } + public function isValidPluginName($pluginName) + { + return (bool) preg_match('/^[a-zA-Z]([a-zA-Z0-9]*)$/D', $pluginName); + } + /** * @param $pluginName * @return Plugin @@ -906,8 +905,8 @@ class Manager $pluginFileName = sprintf("%s/%s.php", $pluginName, $pluginName); $pluginClassName = $pluginName; - if (!Filesystem::isValidFilename($pluginName)) { - throw new \Exception(sprintf("The plugin filename '%s' is not a valid filename", $pluginFileName)); + if (!$this->isValidPluginName($pluginName)) { + throw new \Exception(sprintf("The plugin filename '%s' is not a valid plugin name", $pluginFileName)); } $path = self::getPluginsDirectory() . $pluginFileName; @@ -1071,11 +1070,20 @@ class Manager if ($saveConfig) { PiwikConfig::getInstance()->forceSave(); + $this->clearCache($pluginName); } } public function isTrackerPlugin(Plugin $plugin) { + if (!$this->isPluginInstalled($plugin->getPluginName())) { + return false; + } + + if ($plugin->isTrackerPlugin()) { + return true; + } + $dimensions = VisitDimension::getDimensions($plugin); if (!empty($dimensions)) { return true; @@ -1102,10 +1110,6 @@ class Manager return true; } - if ($plugin->isTrackerPlugin()) { - return true; - } - return false; } diff --git a/core/Plugin/PluginException.php b/core/Plugin/PluginException.php index 90aa03a342c66c80d8afbeba5eea721f6ec79e7b..83816ca365bc996e627616e0a76576c236de7211 100644 --- a/core/Plugin/PluginException.php +++ b/core/Plugin/PluginException.php @@ -8,14 +8,28 @@ namespace Piwik\Plugin; +use Piwik\Common; + class PluginException extends \Exception { public function __construct($pluginName, $message) { - parent::__construct("There was a problem installing the plugin " . $pluginName . ": " . $message . " - If this plugin has already been installed, and if you want to hide this message</b>, you must add the following line under the - [PluginsInstalled] - entry in your config/config.ini.php file: - PluginsInstalled[] = $pluginName"); + $pluginName = Common::sanitizeInputValue($pluginName); + $message = Common::sanitizeInputValue($message); + + parent::__construct("There was a problem installing the plugin $pluginName: <br /><br /> + $message + <br /><br /> + If you want to hide this message you must remove the following line under the [Plugins] entry in your + 'config/config.ini.php' file to disable this plugin.<br /> + Plugins[] = $pluginName + <br /><br />If this plugin has already been installed, you must add the following line under the + [PluginsInstalled] entry in your 'config/config.ini.php' file:<br /> + PluginsInstalled[] = $pluginName"); + } + + public function isHtmlMessage() + { + return true; } } diff --git a/core/Plugin/RequestProcessors.php b/core/Plugin/RequestProcessors.php new file mode 100644 index 0000000000000000000000000000000000000000..827274485e134fb1acd20ad427f5b5aadc122028 --- /dev/null +++ b/core/Plugin/RequestProcessors.php @@ -0,0 +1,27 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugin; + +use Piwik\Container\StaticContainer; + +class RequestProcessors +{ + public function getRequestProcessors() + { + $manager = Manager::getInstance(); + $processors = $manager->findMultipleComponents('Tracker', 'Piwik\\Tracker\\RequestProcessor'); + + $instances = array(); + foreach ($processors as $processor) { + $instances[] = StaticContainer::get($processor); + } + + return $instances; + } +} diff --git a/core/Plugin/Segment.php b/core/Plugin/Segment.php index 8a9688fb0b0ae7ca356c5ea3ba39f23c7918609e..2a20208ea28f050e9304a4c2dbdfef59a7373dba 100644 --- a/core/Plugin/Segment.php +++ b/core/Plugin/Segment.php @@ -7,6 +7,7 @@ * */ namespace Piwik\Plugin; +use Exception; /** * Creates a new segment that can be used for instance within the {@link \Piwik\Columns\Dimension::configureSegment()} @@ -51,6 +52,7 @@ class Segment private $acceptValues; private $permission; private $suggestedValuesCallback; + private $unionOfSegments; /** * If true, this segment will only be visible to the user if the user has view access @@ -122,6 +124,7 @@ class Segment public function setSegment($segment) { $this->segment = $segment; + $this->check(); } /** @@ -165,6 +168,29 @@ class Segment public function setSqlSegment($sqlSegment) { $this->sqlSegment = $sqlSegment; + $this->check(); + } + + /** + * Set a list of segments that should be used instead of fetching the values from a single column. + * All set segments will be applied via an OR operator. + * + * @param array $segments + * @api + */ + public function setUnionOfSegments($segments) + { + $this->unionOfSegments = $segments; + $this->check(); + } + + /** + * @return array + * @ignore + */ + public function getUnionOfSegments() + { + return $this->unionOfSegments; } /** @@ -195,6 +221,15 @@ class Segment return $this->type; } + /** + * @return string + * @ignore + */ + public function getName() + { + return $this->name; + } + /** * Returns the name of this segment as it should appear in segment expressions. * @@ -241,6 +276,10 @@ class Segment 'sqlSegment' => $this->sqlSegment, ); + if (!empty($this->unionOfSegments)) { + $segment['unionOfSegments'] = $this->unionOfSegments; + } + if (!empty($this->sqlFilter)) { $segment['sqlFilter'] = $this->sqlFilter; } @@ -288,4 +327,15 @@ class Segment { $this->requiresAtLeastViewAccess = $requiresAtLeastViewAccess; } + + private function check() + { + if ($this->sqlSegment && $this->unionOfSegments) { + throw new Exception(sprintf('Union of segments and SQL segment is set for segment "%s", use only one of them', $this->name)); + } + + if ($this->segment && $this->unionOfSegments && in_array($this->segment, $this->unionOfSegments, true)) { + throw new Exception(sprintf('The segment %s contains a union segment to itself', $this->name)); + } + } } diff --git a/core/Plugin/Visualization.php b/core/Plugin/Visualization.php index 81e99c9f25c8b7a53f5348a95df57b95e41918cb..da2c60c18eb53b744717df577843e4a1fe42d8db 100644 --- a/core/Plugin/Visualization.php +++ b/core/Plugin/Visualization.php @@ -273,7 +273,18 @@ class Visualization extends ViewDataTable $idSite = Common::getRequestVar('idSite', null, 'string', $request); $module = $this->requestConfig->getApiModuleToRequest(); $action = $this->requestConfig->getApiMethodToRequest(); - $metadata = ApiApi::getInstance()->getMetadata($idSite, $module, $action); + + $apiParameters = array(); + $idDimension = Common::getRequestVar('idDimension', 0, 'int'); + $idGoal = Common::getRequestVar('idGoal', 0, 'int'); + if ($idDimension > 0) { + $apiParameters['idDimension'] = $idDimension; + } + if ($idGoal > 0) { + $apiParameters['idGoal'] = $idGoal; + } + + $metadata = ApiApi::getInstance()->getMetadata($idSite, $module, $action, $apiParameters); if (!empty($metadata)) { return array_shift($metadata); @@ -360,7 +371,7 @@ class Visualization extends ViewDataTable $this->metadata = $this->dataTable->getAllTableMetadata(); if (isset($this->metadata[DataTable::ARCHIVED_DATE_METADATA_NAME])) { - $this->config->report_last_updated_message = $this->makePrettyArchivedOnText(); + $this->reportLastUpdatedMessage = $this->makePrettyArchivedOnText(); } } @@ -474,7 +485,8 @@ class Visualization extends ViewDataTable $prettyDate = $date->getLocalized(Date::DATE_FORMAT_SHORT); - return Piwik::translate('CoreHome_ReportGeneratedOn', $prettyDate); + $timezoneAppend = ' (UTC)'; + return Piwik::translate('CoreHome_ReportGeneratedOn', $prettyDate) . $timezoneAppend; } /** diff --git a/core/Profiler.php b/core/Profiler.php index c1b0875fa646e99f6ea971ebdb35614c82ccd5f1..12c1e46ff6025394923f306b3b8a92b1af08e36f 100644 --- a/core/Profiler.php +++ b/core/Profiler.php @@ -209,13 +209,9 @@ class Profiler return; } - $xhProfPath = PIWIK_INCLUDE_PATH . '/vendor/facebook/xhprof/extension/modules/xhprof.so'; - if (!file_exists($xhProfPath)) { - throw new Exception("Cannot find xhprof, run 'composer install --dev' and build the extension."); - } - if (!function_exists('xhprof_enable')) { - throw new Exception("Cannot find xhprof_enable, make sure to add 'extension=$xhProfPath' to your php.ini."); + $xhProfPath = PIWIK_INCLUDE_PATH . '/vendor/facebook/xhprof/extension/modules/xhprof.so'; + throw new Exception("Cannot find xhprof_enable, make sure to 1) install xhprof: run 'composer install --dev' and build the extension, and 2) add 'extension=$xhProfPath' to your php.ini."); } $outputDir = ini_get("xhprof.output_dir"); diff --git a/core/Segment.php b/core/Segment.php index 451afdb393282dc2ebe8ebff64bd53647f80ef99..d9f8d163c6895575766dcbe94ee15bcc37f1a022 100644 --- a/core/Segment.php +++ b/core/Segment.php @@ -110,6 +110,35 @@ class Segment } } + private function getAvailableSegments() + { + // segment metadata + if (empty($this->availableSegments)) { + $this->availableSegments = API::getInstance()->getSegmentsMetadata($this->idSites, $_hideImplementationData = false); + } + + return $this->availableSegments; + } + + private function getSegmentByName($name) + { + $segments = $this->getAvailableSegments(); + + foreach ($segments as $segment) { + if ($segment['segment'] == $name && !empty($name)) { + + // check permission + if (isset($segment['permission']) && $segment['permission'] != 1) { + throw new NoAccessException("You do not have enough permission to access the segment " . $name); + } + + return $segment; + } + } + + throw new Exception("Segment '$name' is not a supported segment."); + } + /** * @param $string * @param $idSites @@ -127,6 +156,7 @@ class Segment // parse segments $expressions = $segment->parseSubExpressions(); + $expressions = $this->getExpressionsWithUnionsResolved($expressions); // convert segments name to sql segment // check that user is allowed to view this segment @@ -142,6 +172,41 @@ class Segment $segment->setSubExpressionsAfterCleanup($cleanedExpressions); } + private function getExpressionsWithUnionsResolved($expressions) + { + $expressionsWithUnions = array(); + foreach ($expressions as $expression) { + $operand = $expression[SegmentExpression::INDEX_OPERAND]; + $name = $operand[SegmentExpression::INDEX_OPERAND_NAME]; + + $availableSegment = $this->getSegmentByName($name); + + if (!empty($availableSegment['unionOfSegments'])) { + $count = 0; + foreach ($availableSegment['unionOfSegments'] as $segmentNameOfUnion) { + $count++; + $operator = SegmentExpression::BOOL_OPERATOR_OR; // we connect all segments within that union via OR + if ($count === count($availableSegment['unionOfSegments'])) { + $operator = $expression[SegmentExpression::INDEX_BOOL_OPERATOR]; + } + + $operand[SegmentExpression::INDEX_OPERAND_NAME] = $segmentNameOfUnion; + $expressionsWithUnions[] = array( + SegmentExpression::INDEX_BOOL_OPERATOR => $operator, + SegmentExpression::INDEX_OPERAND => $operand + ); + } + } else { + $expressionsWithUnions[] = array( + SegmentExpression::INDEX_BOOL_OPERATOR => $expression[SegmentExpression::INDEX_BOOL_OPERATOR], + SegmentExpression::INDEX_OPERAND => $operand + ); + } + } + + return $expressionsWithUnions; + } + /** * Returns `true` if the segment is empty, `false` if otherwise. */ @@ -154,33 +219,15 @@ class Segment protected function getCleanedExpression($expression) { - if (empty($this->availableSegments)) { - $this->availableSegments = API::getInstance()->getSegmentsMetadata($this->idSites, $_hideImplementationData = false); - } + $name = $expression[SegmentExpression::INDEX_OPERAND_NAME]; + $matchType = $expression[SegmentExpression::INDEX_OPERAND_OPERATOR]; + $value = $expression[SegmentExpression::INDEX_OPERAND_VALUE]; - $name = $expression[0]; - $matchType = $expression[1]; - $value = $expression[2]; - $sqlName = ''; + $segment = $this->getSegmentByName($name); + $sqlName = $segment['sqlSegment']; - foreach ($this->availableSegments as $segment) { - if ($segment['segment'] != $name) { - continue; - } - - $sqlName = $segment['sqlSegment']; - - // check permission - if (isset($segment['permission']) - && $segment['permission'] != 1 - ) { - throw new NoAccessException("You do not have enough permission to access the segment " . $name); - } - - if ($matchType == SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY - || $matchType == SegmentExpression::MATCH_IS_NULL_OR_EMPTY) { - break; - } + if ($matchType != SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY + && $matchType != SegmentExpression::MATCH_IS_NULL_OR_EMPTY) { if (isset($segment['sqlFilterValue'])) { $value = call_user_func($segment['sqlFilterValue'], $value); @@ -201,12 +248,6 @@ class Segment $matchType = SegmentExpression::MATCH_ACTIONS_CONTAINS; } } - - break; - } - - if (empty($sqlName)) { - throw new Exception("Segment '$name' is not a supported segment."); } return array($sqlName, $matchType, $value); diff --git a/core/Segment/SegmentExpression.php b/core/Segment/SegmentExpression.php index 7eac1bcdb0581a4070b683bbbf8bd0e0648852d0..605cd136824eebdf76770ca853dd78ec203d471d 100644 --- a/core/Segment/SegmentExpression.php +++ b/core/Segment/SegmentExpression.php @@ -27,6 +27,12 @@ class SegmentExpression const MATCH_LESS = '<'; const MATCH_CONTAINS = '=@'; const MATCH_DOES_NOT_CONTAIN = '!@'; + const MATCH_STARTS_WITH = '=^'; + const MATCH_ENDS_WITH = '=$'; + + const BOOL_OPERATOR_OR = 'OR'; + const BOOL_OPERATOR_AND = 'AND'; + const BOOL_OPERATOR_END = ''; // Note: you can't write this in the API, but access this feature // via field!= <- IS NOT NULL @@ -40,6 +46,10 @@ class SegmentExpression const INDEX_BOOL_OPERATOR = 0; const INDEX_OPERAND = 1; + const INDEX_OPERAND_NAME = 0; + const INDEX_OPERAND_OPERATOR = 1; + const INDEX_OPERAND_VALUE = 2; + const SQL_WHERE_DO_NOT_MATCH_ANY_ROW = "(1 = 0)"; const SQL_WHERE_MATCHES_ALL_ROWS = "(1 = 1)"; @@ -89,7 +99,9 @@ class SegmentExpression . self::MATCH_LESS_OR_EQUAL . '|' . self::MATCH_LESS . '|' . self::MATCH_CONTAINS . '|' - . self::MATCH_DOES_NOT_CONTAIN + . self::MATCH_DOES_NOT_CONTAIN . '|' + . preg_quote(self::MATCH_STARTS_WITH) . '|' + . preg_quote(self::MATCH_ENDS_WITH) . '){1}(.*)/'; $match = preg_match($pattern, $operand, $matches); if ($match == 0) { @@ -115,9 +127,9 @@ class SegmentExpression $parsedSubExpressions[] = array( self::INDEX_BOOL_OPERATOR => $operator, self::INDEX_OPERAND => array( - $leftMember, - $operation, - $valueRightMember, + self::INDEX_OPERAND_NAME => $leftMember, + self::INDEX_OPERAND_OPERATOR => $operation, + self::INDEX_OPERAND_VALUE => $valueRightMember, )); } $this->parsedSubExpressions = $parsedSubExpressions; @@ -146,14 +158,17 @@ class SegmentExpression $operator = $leaf[self::INDEX_BOOL_OPERATOR]; $operandDefinition = $leaf[self::INDEX_OPERAND]; - $operand = $this->getSqlMatchFromDefinition($operandDefinition, $availableTables); - if ($operand[1] !== null) { - $this->valuesBind = array_merge($this->valuesBind, $operand[1]); + if ($operand[self::INDEX_OPERAND_OPERATOR] !== null) { + if (is_array($operand[self::INDEX_OPERAND_OPERATOR])) { + $this->valuesBind = array_merge($this->valuesBind, $operand[self::INDEX_OPERAND_OPERATOR]); + } else { + $this->valuesBind[] = $operand[self::INDEX_OPERAND_OPERATOR]; + } } - $operand = $operand[0]; + $operand = $operand[self::INDEX_OPERAND_NAME]; $sqlSubExpressions[] = array( self::INDEX_BOOL_OPERATOR => $operator, @@ -177,12 +192,12 @@ class SegmentExpression */ protected function getSqlMatchFromDefinition($def, &$availableTables) { - $fields = $def[0]; + $field = $def[0]; $matchType = $def[1]; $value = $def[2]; // Segment::getCleanedExpression() may return array(null, $matchType, null) - $operandWillNotMatchAnyRow = empty($fields) && is_null($value); + $operandWillNotMatchAnyRow = empty($field) && is_null($value); if($operandWillNotMatchAnyRow) { if($matchType == self::MATCH_EQUAL) { // eg. pageUrl==DoesNotExist @@ -193,7 +208,9 @@ class SegmentExpression // Not equal to NULL means it matches all rows $sqlExpression = self::SQL_WHERE_MATCHES_ALL_ROWS; } elseif($matchType == self::MATCH_CONTAINS - || $matchType == self::MATCH_DOES_NOT_CONTAIN) { + || $matchType == self::MATCH_DOES_NOT_CONTAIN + || $matchType == self::MATCH_STARTS_WITH + || $matchType == self::MATCH_ENDS_WITH) { // no action was found for CONTAINS / DOES NOT CONTAIN // eg. pageUrl=@DoesNotExist -> matches no row // eg. pageUrl!@DoesNotExist -> matches no rows @@ -207,10 +224,6 @@ class SegmentExpression return array($sqlExpression, $value = null); } - if (!is_array($fields)) { - $fields = array($fields); - } - $alsoMatchNULLValues = false; switch ($matchType) { case self::MATCH_EQUAL: @@ -241,6 +254,14 @@ class SegmentExpression $value = '%' . $this->escapeLikeString($value) . '%'; $alsoMatchNULLValues = true; break; + case self::MATCH_STARTS_WITH: + $sqlMatch = '%s LIKE'; + $value = $this->escapeLikeString($value) . '%'; + break; + case self::MATCH_ENDS_WITH: + $sqlMatch = '%s LIKE'; + $value = '%' . $this->escapeLikeString($value); + break; case self::MATCH_IS_NOT_NULL_NOR_EMPTY: $sqlMatch = '%s IS NOT NULL AND (%s <> \'\' OR %s = 0)'; @@ -258,7 +279,7 @@ class SegmentExpression // it can be used internally to inject sub-expressions into the query. // see Segment::getCleanedExpression() $sqlMatch = '%s IN (' . $value['SQL'] . ')'; - $value = $this->escapeLikeString($value['bind']); + $value = $value['bind']; break; default: throw new Exception("Filter contains the match type '" . $matchType . "' which is not supported"); @@ -267,44 +288,23 @@ class SegmentExpression // We match NULL values when rows are excluded only when we are not doing a $alsoMatchNULLValues = $alsoMatchNULLValues && !empty($value); + $sqlMatch = str_replace('%s', $field, $sqlMatch); - $sqlExpressions = array(); - $values = array(); - foreach ($fields as $field) { - $sqlMatchReplaced = str_replace('%s', $field, $sqlMatch); - - if ($matchType === self::MATCH_ACTIONS_CONTAINS - || is_null($value) - ) { - $sqlExpression = "( $sqlMatchReplaced )"; + if ($matchType === self::MATCH_ACTIONS_CONTAINS + || is_null($value) + ) { + $sqlExpression = "( $sqlMatch )"; + } else { + if ($alsoMatchNULLValues) { + $sqlExpression = "( $field IS NULL OR $sqlMatch ? )"; } else { - if ($alsoMatchNULLValues) { - $sqlExpression = "( $field IS NULL OR $sqlMatchReplaced ? )"; - } else { - $sqlExpression = "$sqlMatchReplaced ?"; - } - } - - $sqlExpressions[] = $sqlExpression; - - if ($value !== null) { - if(is_array($value)) { - $values = array_merge($values, $value); - } else { - $values[] = $value; - } + $sqlExpression = "$sqlMatch ?"; } - - $this->checkFieldIsAvailable($field, $availableTables); } - if (count($fields) == 1) { - $sqlExpression = reset($sqlExpressions); - } else { - $sqlExpression = '((' . implode(") OR (", $sqlExpressions) . '))'; - } + $this->checkFieldIsAvailable($field, $availableTables); - return array($sqlExpression, $values); + return array($sqlExpression, $value); } /** @@ -337,8 +337,14 @@ class SegmentExpression */ private function escapeLikeString($str) { - $str = str_replace("%", "\%", $str); - $str = str_replace("_", "\_", $str); + if (false !== strpos($str, '%')) { + $str = str_replace("%", "\%", $str); + } + + if (false !== strpos($str, '_')) { + $str = str_replace("_", "\_", $str); + } + return $str; } @@ -372,15 +378,15 @@ class SegmentExpression $operand = substr($operand, 0, -1); } $operand .= $char; - $tree[] = array(self::INDEX_BOOL_OPERATOR => '', self::INDEX_OPERAND => $operand); + $tree[] = array(self::INDEX_BOOL_OPERATOR => self::BOOL_OPERATOR_END, self::INDEX_OPERAND => $operand); break; } if ($isAND && !$isBackslash) { - $tree[] = array(self::INDEX_BOOL_OPERATOR => 'AND', self::INDEX_OPERAND => $operand); + $tree[] = array(self::INDEX_BOOL_OPERATOR => self::BOOL_OPERATOR_AND, self::INDEX_OPERAND => $operand); $operand = ''; } elseif ($isOR && !$isBackslash) { - $tree[] = array(self::INDEX_BOOL_OPERATOR => 'OR', self::INDEX_OPERAND => $operand); + $tree[] = array(self::INDEX_BOOL_OPERATOR => self::BOOL_OPERATOR_OR, self::INDEX_OPERAND => $operand); $operand = ''; } else { if ($isBackslash && ($isAND || $isOR)) { @@ -413,7 +419,7 @@ class SegmentExpression $operator = $expression[self::INDEX_BOOL_OPERATOR]; $operand = $expression[self::INDEX_OPERAND]; - if ($operator == 'OR' + if ($operator == self::BOOL_OPERATOR_OR && !$subExpression ) { $sql .= ' ('; @@ -424,7 +430,7 @@ class SegmentExpression $sql .= $operand; - if ($operator == 'AND' + if ($operator == self::BOOL_OPERATOR_AND && $subExpression ) { $sql .= ')'; diff --git a/core/SettingsServer.php b/core/SettingsServer.php index 3f6fbb8878b7ef1eb647faa1567db89da1b94448..d84e3ff483ff770eb708a3d3bc36ce8218790337 100644 --- a/core/SettingsServer.php +++ b/core/SettingsServer.php @@ -127,9 +127,14 @@ class SettingsServer { static $gd = null; if (is_null($gd)) { + $gd = false; + $extensions = @get_loaded_extensions(); - $gd = in_array('gd', $extensions) && function_exists('imageftbbox'); + if (is_array($extensions)) { + $gd = in_array('gd', $extensions) && function_exists('imageftbbox'); + } } + return $gd; } diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php index b30d695e73648469132893169634b89321fd20a0..b841c210a95ba5e75fda1271ae5cc46cabd804c9 100644 --- a/core/Tracker/Action.php +++ b/core/Tracker/Action.php @@ -62,6 +62,7 @@ abstract class Action private $idLinkVisitAction; private $actionIdsCached = array(); + private $customFields = array(); private $actionName; private $actionType; @@ -228,6 +229,16 @@ abstract class Action return false; } + public function setCustomField($field, $value) + { + $this->customFields[$field] = $value; + } + + public function getCustomFields() + { + return $this->customFields; + } + public function getIdActionUrl() { $idUrl = $this->actionIdsCached['idaction_url']; @@ -379,13 +390,7 @@ abstract class Action $visitAction[self::DB_COLUMN_CUSTOM_FLOAT] = Common::forceDotAsSeparatorForDecimalPoint($customValue); } - $customVariables = $this->getCustomVariables(); - if (!empty($customVariables)) { - Common::printDebug("Page level Custom Variables: "); - Common::printDebug($customVariables); - } - - $visitAction = array_merge($visitAction, $customVariables); + $visitAction = array_merge($visitAction, $this->customFields); $this->idLinkVisitAction = $this->getModel()->createAction($visitAction); diff --git a/core/Tracker/Model.php b/core/Tracker/Model.php index c39820e5719c0e614785b1386b7cec8eecff1910..afffd5faeb81fcb23a0c4170e7d796560704bd0b 100644 --- a/core/Tracker/Model.php +++ b/core/Tracker/Model.php @@ -289,7 +289,7 @@ class Model public function updateVisit($idSite, $idVisit, $valuesToUpdate) { - list($updateParts, $sqlBind) = $this->visitFieldsToQuery($valuesToUpdate); + list($updateParts, $sqlBind) = $this->fieldsToQuery($valuesToUpdate); $parts = implode($updateParts, ', '); $table = Common::prefixTable('log_visit'); @@ -312,6 +312,34 @@ class Model return $wasInserted; } + public function updateAction($idLinkVa, $valuesToUpdate) + { + if (empty($idLinkVa)) { + return; + } + + list($updateParts, $sqlBind) = $this->fieldsToQuery($valuesToUpdate); + + $parts = implode($updateParts, ', '); + $table = Common::prefixTable('log_link_visit_action'); + + $sqlQuery = "UPDATE $table SET $parts WHERE idlink_va = ?"; + + $sqlBind[] = $idLinkVa; + + $db = $this->getDb(); + $result = $db->query($sqlQuery, $sqlBind); + $wasInserted = $db->rowCount($result) != 0; + + if (!$wasInserted) { + Common::printDebug("Action with this idLinkVa wasn't found in the DB."); + Common::printDebug("$sqlQuery --- "); + Common::printDebug($sqlBind); + } + + return $wasInserted; + } + public function findVisitor($idSite, $configId, $idVisitor, $fieldsToRead, $shouldMatchOneFieldOnly, $isVisitorIdToLookup, $timeLookBack, $timeLookAhead) { $selectCustomVariables = ''; @@ -396,7 +424,7 @@ class Model return $result == null; } - private function visitFieldsToQuery($valuesToUpdate) + private function fieldsToQuery($valuesToUpdate) { $updateParts = array(); $sqlBind = array(); diff --git a/core/Tracker/Request.php b/core/Tracker/Request.php index 7f194f7d1a52bbdc0f0a98ac0a245bfff0ea3c3a..e714ecded7b02a6ea8bd5247a003d488ad2b214e 100644 --- a/core/Tracker/Request.php +++ b/core/Tracker/Request.php @@ -288,6 +288,15 @@ class Request 'i' => (string)Common::getRequestVar('m', $this->getCurrentDate("i"), 'int', $this->params), 's' => (string)Common::getRequestVar('s', $this->getCurrentDate("s"), 'int', $this->params) ); + if($localTimes['h'] < 0 || $localTimes['h'] > 23) { + $localTimes['h'] = 0; + } + if($localTimes['i'] < 0 || $localTimes['i'] > 59) { + $localTimes['i'] = 0; + } + if($localTimes['s'] < 0 || $localTimes['s'] > 59) { + $localTimes['s'] = 0; + } foreach ($localTimes as $k => $time) { if (strlen($time) == 1) { $localTimes[$k] = '0' . $time; diff --git a/core/Tracker/RequestProcessor.php b/core/Tracker/RequestProcessor.php index 3a8b01549a1c468888b3e962950319400b7dc778..8d50d3b28fa6d469bf9a79d63caf01b28f58b621 100644 --- a/core/Tracker/RequestProcessor.php +++ b/core/Tracker/RequestProcessor.php @@ -68,14 +68,7 @@ use Piwik\Tracker\Visit\VisitProperties; * a {@link Dimension} class._ * * To create a new RequestProcessor, create a new class that derives from this one, and implement the - * methods you need. Then in your plugin's DI config file (located at - * `/path/to/piwik/plugins/YourPlugin/config/config.php`), add the following to the array: - * - * ``` - * 'tracker.request.processors' => DI\add(array( - * DI\get('Piwik\Plugins\Goals\Tracker\GoalsRequestProcessor'), - * )), - * ``` + * methods you need. Then put this class inside the `Tracker` directory of your plugin. * * Final note: RequestProcessors are shared between tracking requests, and so, should ideally be * stateless. They are stored in DI, so they can contain references to other objects in DI, but diff --git a/core/Tracker/TableLogAction.php b/core/Tracker/TableLogAction.php index db9f7859fd964cfb605443fe65b5b786bb0bf4f5..9552e7ae812d5a086500fe3bd64f64f6f40a2492 100644 --- a/core/Tracker/TableLogAction.php +++ b/core/Tracker/TableLogAction.php @@ -65,13 +65,21 @@ class TableLogAction $sql = 'SELECT idaction FROM ' . Common::prefixTable('log_action') . ' WHERE %s AND type = ' . $actionType . ' )'; switch ($matchType) { - case '=@': + case SegmentExpression::MATCH_CONTAINS: // use concat to make sure, no %s occurs because some plugins use %s in their sql $where = '( name LIKE CONCAT(\'%\', ?, \'%\') '; break; - case '!@': + case SegmentExpression::MATCH_DOES_NOT_CONTAIN: $where = '( name NOT LIKE CONCAT(\'%\', ?, \'%\') '; break; + case SegmentExpression::MATCH_STARTS_WITH: + // use concat to make sure, no %s occurs because some plugins use %s in their sql + $where = '( name LIKE CONCAT(?, \'%\') '; + break; + case SegmentExpression::MATCH_ENDS_WITH: + // use concat to make sure, no %s occurs because some plugins use %s in their sql + $where = '( name LIKE CONCAT(\'%\', ?) '; + break; default: throw new \Exception("This match type $matchType is not available for action-segments."); break; @@ -166,29 +174,34 @@ class TableLogAction */ public static function getIdActionFromSegment($valueToMatch, $sqlField, $matchType, $segmentName) { - $actionType = self::guessActionTypeFromSegment($segmentName); - - if ($actionType == Action::TYPE_PAGE_URL) { - // for urls trim protocol and www because it is not recorded in the db - $valueToMatch = preg_replace('@^http[s]?://(www\.)?@i', '', $valueToMatch); - } - - $valueToMatch = self::normaliseActionString($actionType, $valueToMatch); + if ($segmentName === 'actionType') { + $actionType = (int) $valueToMatch; + $valueToMatch = array(); + $sql = 'SELECT idaction FROM ' . Common::prefixTable('log_action') . ' WHERE type = ' . $actionType . ' )'; + } else { + $actionType = self::guessActionTypeFromSegment($segmentName); + if ($actionType == Action::TYPE_PAGE_URL) { + // for urls trim protocol and www because it is not recorded in the db + $valueToMatch = preg_replace('@^http[s]?://(www\.)?@i', '', $valueToMatch); + } - if ($matchType == SegmentExpression::MATCH_EQUAL - || $matchType == SegmentExpression::MATCH_NOT_EQUAL - ) { - $idAction = self::getModel()->getIdActionMatchingNameAndType($valueToMatch, $actionType); - // Action is not found (eg. &segment=pageTitle==VÄ›trnásssssss) - if (empty($idAction)) { - $idAction = null; + $valueToMatch = self::normaliseActionString($actionType, $valueToMatch); + if ($matchType == SegmentExpression::MATCH_EQUAL + || $matchType == SegmentExpression::MATCH_NOT_EQUAL + ) { + $idAction = self::getModel()->getIdActionMatchingNameAndType($valueToMatch, $actionType); + // Action is not found (eg. &segment=pageTitle==VÄ›trnásssssss) + if (empty($idAction)) { + $idAction = null; + } + return $idAction; } - return $idAction; + + // "name contains $string" match can match several idaction so we cannot return yet an idaction + // special case + $sql = self::getSelectQueryWhereNameContains($matchType, $actionType); } - // "name contains $string" match can match several idaction so we cannot return yet an idaction - // special case - $sql = TableLogAction::getSelectQueryWhereNameContains($matchType, $actionType); $cache = StaticContainer::get('Piwik\Tracker\TableLogAction\Cache'); return $cache->getIdActionFromSegment($valueToMatch, $sql); @@ -261,6 +274,8 @@ class TableLogAction $actionsTypesStoredUnsanitized = array( $actionType == Action::TYPE_DOWNLOAD, $actionType == Action::TYPE_OUTLINK, + $actionType == Action::TYPE_PAGE_URL, + $actionType == Action::TYPE_CONTENT, ); return in_array($actionType, $actionsTypesStoredUnsanitized); diff --git a/core/Tracker/TrackerCodeGenerator.php b/core/Tracker/TrackerCodeGenerator.php index fbf4b4c2be438293e7ab3ea1c171a51cf3387fee..c985db88e75541294aa53616a79c57de5340c8cb 100644 --- a/core/Tracker/TrackerCodeGenerator.php +++ b/core/Tracker/TrackerCodeGenerator.php @@ -172,13 +172,23 @@ class TrackerCodeGenerator } // We need to parse_url to isolate hosts $websiteHosts = array(); + $firstHost = null; foreach ($websiteUrls as $site_url) { $referrerParsed = parse_url($site_url); - $websiteHosts[] = $referrerParsed['host']; + + if (!isset($firstHost)) { + $firstHost = $referrerParsed['host']; + } + + $url = $referrerParsed['host']; + if (!empty($referrerParsed['path'])) { + $url .= $referrerParsed['path']; + } + $websiteHosts[] = $url; } $options = ''; - if ($mergeSubdomains && !empty($websiteHosts)) { - $options .= ' _paq.push(["setCookieDomain", "*.' . $websiteHosts[0] . '"]);' . "\n"; + if ($mergeSubdomains && !empty($firstHost)) { + $options .= ' _paq.push(["setCookieDomain", "*.' . $firstHost . '"]);' . "\n"; } if ($mergeAliasUrls && !empty($websiteHosts)) { $urls = '["*.' . implode('","*.', $websiteHosts) . '"]'; diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php index a78bb30b401fc37b8a027a2ff6d18b96f6abd160..80d8d13613757216caa3fb6f063a30b2b0772e1a 100644 --- a/core/Tracker/Visit.php +++ b/core/Tracker/Visit.php @@ -17,6 +17,7 @@ use Piwik\Date; use Piwik\Exception\UnexpectedWebsiteFoundException; use Piwik\Network\IPUtils; use Piwik\Piwik; +use Piwik\Plugin; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Tracker; use Piwik\Tracker\Visit\VisitProperties; @@ -76,7 +77,8 @@ class Visit implements VisitInterface public function __construct() { - $this->requestProcessors = StaticContainer::get('tracker.request.processors'); + $requestProcessors = StaticContainer::get('Piwik\Plugin\RequestProcessors'); + $this->requestProcessors = $requestProcessors->getRequestProcessors(); $this->visitorRecognizer = StaticContainer::get('Piwik\Tracker\VisitorRecognizer'); $this->visitProperties = null; $this->userSettings = StaticContainer::get('Piwik\Tracker\Settings'); diff --git a/core/Tracker/Visit/ReferrerSpamFilter.php b/core/Tracker/Visit/ReferrerSpamFilter.php index 3d49362444ca5d55aa9bd46078330163239470d6..177200bf6a75bbb39ebc928484c9bf2d92489603 100644 --- a/core/Tracker/Visit/ReferrerSpamFilter.php +++ b/core/Tracker/Visit/ReferrerSpamFilter.php @@ -58,6 +58,10 @@ class ReferrerSpamFilter $cache->save($cacheId, $list); } + if(!is_array($list)) { + Common::printDebug('Warning: could not read list of spammers from cache.'); + return array(); + } return $list; } diff --git a/core/Tracker/VisitExcluded.php b/core/Tracker/VisitExcluded.php index 0bc6fa2fbb599714a789bcbde93ae3072114f86b..a644d4479f1e7e293f3183e8e7128045e581f891 100644 --- a/core/Tracker/VisitExcluded.php +++ b/core/Tracker/VisitExcluded.php @@ -13,6 +13,7 @@ use Piwik\Common; use Piwik\DeviceDetectorFactory; use Piwik\Network\IP; use Piwik\Piwik; +use Piwik\Plugins\SitesManager\SiteUrls; use Piwik\Tracker\Visit\ReferrerSpamFilter; /** @@ -290,14 +291,17 @@ class VisitExcluded { $site = Cache::getCacheWebsiteAttributes($this->idSite); - if (!empty($site['exclude_unknown_urls']) && !empty($site['hosts'])) { - $trackingHost = parse_url($this->request->getParam('url'), PHP_URL_HOST); - foreach ($site['hosts'] as $siteHost) { - if ($trackingHost == $siteHost || (substr($trackingHost, -strlen($siteHost) - 1) === ('.' . $siteHost))) { - return false; - } - } - return true; + if (!empty($site['exclude_unknown_urls']) && !empty($site['urls'])) { + $url = $this->request->getParam('url'); + $parsedUrl = parse_url($url); + + $trackingUrl = new SiteUrls(); + $urls = $trackingUrl->groupUrlsByHost(array($this->idSite => $site['urls'])); + + $idSites = $trackingUrl->getIdSitesMatchingUrl($parsedUrl, $urls); + $isUrlExcluded = !isset($idSites) || !in_array($this->idSite, $idSites); + + return $isUrlExcluded; } return false; diff --git a/core/Url.php b/core/Url.php index fc618d752bd0c4064363b4ae083a951d46eee57f..cacf76ad060aa4449af161178e9744a68af80c43 100644 --- a/core/Url.php +++ b/core/Url.php @@ -181,11 +181,12 @@ class Url } catch (Exception $e) { $assume_secure_protocol = false; } - if ($assume_secure_protocol - || (isset($_SERVER['HTTPS']) - && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === true)) - || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') - ) { + if ($assume_secure_protocol) { + return 'https'; + } + if( (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === true)) + || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')){ + return 'https'; } return 'http'; @@ -216,6 +217,7 @@ class Url return true; } } + // if host is in hardcoded whitelist, assume it's valid if (in_array($host, self::getAlwaysTrustedHosts())) { return true; diff --git a/core/UrlHelper.php b/core/UrlHelper.php index 4a0ac0fa0ada317c0700127ee7d30ffc7e6b8697..66a0e64e2530db9e82bc553bf6b5c629a99a8a7e 100644 --- a/core/UrlHelper.php +++ b/core/UrlHelper.php @@ -258,242 +258,6 @@ class UrlHelper return $result; } - /** - * Extracts a keyword from a raw not encoded URL. - * Will only extract keyword if a known search engine has been detected. - * Returns the keyword: - * - in UTF8: automatically converted from other charsets when applicable - * - strtolowered: "QUErY test!" will return "query test!" - * - trimmed: extra spaces before and after are removed - * - * Lists of supported search engines can be found in /core/DataFiles/SearchEngines.php - * The function returns false when a keyword couldn't be found. - * eg. if the url is "http://www.google.com/partners.html" this will return false, - * as the google keyword parameter couldn't be found. - * - * @see unit tests in /tests/core/Common.test.php - * @param string $referrerUrl URL referrer URL, eg. $_SERVER['HTTP_REFERER'] - * @return array|bool false if a keyword couldn't be extracted, - * or array( - * 'name' => 'Google', - * 'keywords' => 'my searched keywords') - */ - public static function extractSearchEngineInformationFromUrl($referrerUrl) - { - $referrerParsed = @parse_url($referrerUrl); - $referrerHost = ''; - if (isset($referrerParsed['host'])) { - $referrerHost = $referrerParsed['host']; - } - if (empty($referrerHost)) { - return false; - } - // some search engines (eg. Bing Images) use the same domain - // as an existing search engine (eg. Bing), we must also use the url path - $referrerPath = ''; - if (isset($referrerParsed['path'])) { - $referrerPath = $referrerParsed['path']; - } - - // no search query - if (!isset($referrerParsed['query'])) { - $referrerParsed['query'] = ''; - } - $query = $referrerParsed['query']; - - // Google Referrers URLs sometimes have the fragment which contains the keyword - if (!empty($referrerParsed['fragment'])) { - $query .= '&' . $referrerParsed['fragment']; - } - - $searchEngines = Common::getSearchEngineUrls(); - - $hostPattern = self::getLossyUrl($referrerHost); - /* - * Try to get the best matching 'host' in definitions - * 1. check if host + path matches an definition - * 2. check if host only matches - * 3. check if host pattern + path matches - * 4. check if host pattern matches - * 5. special handling - */ - if (array_key_exists($referrerHost . $referrerPath, $searchEngines)) { - $referrerHost = $referrerHost . $referrerPath; - } elseif (array_key_exists($referrerHost, $searchEngines)) { - // no need to change host - } elseif (array_key_exists($hostPattern . $referrerPath, $searchEngines)) { - $referrerHost = $hostPattern . $referrerPath; - } elseif (array_key_exists($hostPattern, $searchEngines)) { - $referrerHost = $hostPattern; - } elseif (!array_key_exists($referrerHost, $searchEngines)) { - if (!strncmp($query, 'cx=partner-pub-', 15)) { - // Google custom search engine - $referrerHost = 'google.com/cse'; - } elseif (!strncmp($referrerPath, '/pemonitorhosted/ws/results/', 28)) { - // private-label search powered by InfoSpace Metasearch - $referrerHost = 'wsdsold.infospace.com'; - } elseif (strpos($referrerHost, '.images.search.yahoo.com') != false) { - // Yahoo! Images - $referrerHost = 'images.search.yahoo.com'; - } elseif (strpos($referrerHost, '.search.yahoo.com') != false) { - // Yahoo! - $referrerHost = 'search.yahoo.com'; - } else { - return false; - } - } - $searchEngineName = $searchEngines[$referrerHost][0]; - $variableNames = null; - if (isset($searchEngines[$referrerHost][1])) { - $variableNames = $searchEngines[$referrerHost][1]; - } - if (!$variableNames) { - $searchEngineNames = Common::getSearchEngineNames(); - $url = $searchEngineNames[$searchEngineName]; - $variableNames = $searchEngines[$url][1]; - } - if (!is_array($variableNames)) { - $variableNames = array($variableNames); - } - - $key = null; - if ($searchEngineName === 'Google Images' - || ($searchEngineName === 'Google' && strpos($referrerUrl, '/imgres') !== false) - ) { - if (strpos($query, '&prev') !== false) { - $query = urldecode(trim(self::getParameterFromQueryString($query, 'prev'))); - $query = str_replace('&', '&', strstr($query, '?')); - } - $searchEngineName = 'Google Images'; - } elseif ($searchEngineName === 'Google' - && (strpos($query, '&as_') !== false || strpos($query, 'as_') === 0) - ) { - $keys = array(); - $key = self::getParameterFromQueryString($query, 'as_q'); - if (!empty($key)) { - array_push($keys, $key); - } - $key = self::getParameterFromQueryString($query, 'as_oq'); - if (!empty($key)) { - array_push($keys, str_replace('+', ' OR ', $key)); - } - $key = self::getParameterFromQueryString($query, 'as_epq'); - if (!empty($key)) { - array_push($keys, "\"$key\""); - } - $key = self::getParameterFromQueryString($query, 'as_eq'); - if (!empty($key)) { - array_push($keys, "-$key"); - } - $key = trim(urldecode(implode(' ', $keys))); - } - - if ($searchEngineName === 'Google') { - // top bar menu - $tbm = self::getParameterFromQueryString($query, 'tbm'); - switch ($tbm) { - case 'isch': - $searchEngineName = 'Google Images'; - break; - case 'vid': - $searchEngineName = 'Google Video'; - break; - case 'shop': - $searchEngineName = 'Google Shopping'; - break; - } - } - - if (empty($key)) { - foreach ($variableNames as $variableName) { - if ($variableName[0] == '/') { - // regular expression match - if (preg_match($variableName, $referrerUrl, $matches)) { - $key = trim(urldecode($matches[1])); - break; - } - } else { - // search for keywords now &vname=keyword - $key = self::getParameterFromQueryString($query, $variableName); - $key = trim(urldecode($key)); - - // Special cases: empty or no keywords - if (empty($key) - && ( - // Google search with no keyword - ($searchEngineName == 'Google' - && (empty($query) && (empty($referrerPath) || $referrerPath == '/') && empty($referrerParsed['fragment'])) - ) - - // Yahoo search with no keyword - || ($searchEngineName == 'Yahoo!' - && ($referrerParsed['host'] == 'r.search.yahoo.com') - ) - - // empty keyword parameter - || strpos($query, sprintf('&%s=', $variableName)) !== false - || strpos($query, sprintf('?%s=', $variableName)) !== false - - // search engines with no keyword - || $searchEngineName == 'Ixquick' - || $searchEngineName == 'Google Images' - || $searchEngineName == 'DuckDuckGo') - ) { - $key = false; - } - if (!empty($key) - || $key === false - ) { - break; - } - } - } - } - - // $key === false is the special case "No keyword provided" which is a Search engine match - if ($key === null - || $key === '' - ) { - return false; - } - - if (!empty($key)) { - if (function_exists('iconv') - && isset($searchEngines[$referrerHost][3]) - ) { - // accepts string, array, or comma-separated list string in preferred order - $charsets = $searchEngines[$referrerHost][3]; - if (!is_array($charsets)) { - $charsets = explode(',', $charsets); - } - - if (!empty($charsets)) { - $charset = $charsets[0]; - if (count($charsets) > 1 - && function_exists('mb_detect_encoding') - ) { - $charset = mb_detect_encoding($key, $charsets); - if ($charset === false) { - $charset = $charsets[0]; - } - } - - $newkey = @iconv($charset, 'UTF-8//IGNORE', $key); - if (!empty($newkey)) { - $key = $newkey; - } - } - } - - $key = Common::mb_strtolower($key); - } - - return array( - 'name' => $searchEngineName, - 'keywords' => $key, - ); - } - /** * Returns the query part from any valid url and adds additional parameters to the query part if needed. * diff --git a/core/ViewDataTable/Config.php b/core/ViewDataTable/Config.php index 22cb8c4429c0fb46f1a8596532efaabc17a0df3c..f275aebe587fddfbe1da17bf04af9ce8ff822c58 100644 --- a/core/ViewDataTable/Config.php +++ b/core/ViewDataTable/Config.php @@ -10,6 +10,7 @@ namespace Piwik\ViewDataTable; use Piwik\API\Request as ApiRequest; +use Piwik\Common; use Piwik\DataTable; use Piwik\DataTable\Filter\PivotByDimension; use Piwik\Metrics; @@ -486,7 +487,28 @@ class Config { $this->metrics_documentation = array(); - $report = API::getInstance()->getMetadata(0, $this->controllerName, $this->controllerAction); + $idSite = Common::getRequestVar('idSite', 0, 'int'); + + if ($idSite < 1) { + return; + } + + $apiParameters = array(); + $idDimension = Common::getRequestVar('idDimension', 0, 'int'); + $idGoal = Common::getRequestVar('idGoal', 0, 'int'); + if ($idDimension > 0) { + $apiParameters['idDimension'] = $idDimension; + } + if ($idGoal > 0) { + $apiParameters['idGoal'] = $idGoal; + } + + $report = API::getInstance()->getMetadata($idSite, $this->controllerName, $this->controllerAction, $apiParameters); + + if (empty($report)) { + return; + } + $report = $report[0]; if (isset($report['metricsDocumentation'])) { @@ -556,6 +578,17 @@ class Config $this->columns_to_display = array_filter($columnsToDisplay); } + public function removeColumnToDisplay($columnToRemove) + { + if (!empty($this->columns_to_display)) { + + $key = array_search($columnToRemove, $this->columns_to_display); + if (false !== $key) { + unset($this->columns_to_display[$key]); + } + } + } + /** * @ignore */ diff --git a/core/testMinimumPhpVersion.php b/core/testMinimumPhpVersion.php index 5c041d8ec62025dce6e41cdbfd1fb46fb4b5da9c..707d0e161564c196384e369cab9c729dc178debd 100644 --- a/core/testMinimumPhpVersion.php +++ b/core/testMinimumPhpVersion.php @@ -16,7 +16,10 @@ $piwik_errorMessage = ''; // Minimum requirement: stream_resolve_include_path, working json_encode in 5.3.3, namespaces in 5.3 -$piwik_minimumPHPVersion = '5.4.0'; +// NOTE: when changing this variable, we also need to update +// 1) api.piwik.org +// 2) tests/travis/generator/Generator.php +$piwik_minimumPHPVersion = '5.5.0'; $piwik_currentPHPVersion = PHP_VERSION; $minimumPhpInvalid = version_compare($piwik_minimumPHPVersion, $piwik_currentPHPVersion) > 0; if ($minimumPhpInvalid) { diff --git a/js/README.md b/js/README.md index 06c7cf0ae324afba606c705aea88976c325d7da3..d24f8d8c9dca78876fc2cbea1bb57af210c708c1 100644 --- a/js/README.md +++ b/js/README.md @@ -48,9 +48,6 @@ The js/ folder contains: * In a production environment, the tests/javascript folder is not used and can be removed (if present). - Note: if the file "js/tests/enable_sqlite" exists, additional unit tests - (requires the sqlite extension) are enabled. - * We use /*! to include Piwik's license header in the minified source. Read Stallman's "The JavaScript Trap" for more information. diff --git a/js/piwik.js b/js/piwik.js index b5608f1230030297490f44a210f653111632d6b5..344e5436e9c3b9c3e443be65142c9746398074c0 100644 --- a/js/piwik.js +++ b/js/piwik.js @@ -28,7 +28,7 @@ /*global JSON2:true */ -if (typeof JSON2 !== 'object' && window.JSON) { +if (typeof JSON2 !== 'object' && typeof window.JSON === 'object' && window.JSON.stringify && window.JSON.parse) { JSON2 = window.JSON; } else { (function () { @@ -979,8 +979,8 @@ if (typeof JSON2 !== 'object' && window.JSON) { getAttributionReferrerTimestamp, getAttributionReferrerUrl, setCustomData, getCustomData, setCustomRequestProcessing, - setCustomVariable, getCustomVariable, deleteCustomVariable, storeCustomVariablesInCookie, - setDownloadExtensions, addDownloadExtensions, removeDownloadExtensions, + setCustomVariable, getCustomVariable, deleteCustomVariable, storeCustomVariablesInCookie, setCustomDimension, getCustomDimension, + deleteCustomDimension, setDownloadExtensions, addDownloadExtensions, removeDownloadExtensions, setDomains, setIgnoreClasses, setRequestMethod, setRequestContentType, setReferrerUrl, setCustomUrl, setAPIUrl, setDocumentTitle, setDownloadClasses, setLinkClasses, @@ -1021,7 +1021,7 @@ if (typeof JSON2 !== 'object' && window.JSON) { trackVisibleContentImpressions, isTrackOnlyVisibleContentEnabled, port, isUrlToCurrentDomain, isNodeAuthorizedToTriggerInteraction, replaceHrefIfInternalLink, getConfigDownloadExtensions, disableLinkTracking, substr, setAnyAttribute, wasContentTargetAttrReplaced, max, abs, childNodes, compareDocumentPosition, body, - getConfigVisitorCookieTimeout, getRemainingVisitorCookieTimeout, + getConfigVisitorCookieTimeout, getRemainingVisitorCookieTimeout, getDomains, getConfigCookiePath, newVisitor, uuid, createTs, visitCount, currentVisitTs, lastVisitTs, lastEcommerceOrderTs, "", "\b", "\t", "\n", "\f", "\r", "\"", "\\", apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length, parse, prototype, push, replace, @@ -1143,6 +1143,23 @@ if (typeof Piwik !== 'object') { return typeof property === 'string' || property instanceof String; } + function isObjectEmpty(property) + { + if (!property) { + return true; + } + + var i; + var isEmpty = true; + for (i in property) { + if (Object.prototype.hasOwnProperty.call(property, i)) { + isEmpty = false; + } + } + + return isEmpty; + } + /* * apply wrapper * @@ -1535,6 +1552,14 @@ if (typeof Piwik !== 'object') { * Fix-up URL when page rendered from search engine cache or translated page */ function urlFixup(hostName, href, referrer) { + if (!hostName) { + hostName = ''; + } + + if (!href) { + href = ''; + } + if (hostName === 'translate.googleusercontent.com') { // Google if (referrer === '') { referrer = href; @@ -1568,6 +1593,10 @@ if (typeof Piwik !== 'object') { domain = domain.slice(1); } + if (domain.indexOf('/') !== -1) { + domain = domain.substr(0, domain.indexOf('/')); + } + return domain; } @@ -2648,7 +2677,7 @@ if (typeof Piwik !== 'object') { // check whether we were redirected from the piwik overlay plugin var referrerRegExp = new RegExp('index\\.php\\?module=Overlay&action=startOverlaySession' - + '&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)$'); + + '&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=.*)?$'); var match = referrerRegExp.exec(documentAlias.referrer); @@ -2662,15 +2691,22 @@ if (typeof Piwik !== 'object') { // store overlay session info in window name var period = match[2], - date = match[3]; + date = match[3], + segment = match[4]; + + if (!segment) { + segment = ''; + } else if (segment.indexOf('&segment=') === 0) { + segment = segment.substr('&segment='.length); + } - windowAlias.name = windowName + '###' + period + '###' + date; + windowAlias.name = windowName + '###' + period + '###' + date + '###' + segment; } // retrieve and check data from window name var windowNameParts = windowAlias.name.split('###'); - return windowNameParts.length === 3 && windowNameParts[0] === windowName; + return windowNameParts.length === 4 && windowNameParts[0] === windowName; } /* @@ -2680,12 +2716,13 @@ if (typeof Piwik !== 'object') { var windowNameParts = windowAlias.name.split('###'), period = windowNameParts[1], date = windowNameParts[2], + segment = windowNameParts[3], piwikUrl = getPiwikUrlForOverlay(configTrackerUrl, configApiUrl); loadScript( piwikUrl + 'plugins/Overlay/client/client.js?v=1', function () { - Piwik_Overlay_Client.initialize(piwikUrl, configTrackerSiteId, period, date); + Piwik_Overlay_Client.initialize(piwikUrl, configTrackerSiteId, period, date, segment); } ); } @@ -2848,6 +2885,9 @@ if (typeof Piwik !== 'object') { // Custom Variables, scope "event" customVariablesEvent = {}, + // Custom Dimensions (can be any scope) + customDimensions = {}, + // Custom Variables names and values are each truncated before being sent in the request or recorded in the cookie customVariableMaximumLength = 200, @@ -2976,10 +3016,115 @@ if (typeof Piwik !== 'object') { return baseUrl + url; } + function isSameHost (hostName, alias) { + var offset; + + hostName = String(hostName).toLowerCase(); + alias = String(alias).toLowerCase(); + + if (hostName === alias) { + return true; + } + + if (alias.slice(0, 1) === '.') { + if (hostName === alias.slice(1)) { + return true; + } + + offset = hostName.length - alias.length; + + if ((offset > 0) && (hostName.slice(offset) === alias)) { + return true; + } + } + + return false; + } + + function stringEndsWith(str, suffix) { + str = String(str); + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + + function removeCharactersFromEndOfString(str, numCharactersToRemove) { + str = String(str); + return str.substr(0, str.length - numCharactersToRemove); + } + + /* + * Extract pathname from URL. element.pathname is actually supported by pretty much all browsers including + * IE6 apart from some rare very old ones + */ + function getPathName(url) { + var parser = document.createElement('a'); + if (url.indexOf('//') !== 0 && url.indexOf('http') !== 0) { + url = 'http://' + url; + } + + parser.href = content.toAbsoluteUrl(url); + if (parser.pathname) { + return parser.pathname; + } + + return ''; + } + + function isSitePath (path, pathAlias) + { + var matchesAnyPath = (!pathAlias || pathAlias === '/'); + + if (matchesAnyPath) { + return true; + } + + if (path === pathAlias) { + return true; + } + + if (!path) { + return false; + } + + pathAlias = String(pathAlias).toLowerCase(); + path = String(path).toLowerCase(); + + // we need to append slashes so /foobarbaz won't match a site /foobar + if (!stringEndsWith(path, '/')) { + path += '/'; + } + + if (!stringEndsWith(pathAlias, '/')) { + pathAlias += '/'; + } + + return path.indexOf(pathAlias) === 0; + } + + function isSiteHostPath(host, path) + { + var i, + alias, + configAlias, + aliasHost, + aliasPath; + + for (i = 0; i < configHostsAlias.length; i++) { + aliasHost = domainFixup(configHostsAlias[i]); + aliasPath = getPathName(configHostsAlias[i]); + + if (isSameHost(host, aliasHost) && isSitePath(path, aliasPath)) { + return true; + } + } + + return false; + } + /* * Is the host local? (i.e., not an outlink) */ function isSiteHostName(hostName) { + var i, alias, offset; @@ -3678,6 +3823,34 @@ if (typeof Piwik !== 'object') { } } + var customDimensionIdsAlreadyHandled = []; + if (customData) { + for (i in customData) { + if (Object.prototype.hasOwnProperty.call(customData, i) && /^dimension\d+$/.test(i)) { + var index = i.replace('dimension', ''); + customDimensionIdsAlreadyHandled.push(parseInt(index, 10)); + customDimensionIdsAlreadyHandled.push(String(index)); + request += '&' + i + '=' + customData[i]; + delete customData[i]; + } + } + } + + if (customData && isObjectEmpty(customData)) { + customData = null; + // we deleted all keys from custom data + } + + // custom dimensions + for (i in customDimensions) { + if (Object.prototype.hasOwnProperty.call(customDimensions, i)) { + var isNotSetYet = (-1 === customDimensionIdsAlreadyHandled.indexOf(i)); + if (isNotSetYet) { + request += '&dimension' + i + '=' + customDimensions[i]; + } + } + } + // custom data if (customData) { request += '&data=' + encodeWrapper(JSON2.stringify(customData)); @@ -3940,6 +4113,8 @@ if (typeof Piwik !== 'object') { return; } + var originalSourcePath = sourceElement.pathname || getPathName(sourceElement.href); + // browsers, such as Safari, don't downcase hostname and href var originalSourceHostName = sourceElement.hostname || getHostName(sourceElement.href); var sourceHostName = originalSourceHostName.toLowerCase(); @@ -3950,7 +4125,7 @@ if (typeof Piwik !== 'object') { if (!scriptProtocol.test(sourceHref)) { // track outlinks and all downloads - var linkType = getLinkType(sourceElement.className, sourceHref, isSiteHostName(sourceHostName), query.hasNodeAttribute(sourceElement, 'download')); + var linkType = getLinkType(sourceElement.className, sourceHref, isSiteHostPath(sourceHostName, originalSourcePath), query.hasNodeAttribute(sourceElement, 'download')); if (linkType) { return { @@ -4716,6 +4891,60 @@ if (typeof Piwik !== 'object') { }); } + /** + * Note: While we check whether the user is on a configHostAlias path we do not check whether the user is + * actually on the configHostAlias domain. This is already done where this method is called and for + * simplicity we do not check this again. + * + * Also we currently assume that all configHostAlias domains start with the same wild card of '*.', '.' or + * none. Eg either all like '*.piwik.org' or '.piwik.org' or 'piwik.org'. Piwik always adds '*.' so it + * should be fine. + */ + function findConfigCookiePathToUse(configHostAlias, currentUrl) + { + var aliasPath = getPathName(configHostAlias); + var currentPath = getPathName(currentUrl); + + if (!aliasPath || aliasPath === '/' || !currentPath || currentPath === '/') { + // no path set that would be useful for cookiePath + return; + } + + var aliasDomain = domainFixup(configHostAlias); + + if (isSiteHostPath(aliasDomain, '/')) { + // there is another configHostsAlias having same domain that allows all paths + // eg this alias is for piwik.org/support but there is another alias allowing + // piwik.org + return; + } + + if (stringEndsWith(aliasPath, '/')) { + aliasPath = removeCharactersFromEndOfString(aliasPath, 1); + } + + // eg if we're in the case of "apache.piwik/foo/bar" we check whether there is maybe + // also a config alias allowing "apache.piwik/foo". In this case we're not allowed to set + // the cookie for "/foo/bar" but "/foo" + var pathAliasParts = aliasPath.split('/'); + var i; + for (i = 2; i < pathAliasParts.length; i++) { + var lessRestrctivePath = pathAliasParts.slice(0, i).join('/'); + if (isSiteHostPath(aliasDomain, lessRestrctivePath)) { + aliasPath = lessRestrctivePath; + break; + } + } + + if (!isSitePath(currentPath, aliasPath)) { + // current path of current URL does not match the alias + // eg user is on piwik.org/demo but configHostAlias is for piwik.org/support + return; + } + + return aliasPath; + } + /* * Browser features (plugins, resolution, cookies) */ @@ -4853,6 +5082,12 @@ if (typeof Piwik !== 'object') { internalIsNodeVisible: isVisible, isNodeAuthorizedToTriggerInteraction: isNodeAuthorizedToTriggerInteraction, replaceHrefIfInternalLink: replaceHrefIfInternalLink, + getDomains: function () { + return configHostsAlias; + }, + getConfigCookiePath: function () { + return configCookiePath; + }, getConfigDownloadExtensions: function () { return configDownloadExtensions; }, @@ -5092,6 +5327,50 @@ if (typeof Piwik !== 'object') { plugins[pluginName] = pluginObj; }, + /** + * Set Custom Dimensions. Any set Custom Dimension will be cleared after a tracked pageview. Make + * sure to set them again if needed. + * + * @param int index A Custom Dimension index + * @param string value + */ + setCustomDimension: function (customDimensionId, value) { + customDimensionId = parseInt(customDimensionId, 10); + if (customDimensionId > 0) { + if (!isDefined(value)) { + value = ''; + } + if (!isString(value)) { + value = String(value); + } + customDimensions[customDimensionId] = value; + } + }, + + /** + * Get a stored value for a specific Custom Dimension index. + * + * @param int index A Custom Dimension index + */ + getCustomDimension: function (customDimensionId) { + customDimensionId = parseInt(customDimensionId, 10); + if (customDimensionId > 0 && Object.prototype.hasOwnProperty.call(customDimensions, customDimensionId)) { + return customDimensions[customDimensionId]; + } + }, + + /** + * Delete a custom dimension. + * + * @param int index Custom dimension Id + */ + deleteCustomDimension: function (customDimensionId) { + customDimensionId = parseInt(customDimensionId, 10); + if (customDimensionId > 0) { + delete customDimensions[customDimensionId]; + } + }, + /** * Set custom variable within this visit * @@ -5165,6 +5444,7 @@ if (typeof Piwik !== 'object') { * Delete custom variable * * @param int index Custom variable slot ID from 1-5 + * @param string scope */ deleteCustomVariable: function (index, scope) { // Only delete if it was there already @@ -5238,13 +5518,44 @@ if (typeof Piwik !== 'object') { }, /** - * Set array of domains to be treated as local + * Set array of domains to be treated as local. Also supports path, eg '.piwik.org/subsite1'. In this + * case all links that don't go to '*.piwik.org/subsite1/ *' would be treated as outlinks. + * For example a link to 'piwik.org/' or 'piwik.org/subsite2' both would be treated as outlinks. + * + * We might automatically set a cookieConfigPath to avoid creating several cookies under one domain + * if there is a hostAlias defined with a path. Say a user is visiting 'http://piwik.org/subsite1' + * and '.piwik.org/subsite1' is set as a hostsAlias. Piwik will automatically use '/subsite1' as + * cookieConfigPath. * * @param string|array hostsAlias */ setDomains: function (hostsAlias) { configHostsAlias = isString(hostsAlias) ? [hostsAlias] : hostsAlias; - configHostsAlias.push(domainAlias); + + var hasDomainAliasAlready = false, i; + for (i in configHostsAlias) { + if (Object.prototype.hasOwnProperty.call(configHostsAlias, i) + && isSameHost(domainAlias, domainFixup(String(configHostsAlias[i])))) { + hasDomainAliasAlready = true; + + if (!configCookiePath) { + var path = findConfigCookiePathToUse(configHostsAlias[i], locationHrefAlias); + if (path) { + this.setCookiePath(path); + } + + break; + } + } + } + + if (!hasDomainAliasAlready) { + /** + * eg if domainAlias = 'piwik.org' and someone set hostsAlias = ['piwik.org/foo'] then we should + * not add piwik.org as it would increase the allowed scope. + */ + configHostsAlias.push(domainAlias); + } }, /** @@ -5904,10 +6215,11 @@ if (typeof Piwik !== 'object') { * @param string action The Event's Action (Play, Pause, Duration, Add Playlist, Downloaded, Clicked...) * @param string name (optional) The Event's object Name (a particular Movie name, or Song name, or File name...) * @param float value (optional) The Event's value + * @param mixed customData */ - trackEvent: function (category, action, name, value) { + trackEvent: function (category, action, name, value, customData) { trackCallback(function () { - logEvent(category, action, name, value); + logEvent(category, action, name, value, customData); }); }, @@ -5917,10 +6229,11 @@ if (typeof Piwik !== 'object') { * @param string keyword * @param string category * @param int resultsCount + * @param mixed customData */ - trackSiteSearch: function (keyword, category, resultsCount) { + trackSiteSearch: function (keyword, category, resultsCount, customData) { trackCallback(function () { - logSiteSearch(keyword, category, resultsCount); + logSiteSearch(keyword, category, resultsCount, customData); }); }, @@ -6084,7 +6397,7 @@ if (typeof Piwik !== 'object') { asyncTracker = new Tracker(); - var applyFirst = ['disableCookies', 'setTrackerUrl', 'setAPIUrl', 'setCookiePath', 'setCookieDomain', 'setUserId', 'setSiteId', 'enableLinkTracking']; + var applyFirst = ['disableCookies', 'setTrackerUrl', 'setAPIUrl', 'setCookiePath', 'setCookieDomain', 'setDomains', 'setUserId', 'setSiteId', 'enableLinkTracking']; _paq = applyMethodsInOrder(_paq, applyFirst); // apply the queue of actions diff --git a/lang/bg.json b/lang/bg.json index f42c8bfe23dc120505642db3b01208c0db0bbcc8..b1e76019001060b44c96ba63a7621feeff443aba 100644 --- a/lang/bg.json +++ b/lang/bg.json @@ -367,7 +367,6 @@ "VisitorSettings": "ÐаÑтройки на поÑетителÑ", "VisitTypeExample": "Ðапример, ако изберете вÑички поÑетители, които Ñа Ñе завърнали на Ñайта, включително тези, които Ñа купили нещо при предишните поÑещениÑ, API заÑвката ще Ñъдържа %s", "Warning": "Предупреждение", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik ще Ñпре поддръжката на тази PHP верÑÐ¸Ñ Ð½Ð° %s. Обновете вашата PHP верÑÐ¸Ñ Ð¿Ñ€ÐµÐ´Ð¸ крайниÑÑ‚ Ñрок да е изтекъл!", "WarningFileIntegrityNoManifest": "ЦÑлоÑтната проверка на файла не може да бъде изпълнена поради липÑата на manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Ð’ Ñлучай, че Piwik Ñе внедрÑва поÑредÑтвом Git, е нормално това Ñъобщение да Ñе поÑвÑва.", "WarningFileIntegrityNoMd5file": "ЦÑлоÑтната проверка не може да бъде оÑъщеÑтвена поради липÑата на md5_file() функциÑта.", diff --git a/lang/cs.json b/lang/cs.json index b4e6e92ba47a67affa11a89d2e74e6c04a26261d..1050a3f259bffd8ca6b58da14a363270342f3800 100644 --- a/lang/cs.json +++ b/lang/cs.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "12-hodinový formát", + "24HourClock": "24-hodinový formát", "AbandonedCarts": "Neobjednané koÅ¡Ãky", "AboutPiwikX": "O Piwiku %s", "Action": "Akce", @@ -11,6 +13,7 @@ "AllWebsitesDashboard": "NástÄ›nka pro vÅ¡echny weby", "And": "a", "API": "API", + "Apply": "PoužÃt", "ArchivingInlineHelp": "Pro web stránky se stÅ™ednà nebo vysokou návÅ¡tÄ›vnostà je doporuÄeno zakázat archivovánà Piwiku z webového prohlÞeÄe. MÃsto toho doporuÄujeme vytvoÅ™enà úlohy pro cron", "ArchivingTriggerDescription": "DoporuÄeno pro vÄ›tšà instalace Piwiku, potÅ™ebujete %snastavit cron úlohu%s na automatické spracovánà hlášenÃ.", "AuthenticationMethodSmtp": "AutentizaÄnà metoda SMTP", @@ -33,7 +36,7 @@ "Close": "ZavÅ™Ãt", "ClickToSearch": "KliknÄ›te pro hledánÃ", "ColumnActionsPerVisit": "Akcà za návÅ¡tÄ›vu", - "ColumnActionsPerVisitDocumentation": "PrůmÄ›rný poÄet akcà (zobrazenà stránek, staženà nebo externÃch odkazů) za návÅ¡tÄ›vu.", + "ColumnActionsPerVisitDocumentation": "PrůmÄ›rný poÄet akcà (zobrazenà stránek, staženà nebo externÃch odkazů) provedených bÄ›hem návÅ¡tÄ›vy.", "ColumnAverageGenerationTime": "PrůmÄ›rný Äas generovánÃ", "ColumnAverageGenerationTimeDocumentation": "PrůmÄ›rný Äas, za který byla stránka vygenerována. Toto měřenà zahrnuje Äas, který potÅ™eboval server k vygenerovánà stránky plus Äas, který potÅ™eboval klient k jejÃmu staženÃ. Kratšà průmÄ›rný Äas znamená rychlejšà stránku.", "ColumnAverageTimeOnPage": "PrůmÄ›rný Äas na stránce", @@ -43,7 +46,7 @@ "ColumnBounceRate": "Odchozà frekvence", "ColumnBounceRateDocumentation": "Procento návÅ¡tÄ›v, které mÄ›ly jedno zobrazenÃ. To znamená návÅ¡tÄ›vnÃci, kteřà po zobrazenà stránky okamžitÄ› odeÅ¡li.", "ColumnBounces": "Ihned odchozÃ", - "ColumnBouncesDocumentation": "PoÄet návÅ¡tÄ›v, které zaÄaly a skonÄily na této stránce. To znamená, kteřà navÅ¡tÃvily jen tuto stránku.", + "ColumnBouncesDocumentation": "PoÄet návÅ¡tÄ›v, které zaÄaly a skonÄily na této stránce. To znamená, že návÅ¡tÄ›vnÃk opustil web po zobrazenà pouze této stránky.", "ColumnConversionRate": "Frekvence konverzÃ", "ColumnConversionRateDocumentation": "Procento návÅ¡tÄ›v, které provedly konverzi CÃle.", "ColumnDestinationPage": "CÃlová stránka", @@ -60,11 +63,11 @@ "ColumnNbActions": "Akce", "ColumnNbActionsDocumentation": "PoÄet akcà VaÅ¡ich návÅ¡tÄ›vnÃků. Akcà se rozumà zobrazenà stránky, staženà a kliknutà na externà odkazy.", "ColumnNbUniqVisitors": "JedineÄnà návÅ¡tÄ›vnÃci", - "ColumnNbUniqVisitorsDocumentation": "PoÄet neduplicitnÃch návÅ¡tÄ›vnÃků, kteřà navÅ¡tÃvili vaÅ¡e stránky. Každý návÅ¡tÄ›vnÃk je poÄÃtán pouze jednou, ikdyž tÅ™eba pÅ™iÅ¡el nÄ›kolikrát za den.", + "ColumnNbUniqVisitorsDocumentation": "PoÄet neduplicitnÃch návÅ¡tÄ›vnÃků, kteřà navÅ¡tÃvili vaÅ¡e stránky. Každý návÅ¡tÄ›vnÃk je poÄÃtán pouze jednou, i pokud pÅ™iÅ¡el nÄ›kolikrát za den.", "ColumnNbUsers": "Uživatelé", "ColumnNbUsersDocumentation": "PoÄet uživatelů pÅ™ihlášených na vaÅ¡ich stránkách. Je to poÄet unikátnÃch aktivnÃch uživatelů, kteřà majà nastavené ID pomocà sledovacà funkce 'setUserId'.", "ColumnNbVisits": "NávÅ¡tÄ›v", - "ColumnNbVisitsDocumentation": "Pokud návÅ¡tÄ›vnÃk pÅ™ijde na vaÅ¡e stránky poprvé nebo po tÅ™iceti minutách, je tato návÅ¡tÄ›va zapoÄÃtána jako nová.", + "ColumnNbVisitsDocumentation": "Pokud návÅ¡tÄ›vnÃk pÅ™ijde na stránku poprvé nebo opakovanÄ› po vÃce než 30ti minutách, je návÅ¡tÄ›va zapoÄÃtána jako nová.", "ColumnPageBounceRateDocumentation": "Procento návÅ¡tÄ›v, které zaÄaly touto stránkou a ihned ji opustili.", "ColumnPageviews": "Zobrazenà stránek", "ColumnPageviewsDocumentation": "PoÄet návÅ¡tÄ›v této stránky.", @@ -98,6 +101,7 @@ "DateRange": "Rozsah:", "DateRangeFrom": "Od", "DateRangeFromTo": "Od %s do %s", + "DateRangeInPeriodList": "Rozsah datumů", "DateRangeTo": "Do", "DaysHours": "%1$s dnà %2$s hodin", "DaysSinceFirstVisit": "Dnů od prvnà návÅ¡tÄ›vy", @@ -131,14 +135,14 @@ "Error": "Chyba", "ErrorRequest": "Ajaj! PÅ™i požadavku doÅ¡lo k chybÄ›. Na serveru mohlo dojÃt k doÄasnému problému, nebo jste požádali o hlášenà s pÅ™ÃliÅ¡ mnoha daty. ProsÃm, zkuste to znovu. Pokud se bude problém opakovat, %skontaktujte svého administrátora Piwiku%s.", "EvolutionOverPeriod": "Vývoj za periodu", - "EvolutionSummaryGeneric": "%1$s v %2$s srovnáno s %3$s v %4$s. Vývin: %5$s", - "ExceptionContactSupportGeneric": "Pokud problém pÅ™etrvá, %skontaktujte pro pomoc vaÅ¡eho Piwik administrátora%s.", + "EvolutionSummaryGeneric": "%1$s v %2$s srovnáno s %3$s v %4$s. Vývoj: %5$s", + "ExceptionContactSupportGeneric": "Pokud problém pÅ™etrvá, %skontaktujte pro pomoc svého Piwik administrátora%s.", "ExceptionCheckUserHasSuperUserAccessOrIsTheUser": "Uživatel musà být super uživatel nebo uživatel %s.", "ExceptionConfigurationFileNotFound": "KonfiguraÄnà soubor {%s} nebyl nalezen", "ExceptionConfigurationFileNotFound2": "Pokud soubor existuje, ověřte, že %s může ÄÃst uživatel '%s'.", "ExceptionDatabaseVersion": "VaÅ¡e %1$s verze je %2$s ale Piwik vyžaduje minimálnÄ› %3$s.", "ExceptionDatabaseVersionNewerThanCodebase": "Kód Piwiku je z verze %1$s, ale bylo zjiÅ¡tÄ›no, že databáze byla již aktualizována na verzi %2$s.", - "ExceptionDatabaseVersionNewerThanCodebaseWait": "VaÅ¡i administrátoÅ™i možná pracujà na aktualizaci. Zkuste to, prosÃm, za pár minut.", + "ExceptionDatabaseVersionNewerThanCodebaseWait": "VaÅ¡i administrátoÅ™i možná pracujà na aktualizaci. Zkuste to prosÃm za pár minut.", "ExceptionFileIntegrity": "Test integrity selhal: %s", "ExceptionFilesizeMismatch": "Nesouhlasà velikost souboru: %1$s (oÄekávaná délka: %2$s, nalezeno: %3$s)", "ExceptionIncompatibleClientServerVersions": "VaÅ¡e %1$s verze klienta je %2$s tato je ale nekompatibilnà se serverem %3$s.", @@ -167,7 +171,7 @@ "ExpandDataTableFooter": "ZmÄ›nit vizualizaci nebo nastavit hlášenÃ", "Export": "Exportovat", "ExportAsImage": "Exportovat obrázek", - "ExportThisReport": "Exportovat data v ostatnÃch formátech", + "ExportThisReport": "Exportovat data v jiných formátech", "Faq": "FAQ", "FileIntegrityWarningExplanation": "Test integrity selhal a nahlásil nÄ›jaké chyby. To je kvůli ÄásteÄnÄ› nebo Å¡patnÄ› nahraným souborům Piwiku. MÄ›li byste znovu nahrát vÅ¡echny soubory Piwiku v módu BINARY.", "First": "PrvnÃ", @@ -184,11 +188,11 @@ "GraphHelp": "VÃce informacà o zobrazovánà grafů v Piwiku", "HelloUser": "Ahoj, %s!", "Help": "Pomoc", - "HelpTranslatePiwik": "Možná byste chtÄ›li %1$snám pomoct s pÅ™ekladem Piwiku%2$s.", + "HelpTranslatePiwik": "Možná byste nám chtÄ›li %1$s pomoci s pÅ™ekladem Piwiku%2$s.", "Hide": "skrýt", "HoursMinutes": "%1$s hodin %2$s min.", "Id": "ID", - "IfArchivingIsFastYouCanSetupCronRunMoreOften": "V pÅ™ÃpadÄ›, že je zálohovánà dost rychlé, můžete jej spouÅ¡tÄ›t v cronu ÄastÄ›ji", + "IfArchivingIsFastYouCanSetupCronRunMoreOften": "V pÅ™ÃpadÄ›, že je zálohovánà dost rychlé, jej můžete spouÅ¡tÄ›t v cronu ÄastÄ›ji", "InfoFor": "Informace o %s", "Installed": "Nainstalováno", "InvalidDateRange": "Chybný rozsah, vyberte jej znovu", @@ -200,12 +204,12 @@ "LastDaysShort": "PoslednÃch %s dnÃ", "LearnMore": "%1$sdozvÄ›dÄ›t se vÃce%2$s", "Live": "ŽivÄ›", - "Loading": "NaÄÃtám...", - "LoadingData": "NaÄÃtám data...", - "LoadingPopover": "NaÄÃtám %s...", - "LoadingPopoverFor": "NaÄÃtám %s", + "Loading": "NaÄÃtánÃ...", + "LoadingData": "NaÄÃtánà dat...", + "LoadingPopover": "NaÄÃtánà %s...", + "LoadingPopoverFor": "NaÄÃtánà %s pro", "Locale": "cs_CZ.UTF-8", - "Logout": "Odhlásit se", + "Logout": "Odhlásit", "MainMetrics": "Hlavnà měřenÃ", "Matches": "Shody", "MediumToHighTrafficItIsRecommendedTo": "Pro weby se stÅ™ednÃm nebo velkým provozem doporuÄujeme zpracovat dneÅ¡nà hlášenà každou půlhodinu (%s vteÅ™in), nebo každou hodinu (%s vteÅ™in)", @@ -222,12 +226,12 @@ "More": "VÃce", "MoreDetails": "VÃce podrobnostÃ", "MoreLowerCase": "vÃce", - "MultiSitesSummary": "vÅ¡echny weby", + "MultiSitesSummary": "VÅ¡echny weby", "Name": "Jméno", "NbActions": "PoÄet akcÃ", "NbSearches": "PoÄet internÃch vyhledávánÃ", "Never": "Nikdy", - "NewReportsWillBeProcessedByCron": "Pokud nenà archivovánà spouÅ¡tÄ›no web prohlÞeÄem, budou nová hlášenà zpracovávána cronem", + "NewReportsWillBeProcessedByCron": "Pokud nenà archivovánà spouÅ¡tÄ›no webovým prohlÞeÄem, budou nová hlášenà zpracovávána cronem.", "NewUpdatePiwikX": "Nová aktualizace: Piwik %s", "NewVisitor": "Nový návÅ¡tÄ›vnÃk", "NewVisits": "Nové návÅ¡tÄ›vy", @@ -248,7 +252,7 @@ "OneVisit": "1 návÅ¡tÄ›va", "OnlyEnterIfRequired": "Uživatelské jméno zadejte pouze v pÅ™ÃpadÄ›, že jej váš SMTP server vyžaduje", "OnlyEnterIfRequiredPassword": "Heslo zadejte pouze v pÅ™ÃpadÄ›, že jej váš SMTP server vyžaduje", - "OnlyUsedIfUserPwdIsSet": "Použito pouze v pÅ™ÃpadÄ›, že je nastaveno uživatelské jméno\/heslo. V pÅ™ÃpadÄ› že si nejste jisti jakou metodu použÃt, zeptejte se vaÅ¡eho poskytovatele", + "OnlyUsedIfUserPwdIsSet": "Použito pouze v pÅ™ÃpadÄ›, že je nastaveno uživatelské jméno\/heslo. V pÅ™ÃpadÄ› že si nejste jisti jakou metodu použÃt, zeptejte se svého poskytovatele", "OpenSourceWebAnalytics": "Open Source Web Analytics", "OperationAtLeast": "Aspoň", "OperationAtMost": "NejvÃce", @@ -260,8 +264,11 @@ "OperationIsNot": "NenÃ", "OperationLessThan": "Menšà než", "OperationNotEquals": "Nenà rovno", + "OperationStartsWith": "ZaÄÃná na", + "OperationEndsWith": "KonÄà na", "OptionalSmtpPort": "Volitelné. Pro neÅ¡ifrovaná a TLS SMTP spojenà je výchozà 25, pro SSL SMTP spojenà je výchozà 465.", "Options": "NastavenÃ", + "Or": "nebo", "OrCancel": "nebo %s ZruÅ¡it %s", "Others": "OstatnÃ", "Outlink": "Odchozà odkaz", @@ -280,7 +287,7 @@ "PiwikXIsAvailablePleaseNotifyPiwikAdmin": "%1$s je dostupný. ProsÃm, upozornÄ›te %2$sadministrátora Piwiku%3$s.", "PiwikXIsAvailablePleaseUpdateNow": "Je k dispozici Piwik %1$s. %2$s ProsÃm aktualizujte jej!%3$s (viz %4$s zmÄ›ny%5$s).", "PleaseSpecifyValue": "ProsÃm zapiÅ¡tÄ› hodnotu pro '%s'.", - "PleaseUpdatePiwik": "ProsÃm aktualizujte Piwik", + "PleaseUpdatePiwik": "Aktualizujte prosÃm svůj Piwik", "Plugin": "Plugin", "Plugins": "Zásuvné moduly", "PoweredBy": "Běžà na", @@ -327,7 +334,7 @@ "SeeTheOfficialDocumentationForMoreInformation": "Pro vÃce informacà navÅ¡tivte %soficiálnà dokumentaci%s.", "SeeThisFaq": "PodÃvejte se na %1$stento Äasto kladený dotaz%2$s.", "Segment": "Část", - "SelectYesIfYouWantToSendEmailsViaServer": "Zvolte \"Ano\" pokud chcete e-mail posÃlat pomocà uvedeného serveru mÃsto lokálnà funkce PHP mail", + "SelectYesIfYouWantToSendEmailsViaServer": "Zvolte \"Ano\" pokud chcete email posÃlat pomocà uvedeného serveru mÃsto lokálnà funkce PHP mail", "Settings": "NastavenÃ", "Shipping": "Doprava", "Show": "zobrazit", @@ -339,18 +346,22 @@ "SmtpServerAddress": "Adresa SMTP serveru", "SmtpUsername": "Uživatelské jméno SMTP", "Source": "Zdroj", - "StatisticsAreNotRecorded": "Zaznamenávánà statistik návÅ¡tÄ›vnÃků Pywikem je aktuálnÄ› zakázáno. Povolte ho nastavenÃm record_statistics = 1 ve vaÅ¡em souboru config\/config.ini.php.", + "StatisticsAreNotRecorded": "Zaznamenávánà statistik návÅ¡tÄ›vnÃků Piwikem je aktuálnÄ› zakázáno. Povolte ho nastavenÃm record_statistics = 1 ve vaÅ¡em souboru config\/config.ini.php.", "Subtotal": "MezisouÄet", "Summary": "Souhrn", "Table": "Tabulka", "TagCloud": "Oblak tagů", "Tax": "Daň", "TimeAgo": "PÅ™ed %s", + "TimeFormat": "Formát Äasu", "TimeOnPage": "ÄŒas na stránce", "Total": "Celkem", "TotalRatioTooltip": "Toto je %1$s ze vÅ¡ech %2$s %3$s.", "TotalRevenue": "Celková hodnota", "TotalVisitsPageviewsActionsRevenue": "(Celkem: %s návÅ¡tÄ›v, %s zobrazenÃ, %s akcÃ, %s pÅ™Ãjem)", + "TrackingScopeAction": "Akce", + "TrackingScopePage": "Stránka", + "TrackingScopeVisit": "NávÅ¡tÄ›va", "TransitionsRowActionTooltip": "PodÃvejte se, co dÄ›lali návÅ¡tÄ›vnÃci pÅ™ed a po návÅ¡tÄ›vÄ› této stránky", "TransitionsRowActionTooltipTitle": "OtevÅ™Ãt pÅ™echody", "TranslatorName": "Filip Bartmann, Jakub Baláš, Michal ÄŒihaÅ™", @@ -360,7 +371,7 @@ "UsePlusMinusIconsDocumentation": "Použijte ikonu plus a mÃnus vlevo od navigace.", "UserId": "ID uživatele", "Username": "Uživatelské jméno", - "UseSMTPServerForEmail": "Pro e-mail použÃt SMTP server", + "UseSMTPServerForEmail": "Pro email použÃt SMTP server", "Value": "Hodnota", "VBarGraph": "Svislý sloupcový graf", "View": "Zobrazit", @@ -368,7 +379,7 @@ "Visit": "NávÅ¡tÄ›va", "VisitConvertedGoal": "NávÅ¡tÄ›va, která provedla alespoň jednu konverzi CÃle.", "VisitConvertedGoalId": "NávÅ¡tÄ›va, která provedla konverzi konkrétnÃho ID CÃle.", - "VisitConvertedNGoals": "NávÅ¡tÄ›va provedla %s konverzà CÃlůb.", + "VisitConvertedNGoals": "NávÅ¡tÄ›va promÄ›nila %s cÃlů.", "VisitDuration": "PrůmÄ›rná doba trvánà návÅ¡tÄ›v (v sekundách)", "Visitor": "NávÅ¡tÄ›vnÃk", "VisitorID": "ID návÅ¡tÄ›vnÃka", @@ -380,7 +391,7 @@ "VisitTypeExample": "NapÅ™Ãklad pro výbÄ›r vÅ¡ech návÅ¡tÄ›vnÃků, kteřà se vrátili na stránky vÄetnÄ› tÄ›ch, co si v pÅ™edcchozÃch návÅ¡tÄ›vách nÄ›co koupili, by API požadavek obsahoval %s", "Warning": "VarovánÃ", "WarningPhpVersionXIsTooOld": "PHP verze %s, kterou použÃváte již nenà podporována (EOL). DůraznÄ› doporuÄujeme aktualizovat na novÄ›jšà verzi, protože stávajÃcà může obsahovat bezpeÄnostnà a dalšà problémy, které byly opraveny v novÄ›jÅ¡Ãch verzÃch PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik tuto verzi PHP pÅ™estane podporovat za %s. Aktualizujte, dokud je Äas!", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik pÅ™estane podporavat PHP %1$s v dalÅ¡Ãm vydánÃ. Aktualizujte PHP alespoň na %2$s, než bude pozdÄ›.", "WarningFileIntegrityNoManifest": "Test integrity nemůže být proveden z důvodů chybÄ›jÃcÃho souboru manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Pokud nasazujete Piwik z Gitu, pak je tato zpráva normálnÃ.", "WarningFileIntegrityNoMd5file": "Test integrity nemůže být dokonÄen z důvodů chybÄ›jÃcà funkce md5_file().", @@ -400,6 +411,7 @@ "YearsDays": "%1$s roků %2$s dnÃ", "Yes": "Ano", "YouAreCurrentlyUsing": "PoužÃváte Piwik verze %s.", + "YouAreViewingDemoShortMessage": "DÃváte se na demo Piwiku", "YouMustBeLoggedIn": "Abyste mohli využÃvat tyto funkce musÃte být pÅ™ihlášeni", "YourChangesHaveBeenSaved": "VaÅ¡e zmÄ›ny byly uloženy" }, @@ -454,9 +466,9 @@ "PossibleSslErrorExplanation": "DoÅ¡lo k chybÄ›, která může být způsobena neplatným, nebo sám sebou podepsaným SSL certifikátem: \"%s\". PÅ™ihlášenà fungovat může, ale nebude to tak bezpeÄné.", "IgnoreSslError": "Ignorovat chybu SSL", "RatingDontRemindMe": "Neupozorňovat mÄ›", - "RatingNotNow": "Ne nynÃ", + "RatingNotNow": "Nynà ne", "RatingNow": "Dobrá, teÄ to ohodnotÃm", - "RatingPleaseRateUs": "Piwik mobile je volnÄ› Å¡iÅ™itelný software. Proto bychom ocenili, kdybyste si naÅ¡li mnutu k jeho ohodnocenà v %s. Pokud máte návrh na nÄ›jakou novou vlastnost nebo chcete nahlásit chybu, kontaktujte %s", + "RatingPleaseRateUs": "Piwik mobile je volnÄ› Å¡iÅ™itelný software. Proto bychom ocenili, kdybyste si naÅ¡li minutu k jeho ohodnocenà v %s. Pokud máte návrh na nÄ›jakou novou vlastnost nebo chcete nahlásit chybu, kontaktujte %s", "ReleaseToRefresh": "UvolnÄ›te pro obnovenÃ...", "Reloading": "Znovu nahrávám...", "RequestTimedOutShort": "Chyba Äasového limitu sÃtÄ›", @@ -480,7 +492,7 @@ "CompareDocumentation": "KliknÄ›te na odkaz nÞe a otevÅ™ete toto vyskakovacà okno pro jiný řádek ze stejné tabulky kvůli srovnánà vÃce záznamů. <br\/> Použijte shift + kliknutà pro oznaÄenà řádku k porovnánà bez otevÅ™enà tohoto vyskakovacÃho okna.", "CompareRows": "Porovnat řádky", "ComparingRecords": "Porovnávánà %s řádků", - "Documentation": "KliknÄ›te na měřenÃ, pokud je chcete zobrazit ve velkém grafu vývoje. Použijte shoft + kliknutà pro zobrazenà vÃce měřenà najednou.", + "Documentation": "KliknÄ›te na měřenÃ, pokud je chcete zobrazit ve velkém grafu vývoje. Použijte shift + kliknutà pro zobrazenà vÃce měřenà najednou.", "MetricBetweenText": "mezi %s a %s", "MetricChangeText": "%s za interval", "MetricMinMax": "BÄ›hem tohoto obdobà %1$s se pohyboval(a) mezi %2$s a %3$s", diff --git a/lang/da.json b/lang/da.json index e16b0cfd8b6cb6c7e535212022f9b786a81a04f3..050ae1a0c7a8059f663f80ffb650f344d6bed436 100644 --- a/lang/da.json +++ b/lang/da.json @@ -368,7 +368,6 @@ "VisitTypeExample": "F. eks., for at vælge alle besøgende, som er vendt tilbage til hjemmesiden, herunder dem, der har købt noget i deres tidligere besøg, vil API-anmodningen indeholde %s", "Warning": "Advarsel", "WarningPhpVersionXIsTooOld": "PHP version %s har nÃ¥et slutningen af ​​sin levetid (EOL). Du opfordres kraftigt til at opgradere til den aktuelle version, fordi brug af denne version kan udsætte dig for sikkerhedshuller og fejl, som er blevet rettet i nyere versioner af PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik vil ophøre med at understøtte PHP-version i %s. Opgrader PHP versionen, før det er for sent!", "WarningFileIntegrityNoManifest": "Fil integritetstjek kunne ikke udføres pÃ¥ grund af manglende manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Hvis du implementerer Piwik fra Git, er meddelelsen normal.", "WarningFileIntegrityNoMd5file": "Fil integritetstjek kunne ikke gennemføres pga. manglende md5_file () funktion.", diff --git a/lang/de.json b/lang/de.json index 25650ebf009fb9735de6d98c45ee3d3aa4e2e302..0f975ee0659d83ac7b6e491f5a74499d01ef3407 100644 --- a/lang/de.json +++ b/lang/de.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "12-Stunden Uhr", + "24HourClock": "24-Stunden Uhr", "AbandonedCarts": "Verlassene Warenkörbe", "AboutPiwikX": "Über Piwik %s", "Action": "Aktion", @@ -262,8 +264,11 @@ "OperationIsNot": "Entspricht nicht", "OperationLessThan": "Weniger als", "OperationNotEquals": "Entspricht nicht", + "OperationStartsWith": "Startet mit", + "OperationEndsWith": "Endet mit", "OptionalSmtpPort": "Optional. Standard ist 25 für unverschlüsseltes SMTP sowie SMTP mit TLS, und 465 für SMTP mit SSL.", "Options": "Optionen", + "Or": "oder", "OrCancel": "oder %s abbrechen %s", "Others": "Andere", "Outlink": "Ausgehender Verweis", @@ -348,11 +353,15 @@ "TagCloud": "Schlagwortwolke", "Tax": "Steuer", "TimeAgo": "vor %s", + "TimeFormat": "Zeitformat", "TimeOnPage": "Zeit auf Seite", "Total": "Gesamt", "TotalRatioTooltip": "Das entspricht %1$s von %2$s %3$s.", "TotalRevenue": "Gesamteinnahmen", "TotalVisitsPageviewsActionsRevenue": "(Gesamt: %s Besuche, %s Seitenansichten, %s Aktionen, %s Einnahmen)", + "TrackingScopeAction": "Aktion", + "TrackingScopePage": "Seite", + "TrackingScopeVisit": "Besuch", "TransitionsRowActionTooltip": "Die Aktionen vor und nach dieser Seite auswerten", "TransitionsRowActionTooltipTitle": "Transitions öffnen", "TranslatorName": "Frank Bueltge, Thorsten Taube, Arthur W. Borens, Marco Ziesing, Andreas Just, Fabian Becker, Henry Müller, Pascal Herbert, Christian W. Schneider, Michael Stenz, Itransition, Timo Besenreuther, Stefan Giehl", @@ -382,7 +391,7 @@ "VisitTypeExample": "Um beispielsweise alle wiederkehrenden Besucher abzufragen, die Bestellungen getätigt haben, muss der API Aufruf folgendes enthalten: %s", "Warning": "Warnung", "WarningPhpVersionXIsTooOld": "Die von Ihnen eingesetzte PHP Version %s hat das Ende der Lebensdauer (EOL) erreicht. Es wird dringend angeraten, ein Update auf eine aktuelle Version durchzuführen, da der Einsatz dieser Version zu Sicherheitsrisiken und Fehlern führen kann, welche in neueren PHP Versionen korrigiert wurden.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik wird die Unterstützung für diese PHP Version im %s einstellen. Aktualisieren Sie ihre PHP Version, bevor es zu spät ist!", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik wird die Unterstützung für PHP %1$s in der nächsten Hauptversion einstellen. Aktualisieren Sie ihre PHP Version auf mindestens %2$s, bevor es zu spät ist!", "WarningFileIntegrityNoManifest": "Aufgrund der fehlenden Datei manifest.inc.php konnte die Integritätsprüfung nicht durchgeführt werden.", "WarningFileIntegrityNoManifestDeployingFromGit": "Wenn Sie Piwik von Git deployen ist diese Nachricht normal.", "WarningFileIntegrityNoMd5file": "Durch die fehlende md5_file() Funktion konnte die Integritätsprüfung nicht durchgeführt werden.", diff --git a/lang/el.json b/lang/el.json index 8da0175a431dca007e93d8c022ffbaf2f3efca79..c8a479aaef80f73379ea615a7858142b8855655f 100644 --- a/lang/el.json +++ b/lang/el.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "Ρολόι σε μοÏφή 12 ωÏών", + "24HourClock": "Ρολόι σε μοÏφή 24 ωÏών", "AbandonedCarts": "ΕγκαταλειμμÎνα Καλάθια ΑγοÏών", "AboutPiwikX": "Σχετικά με το Piwik %s", "Action": "ΔÏαστηÏιότητα", @@ -262,8 +264,11 @@ "OperationIsNot": "Δεν είναι", "OperationLessThan": "ΜικÏότεÏο από", "OperationNotEquals": "Δεν ισοÏται", + "OperationStartsWith": "ΑÏχίζει με", + "OperationEndsWith": "Τελειώνει σε", "OptionalSmtpPort": "Î ÏοαιÏετικό: Η 25 είναι η Ï€ÏοεπιλεγμÎνη θÏÏα για μη κÏυπτογÏαφημÎνο και TLS SMTP. Η 465 για SSL SMTP.", "Options": "ΕπιλογÎÏ‚", + "Or": "ή", "OrCancel": "ή %s ΆκυÏο %s", "Others": "Άλλα", "Outlink": "ΕξωτεÏικός σÏνδεσμος", @@ -348,11 +353,15 @@ "TagCloud": "ΣÏννεφο λÎξεων", "Tax": "ΦόÏος", "TimeAgo": "Ï€Ïιν από %s", + "TimeFormat": "ΜοÏφή ÏŽÏας", "TimeOnPage": "ΧÏόνος στη σελίδα", "Total": "ΣÏνολο", "TotalRatioTooltip": "Αυτό είναι το %1$s από όλες τις %2$s %3$s.", "TotalRevenue": "Συνολική Î Ïόσοδος", "TotalVisitsPageviewsActionsRevenue": "(ΣÏνολα: %s επισκÎψεις, %s Ï€ÏοβολÎÏ‚ σελίδων, %s ενÎÏγειες, %s κÎÏδος)", + "TrackingScopeAction": "ΕνÎÏγεια", + "TrackingScopePage": "Σελίδα", + "TrackingScopeVisit": "Επίσκεψη", "TransitionsRowActionTooltip": "Δείτε τι Îκαναν οι επισκÎπτες Ï€Ïιν και μετά την Ï€Ïοβολή αυτής της σελίδας", "TransitionsRowActionTooltipTitle": "Άνοιγμα Μεταβάσεων", "TranslatorName": "Jim Black www.jblack.info, ΓεώÏγιος ΤÎλλος OnSite.Net VoIP & IT Solutions, Παναγιώτης Παπάζογλου ΔÏ. Δασολόγος-ΠεÏιβαλλοντολόγος, <a href=\"http:\/\/www.lourdas.name\">ΛοÏÏδας Βασίλειος<\/a>", @@ -382,7 +391,7 @@ "VisitTypeExample": "Για παÏάδειγμα, για να επιλÎξετε όλους τους επισκÎπτες που Îχουν επιστÏÎψει στην ιστοσελίδα και να πεÏιλάβετε αυτοÏÏ‚ που Îχουν αγοÏάσει κάτι στις Ï€ÏοηγοÏμενες επισκÎψεις, το αίτημα API θα πεÏιÎχει %s", "Warning": "Î Ïοειδοποίηση", "WarningPhpVersionXIsTooOld": "Η Îκδοση PHP %s που χÏησιμοποιείτε Îχει φτάσει στο ΤÎλος Ζωής της (EOL). Συνιστάται να αναβαθμίσετε στην Ï„ÏÎχουσα Îκδοση, καθώς η χÏήση αυτή της Îκδοσης μποÏεί να σας εκθÎσει σε Ï€Ïοβλήματα ασφαλείας και σφάλματα που Îχουν διοÏθωθεί στις Ï€Ïόσφατες εκδόσεις της PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Το Piwik θα σταματήσει να υποστηÏίζει αυτή την Îκδοση στο %s. Αναβαθμίστε την Îκδοση της PHP σας Ï€ÏÎ¿Ï„Î¿Ï ÎµÎ¯Î½Î±Î¹ αÏγά!", + "WarningPiwikWillStopSupportingPHPVersion": "Το Piwik θα σταματήσει να υποστηÏίζει την PHP %1$s στην επόμενη σημαντική Îκδοσή του. Αναβαθμίστε την PHP τουλάχιστον στην Îκδοση %2$s, Ï€ÏÎ¿Ï„Î¿Ï ÎµÎ¯Î½Î±Î¹ αÏγά!", "WarningFileIntegrityNoManifest": "Ο Îλεγχος ακεÏαιότητας αÏχείου δεν μποÏεί να Ï€Ïαγματοποιηθεί επειδή λείπει το αÏχείο manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Αν παίÏνετε το Piwik από το Git, το μήνυμα αυτό είναι φυσιολογικό.", "WarningFileIntegrityNoMd5file": "Ο Îλεγχος ακεÏαιότητας αÏχείου δεν μποÏεί να ολοκληÏωθεί γιατί είναι ανενεÏγή η συνάÏτηση md5_file().", diff --git a/lang/en.json b/lang/en.json index a3da13491cc75d491ea25ceb3bb228d9530a2cef..6581f7fc47ced6ff023125fe05f24403a2f3d4f8 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "12-hour clock", + "24HourClock": "24-hour clock", "AbandonedCarts": "Abandoned Carts", "AboutPiwikX": "About Piwik %s", "Action": "Action", @@ -263,8 +265,11 @@ "OperationIsNot": "Is not", "OperationLessThan": "Less than", "OperationNotEquals": "Not Equals", + "OperationStartsWith": "Starts with", + "OperationEndsWith": "Ends with", "OptionalSmtpPort": "Optional. Defaults to 25 for unencrypted and TLS SMTP, and 465 for SSL SMTP.", "Options": "Options", + "Or": "or", "OrCancel": "or %s Cancel %s", "Others": "Others", "Outlink": "Outlink", @@ -349,11 +354,15 @@ "TagCloud": "Tag Cloud", "Tax": "Tax", "TimeAgo": "%s ago", + "TimeFormat": "Time format", "TimeOnPage": "Time on page", "Total": "Total", "TotalRatioTooltip": "This is %1$s of all %2$s %3$s.", "TotalRevenue": "Total Revenue", "TotalVisitsPageviewsActionsRevenue": "(Total: %s visits, %s pageviews, %s actions, %s revenue)", + "TrackingScopeAction": "Action", + "TrackingScopePage": "Page", + "TrackingScopeVisit": "Visit", "TransitionsRowActionTooltip": "See what visitors did before and after viewing this page", "TransitionsRowActionTooltipTitle": "Open Transitions", "TranslatorName": "-", @@ -383,7 +392,7 @@ "VisitTypeExample": "For example, to select all visitors who have returned to the website, including those who have bought something in their previous visits, the API request would contain %s", "Warning": "Warning", "WarningPhpVersionXIsTooOld": "The PHP version %s you are using has reached its End of Life (EOL). You are strongly urged to upgrade to a current version, as using this version may expose you to security vulnerabilities and bugs that have been fixed in more recent versions of PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik will stop supporting this PHP version in %s. Upgrade your PHP version before it's too late!", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik will stop supporting PHP %1$s in the next major version. Upgrade your PHP to at least PHP %2$s, before it's too late!", "WarningFileIntegrityNoManifest": "File integrity check could not be performed due to missing manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "If you are deploying Piwik from Git, this message is normal.", "WarningFileIntegrityNoMd5file": "File integrity check could not be completed due to missing md5_file() function.", diff --git a/lang/es.json b/lang/es.json index 869b0500fe753287daf6b00c3602f4f46cd1e6fc..5c2a97a67d1a2cc1cc51c7e720aba766d2b8c2f4 100644 --- a/lang/es.json +++ b/lang/es.json @@ -378,7 +378,6 @@ "VisitTypeExample": "Por ejemplo, para seleccionar todos los visitantes que han vuelto al sitio, incluyendo a aquellos que han comprado algo en sus anteriores visitas, la solicitud de la API debe contener %s", "Warning": "Advertencia", "WarningPhpVersionXIsTooOld": "La versión %s de PHP que está utilizando ha alcanzado su End of LIfe (EOL). Necesitas urgentemente actualizar a una versión más reciente, ya que usando esta versión puede exponerlo a vulnerabilidades de seguridad y errores que han sido arreglados en versiones más recientes de PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik dejará de dar asistencia a esta versión de PHP en la versión %s. ¡Actualice su versión de PHP antes que sea tarde!", "WarningFileIntegrityNoManifest": "La verificación de integridad de archivos no se pudo realizar debido a que falta manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Si está desplegando Piwik con Git, este mensaje es normal.", "WarningFileIntegrityNoMd5file": "La verificación de integridad no pudo ser completada debido a que falta la función md5_file().", diff --git a/lang/fi.json b/lang/fi.json index ba4ffb0b0aa15df77a5458fe4d3eefffae1a06ca..702aced3099febdf7013a34c4ad9aa46a8df2865 100644 --- a/lang/fi.json +++ b/lang/fi.json @@ -369,7 +369,6 @@ "VisitTypeExample": "Voit esimerkiksi valita kaikki kävijät jotka palasivat sivulle ja ostivat edellisellä käynnillä. Esimerkki pyynnöstä on %s", "Warning": "Varoitus", "WarningPhpVersionXIsTooOld": "Käyttämäsi PHP versio %s on ohittanut EOL (End of Life) ajankohdan. Suosittelemme vakavasti ohjelmiston päivittämistä uudempaan versioon, sillä käyttämäsi versio voi altistaa sivuston tietoturva-aukoille ja virheille, jotka ovat korjattu PHP:n uudemmissa versioissa.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik ei tue tätä versiota PHP:stä %s. Päivitä PHP:n versio ennen kuin se on liian myöhäistä!", "WarningFileIntegrityNoManifest": "Tiedostojen eheystarkistusta ei voida suorittaa, tiedosto manifest.inc.php puuttuu", "WarningFileIntegrityNoManifestDeployingFromGit": "Jos olet ottanut Piwikin käyttöön Git-järjestelmän kautta, tämä viesti on normaali.", "WarningFileIntegrityNoMd5file": "Tiedostojen eheystarkistusta ei voi suorittaa, funktio md5_file() puuttuu.", diff --git a/lang/fr.json b/lang/fr.json index 0a20b7cb5a0fa6fec6ee1d90f795e889b0e60498..c43d588f4bf5e02b1ccc30233e4849bca3e47022 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "Système horaire sur 12 heures", + "24HourClock": "Système horaire sur 24 heures", "AbandonedCarts": "Paniers abandonnés", "AboutPiwikX": "À propos de Piwik %s", "Action": "Action", @@ -11,6 +13,7 @@ "AllWebsitesDashboard": "Tableau de bord de tous les sites", "And": "et", "API": "API", + "Apply": "Appliquer", "ArchivingInlineHelp": "Pour les sites à trafic moyen et fort, il est recommandé de désactiver l'archivage de Piwik depuis le navigateur. Nous vous recommandons de mettre en place une tâche planifiée (cron job) qui génère les rapports toutes les heures.", "ArchivingTriggerDescription": "Recommandé pour les installations importantes de Piwik, vous devriez %s mettre en place une tâche planifiée (cron) %s pour générer les rapports automatiquement.", "AuthenticationMethodSmtp": "Méthode d'authentification pour le serveur SMTP", @@ -98,6 +101,7 @@ "DateRange": "Période :", "DateRangeFrom": "Du", "DateRangeFromTo": "De %s à %s", + "DateRangeInPeriodList": "période", "DateRangeTo": "Au", "DaysHours": "%1$s jours %2$s heures", "DaysSinceFirstVisit": "Jours depuis la première visite", @@ -346,6 +350,7 @@ "TagCloud": "Nuage de tags", "Tax": "Taxes", "TimeAgo": "il y a %s", + "TimeFormat": "Format horaire", "TimeOnPage": "Temps sur la page", "Total": "Total", "TotalRatioTooltip": "C'est %1$s de %2$s %3$s.", @@ -380,7 +385,7 @@ "VisitTypeExample": "Par exemple, pour sélectionner tous les visiteurs qui sont retournés sur le site web, en incluant ceux qui ont acheté quelque chose lors de leur dernière visite, la requête à l'API contiendrait %s", "Warning": "Attention", "WarningPhpVersionXIsTooOld": "La version de PHP que vous utilisez (%s) est en fin de support. Nous vous incitons vivement à upgrader vers une version plus récente. Votre version actuelle vous expose à des failles de sécurité et des bugs qui ont été corrigés dans les versions les plus récentes de PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik va arrêter le support de cette version de PHP en %s. Mettez à jour votre version de PHP avant qu'il ne soit trop tard !", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik ne prendra plus en charge PHP %1$s dans la prochaine version majeure. Mettez à jour votre PHP au minimum avec une version %2$s avant qu'il ne soit trop tard !", "WarningFileIntegrityNoManifest": "Le contrôle d'intégrité n'a pu être effectué car le fichier manifest.inc.php est manquant.", "WarningFileIntegrityNoManifestDeployingFromGit": "Si vous déployez Piwik depuis Git, ce message est normal.", "WarningFileIntegrityNoMd5file": "Le contrôle d'intégrité n'a pu être effectué car la fonction md5_file() est manquante.", @@ -400,6 +405,7 @@ "YearsDays": "%1$s années %2$s jours", "Yes": "Oui", "YouAreCurrentlyUsing": "Vous utilisez actuellement Piwik %s", + "YouAreViewingDemoShortMessage": "Vous visionnez la démonstration de Piwik", "YouMustBeLoggedIn": "Vous devez être connecté(e) pour accéder à cette fonctionnalité.", "YourChangesHaveBeenSaved": "Vos modifications ont été enregistrées." }, diff --git a/lang/id.json b/lang/id.json index 76f5d61f42401e98258225c12206cd5a8d11086e..6245ae969fee6863aa490387d04dbdde6fe47b0e 100644 --- a/lang/id.json +++ b/lang/id.json @@ -1,16 +1,19 @@ { "General": { + "12HourClock": "Waktu 12-jam", + "24HourClock": "Waktu 24-jam", "AbandonedCarts": "Keranjang Terabaikan", "AboutPiwikX": "Tentang Piwik %s", "Action": "Tindakan", "Actions": "Tindakan", "Add": "Tambah", - "AfterEntry": "after entereing here", + "AfterEntry": "setelah memasuki di sini", "All": "Semua", "AllowPiwikArchivingToTriggerBrowser": "Arsipkan laporan ketikan meniliknya dari peramban", "AllWebsitesDashboard": "Panel Kendali semua Situs", "And": "dan", "API": "API", + "Apply": "Terapkan", "ArchivingInlineHelp": "Untuk kunjungan situs menengah hingga tinggi, disarankan untuk mematikan pengarsipan Piwik ketika laporan ditampilkan. Kami lebih menyarankan untuk mengatur tugas Cron untuk mengolah laporan pada tiap jam.", "ArchivingTriggerDescription": "Disarankan untuk instalasi Piwik besar untuk %smengatur tugas Cron%s untuk mengolah laporan otomatis.", "AuthenticationMethodSmtp": "Metode otentikasi untuk SMTP", @@ -62,6 +65,7 @@ "ColumnNbUniqVisitors": "Pengunjung unik", "ColumnNbUniqVisitorsDocumentation": "Jumlah pengunjung unik yang mengunjungi situs Anda. Setiap pengguna hanya terhitung satu kali, walaupun mengunjungi situs beberapa kali.", "ColumnNbUsers": "Pengguna", + "ColumnNbUsersDocumentation": "Jumlah pengguna yang masuk-log ke situs Anda. Ini adalah jumlah pengguna aktif dengan ID Pengguna yang diatur (melalui fungsi Pelacakan 'setUserId').", "ColumnNbVisits": "Kunjungan", "ColumnNbVisitsDocumentation": "Bila pengunjung mengunjungi situs Anda untuk pertama kali atau bila mengunjungi sebuah halaman lebih dari 30 menit setelah halaman terakhir tampil, ini akan tercatat sebagai kunjungan baru.", "ColumnPageBounceRateDocumentation": "Persentase kunjungan yang berawal pada halaman ini dan meninggalkan situs langsung.", @@ -97,6 +101,7 @@ "DateRange": "Rentang tanggal:", "DateRangeFrom": "Dari", "DateRangeFromTo": "Dari %s ke %s", + "DateRangeInPeriodList": "rentang tanggal", "DateRangeTo": "Kepada", "DaysHours": "%1$s hari %2$s jam", "DaysSinceFirstVisit": "Hari sejak kujungan pertama", @@ -112,6 +117,7 @@ "DisplaySimpleTable": "Tampilan tabel sederhana", "DisplayTableWithGoalMetrics": "Menampilkan tabel dengan pengukuran Tujuan", "DisplayTableWithMoreMetrics": "Menampilkan tabel dengan pengukuran lebih banyak", + "Documentation": "Dokumentasi", "Donate": "Menyumbang", "Done": "Selesai", "Download": "Unduh", @@ -127,9 +133,13 @@ "Edit": "Sunting", "EncryptedSmtpTransport": "Masukkan penyandian lapisan transpor yang dibutuhkan peladen SMTP.", "Error": "Galat", + "ErrorRequest": "Ups.. terdapat kesalahan selama melakukan permintaan. Mungkin peladen mendapat masalah sementara, atau mungkin Anda melakukan permintaan dengan data yang terlalu besar. Silakan coba kembali. Bila galat ini terjadi berulang, silakan %shubungi pengelola Piwik Anda%s untuk bantuan.", "EvolutionOverPeriod": "Perkembangan selama periode", "EvolutionSummaryGeneric": "%1$s di %2$s dibandingkan dengan %3$s di %4$s. Perubahan: %5$s", + "ExceptionContactSupportGeneric": "Bila Anda tetap mengalami kendala, silakan %shubungi pengelola Piwik Anda%s untuk bantuan.", + "ExceptionCheckUserHasSuperUserAccessOrIsTheUser": "Pengguna harus menjadi Pengguna Super atau pengguna '%s' itu sendiri.", "ExceptionConfigurationFileNotFound": "Berkas konfigurasi {%s} tak ditemukan.", + "ExceptionConfigurationFileNotFound2": "Bila berkas tersebut ada, harap memeriksa bahwa berkas %s dapat dibaca oleh pengguna '%s'.", "ExceptionDatabaseVersion": "Versi %1$s Anda adalah %2$s, tetapi Piwik membtuhkan setidaknya versi %3$s.", "ExceptionFileIntegrity": "Pemerikasaa intergritas gagal: %s", "ExceptionFilesizeMismatch": "Ukuran berkas tak sesuai: %1$s (diharapkan panjang: %2$s, ditemukan: %3$s)", @@ -342,12 +352,16 @@ "Weekly": "Mingguan", "WeeklyReport": "mingguan", "WeeklyReports": "Laporan mingguan", + "WellDone": "Selamat!", "Widgets": "Gawit", + "Widget": "Gawit", + "XFromY": "%1$s dari %2$s", "YearlyReport": "tahunan", "YearlyReports": "Laporan tahunan", "YearsDays": "%1$s tahun %2$s hari", "Yes": "Ya", "YouAreCurrentlyUsing": "Anda saat ini menggunakan Piwik %s.", + "YouAreViewingDemoShortMessage": "Anda sedang melihat demostrasi Piwik", "YouMustBeLoggedIn": "Anda harus masuk untuk mengakses fungsi ini.", "YourChangesHaveBeenSaved": "Perubahan Anda telah tersimpan." }, @@ -415,8 +429,11 @@ "ShowAll": "Tampilkan semua", "ShowLess": "Tampilkan sedikit", "StaticGraph": "Grafik Iktisar", + "TopVisitedWebsites": "Situs kunjungan tertinggi", + "TryIt": "Cobalah!", "UseSearchBarHint": "Hanya situs %s pertama ditampilkan di sini. Harap menggunakan batang pencarian untuk mengakses situs Anda yang lain.", "VerifyAccount": "Memverifikasi Akun", + "ValidateSslCertificate": "Pengesahan Sertifikat SSL", "VerifyLoginData": "Pastikan bahwa nama-id dan sandi Anda sesuai.", "YouAreOffline": "Maaf, Anda sekarang luring" }, diff --git a/lang/it.json b/lang/it.json index e6d25b85b501ff44815d21ebcb32373494ce01b3..a7c540aead36b3ce1676994cdfea5fb0e1e887c5 100644 --- a/lang/it.json +++ b/lang/it.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "Formato 12 ore", + "24HourClock": "Formato 24 ore", "AbandonedCarts": "Carrelli abbandonati", "AboutPiwikX": "Informazioni su Piwik %s", "Action": "Azione", @@ -88,8 +90,8 @@ "CurrentMonth": "Mese corrente", "CurrentWeek": "Settimana corrente", "CurrentYear": "Anno corrente", - "Daily": "Giornalmente", - "DailyReport": "giornalmente", + "Daily": "Giornaliero", + "DailyReport": "giornaliero", "DailyReports": "Reports giornalieri", "DailySum": "somma giornaliera", "DashboardForASpecificWebsite": "Dashboard per un sito specifico", @@ -262,8 +264,11 @@ "OperationIsNot": "Non è", "OperationLessThan": "Minore di", "OperationNotEquals": "Diversi", + "OperationStartsWith": "Inizia con", + "OperationEndsWith": "Finisce con", "OptionalSmtpPort": "Opzionale. Default a 25 per non cifrato e TLS SMTP, e 465 per SSL SMTP.", "Options": "Opzioni", + "Or": "o", "OrCancel": "oppure %s Annulla %s", "Others": "Altri", "Outlink": "Outlink (link esterno)", @@ -348,11 +353,15 @@ "TagCloud": "Tag Cloud", "Tax": "Tasse", "TimeAgo": "%s fa", + "TimeFormat": "Formato ora", "TimeOnPage": "Tempo nella pagina", "Total": "Totale", "TotalRatioTooltip": "Questo è %1$s di tuttti i %2$s %3$s.", "TotalRevenue": "Totale guadagni", "TotalVisitsPageviewsActionsRevenue": "(Totale: %s visite, %s pagine, %s azioni, %s ricavi)", + "TrackingScopeAction": "Azione", + "TrackingScopePage": "Pagina", + "TrackingScopeVisit": "Visita", "TransitionsRowActionTooltip": "Guarda cosa hanno fatto i visitatori prima e dopo aver visto questa pagina", "TransitionsRowActionTooltipTitle": "Apri Transizioni", "TranslatorName": "Alessandro Coscia, Giovdi, Yusef Maali, Andrea Marchitelli (CILEA), Fabrizio Rocca, Ted Mosby, Alfio E. Fresta, Giovanni Matina, Blau", @@ -382,7 +391,7 @@ "VisitTypeExample": "Ad esempio, per selezionare tutti i visitatori che sono ritornati al sito Web, compresi quelli che hanno comprato qualcosa nelle loro precedenti visite, la richiesta di API dovrebbe contenere %s", "Warning": "Attenzione", "WarningPhpVersionXIsTooOld": "La versione %s di PHP che stai utilizzando ha raggiunto il fine vita (EOL). Si invita caldamente ad aggiornare con urgenza all'ultima versione, perché l'uso di questa versione può esporti a vulnerabilità nella sicurezza e ai bug che sono stati corretti nelle versioni più recenti di PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik cesserà di supportare questa versione del PHP nel %s. Aggiorna la tua versione del PHP prima che sia troppo tardi!", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik cesserà di supportare PHP %1$s a partire dalla prossima versione maggiore. Aggiorna il tuo PHP almeno alla versione %2$s prima che sia troppo tardi!", "WarningFileIntegrityNoManifest": "Il controllo dell'integrità dei file non può essere eseguito per la mancanza del file manifest.inc.php", "WarningFileIntegrityNoManifestDeployingFromGit": "Se stai sviluppando Piwik da Git, questo messaggio è normale.", "WarningFileIntegrityNoMd5file": "Il controllo d'integrità dei file non ha potuto essere completato per la mancanza della funzione md5_file().", @@ -397,7 +406,7 @@ "Widget": "Widget", "XComparedToY": "%1$s confrontato con %2$s", "XFromY": "%1$s da %2$s", - "YearlyReport": "annualmente", + "YearlyReport": "annuale", "YearlyReports": "Report annuali", "YearsDays": "%1$s anni %2$s giorni", "Yes": "Sì", diff --git a/lang/ja.json b/lang/ja.json index ec59bfa6d33ae2044b75446ec587afd0d8e674fa..57afecc7e406665ef094ffc6bd0c6f6be2b70fd3 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "12 時間時計", + "24HourClock": "24 時間時計", "AbandonedCarts": "放棄ã•れãŸè²·ã„物ã‹ã”", "AboutPiwikX": "Piwik %s ã«ã¤ã„ã¦", "Action": "アクション", @@ -7,9 +9,11 @@ "Add": "è¿½åŠ ", "AfterEntry": "ã“ã“ã«å…¥ã£ãŸå¾Œ", "All": "ã™ã¹ã¦", + "AllowPiwikArchivingToTriggerBrowser": "アーカイブレãƒãƒ¼ãƒˆãŒãƒ–ラウザã§è¡¨ç¤ºã•ã‚ŒãŸæ™‚", "AllWebsitesDashboard": "全ウェブサイトã®ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰", "And": "ãã—ã¦", "API": "API", + "Apply": "é©ç”¨", "ArchivingInlineHelp": "比較的トラフィックã®é«˜ã„ウェブサイトã§ã¯ã€ãƒ–ラウザã§ã®è¡¨ç¤ºã‚’トリガーã¨ã™ã‚‹ Piwik アーカイブ処ç†ã‚’無効ã«ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚ 代ã‚りã«ã€1時間ã”ã¨ã« Piwik リãƒãƒ¼ãƒˆã‚’処ç†ã™ã‚‹ cron ジョブをセットアップã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚", "ArchivingTriggerDescription": "比較的トラフィックã®é«˜ã„ã‚¦ã‚§ãƒ–ã‚µã‚¤ãƒˆã«æŽ¨å¥¨ã—ã¾ã™ã€‚ 自動リãƒãƒ¼ãƒˆå‡¦ç†ã«ã¯ %scron ジョブã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—%sãŒå¿…è¦ã¨ãªã‚Šã¾ã™ã€‚", "AuthenticationMethodSmtp": "SMTP ã®èªè¨¼æ–¹æ³•", @@ -30,6 +34,7 @@ "ClickHere": "詳細ã¯ã“ã¡ã‚‰ã‚’クリック", "ClickToChangePeriod": "期間を変更ã™ã‚‹ã«ã¯ã€ã‚‚ã†ä¸€åº¦ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„", "Close": "é–‰ã˜ã‚‹", + "ClickToSearch": "クリックã—ã¦æ¤œç´¢", "ColumnActionsPerVisit": "ビジットå˜ä½ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³æ•°", "ColumnActionsPerVisitDocumentation": "訪å•ä¸ã«å®Ÿè¡Œã•れãŸå¹³å‡ã‚¢ã‚¯ã‚·ãƒ§ãƒ³æ•°ï¼ˆãƒšãƒ¼ã‚¸ãƒ“ューã€ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã€å¤–部リンク)", "ColumnAverageGenerationTime": "ç”Ÿæˆæ™‚é–“ã®å¹³å‡", @@ -96,6 +101,7 @@ "DateRange": "期間:", "DateRangeFrom": "From", "DateRangeFromTo": "%s ã‹ã‚‰ %s ã¾ã§", + "DateRangeInPeriodList": "期間", "DateRangeTo": "To", "DaysHours": "%1$s æ—¥ %2$s 時間", "DaysSinceFirstVisit": "最åˆã®è¨ªå•ã‹ã‚‰ã®æ—¥æ•°", @@ -219,7 +225,7 @@ "MonthlyReports": "月次リãƒãƒ¼ãƒˆ", "More": "以上", "MoreDetails": "詳細", - "MoreLowerCase": "ã‚‚ã£ã¨", + "MoreLowerCase": "詳ã—ã見る", "MultiSitesSummary": "全ウェブサイト", "Name": "åå‰", "NbActions": "アクション数", @@ -236,6 +242,7 @@ "NotDefined": "%s ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“", "Note": "注æ„", "NotInstalled": "インストールã•れã¦ã„ã¾ã›ã‚“", + "NotRecommended": "éžæŽ¨å¥¨", "NotValid": "%s ã¯æœ‰åйã§ã¯ã‚りã¾ã›ã‚“", "NumberOfVisits": "è¨ªå•æ•°", "NUsers": "%s ユーザー", @@ -259,6 +266,7 @@ "OperationNotEquals": "ç‰ã—ããªã„", "OptionalSmtpPort": "オプションã§ã™ã€‚ éžæš—å·åŒ–㨠TLS SMTP ã§ã¯ 25 ãŒã€SSL SMTP ã§ã¯ 465 ãŒãƒ‡ãƒ•ォルトã«ãªã‚Šã¾ã™ã€‚", "Options": "オプション", + "Or": "ã¾ãŸã¯", "OrCancel": "ã¾ãŸã¯ %s ã‚ャンセル %s", "Others": "ãã®ä»–", "Outlink": "外部リンク", @@ -287,10 +295,13 @@ "Price": "ä¾¡æ ¼", "ProductConversionRate": "製å“ã®ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³çއ", "ProductRevenue": "製å“ã®åŽç›Š", + "Measurable": "測定å¯èƒ½", + "Measurables": "測定å¯èƒ½", "PurchasedProducts": "購入ã•れãŸè£½å“", "Quantity": "æ•°é‡", "RangeReports": "カスタム期間", "ReadThisToLearnMore": "%1$sRead this to learn more.%2$s", + "Recommended": "推奨", "RecordsToPlot": "プãƒãƒƒãƒˆã™ã‚‹ãƒ¬ã‚³ãƒ¼ãƒ‰", "Refresh": "リフレッシュ", "RefreshPage": "ページã®å†èªã¿è¾¼ã¿", @@ -301,6 +312,7 @@ "ReportGeneratedFrom": "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã¯ã€%s ã®ãƒ‡ãƒ¼ã‚¿ã‚’使用ã—ã¦ç”Ÿæˆã—ã¾ã—ãŸã€‚", "ReportRatioTooltip": "'%1$s' 㯠%5$s ã§ %3$s %4$s ã® %2$s を表ã—ã¦ã„ã¾ã™ã€‚", "Reports": "リãƒãƒ¼ãƒˆ", + "RearchiveTimeIntervalOnlyForTodayReports": "ã“れã¯ä»Šæ—¥ ( ã‚ã‚‹ã„ã¯ä»Šæ—¥ã‚’å«ã‚€æ—¥ä»˜ç¯„囲 ) ã®ãƒ¬ãƒãƒ¼ãƒˆã«ã®ã¿å½±éŸ¿ã—ã¾ã™ã€‚", "ReportsWillBeProcessedAtMostEveryHour": "従ã£ã¦ã€ãƒªãƒãƒ¼ãƒˆã¯1時間ã”ã¨ã«å‡¦ç†ã•れã¾ã™ã€‚", "RequestTimedOut": "%s ã¸ã®ãƒ‡ãƒ¼ã‚¿ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒã‚¿ã‚¤ãƒ アウトã—ã¾ã—ãŸã€‚ å†è©¦è¡Œã—ã¦ãã ã•ã„。", "Required": "%s ã¯å¿…é ˆã§ã™", @@ -338,10 +350,15 @@ "TagCloud": "タグクラウド", "Tax": "税", "TimeAgo": "%s å‰", + "TimeFormat": "時刻ã®å½¢å¼", "TimeOnPage": "ã“ã®ãƒšãƒ¼ã‚¸ã®æ»žåœ¨æ™‚é–“", "Total": "åˆè¨ˆ", "TotalRatioTooltip": "ã“れã¯ã€å…¨ã¦ã® %2$s %3$s ã® %1$sã§ã™ã€‚", "TotalRevenue": "ç·åŽç›Š", + "TotalVisitsPageviewsActionsRevenue": "( åˆè¨ˆ : ビジット数 %s ã€ãƒšãƒ¼ã‚¸ãƒ“ュー %s ã€ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ %s ã€åˆ©ç›Š %s )", + "TrackingScopeAction": "アクション", + "TrackingScopePage": "ページ", + "TrackingScopeVisit": "ビジット", "TransitionsRowActionTooltip": "訪å•者ãŒã€ã“ã®ãƒšãƒ¼ã‚¸ã®è¡¨ç¤ºå‰å¾Œã«ä½•ã‚’ã—ã¦ã„ãŸã‹è¦‹ã¦ãã ã•ã„", "TransitionsRowActionTooltipTitle": "トランジションを開ã", "TranslatorName": "Takafumi\/Drupal Japan - http:\/\/drupal.jp Takeshi Ueda\/Piwik Japan Team - http:\/\/piwikjapan.org", @@ -367,10 +384,10 @@ "Visitors": "ビジター", "VisitsWith": "%s ã®ãƒ“ジット", "VisitorSettings": "ビジターã®ç’°å¢ƒ", + "VisitType": "ビジットタイプ", "VisitTypeExample": "例ãˆã°ã€å‰å›žã®ãƒ“ジットã§ä½•ã‹ã‚’購入ã—ãŸè¨ªå•者をå«ã‚€ã€å…¨ã¦ã®ãƒªãƒ”ãƒ¼ã‚¿ãƒ¼ã‚’é¸æŠžã™ã‚‹ãŸã‚ã®APIリクエスト㯠%s ã‚’å«ã‚€ã‚‚ã®ã¨ãªã‚Šã¾ã™ã€‚", "Warning": "è¦å‘Š", "WarningPhpVersionXIsTooOld": "ã”利用㮠PHP ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s ã¯ã€åˆ©ç”¨æœŸé–“ãŒçµ‚了( EOL )ã—ã¦ã„ã¾ã™ã€‚ã‚»ã‚ュリティã®è„†å¼±æ€§ã¨ã€æœ€æ–°ã® PHP ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§æ—¢ã«ä¿®æ£ã•れãŸãƒã‚°ã«å¯¾ã™ã‚‹ãƒªã‚¹ã‚¯ã‚’é¿ã‘ã‚‹ãŸã‚ã€å¿…ãšæœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã‚¢ãƒƒãƒ—グレードã—ã¦ãã ã•ã„。", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik ã¯ã“ã® PHP ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s ã§ã‚µãƒãƒ¼ãƒˆã‚’åœæ¢ã—ã¾ã™ã€‚手é…れã«ãªã‚‹å‰ã« PHP ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’アップグレード ã—ã¾ã—ょã†ï¼", "WarningFileIntegrityNoManifest": "manifest.inc.php ãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã€ãƒ•ã‚¡ã‚¤ãƒ«ã®æ•´åˆæ€§ãƒã‚§ãƒƒã‚¯ã‚’実行ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚", "WarningFileIntegrityNoManifestDeployingFromGit": "Git ã‹ã‚‰ Piwik を開発ã—ã¦ã„ã‚‹å ´åˆã€ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯æ£å¸¸ã§ã™ã€‚", "WarningFileIntegrityNoMd5file": "md5_file() 関数ãŒå˜åœ¨ã—ãªã„ãŸã‚ã€ãƒ•ã‚¡ã‚¤ãƒ«ã®æ•´åˆæ€§ãƒã‚§ãƒƒã‚¯ã‚’完了ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚", @@ -389,6 +406,7 @@ "YearsDays": "%1$s å¹´ %2$s æ—¥", "Yes": "ã¯ã„", "YouAreCurrentlyUsing": "ç¾åœ¨Piwik %s を利用ã—ã¦ã„ã¾ã™", + "YouAreViewingDemoShortMessage": "Piwik ã®ãƒ‡ãƒ¢ã‚’表示ã—ã¾ã™ã€‚", "YouMustBeLoggedIn": "ã“ã®æ©Ÿèƒ½ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ãƒã‚°ã‚¤ãƒ³ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚", "YourChangesHaveBeenSaved": "変更ã¯ä¿å˜ã•れã¾ã—ãŸã€‚" }, @@ -440,6 +458,7 @@ "NoWebsitesShort": "ウェブサイトãªã—", "PullDownToRefresh": "プルダウンã—ã¦æ›´æ–° …", "PossibleSslError": "SSL 証明エラーã®å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚", + "PossibleSslErrorExplanation": "証明書ãŒç„¡åŠ¹ã‚‚ã—ãã¯è‡ªå·±ç½²åã§ã‚ã‚‹ãŸã‚ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—㟠: \" %s \"。SSL ãƒãƒªãƒ‡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’無視ã™ã‚Œã°ãƒã‚°ã‚¤ãƒ³ã§ãã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“ãŒã€å®‰å…¨æ€§ãŒä½Žã„ã§ã™ã€‚è¨å®šã¯ã„ã¤ã§ã‚‚変更ã§ãã¾ã™ã€‚", "IgnoreSslError": "SSL エラーを無視", "RatingDontRemindMe": "リマインドã—ãªã„ã§ãã ã•ã„。", "RatingNotNow": "今ã§ã¯ã‚りã¾ã›ã‚“。", diff --git a/lang/ko.json b/lang/ko.json index 01234f423182fd1abbaecf9bfb5de25ef030200d..29cbaff91bce2a84f3dd5d484e49bb76b390488c 100644 --- a/lang/ko.json +++ b/lang/ko.json @@ -1,9 +1,11 @@ { "General": { + "12HourClock": "12 시간 형태", + "24HourClock": "24 시간 형태", "AbandonedCarts": "ë²„ë ¤ì§„ 장바구니", "AboutPiwikX": "Piwik %sì€...", - "Action": "ë™ìž‘", - "Actions": "활ë™", + "Action": "활ë™", + "Actions": "활ë™ë“¤", "Add": "추가", "AfterEntry": "ì—¬ê¸°ì— ë“¤ì–´ê°„ 후", "All": "모ë‘", @@ -11,6 +13,7 @@ "AllWebsitesDashboard": "ì „ì²´ 웹사ì´íŠ¸ì˜ ëŒ€ì‹œë³´ë“œ", "And": "ê·¸ë¦¬ê³ ", "API": "API", + "Apply": "ì ìš©", "ArchivingInlineHelp": "비êµì íŠ¸ëž˜í”½ì´ ë†’ì€ ì›¹ì‚¬ì´íŠ¸ëŠ” 브ë¼ìš°ì € 트리거를 Piwikì— ë³´ê´€í•˜ëŠ” ê²ƒì„ ë¹„í™œì„±í™”í•˜ëŠ” ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤. ëŒ€ì‹ , 1 시간마다 Piwik ë³´ê³ ì„œë¥¼ 처리하는 cron ìž‘ì—…ì„ ì„¤ì •í•˜ëŠ” ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤.", "ArchivingTriggerDescription": "비êµì íŠ¸ëž˜í”½ì´ ë†’ì€ ì›¹ì‚¬ì´íŠ¸ì— ê¶Œìž¥í•©ë‹ˆë‹¤. ìžë™ ë³´ê³ ì„œ 처리는 %scron 작업 ì„¤ì •%sì´ í•„ìš”í•©ë‹ˆë‹¤.", "AuthenticationMethodSmtp": "SMTP ì¸ì¦ 방법", @@ -31,8 +34,10 @@ "ClickHere": "ìžì„¸í•œ ë‚´ìš©ì€ ì´ê³³ì„ í´ë¦í•˜ì„¸ìš”.", "ClickToChangePeriod": "ê¸°ê°„ì„ ë³€ê²½í•˜ë ¤ë©´ 다시 í´ë¦í•˜ì„¸ìš”.", "Close": "닫기", + "ClickToSearch": "검색하기 위해서 í´ë¦í•´ì£¼ì„¸ìš”.", "ColumnActionsPerVisit": "방문 당 í™œë™ ìˆ˜", "ColumnActionsPerVisitDocumentation": "방문하는 ë™ì•ˆ ì‹¤í–‰ëœ í‰ê· 작업 수 (페ì´ì§€ ë·°, 다운로드, 외부 ë§í¬)", + "ColumnAverageGenerationTime": "í‰ê· 페ì´ì§€ ìƒì„± 시간", "ColumnAverageTimeOnPage": "페ì´ì§€ì— 머문 시간 í‰ê· ", "ColumnAverageTimeOnPageDocumentation": "ì´ íŽ˜ì´ì§€ë¥¼ 방문한 방문ìžì˜ 머문 ì‹œê°„ì˜ í‰ê· (페ì´ì§€ë§Œ 해당, ì „ì²´ 웹사ì´íЏ 아님).", "ColumnAvgTimeOnSite": "웹사ì´íЏ í‰ê· 시간", @@ -50,6 +55,7 @@ "ColumnExitRateDocumentation": "ì´ íŽ˜ì´ì§€ë¥¼ 본 후 사ì´íЏì—서 나간 방문 비율입니다.", "ColumnExits": "ì´íƒˆ 수", "ColumnExitsDocumentation": "ì´ íŽ˜ì´ì§€ì—서 ê²€ìƒ‰ì„ ì¢…ë£Œí•œ 방문 수입니다.", + "ColumnGenerationTime": "ìƒì„± 시간", "ColumnKeyword": "검색어", "ColumnLabel": "ë¼ë²¨", "ColumnMaxActions": "한번 ë°©ë¬¸ì— ìµœëŒ€ í™œë™ ìˆ˜", @@ -83,6 +89,7 @@ "CurrentWeek": "ì´ë²ˆì£¼", "CurrentYear": "올해", "Daily": "ì¼ê°„", + "DailyReport": "ì¼ê°„", "DailyReports": "ì¼ê°„ ë³´ê³ ì„œ", "DailySum": "ì¼ë³„", "DashboardForASpecificWebsite": "íŠ¹ì • 웹사ì´íŠ¸ì˜ ëŒ€ì‹œë³´ë“œ", @@ -92,6 +99,7 @@ "DateRange": "기간:", "DateRangeFrom": "From", "DateRangeFromTo": "%sì—서 %s까지", + "DateRangeInPeriodList": "기간", "DateRangeTo": "To", "DaysHours": "%1$sì¼ %2$s 시간", "DaysSinceFirstVisit": "첫 방문ì¼", @@ -125,6 +133,7 @@ "Error": "ì—러", "EvolutionOverPeriod": "기간ë™ì•ˆ ì§„í–‰ ê³¼ì •", "EvolutionSummaryGeneric": "%2$sì˜ %1$s와 %4$sì˜ %3$s 비êµ. 변화 ì¶”ì´: %5$s", + "ExceptionContactSupportGeneric": "만약 해당 ë¬¸ì œê°€ ê³„ì† ë°œìƒí•œë‹¤ë©´ %sPiwik 관리ìžì—게 ì—°ë½í•˜ì—¬ ë„움%sì„ êµ¬í•˜ì„¸ìš”.", "ExceptionConfigurationFileNotFound": "ì„¤ì •íŒŒì¼ {%s}ì„ ì°¾ì„ ìˆ˜ 없습니다.", "ExceptionDatabaseVersion": "현재 %1$s ë²„ì „ %2$s ì´ì§€ë§Œ Piwikì—는 ì ì–´ë„ %3$sê°€ 필요합니다.", "ExceptionFileIntegrity": "무결성 검사 실패: %s", @@ -197,6 +206,7 @@ "MinutesSeconds": "%1$së¶„ %2$sì´ˆ", "Mobile": "모바ì¼", "Monthly": "월간", + "MonthlyReport": "월간", "MonthlyReports": "월간 ë³´ê³ ì„œ", "MoreDetails": "ìžì„¸ížˆ", "MultiSitesSummary": "ì „ì²´ 웹사ì´íЏ", @@ -220,11 +230,16 @@ "NumberOfVisits": "방문수", "NVisits": "%s회 방문", "Ok": "확ì¸", + "OneAction": "1회 활ë™", "OneVisit": "1회 방문", "OnlyEnterIfRequired": "SMTP 서버가 ì‚¬ìš©ìž ì´ë¦„ì„ í•„ìš”ë¡œí•˜ëŠ” 경우ì—ë§Œ ìž…ë ¥í•©ë‹ˆë‹¤.", "OnlyEnterIfRequiredPassword": "SMTP 서버가 암호를 필요로하는 경우ì—ë§Œ ìž…ë ¥í•©ë‹ˆë‹¤.", "OnlyUsedIfUserPwdIsSet": "ì‚¬ìš©ìž ì´ë¦„\/암호가 ì„¤ì •ë˜ì–´ìžˆëŠ” 경우ì—ë§Œ 사용ë©ë‹ˆë‹¤. ì–´ë–¤ ë°©ë²•ì„ ì‚¬ìš©í•´ì•¼í•˜ëŠ”ì§€ 잘 모르는 경우, 공급ìžì—게 문ì˜í•˜ì„¸ìš”.", "OpenSourceWebAnalytics": "오픈 소스 웹 ë¶„ì„기", + "OperationAtLeast": "ì ì–´ë„", + "OperationAtMost": "많아야", + "OperationContains": "í¬í•¨í•˜ê¸°", + "OperationDoesNotContain": "í¬í•¨í•˜ì§€ 않기", "OptionalSmtpPort": "옵션입니다. 비 암호화 ë° TLS SMTP는 25ê°€ SSL SMTP는 465ì´ ê¸°ë³¸ìž…ë‹ˆë‹¤.", "Options": "ì„¤ì •", "OrCancel": "ë˜ëŠ” %s 취소 %s", @@ -235,11 +250,14 @@ "OverlayRowActionTooltipTitle": "페ì´ì§€ 중첩 열기", "Overview": "개요", "Pages": "페ì´ì§€", + "Pagination": "%s - %s ì˜ %s", + "PaginationWithoutTotal": "%s - %s", "ParameterMustIntegerBetween": "%s 매개변수는 %sì—서 %sê¹Œì§€ì˜ ì •ìˆ˜ë¡œ ê°’ì„ ì§€ì •í•˜ì„¸ìš”.", "Password": "비밀번호", "Period": "기간", "Piechart": "파ì´ì°¨íЏ", - "PiwikXIsAvailablePleaseUpdateNow": "Piwik %1$s ì´ ì‚¬ìš© 가능합니다. %2$s 지금 ì—…ë°ì´íŠ¸í•˜ì„¸ìš”!%3$s (보기: %4$s 변경%5$s).", + "PiwikXIsAvailablePleaseNotifyPiwikAdmin": "%1$sê°€ 가능합니다. %2$sPiwik 관리ìž%3$sì—게 ì•Œë ¤ì£¼ì„¸ìš”.", + "PiwikXIsAvailablePleaseUpdateNow": "Piwik %1$s ì´ ì‚¬ìš© 가능합니다. %2$s 지금 ì—…ë°ì´íŠ¸í•˜ì„¸ìš”!%3$s (보기: %4$s 변경사í•%5$s).", "PleaseSpecifyValue": "'%s'ì˜ ê°’ì„ ì§€ì •í•˜ì„¸ìš”.", "PleaseUpdatePiwik": "Piwikì„ ì—…ë°ì´íŠ¸í•˜ì„¸ìš”", "Plugin": "플러그ì¸", @@ -254,6 +272,7 @@ "PurchasedProducts": "구입한 ì œí’ˆ", "Quantity": "수량", "RangeReports": "기간 ì§€ì •", + "ReadThisToLearnMore": "%1$sìžì„¸ížˆ 알아보기%2$s", "Recommended": "권장", "RecordsToPlot": "êµ¬ë¶„ëœ ë ˆì½”ë“œ", "Refresh": "ìƒˆë¡œê³ ì¹¨", @@ -265,6 +284,7 @@ "ReportGeneratedFrom": "ì´ ë³´ê³ ì„œëŠ” %sì˜ ë°ì´í„°ë¥¼ 사용하여 ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤.", "Reports": "ë³´ê³ ì„œ", "ReportsContainingTodayWillBeProcessedAtMostEvery": "ë³´ê³ ì„œ ì•„ì¹´ì´ë¸Œë¥¼ 몇 ì´ˆì— í•œ 번씩 수행", + "RearchiveTimeIntervalOnlyForTodayReports": "ì´ê²ƒì€ ì˜¤ëŠ˜ì˜ ë³´ê³ ì„œ(í˜¹ì€ ì˜¤ëŠ˜ì´ í¬í•¨ëœ 기간)ì—ë§Œ ì˜í–¥ì„ ì¤ë‹ˆë‹¤.", "ReportsWillBeProcessedAtMostEveryHour": "ë”°ë¼ì„œ, ë³´ê³ ì„œëŠ” 1시간마다 처리ë©ë‹ˆë‹¤.", "RequestTimedOut": "%sì— ë°ì´í„° ìš”ì²ì´ 초과ë˜ì—ˆìŠµë‹ˆë‹¤. 다시 시ë„하세요.", "Required": "%s 필요함", @@ -277,6 +297,7 @@ "Save": "ì €ìž¥", "SaveImageOnYourComputer": "ì´ë¯¸ì§€ë¥¼ ì €ìž¥í•˜ë ¤ë©´ ì´ë¯¸ì§€ë¥¼ 오른쪽으로 í´ë¦í•˜ì—¬ \"다른 ì´ë¦„으로 그림 ì €ìž¥...\"ì„ ì„ íƒí•©ë‹ˆë‹¤", "Search": "검색", + "SeeAll": "다 보기", "SeeTheOfficialDocumentationForMoreInformation": "ìžì„¸í•œ ë‚´ìš©ì€ %s ê³µì‹ ë¬¸ì„œ %s를 참조하세요.", "SelectYesIfYouWantToSendEmailsViaServer": "로컬 mail() 함수 ëŒ€ì‹ ë©”ì¼ì„œë²„를 통해 ì´ë©”ì¼ì„ 보낼 경우, \"예\"를 ì„ íƒí•©ë‹ˆë‹¤", "Settings": "ì„¤ì •", @@ -292,9 +313,12 @@ "Source": "소스", "StatisticsAreNotRecorded": "Piwikì˜ ë°©ë¬¸ìž ì¶”ì ì´ í˜„ìž¬ 비활성화 ë˜ì–´ 있습니다! 다시 ì¶”ì ì„ í™œì„±í™” í•˜ë ¤ë©´ config\/config.ini.php 파ì¼ì„ ì—´ê³ record_statistics = 1로 ì„¤ì •í•˜ì„¸ìš”.", "Subtotal": "소계", + "Summary": "요약", "Table": "í…Œì´ë¸”", "TagCloud": "태그 í´ë¼ìš°ë“œ", "Tax": "세금", + "TimeAgo": "%s ì „", + "TimeFormat": "시간 í¬ë©§", "TimeOnPage": "페ì´ì§€ì— 머문 시간", "Total": "ì´", "TotalRevenue": "ì´ ìˆ˜ìµ", @@ -305,11 +329,13 @@ "Unknown": "알수없ìŒ", "Upload": "업로드", "UsePlusMinusIconsDocumentation": "ì™¼ìª½ì˜ ë”하기와 빼기 ì•„ì´ì½˜ì„ í´ë¦í•˜ì—¬ 작업합니다.", + "UserId": "ì‚¬ìš©ìž ID", "Username": "ì‚¬ìš©ìž ì´ë¦„", "UseSMTPServerForEmail": "ë©”ì¼ì„ 보낼 때 SMTP 서버 사용", "Value": "ê°’", "VBarGraph": "ìˆ˜ì§ ë§‰ëŒ€ 그래프", "View": "보기", + "ViewDocumentationFor": "%1$s ê´€ë ¨ 문서 보기", "Visit": "방문", "VisitConvertedGoal": "í•˜ë‚˜ì˜ ì´ìƒ ëª©í‘œì— ë„달한 방문", "VisitConvertedGoalId": "íŠ¹ì • 목표IDì— ë„달한 방문", @@ -321,19 +347,26 @@ "Visitors": "방문", "VisitsWith": "%sì˜ ë°©ë¬¸", "VisitorSettings": "ë°©ë¬¸ìž ì„¤ì •", + "VisitType": "방문 타입", "VisitTypeExample": "예를 들어, ì´ì „ 방문ì—서 무언가를 구입한 방문ìžë¥¼ í¬í•¨í•œ ëª¨ë“ ë¦¬í”¼í„°ë¥¼ ì„ íƒí•˜ê¸° 위한 API ìš”ì² %s를 í¬í•¨í•©ë‹ˆë‹¤.", "Warning": "ê²½ê³ ", + "WarningPhpVersionXIsTooOld": "현재 ì‚¬ìš©í•˜ê³ ìžˆëŠ” PHP ë²„ì „ %sì€ ì§€ì›ì´ ë났습니다(End of Life, EOL). ìµœê·¼ì— ì—…ê·¸ë ˆì´ë“œ ëœ PHP ë²„ì „ì—서 해결한 보안 ë¬¸ì œë‚˜ 버그 ë“±ì´ ì‚¬ìš©í•˜ê³ ê³„ì‹ ë²„ì „ì—서 남아 ìžˆì„ ìˆ˜ 있으니 ì—…ê·¸ë ˆì´ë“œ 하시길 ê°•ë ¥ížˆ 권장합니다.", "WarningFileIntegrityNoManifest": "manifest.inc.phpê°€ 없기 때문ì—, 파ì¼ì˜ 무결성 검사를 ìˆ˜í–‰í• ìˆ˜ 없습니다.", + "WarningFileIntegrityNoManifestDeployingFromGit": "만약 Git으로부터 Piwik를 ì‚¬ìš©í•˜ê³ ìžˆë‹¤ë©´, ì´ ë©”ì„¸ì§€ëŠ” ì •ìƒìž…니다.", "WarningFileIntegrityNoMd5file": "md5_file() 함수가 존재하지 않기 때문ì—, íŒŒì¼ ë¬´ê²°ì„± 검사를 ì™„ë£Œí• ìˆ˜ 없습니다.", "WarningPasswordStored": "%s ê²½ê³ : %s 암호는 ì„¤ì • 파ì¼ì— ì €ìž¥ë©ë‹ˆë‹¤. ì´ ì„¤ì • 파ì¼ì— 액세스 í• ìˆ˜ìžˆëŠ” 사람ì´ë¼ë©´, 패스워드를 ë³¼ 수 ìžˆì„ ê°€ëŠ¥ì„±ì´ ìžˆë‹¤ëŠ” ì ì— ìœ ì˜í•˜ì„¸ìš”.", "Website": "웹사ì´íЏ", "Weekly": "주간", + "WeeklyReport": "매주", "WeeklyReports": "주간 ë³´ê³ ì„œ", "Widgets": "ìœ„ì ¯", + "Widget": "ìœ„ì ¯", + "YearlyReport": "매년", "YearlyReports": "ì—°ê°„ ë³´ê³ ì„œ", "YearsDays": "%1$së…„ %2$sì¼", "Yes": "예", "YouAreCurrentlyUsing": "현재 Piwik %s를 ì´ìš©í•˜ê³ 있습니다.", + "YouAreViewingDemoShortMessage": "Piwikì˜ ë°ëª¨ë¥¼ ë³´ê³ ìžˆìŠµë‹ˆë‹¤.", "YouMustBeLoggedIn": "ì´ ê¸°ëŠ¥ì— ì ‘ê·¼í•˜ë ¤ë©´ 로그ì¸í•´ì•¼í•©ë‹ˆë‹¤.", "YourChangesHaveBeenSaved": "변경 사í•ì´ ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤." }, @@ -351,22 +384,30 @@ "ChooseHttpTimeout": "HTTP 시간 초과 ê°’ ì„ íƒ", "ChooseMetric": "ì¸¡ì • í•목 ì„ íƒ", "ChooseReport": "ë³´ê³ ì„œ ì„ íƒ", + "ChooseSegment": "세그멘트 ì„ íƒ", "ConfirmRemoveAccount": "현재 ê³„ì •ì„ ì‚ì œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", "DefaultReportDate": "ë³´ê³ ì„œ ë‚ ì§œ", + "EmailUs": "ì´ë©”ì¼ ë³´ë‚´ê¸°", "EnableGraphsLabel": "그래프 표시", "EvolutionGraph": "ì´ë ¥ 그래프", "HelpUsToImprovePiwikMobile": "Piwik 모바ì¼ì— ìµëª…ì˜ ì‚¬ìš© ì¶”ì ì„ ì‚¬ìš©í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", + "HowtoDeleteAnAccount": "ê³„ì •ì„ ì œê±°í•˜ê¸° 위해서 길게 눌러주세요.", "HowtoDeleteAnAccountOniOS": "ì™¼ìª½ì— ì˜¤ë¥¸ìª½ìœ¼ë¡œ ëŒì–´ì„œ ê³„ì • ì‚ì œ", + "HowtoLoginAnonymous": "ìµëª… ì ‘ì†ì„ 위해 ì‚¬ìš©ìž ì´ë¦„ê³¼ ë¹„ë°€ë²ˆí˜¸ëž€ì„ ë¹„ì›Œë‘세요.", "HttpIsNotSecureWarning": "Piwik 승ì¸ì„ 위한 í† í° (token_auth) 발급시 'HTTP'를 사용하면 ì¼ë°˜ í…스트로 ì „ì†¡ë©ë‹ˆë‹¤. ê·¸ë ‡ê¸° ë•Œë¬¸ì— ì¸í„°ë„·ì„ 통한 ë°ì´í„°ì˜ 보안 ì „ì†¡ì„ ìœ„í•´ HTTPS를 사용하는 ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤. ê³„ì† ì§„í–‰ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", "HttpTimeout": "HTTP 시간초과", + "IncompatiblePiwikVersion": "현재 ì‚¬ìš©í•˜ê³ ìžˆëŠ” Piwik ë²„ì „ì€ Piwik ëª¨ë°”ì¼ 2와 호환ë˜ì§€ 않습니다. Piwikì„ ì—…ë°ì´íЏ 후 다시 시ë„해주시거나 Piwik ëª¨ë°”ì¼ 1ì„ ì„¤ì¹˜í•´ì£¼ì„¸ìš”.", "LastUpdated": "최종 ì—…ë°ì´íЏ: %s", + "LoadingReport": "%s 로딩중", "LoginCredentials": "ìžê²©", "LoginUseHttps": "HTTPS 사용", "MultiChartLabel": "스파í¬ë¼ì¸ 표시", "NavigationBack": "뒤로", "NetworkError": "ë„¤íŠ¸ì›Œí¬ ì—러", "NetworkErrorWithStatusCode": "\"%s\" 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. 요ì²ì—서 \"%s\" ìƒíƒœê°€ 반환ë˜ì—ˆìŠµë‹ˆë‹¤. URLì€ \"%s\" 입니다. ìž…ë ¥í•œ URLì„ í™•ì¸í•´ ë³´ê³ ì„œë²„ì˜ ì˜¤ë¥˜ 로그ì—서 ë” ìžì„¸í•œ ë‚´ìš©ì„ ë¶„ì„하여 ì´ ë¬¸ì œë¥¼ 해결하세요.", + "NetworkErrorWithStatusCodeShort": "ë„¤íŠ¸ì›Œí¬ ì—러 %s", "NetworkNotReachable": "네트워í¬ì— ì—°ê²°í• ìˆ˜ ì—†ìŒ", + "NoAccountIsSelected": "í•˜ë‚˜ì˜ ê³„ì •ì„ ì„ íƒí•˜ì…”야 합니다. 만약 í™˜ê²½ì„¤ì •ì„ í•˜ì§€ 않았다면 새로운 ê³„ì •ì„ ì¶”ê°€í•˜ì„¸ìš”.", "NoDataShort": "ë°ì´í„° ì—†ìŒ", "NoPiwikAccount": "Piwik ê³„ì •ì´ ì—†ë‚˜ìš”?", "NoReportsShort": "ë³´ê³ ì„œ ì—†ìŒ", @@ -383,20 +424,23 @@ "RatingPleaseRateUs": "Piwik ëª¨ë°”ì¼ ì•±ì€ ë¬´ë£Œ 소프트웨어입니다. ì—¬ëŸ¬ë¶„ì˜ ì†Œì¤‘í•œ 1분으로 %sì—서 ìš°ë¦¬ì˜ ì• í”Œë¦¬ì¼€ì´ì…˜ì„ í‰ê°€í•´ ì£¼ì‹ ë‹¤ë©´ ì •ë§ ê°ì‚¬í•˜ê² 습니다. 새로운 기능 ì œì•ˆì´ë‚˜ 버그를 발견하셨다면, %s로 ì—°ë½ ë¶€íƒë“œë ¤ìš”", "ReleaseToRefresh": "놓아서 ìƒˆë¡œê³ ì¹¨...", "Reloading": "새로 ê³ ì¹¨ 중...", + "RequestTimedOutShort": "ë„¤íŠ¸ì›Œí¬ íƒ€ìž„ 아웃 오류", "SaveSuccessError": "Piwik URL ë˜ëŠ” 사용ìžì´ë¦„ê³¼ 비밀번호 ì¡°í•©ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤.", "SearchWebsite": "검색 웹사ì´íЏ", "ShowAll": "ëª¨ë‘ ë³´ê¸°", "ShowLess": "작게 보기", "StaticGraph": "그래프 개요", + "TopVisitedWebsites": "ìƒìœ„ ë°©ë¬¸ëœ ì›¹ì‚¬ì´íŠ¸ë“¤", "TryIt": "시ë„í•´ 보세요!", "UseSearchBarHint": "첫 번째 %sì˜ ì›¹ì‚¬ì´íŠ¸ê°€ ì—¬ê¸°ì— í‘œì‹œë©ë‹ˆë‹¤. 다른 웹사ì´íŠ¸ì— ì•¡ì„¸ìŠ¤ í• ìˆ˜ìžˆëŠ” 검색막대를 사용하세요.", "VerifyAccount": "ê³„ì • 확ì¸", + "ValidateSslCertificate": "SSL ì¦ì„œ 확ì¸", "VerifyLoginData": "ì‚¬ìš©ìž ì´ë¦„ê³¼ 비밀번호 ì¡°í•©ì´ ì˜¬ë°”ë¥¸ì§€ 확ì¸í•˜ì„¸ìš”.", "YouAreOffline": "현재 오프ë¼ì¸ ìƒíƒœ" }, "RowEvolution": { "AvailableMetrics": "사용가능한 통계", - "CompareDocumentation": "아래 ë§í¬ë¥¼ í´ë¦í•˜ê³ ë™ì¼í•œ í…Œì¼ë¸”ë‚´ì— ìžˆëŠ” 다른 í–‰ì˜ íŒì—…ì„ ì—´ì–´ 기ë¡ì„ 비êµí• 수 있습ㄴ다.<br \/>íŒì—…ì„ ì—´ì§€ ì•Šê³ í–‰ì„ ë¹„êµ í‘œì‹œí•˜ë ¤ë©´ 시프트-í´ë¦í•˜ì„¸ìš”.", + "CompareDocumentation": "아래 ë§í¬ë¥¼ í´ë¦í•˜ê³ ë™ì¼í•œ í…Œì´ë¸”ë‚´ì— ìžˆëŠ” 다른 í–‰ì˜ íŒì—…ì„ ì—´ì–´ 기ë¡ì„ 비êµí• 수 있습니다.<br \/>íŒì—…ì„ ì—´ì§€ ì•Šê³ í–‰ì„ ë¹„êµ í‘œì‹œí•˜ë ¤ë©´ 쉬프트-í´ë¦í•˜ì„¸ìš”.", "CompareRows": "ê¸°ë¡ ë¹„êµ", "ComparingRecords": "%s í–‰ 비êµ", "Documentation": "í° ì§„í™” 그래프ì—서 í‘œì‹œí• í†µê³„ë¥¼ í´ë¦í•©ë‹ˆë‹¤. 쉬프트-í´ë¦ì„ 사용하여 í•œë²ˆì— ì—¬ëŸ¬ê°œì˜ ì¸¡ì • í•ëª©ì„ í‘œì‹œí•©ë‹ˆë‹¤.", diff --git a/lang/nb.json b/lang/nb.json index b07c46616f948653de1f7d31cc6bd5fdf35c9594..11f1f9e3cb437e4f7903499afa58ff579f1a7a98 100644 --- a/lang/nb.json +++ b/lang/nb.json @@ -1,17 +1,20 @@ { "General": { + "12HourClock": "12-timersklokke", + "24HourClock": "24-timersklokke", "AbandonedCarts": "Forlatte handlevogner", "AboutPiwikX": "Om Piwik %s", "Action": "Handling", "Actions": "Handlinger", "Add": "Legg til", - "AfterEntry": "etter at man har skrevet inn her", + "AfterEntry": "etter Ã¥ ha skrevet her", "All": "Alle", - "AllowPiwikArchivingToTriggerBrowser": "Arkiver rapporter nÃ¥r vist fra nettleseren", + "AllowPiwikArchivingToTriggerBrowser": "Arkiver rapporter nÃ¥r de vises i nettleseren", "AllWebsitesDashboard": "Oversiktspanel for alle nettsteder", "And": "og", "API": "API", - "ArchivingInlineHelp": "For nettsteder med medium til høy trafikk, er det anbefalt Ã¥ slÃ¥ av at nettleseren kan utløse Piwik-arkivering. I stedet anbefaler vi at du setter opp en cron-jobb som prosesserer Piwik-rapporter hver time.", + "Apply": "Bruk", + "ArchivingInlineHelp": "For nettsteder med medium til høy trafikk, er det anbefalt Ã¥ arkivering av rapporter nÃ¥r de vises i nettleseren. I stedet anbefaler vi at du setter opp en cron-jobb som prosesserer Piwik-rapporter hver time.", "ArchivingTriggerDescription": "For større Piwik-installasjoner anbefales det at du setter opp en %scron-jobb%s for Ã¥ behandle rapporter automatisk.", "AuthenticationMethodSmtp": "Autentiseringsmetode for SMTP", "AverageOrderValue": "Gjennomsnittlig ordrepris", @@ -19,11 +22,11 @@ "AverageQuantity": "Gjennomsnittlig antall", "BackToPiwik": "Tilbake til Piwik", "Broken": "Oppdelt", - "BrokenDownReportDocumentation": "Den er delt opp i forskjellige rapporter som er vist i sparklines pÃ¥ bunnen av side. Du kan forstørre grafene ved Ã¥ klikke pÃ¥ den rapporten du ønsker Ã¥ se.", + "BrokenDownReportDocumentation": "Den er delt opp i forskjellige rapporter som vises i minigrafer (sparklines) pÃ¥ bunnen av siden. Du kan forstørre grafene ved Ã¥ klikke pÃ¥ den rapporten du ønsker Ã¥ se.", "Cancel": "Avbryt", "CannotUnzipFile": "Kan ikke pakke opp filen %1$s: %2$s", "ChangePassword": "Endre passord", - "ChangeTagCloudView": "Legg merke til at du kan se pÃ¥ rapporten pÃ¥ andre mÃ¥ter enn som en merkelappsky. Bruk kontrollene pÃ¥ bunnen av rapporten for Ã¥ gjøre det.", + "ChangeTagCloudView": "Legg merke til at du kan se pÃ¥ rapporten pÃ¥ andre mÃ¥ter enn som en stikkordsky. Bruk kontrollene pÃ¥ bunnen av rapporten for Ã¥ gjøre det.", "ChooseDate": "Velg dato", "ChooseLanguage": "Velg sprÃ¥k", "ChoosePeriod": "Velg periode", @@ -32,23 +35,23 @@ "ClickToChangePeriod": "Klikk igjen for Ã¥ endre periode.", "Close": "Lukk", "ClickToSearch": "Klikk for Ã¥ søke", - "ColumnActionsPerVisit": "Handlinger pr. besøk", + "ColumnActionsPerVisit": "Handlinger per besøk", "ColumnActionsPerVisitDocumentation": "Det gjennomsnittlige antallet handlinger (sidevisninger, nettstedsøk, nedlastinger eller utlenker) som ble gjennomført i løpet av besøkene.", "ColumnAverageGenerationTime": "Gj.snitt. genereringstid", - "ColumnAverageGenerationTimeDocumentation": "Den gjennomsnittlige tiden det tok Ã¥ generere siden. Dette mÃ¥ltallet inkludere tiden det tok tjeneren Ã¥ generere siden, pluss tiden det den besøkende Ã¥ laste ned svar fra tjeneren. Et lavere gjennomsnitt betyr et raskere nettsted for dine besøkende!", - "ColumnAverageTimeOnPage": "Gj. tid pÃ¥ side", + "ColumnAverageGenerationTimeDocumentation": "Den gjennomsnittlige tiden det tok Ã¥ generere siden. Dette mÃ¥ltallet inkluderer tiden det tok tjeneren Ã¥ generere siden, pluss tiden det den besøkende Ã¥ laste ned svar fra tjeneren. Et lavere gjennomsnitt betyr et raskere nettsted for dine besøkende!", + "ColumnAverageTimeOnPage": "Gj.snitt. tid pÃ¥ side", "ColumnAverageTimeOnPageDocumentation": "Den gjennomsnittlige tiden besøkende tilbrakte pÃ¥ denne siden (bare siden, ikke hele nettstedet).", - "ColumnAvgTimeOnSite": "Gj. tid pÃ¥ nettstedet", + "ColumnAvgTimeOnSite": "Gj.snitt. tid pÃ¥ nettstedet", "ColumnAvgTimeOnSiteDocumentation": "Gjennomsnittlig varighet for et besøk.", "ColumnBounceRate": "Sprettfrekvens", - "ColumnBounceRateDocumentation": "Prosentandelen av besøk som hadde bare en sidevisning. Dette betyr at den besøkende forlot nettstedet direkte fra inngangssiden.", + "ColumnBounceRateDocumentation": "Prosentandelen av besøk som bare hadde én sidevisning. Dette betyr at den besøkende forlot nettstedet direkte fra inngangssiden.", "ColumnBounces": "Sprett", "ColumnBouncesDocumentation": "Prosentandel av besøk som startet og sluttet pÃ¥ denne siden. Dette betyr at den besøkende forlot nettstedet etter kun Ã¥ ha sett denne siden.", - "ColumnConversionRate": "Konvertingsrate", + "ColumnConversionRate": "Konverteringsrate", "ColumnConversionRateDocumentation": "Prosentandelen av besøk som utløste mÃ¥lkonvertering.", "ColumnDestinationPage": "Destinasjonsside", "ColumnEntrances": "Innganger", - "ColumnEntrancesDocumentation": "Antallet besøk som startet pÃ¥ denne siden.", + "ColumnEntrancesDocumentation": "Antall besøk som startet pÃ¥ denne siden.", "ColumnExitRate": "Utgangsfrekvens", "ColumnExitRateDocumentation": "Prosentandelen av besøk som forlot nettstedet etter Ã¥ ha sett pÃ¥ denne siden.", "ColumnExits": "Utganger", @@ -62,7 +65,7 @@ "ColumnNbUniqVisitors": "Unike besøkende", "ColumnNbUniqVisitorsDocumentation": "Antallet unike besøkende som kommer til nettstedet ditt. Hver bruker blir telt bare en gang selv om han besøker nettstedet flere ganger om dagen.", "ColumnNbUsers": "Brukere", - "ColumnNbUsersDocumentation": "Antallet bruker logget inn pÃ¥ nettstedet ditt. Det er antallet unike aktive brukere som har en bruker-ID satt (via sporsingskodefunksjonen «setUserId»).", + "ColumnNbUsersDocumentation": "Antall brukere som er logget inn pÃ¥ nettstedet ditt. Det er antallet unike aktive brukere som har en bruker-ID satt (via sporsingskodefunksjonen «setUserId»).", "ColumnNbVisits": "Besøk", "ColumnNbVisitsDocumentation": "Hvis en besøkende kommer til nettstedet ditt for første gang eller han besøker nettstedet mer enn 30 minutter etter hans siste sidevisning, sÃ¥ vil det bli registrert som et nytt besøk.", "ColumnPageBounceRateDocumentation": "Prosentandelen av besøk som startet pÃ¥ denne siden og forlot nettstedet med en gang.", @@ -75,7 +78,7 @@ "ColumnUniqueEntrances": "Unike innganger", "ColumnUniqueExits": "Unike utganger", "ColumnUniquePageviews": "Unike sidevisninger", - "ColumnUniquePageviewsDocumentation": "Antallet besøk som inkluderte denne sida. Hvis ei side ble vist flere ganger i løpet av et besøk, telles det bare som en gang.", + "ColumnUniquePageviewsDocumentation": "Antall besøk som inkluderte denne siden. Hvis en side ble vist flere ganger i løpet av et besøk, telles det bare som en gang.", "ColumnValuePerVisit": "Verdi per besøk", "ColumnViewedAfterSearch": "Klikket i søkeresultat", "ColumnViewedAfterSearchDocumentation": "Antallet ganger denne siden var besøkt etter at en besøkende gjorde et søk pÃ¥ nettstedet ditt og klikket pÃ¥ denne siden i søkeresultatene.", @@ -93,11 +96,12 @@ "DailySum": "daglig sum", "DashboardForASpecificWebsite": "Oversiktspanel for et bestemt nettsted", "DataForThisGraphHasBeenPurged": "Dataene for denne grafen er mer enn %s mÃ¥neder gamle og har blitt fjernet.", - "DataForThisTagCloudHasBeenPurged": "Dataene for denne merkelappskyen er mer enn %s mÃ¥neder gamle og har blitt fjernet.", + "DataForThisTagCloudHasBeenPurged": "Dataene for denne stikkordskyen er mer enn %s mÃ¥neder gamle og har blitt fjernet.", "Date": "Dato", "DateRange": "Datointervall:", "DateRangeFrom": "Fra", "DateRangeFromTo": "Fra %s til %s", + "DateRangeInPeriodList": "datointervall", "DateRangeTo": "Til", "DaysHours": "%1$s dager %2$s timer", "DaysSinceFirstVisit": "Dager siden første besøk", @@ -112,30 +116,30 @@ "Discount": "Rabatt", "DisplaySimpleTable": "Vis enkel tabell", "DisplayTableWithGoalMetrics": "Vis en tabell med mÃ¥ltall for mÃ¥l", - "DisplayTableWithMoreMetrics": "Vis en tabell mer flere mÃ¥ltall", + "DisplayTableWithMoreMetrics": "Vis en tabell med mÃ¥ltall for besøkeres engasjement", "Documentation": "Dokumentasjon", "Donate": "Doner", "Done": "Ferdig", "Download": "Last ned", "DownloadFail_FileExists": "Filen %s finnes allerede!", - "DownloadFail_FileExistsContinue": "Prøver Ã¥ fortsette nedlastingen for %s, men en komplett nedlastet fil eksisterer allerede.", - "DownloadFail_HttpRequestFail": "Klarte ikke laste ned fila. Noe kan være galt med nettstedet du laster ned fra. Du kan prøve igjen seinere eller laste ned fila pÃ¥ egenhÃ¥nd.", + "DownloadFail_FileExistsContinue": "Prøver Ã¥ fortsette nedlastingen for %s, men en komplett nedlastet fil eksisterer allerede!", + "DownloadFail_HttpRequestFail": "Klarte ikke laste ned fila. Noe kan være galt med nettstedet du laster ned fra. Du kan prøve igjen senere eller laste ned filen pÃ¥ egenhÃ¥nd.", "DownloadFullVersion": "%1$sLast ned%2$s den fullstendige utgaven! Prøv %3$s", "DownloadPleaseRemoveExisting": "Hvis du vil at den skal erstattes, mÃ¥ du fjerne den eksisterende filen.", "Downloads": "Nedlastinger", "EcommerceOrders": "E-handelordre", "EcommerceVisitStatusDesc": "Besøk e-handelstatus etter slutten av besøket", - "EcommerceVisitStatusEg": "For eksempel, for Ã¥ velge alle besøk som har lagt inn en e-handelordre, sÃ¥ vil API-forespørselen inneholde %s.", - "Edit": "Endre", + "EcommerceVisitStatusEg": "For eksempel: for Ã¥ velge alle besøk som har lagt inn en e-handelordre, sÃ¥ vil API-forespørselen inneholde %s.", + "Edit": "Rediger", "EncryptedSmtpTransport": "Fyll inn transportlagkrypteringen som kreves av din SMTP-tjener.", "Error": "Feil", - "ErrorRequest": "Obs ... Det oppstod et problem under forespørselen. Kanskje tjeneren hadde en midlertidig feil eller kanskje du ba om en rapport med for mye data. Prøv igjen. Hvis feilen oppstÃ¥r gjentatte ganger, %skontakt din Piwik-administrator%s for assistanse.", - "EvolutionOverPeriod": "Utvikling over perioden", + "ErrorRequest": "Oi... Det oppstod et problem under forespørselen. Kanskje tjeneren hadde en midlertidig feil eller kanskje du ba om en rapport med for mye data. Prøv igjen. Hvis feilen oppstÃ¥r gjentatte ganger, %skontakt din Piwik-administrator%s for assistanse.", + "EvolutionOverPeriod": "Utvikling i perioden", "EvolutionSummaryGeneric": "%1$s i %2$s sammenlignet med %3$s i %4$s. Utvikling: %5$s", "ExceptionContactSupportGeneric": "Hvis du fortsatt har dette problemet, %skontakt din Piwik-administrator%s for assistanse.", "ExceptionCheckUserHasSuperUserAccessOrIsTheUser": "Bruker mÃ¥ enten være en superbruker eller brukeren «%s» selv.", - "ExceptionConfigurationFileNotFound": "Klarte ikke finne konfigurasjonsfila {%s}.", - "ExceptionConfigurationFileNotFound2": "Hvis filen eksisterer, vennligst sjekk at %s er lesbar for brukeren '%s'.", + "ExceptionConfigurationFileNotFound": "Klarte ikke finne konfigurasjonsfilen {%s}.", + "ExceptionConfigurationFileNotFound2": "Hvis filen eksisterer, vennligst sjekk at %s er lesbar for brukeren «%s».", "ExceptionDatabaseVersion": "Din %1$s versjon er %2$s, men Piwik krever minst %3$s.", "ExceptionDatabaseVersionNewerThanCodebase": "Din Piwik-kodebase kjører den gamle versjonen %1$s, og vi har oppdaget at din Piwik-database allerede har blitt oppgradert til den nyere versjonen %2$s.", "ExceptionDatabaseVersionNewerThanCodebaseWait": "Kanskje dine Piwik-administratorer holder pÃ¥ med Ã¥ fullføre oppgraderingsprosessen. Prøv igjen om noen fÃ¥ minutter.", @@ -143,6 +147,7 @@ "ExceptionFilesizeMismatch": "Filstørrelse stemmer ikke: %1$s (forventet lengde: %2$s, fant: %3$s)", "ExceptionIncompatibleClientServerVersions": "Din %1$s klientversjon er %2$s som ikke passer med tjenerversjonen %3$s.", "ExceptionInvalidAggregateReportsFormat": "Format «%s» for aggregerte rapporter er ikke gyldig. Prøv en av følgende istedenfor: %s.", + "ExceptionInvalidArchiveTimeToLive": "Arkiveringsintervallet for i dag mÃ¥ være et antall sekunder som er større enn null", "ExceptionInvalidDateFormat": "Datoformatet mÃ¥ være %s eller et nøkkelord støttet av %s-funksjonen (se %s for mer informasjon).", "ExceptionInvalidDateRange": "Datoen «%s» er ikke et gyldig datointervall. Riktig format er: %s", "ExceptionInvalidPeriod": "Perioden «%s» er ikke støttet. Prøv en av følgende istedenfor: %s", @@ -150,24 +155,27 @@ "ExceptionInvalidReportRendererFormat": "Rapportformat «%s» er ikke gyldig. Prøv en av følgende istedenfor: %s.", "ExceptionInvalidStaticGraphType": "Statisk graftype «%s» er ikke gyldig. Prøv en av følgende istedenfor: %s.", "ExceptionInvalidToken": "Token er ikke gyldig.", - "ExceptionLanguageFileNotFound": "Fant ikke sprÃ¥kfila «%s».", + "ExceptionLanguageFileNotFound": "Fant ikke sprÃ¥kfilen «%s».", "ExceptionMethodNotFound": "Metoden «%s» eksisterer ikke eller er ikke tilgjengelig i modulen «%s».", "ExceptionMissingFile": "Mangler fil: %s", - "ExceptionNonceMismatch": "Klarte ikke verifiserer sikkerhetstoken i dette skjemaet.", + "ExceptionNonceMismatch": "Klarte ikke Ã¥ verifisere sikkerhetstoken i dette skjemaet.", "ExceptionPrivilege": "Du har ikke tilgang til denne ressursen siden den krever «%s»-tilgang.", "ExceptionPrivilegeAccessWebsite": "Du har ikke tilgang til denne ressursen siden den krever «%s»-tilgang for nettstedet med id = %d.", "ExceptionPrivilegeAtLeastOneWebsite": "Du har ikke tilgang til denne ressursen siden den krever «%s»-tilgang for minst ett av nettstedene.", - "ExceptionUnableToStartSession": "Klarte ikke starte økt.", - "ExceptionUndeletableFile": "Klarte ikke slette %s", - "ExceptionUnreadableFileDisabledMethod": "Klarte ikke lese konfigurasjonsfila {%s}. Verten din kan ha deaktivert %s.", - "ExceptionReportNotFound": "Den etterspurte rapporten fins ikke.", - "ExceptionWidgetNotFound": "Det etterspurte elementet fins ikke.", + "ExceptionUnableToStartSession": "Klarte ikke Ã¥ starte økt.", + "ExceptionUndeletableFile": "Klarte ikke Ã¥ slette %s", + "ExceptionUnreadableFileDisabledMethod": "Klarte ikke Ã¥ lese konfigurasjonsfilen {%s}. Verten din kan ha deaktivert %s.", + "ExceptionReportNotFound": "Den etterspurte rapporten finnes ikke.", + "ExceptionWidgetNotFound": "Den etterspurte widgeten finnes ikke.", + "ExceptionReportNotEnabled": "Den etterspurte rapporten er ikke aktivert. Dette betyr vanligvis at enten er utvidelsen som definerer rapporten deaktivert, eller sÃ¥ har du ikke nok rettigheter til Ã¥ vise rapporten.", + "ExpandDataTableFooter": "Endre visualiseringen eller konfigurer rapporten", "Export": "Eksporter", "ExportAsImage": "Eksporter som bilde", - "ExportThisReport": "Eksporter dette datasett i andre format", + "ExportThisReport": "Eksporter dette datasettet i andre formater", "Faq": "FAQ", "FileIntegrityWarningExplanation": "Integritetskontrollen av filer oppdaget noen feil. Dette skyldes mest sannsynlig feil under opplasting av Piwik sine filer. Du bør laste opp alle Piwik sine filer pÃ¥ nytt i BINARY-modus og oppfriske siden inntil ingen feil vises.", "First": "Først", + "Flatten": "Gjør flat", "ForExampleShort": "f.eks.", "Forums": "Forum", "FromReferrer": "fra", @@ -180,9 +188,10 @@ "GraphHelp": "Mer informasjon om visning av grafikk i Piwik", "HelloUser": "Hallo, %s!", "Help": "Hjelp", + "HelpTranslatePiwik": "Kanskje du vil %1$shjelpe oss Ã¥ forbedre Piwik-oversettelser%2$s?", "Hide": "skjul", "HoursMinutes": "%1$s timer %2$s min", - "Id": "Id", + "Id": "ID", "IfArchivingIsFastYouCanSetupCronRunMoreOften": "Forutsatt arkivering er raskt for ditt oppsett, kan du sette opp crontab til Ã¥ kjøre oftere.", "InfoFor": "Informasjon for %s", "Installed": "Installert", @@ -195,20 +204,20 @@ "LastDaysShort": "Siste %s dager", "LearnMore": "%1$slær mer%2$s", "Live": "Live", - "Loading": "Laster ...", - "LoadingData": "Laster data ...", + "Loading": "Laster...", + "LoadingData": "Laster data...", "LoadingPopover": "Laster %s...", "LoadingPopoverFor": "Laster %s for", "Locale": "nb_NO.UTF-8", "Logout": "Logg ut", - "MainMetrics": "Hoved mÃ¥ltall", + "MainMetrics": "HovedmÃ¥ltall", "Matches": "Treff", - "MediumToHighTrafficItIsRecommendedTo": "For nettsteder med medium til høy trafikk, er det anbefalt Ã¥ prosesserer dagens rapporter ikke oftere enn hver halvtime (%s sekund) eller hver time (%s sekund).", + "MediumToHighTrafficItIsRecommendedTo": "For nettsteder med medium til høy trafikk, er det anbefalt Ã¥ ikke prosessere dagens rapporter oftere enn hver halvtime (%s sekunder) eller hver time (%s sekunder).", "Metadata": "Metadata", "Metric": "MÃ¥ltall", "Metrics": "MÃ¥ltall", - "MetricsToPlot": "MÃ¥ltall Ã¥ tegne", - "MetricToPlot": "MÃ¥ltall Ã¥ tegne", + "MetricsToPlot": "MÃ¥ltall som skal vises", + "MetricToPlot": "MÃ¥ltall som skal vises", "MinutesSeconds": "%1$s min %2$ss", "Mobile": "Mobil", "Monthly": "MÃ¥nedlig", @@ -224,13 +233,13 @@ "Never": "Aldri", "NewReportsWillBeProcessedByCron": "Hvis Piwik-arkivering ikke blir utløst av nettleseren, sÃ¥ vil nye rapporter bli prosessert ved hjelp av crontab.", "NewUpdatePiwikX": "Ny utgave: Piwik %s", - "NewVisitor": "Ny besøk", + "NewVisitor": "Ny besøker", "NewVisits": "Nye besøk", "Next": "Neste", "No": "Nei", "NoDataForGraph": "Ingen data for denne grafen.", - "NoDataForTagCloud": "Ingen data for denne merkelappskyen.", - "NotDefined": "%s ikke definert", + "NoDataForTagCloud": "Ingen data for denne stikkordskyen.", + "NotDefined": "%s er ikke definert", "Note": "Notat", "NotInstalled": "Ikke installert", "NotRecommended": "ikke anbefalt", @@ -243,8 +252,8 @@ "OneVisit": "1 besøk", "OnlyEnterIfRequired": "Skriv bare inn et brukernavn hvis din SMTP-tjener krever det", "OnlyEnterIfRequiredPassword": "Skriv bare inn et passord hvis din SMTP-tjener krever det", - "OnlyUsedIfUserPwdIsSet": "Brukes kun hvis et brukernavn\/passord er satt, spør din leverandør om du er usikker pÃ¥ hvilken metode som skal brukes.", - "OpenSourceWebAnalytics": "Ã…pen kildekode nettstatistikk", + "OnlyUsedIfUserPwdIsSet": "Brukes kun hvis et brukernavn\/passord er satt. Spør din leverandør om du er usikker pÃ¥ hvilken metode som skal brukes.", + "OpenSourceWebAnalytics": "Nettstatistikk med Ã¥pen kildekode", "OperationAtLeast": "Minst", "OperationAtMost": "Høyst", "OperationContains": "Inneholder", @@ -259,30 +268,40 @@ "Options": "Alternativer", "OrCancel": "eller %s avbryt %s", "Others": "Andre", + "Outlink": "Utlenke", "Outlinks": "Utlenker", + "OverlayRowActionTooltip": "Se analysedata direkte pÃ¥ ditt nettsted (Ã¥pner en ny fane)", + "OverlayRowActionTooltipTitle": "Ã…pne sideoverlegg", "Overview": "Oversikt", "Pages": "Sider", - "Pagination": "%s - %s av %s", - "PaginationWithoutTotal": "%s - %s", + "Pagination": "%s – %s av %s", + "PaginationWithoutTotal": "%s – %s", "ParameterMustIntegerBetween": "Parameteret %s mÃ¥ være et heltall mellom %s og %s.", "Password": "Passord", "Period": "Periode", "Piechart": "Kakediagram", + "PiwikIsACollaborativeProjectYouCanContributeAndDonate": "%1$sPiwik%2$s er et samarbeidsprosjekt mellom %7$sPiwik-teamets%8$s medlemmer og mange andre bidragsytere over hele verden. Hvis du liker Piwik, kan du hjelpe oss: finn ut %3$shvordan delta i Piwik%4$s eller %5$sdoner nÃ¥%6$s for Ã¥ støtte utviklingen av Piwik 3.0!", "PiwikXIsAvailablePleaseNotifyPiwikAdmin": "%1$s er tilgjengelig. Vennligst gi beskjed til %2$sPiwik administrator%3$s.", "PiwikXIsAvailablePleaseUpdateNow": "Piwik %1$s er tilgjengelig. %2$s Oppdater nÃ¥!%3$s (se %4$s endringer%5$s).", "PleaseSpecifyValue": "Oppgi en verdi for «%s».", - "PleaseUpdatePiwik": "Oppdatering din Piwik", - "Plugin": "Tillegg", - "Plugins": "Tillegg", + "PleaseUpdatePiwik": "Vennligst oppdater din Piwik", + "Plugin": "Utvidelse", + "Plugins": "Utvidelser", "PoweredBy": "Drevet av", "Previous": "Forrige", - "PreviousDays": "Tidligere %s dager (ikke inkludert i dag)", + "PreviousDays": "Forrige %s dager (ikke inkludert i dag)", "PreviousDaysShort": "Forrige %s dager", "Price": "Pris", + "ProductConversionRate": "Produktets konverteringsrate", + "ProductRevenue": "Produktets inntjening", + "Measurable": "MÃ¥lbart", + "Measurables": "MÃ¥lbare", "PurchasedProducts": "Kjøpte produkter", "Quantity": "Antall", + "RangeReports": "Tilpassede datointervaller", "ReadThisToLearnMore": "%1$sLes dette for Ã¥ lære mer.%2$s", "Recommended": "Anbefalt", + "RecordsToPlot": "Oppføringer som skal vises", "Refresh": "Oppdater", "RefreshPage": "Last siden pÃ¥ nytt", "RelatedReport": "Relatert rapport", @@ -290,48 +309,60 @@ "Remove": "Fjern", "Report": "Rapport", "ReportGeneratedFrom": "Denne rapporten ble generert ved hjelp av data fra %s.", - "ReportRatioTooltip": "'%1$s' representerer %2$s av %3$s %4$s med %5$s.", + "ReportRatioTooltip": "«%1$s» representerer %2$s av %3$s %4$s med %5$s.", "Reports": "Rapporter", + "ReportsContainingTodayWillBeProcessedAtMostEvery": "Arkiver rapporter som mest hvert X sekund", + "RearchiveTimeIntervalOnlyForTodayReports": "Dette pÃ¥virker kun rapporter for i dag (eller andre datointervaller som inkluderer i dag)", + "ReportsWillBeProcessedAtMostEveryHour": "Rapporter vil derfor prosesseres som mest hver time.", "RequestTimedOut": "En dataforespørsel til %s fikk tidsavbrudd. Prøv igjen.", "Required": "%s pÃ¥krevd", "ReturningVisitor": "Tilbakevendende besøkende", "ReturningVisitorAllVisits": "Vis alle besøk", + "RowEvolutionRowActionTooltip": "Se hvordan mÃ¥ltallet for raden endret seg over tid", + "RowEvolutionRowActionTooltipTitle": "Ã…pne radutvikling", "Rows": "Rader", - "RowsToDisplay": "Rader for visning", + "RowsToDisplay": "Rader som skal vises", "Save": "Lagre", - "SaveImageOnYourComputer": "For Ã¥ lagre bildet pÃ¥ din datamaskin, høyreklikk pÃ¥ bildet og velg \"Lagre bilde som ...\"", + "SaveImageOnYourComputer": "For Ã¥ lagre bildet pÃ¥ din datamaskin, høyreklikk pÃ¥ bildet og velg «Lagre bilde som...»", "Search": "Søk", "Clear": "Tøm", "SearchNoResults": "Ingen resultater", "SeeAll": "se alle", "SeeTheOfficialDocumentationForMoreInformation": "Se %sden offisielle dokumentasjonen%s for mer informasjon.", - "SeeThisFaq": "Se %1$sdenne FAQ'en%2$s.", + "SeeThisFaq": "Se %1$sdenne FAQ-en%2$s.", "Segment": "Segment", "SelectYesIfYouWantToSendEmailsViaServer": "Velg «Ja» hvis du vil sende e-post med en navngitt tjener istedenfor den lokale mail-funksjonen", "Settings": "Innstillinger", "Shipping": "Frakt", "Show": "vis", - "SmallTrafficYouCanLeaveDefault": "For nettsteder med liten trafikk, sÃ¥ kan du beholde standardvalget %s sekund og ha tilgang til alle rapporter i sanntid.", + "SingleWebsitesDashboard": "Oversiktspanel for ett nettsted", + "SmallTrafficYouCanLeaveDefault": "PÃ¥ nettsteder med lite trafikk kan du beholde standardvalget %s sekunder og ha tilgang til alle rapporter i sanntid.", "SmtpEncryption": "SMTP-kryptering", "SmtpPassword": "SMTP-passord", "SmtpPort": "SMTP-port", "SmtpServerAddress": "SMTP-tjeneradresse", "SmtpUsername": "SMTP-brukernavn", "Source": "Kilde", + "StatisticsAreNotRecorded": "Piwik besøkssporing er deaktivert! Aktiver sporing igjen ved Ã¥ sette record_statistics = 1 i din config\/config.ini.php-fil.", "Subtotal": "Delsum", "Summary": "Sammendrag", "Table": "Tabell", - "TagCloud": "Merkelappsky", + "TagCloud": "Stikkordsky", "Tax": "Skatt", "TimeAgo": "%s siden", + "TimeFormat": "Tidsformat", "TimeOnPage": "Tid pÃ¥ side", "Total": "Totalt", "TotalRatioTooltip": "Dette er %1$s av alle %2$s %3$s.", + "TotalRevenue": "Total inntjening", "TotalVisitsPageviewsActionsRevenue": "(Totalt: %s besøk, %s sidevisninger, %s handlinger, %s inntekter)", + "TransitionsRowActionTooltip": "Se hva besøkende gjorde før og etter Ã¥ ha sett denne siden", + "TransitionsRowActionTooltipTitle": "Ã…pne overganger", "TranslatorName": "Hans Fredrik Nordhaug", "UniquePurchases": "Unike kjøp", "Unknown": "Ukjent", "Upload": "Last opp", + "UsePlusMinusIconsDocumentation": "Bruk pluss- og minus-ikonene til venstre for Ã¥ navigere.", "UserId": "Bruker-ID", "Username": "Brukernavn", "UseSMTPServerForEmail": "Bruk SMTP-tjener for e-post", @@ -340,25 +371,32 @@ "View": "Vis", "ViewDocumentationFor": "Vis dokumentasjon for %1$s", "Visit": "Besøk", + "VisitConvertedGoal": "Besøk som er konvertert til minst ett mÃ¥l", + "VisitConvertedGoalId": "Besøk konvertert til et spesifikt mÃ¥l-ID", "VisitConvertedNGoals": "Besøk konverterte %s mÃ¥l", - "VisitDuration": "Gj. besøksvarighet (i sekunder)", - "VisitorID": "Besøks-ID", - "VisitorIP": "IP for besøkende", - "Visitors": "Besøkende", + "VisitDuration": "Gj.snitt. besøksvarighet (i sekunder)", + "Visitor": "Besøker", + "VisitorID": "Besøker-ID", + "VisitorIP": "IP for besøker", + "Visitors": "Besøkere", "VisitsWith": "Besøk med %s", - "VisitorSettings": "Besøkendes innstillinger", + "VisitorSettings": "Besøkers innstillinger", "VisitType": "Besøkstype", + "VisitTypeExample": "For eksempel: for Ã¥ velge alle besøkere som har returnert til nettstedet, inkludert de som har kjøpt noe i deres tidligere besøk, mÃ¥ API-forespørselen inneholde %s", "Warning": "Advarsel", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik kutter støtte for denne PHP-versjonen i %s. Oppgrader din PHP-versjon før det er for sent.", - "WarningFileIntegrityNoManifest": "Klarte ikke utføre integritetskontroll av filer fordi manifest.inc.php mangler.", + "WarningPhpVersionXIsTooOld": "PHP-versjonen du bruker (%s) er utdatert. Du bør oppgradere til en støttet versjon, siden den versjonen du bruker kan eksponere deg for sÃ¥rbarheter og feil som har blitt fikset i nyere versjoner av PHP.", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik vil slutte Ã¥ støtte PHP %1$s i neste versjon. Oppgrader din PHP til minst PHP %2$s, før det er for sent!", + "WarningFileIntegrityNoManifest": "Klarte ikke Ã¥ utføre integritetskontroll av filer fordi manifest.inc.php mangler.", + "WarningFileIntegrityNoManifestDeployingFromGit": "Hvis du installerer Piwik fra Git, er denne meldingen normal.", "WarningFileIntegrityNoMd5file": "Klarte ikke utføre integritetskontroll av filer fordi funksjonen md5_file mangler.", "WarningPasswordStored": "%sAdvarsel:%s Dette passordet lagres i klartekst i konfigurasjonsfilen slik at alle med tilgang kan lese det.", + "WarningDebugOnDemandEnabled": "Sporingsmodus %s er aktivert. PÃ¥ grunn av sikkerheten bør dette kun være aktivert i en kort periode. For Ã¥ deaktivere, sett %s til %s i %s", "Website": "Nettsted", "Weekly": "Ukentlig", "WeeklyReport": "ukentlig", "WeeklyReports": "Ukentlige rapporter", "WellDone": "Bra jobba!", - "Widgets": "Element", + "Widgets": "Widgeter", "Widget": "Widget", "XComparedToY": "%1$s sammenlignet med %2$s", "XFromY": "%1$s fra %2$s", @@ -367,8 +405,9 @@ "YearsDays": "%1$s Ã¥r %2$s dager", "Yes": "Ja", "YouAreCurrentlyUsing": "Du bruker for øyeblikket Piwik %s.", + "YouAreViewingDemoShortMessage": "Du ser demoen av Piwik", "YouMustBeLoggedIn": "Du mÃ¥ være innlogget for Ã¥ bruke denne funksjonaliteten.", - "YourChangesHaveBeenSaved": "Din endringer er lagret." + "YourChangesHaveBeenSaved": "Dine endringer er lagret." }, "Mobile": { "AboutPiwikMobile": "Om Piwik Mobile", @@ -380,18 +419,19 @@ "Advanced": "Avansert", "AnonymousAccess": "Anonym tilgang", "AnonymousTracking": "Anonym sporing", - "ChooseHttpTimeout": "Velg HTTP-tidsavbrudd verdi", + "AskForAnonymousTrackingPermission": "NÃ¥r aktivert vil Piwik Mobile sende anonym bruksdata til piwik.org. Hensikten er Ã¥ bruke dataen til Ã¥ hjelpe Piwik Mobile-utviklere Ã¥ bedre skjønne hvordan appen brukes. Informasjon som blir sendt er: menyer og innstillinger som klikkes pÃ¥, navn og versjon pÃ¥ OS, og feilmeldinger som vises i Piwik Mobile. Vi vil IKKE spore dine analysedata. Dataen som sendes vil ikke bli offentliggjort. Du kan deaktivere og aktivere anonym sporing i innstillingene nÃ¥r som helst.", + "ChooseHttpTimeout": "Velg verdi for HTTP-tidsavbrudd", "ChooseMetric": "Velg mÃ¥ltall", "ChooseReport": "Velg en rapport", "ChooseSegment": "Velg segment", "ConfirmRemoveAccount": "Vil du fjerne denne kontoen?", "DefaultReportDate": "Rapportdato", - "EmailUs": "Send epost til oss", + "EmailUs": "Send e-post til oss", "EnableGraphsLabel": "Vis grafer", "EvolutionGraph": "Historisk graf", - "HelpUsToImprovePiwikMobile": "Vil du slÃ¥ pÃ¥ anonym sporing av bruk i Piwik Mobile?", + "HelpUsToImprovePiwikMobile": "Vil du aktivere anonym sporing av bruk i Piwik Mobile?", "HowtoDeleteAnAccount": "Trykk lenge for Ã¥ fjerne en konto.", - "HowtoDeleteAnAccountOniOS": "Sveip høyre til venstre for Ã¥ slette en konto", + "HowtoDeleteAnAccountOniOS": "Sveip fra høyre til venstre for Ã¥ slette en konto", "HowtoLoginAnonymous": "La brukernavn og passord være tomt for anonym innlogging.", "HttpIsNotSecureWarning": "Din Piwik autorisasjonstoken (token_auth) blir sendt i klartekst hvis du bruker HTTP. Av den grunn anbefaler vi HTTPS for sikker transport av data over internett. Vil du fortsette?", "HttpTimeout": "HTTP-tidsavbrudd", @@ -401,7 +441,7 @@ "LoginCredentials": "PÃ¥loggingsinformasjon", "LoginToPiwikToChangeSettings": "Logg inn pÃ¥ din Piwik-tjener for Ã¥ opprette og oppdatere nettsted og brukere eller for Ã¥ endre generelle innstillinger som «Rapport som skal lastes som standard».", "LoginUseHttps": "Bruk HTTPS", - "MultiChartLabel": "Vis sparklines", + "MultiChartLabel": "Vis minigrafer", "NavigationBack": "Tilbake", "NetworkError": "Nettverksfeil", "NetworkErrorWithStatusCode": "Det oppstod en «%s»-feil. Forespørselen returnerte statusen «%s». URL-en var «%s». Sjekk URL-en du skrev inn og feilloggene pÃ¥ denne tjeneren for mer informasjon om feilen og hvordan du kan løse problemet.", @@ -419,17 +459,17 @@ "PossibleSslError": "Mulig feil med SSL-sertifikat", "PossibleSslErrorExplanation": "En feil oppstod som kan være forÃ¥rsaket av et ugyldig eller selvsignert sertifikat: «%s» Innlogging kan virke for deg hvis du ignorerer SSL-validering, men det er mindre sikkert. Du kan endre SSL-validering nÃ¥r som helst i innstillingene.", "IgnoreSslError": "Ignorer SSL-feil", - "RatingDontRemindMe": "Ikke minn meg pÃ¥", + "RatingDontRemindMe": "Ikke minn meg pÃ¥ dette", "RatingNotNow": "Ikke nÃ¥", - "RatingNow": "OK, jeg vil vurdere det nÃ¥", + "RatingNow": "OK, jeg vil vurdere den nÃ¥", "RatingPleaseRateUs": "Appen Piwik Mobil er fri programvare. Vi ville virkelig sette pris pÃ¥ om du brukte 1 minutt pÃ¥ Ã¥ vurdere denne appen i %s. Hvis du har forslag til nye funksjoner eller feilrapporter, kontakt %s", "ReleaseToRefresh": "Slipp for Ã¥ oppdatere...", "Reloading": "Laster inn pÃ¥ nytt ...", - "RequestTimedOutShort": "Nettverksfeil - tidsavbrudd", + "RequestTimedOutShort": "Nettverksfeil – tidsavbrudd", "RestrictedCompatibility": "Begrenset kompatibilitet", - "RestrictedCompatibilityExplanation": "Piwik-versjonen %s som du bruker er ikke fullt støttet av Piwik Mobile 2. Du kan oppleve noen feil. Vi anbefaler at du enten oppdatere Piwik til siste utgave eller bruker Piwik Mobile 1.", + "RestrictedCompatibilityExplanation": "Piwik-versjonen %s som du bruker er ikke fullt støttet av Piwik Mobile 2. Du kan oppleve noen feil. Vi anbefaler at du enten oppdaterer Piwik til siste utgave eller bruker Piwik Mobile 1.", "SaveSuccessError": "Piwik-URL eller kombinasjonen av brukernavn og passord er feil.", - "SearchWebsite": "Søk nettsteder", + "SearchWebsite": "Søk i nettsteder", "ShowAll": "Vis alle", "ShowLess": "Vis mindre", "StaticGraph": "Oversiktsgraf", @@ -443,15 +483,16 @@ }, "RowEvolution": { "AvailableMetrics": "Tilgjengelige mÃ¥ltall", + "CompareDocumentation": "Klikk lenken nedenfor og Ã¥pne dette popup-vunduet for en annen rad i samme tabell for Ã¥ sammenlikne flere oppføringer.<br \/>Bruk SHIFT-klikk for Ã¥ markere raden for sammenlikning uten Ã¥ Ã¥pne dette popup-vinduet.", "CompareRows": "Sammenlign oppføringer", "ComparingRecords": "Sammenligner %s rader", "Documentation": "Klikk mÃ¥ltallet for Ã¥ vise det i den store utviklingsgrafen. Bruk SHIFT-klikk for Ã¥ vise flere mÃ¥ltall pÃ¥ en gang.", "MetricBetweenText": "mellom %s og %s", - "MetricChangeText": "%s endring over perioden", - "MetricMinMax": "%1$s rangert mellom %2$s og %3$s over perioden", + "MetricChangeText": "%s endring i perioden", + "MetricMinMax": "%1$s rangert mellom %2$s og %3$s i perioden", "MetricsFor": "MÃ¥ltall for %s", "MultiRowEvolutionTitle": "Utvikling av flere rader", - "PickAnotherRow": "Velg en annen rad Ã¥ sammenligne", - "PickARow": "Velg en rad Ã¥ sammenlign" + "PickAnotherRow": "Velg en annen rad Ã¥ sammenlikne med", + "PickARow": "Velg en rad Ã¥ sammenlikne med" } } \ No newline at end of file diff --git a/lang/nl.json b/lang/nl.json index dfefa26737fc10f861b1a186a81676c1af047224..c8b0818e185c29530e4ce6ddfe914a7c21aaa8f3 100644 --- a/lang/nl.json +++ b/lang/nl.json @@ -379,7 +379,6 @@ "VisitTypeExample": "Om bijvoorbeeld het aantal terugkerende bezoekers (inclusief die bezoekers die iets gekocht hebben) te selecteren moet de API %s bevatten", "Warning": "Let op", "WarningPhpVersionXIsTooOld": "Je gebruikt PHP versie %s. Deze heeft de status 'End of Life (OEL)'. We adviseren je ten zeerste om te upgraden naar de recente versie van PHP, omdat de versie die nu gebruikt beveiligingslekken en bugs kan bevatten, welke in meer recente versies van PHP opgelost zijn.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik stopt de ondersteuning van deze PHP versie in %s. Upgrade je PHP versie voor het te laat is!", "WarningFileIntegrityNoManifest": "Bestand integriteits controle kon niet worden uitgevoerd vanwege ontbrekend manifest.inc.php", "WarningFileIntegrityNoManifestDeployingFromGit": "Als je Piwik vanuit Git deployed, dan is deze melding normaal.", "WarningFileIntegrityNoMd5file": "Bestand integriteit controle kon niet worden voltooid vanwege ontbrekende md5_file() functie.", diff --git a/lang/pl.json b/lang/pl.json index 2edf0aecbf84793595828c0d528e347f6131d6de..c68085a88f66783b2c5247316d5cd0bc46b4be0c 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -344,7 +344,6 @@ "VisitorSettings": "Konfiguracje użytkownika", "VisitTypeExample": "PrzykÅ‚adowo, aby wybrać wszystkich odwiedzajÄ…cych, którzy powrócili na serwis, włączajÄ…c tych, którzy zakupili coÅ› podczas poprzednich wizyt, zapytanie API bÄ™dzie zawierać %s", "Warning": "Ostrzeżenie", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik przestanie wspierać tÄ… wersjÄ™ PHP w %s. Zauktualizuj wersjÄ™ PHP zanim bÄ™dzie za późno!", "WarningFileIntegrityNoManifest": "Weryfikacja integralnoÅ›ci plików nie mogÅ‚a zostać przeprowadzona z powodu braku pliku manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "W przypadku wdrażania Piwik z Git, komunikat ten jest prawidÅ‚owy.", "WarningFileIntegrityNoMd5file": "Weryfikacja integralnoÅ›ci plików nie mogÅ‚a zostać zakoÅ„czona z powodu braku funkcji md5_file().", diff --git a/lang/pt-br.json b/lang/pt-br.json index 9b16a71640cba8f345637440e18f333a73aac25c..2bed8292e5d2cf94128637d3f0972991056e39ce 100644 --- a/lang/pt-br.json +++ b/lang/pt-br.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "Relógio de 12 horas", + "24HourClock": "Relógio de 24 horas", "AbandonedCarts": "Compras abandonadas", "AboutPiwikX": "Sobre o Piwik %s", "Action": "Ação", @@ -171,7 +173,7 @@ "ExportAsImage": "Exportar como imagem", "ExportThisReport": "Exportar este conjunto de dados noutros formatos", "Faq": "FAQ", - "FileIntegrityWarningExplanation": "O check de integridade do arquivo falhou e reportou alguns erros. Isso é mais provável devido a uma parcial ou upload falho de algum arquivo Piwik. Você deveria refazer o upload de todos os arquivos Piwik e recarregar a página até que nenhum erro seja exibido.", + "FileIntegrityWarningExplanation": "A verificação de integridade do arquivo falhou e reportou alguns erros. Isso é mais provável devido a um carregamento parcial ou falho de algum arquivo Piwik. Você deve recarregar todos os arquivos Piwik em modo BINÃRIO e também recarregar a página até que nenhum erro seja exibido.", "First": "Primeiro", "Flatten": "Achatar", "ForExampleShort": "ex.", @@ -262,8 +264,11 @@ "OperationIsNot": "não é", "OperationLessThan": "menos que", "OperationNotEquals": "não é igual a", + "OperationStartsWith": "Inicia com", + "OperationEndsWith": "Finaliza com", "OptionalSmtpPort": "Opcional. O padrão é 25 para não criptografadas e TLS SMTP, e 465 para SMTP SSL.", "Options": "Opções", + "Or": "ou", "OrCancel": "ou %s Cancele %s", "Others": "Outros", "Outlink": "SaÃda", @@ -348,17 +353,21 @@ "TagCloud": "Núvem de Tag", "Tax": "Taxas", "TimeAgo": "%s atrás", + "TimeFormat": "Formato do horário", "TimeOnPage": "Tempo na página", "Total": "Total", "TotalRatioTooltip": "Este é %1$s de todos os %2$s %3$s.", "TotalRevenue": "Total de Revendas", "TotalVisitsPageviewsActionsRevenue": "(Total: %s visitas , %s exibições de página, %s actions, %s receita)", + "TrackingScopeAction": "Ação", + "TrackingScopePage": "Página", + "TrackingScopeVisit": "Visita", "TransitionsRowActionTooltip": "Veja o que os visitantes fizeram antes e depois de verem este página", "TransitionsRowActionTooltipTitle": "Transições abertas", "TranslatorName": "Marcos Napier, Marcela Ferraro, Zob, Raphael Milani, Fernando Fraga Rodrigues", "UniquePurchases": "Pedidos únicos", "Unknown": "Desconhecido", - "Upload": "Enviar", + "Upload": "Carregar", "UsePlusMinusIconsDocumentation": "Use os Ãcones de mais e menos à esquerda para navegar.", "UserId": "ID do usuário", "Username": "Nome de Usuário", @@ -382,7 +391,7 @@ "VisitTypeExample": "Por exemplo, para selecionar todos os visitantes que voltaram para o site, incluindo aqueles que compraram algo em suas visitas anteriores, a requisição a API deve conter %s", "Warning": "Aviso", "WarningPhpVersionXIsTooOld": "A versão %s do PHP que você está usando atingiu seu limite de vida (EOL). Encorajamos fortemente a atualizar para a versão mais atual, podendo a utilização desta versão expô-lo a vulnerabilidades de segurança e bugs que foram corrigidos em versões mais recentes do PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik vai deixar de suportar esta versão PHP em %s. Atualize a sua versão do PHP, antes que seja tarde demais!", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik vai parar de suportar PHP %1$s na próxima versão principal. Atualize o seu PHP para, pelo menos, PHP %2$s, antes que seja tarde demais!", "WarningFileIntegrityNoManifest": "O check de integridade do arquivo não pode ser feita enquanto estiver faltando manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Se você estiver implantando Piwik a partir do repositório Git, esta mensagem é normal.", "WarningFileIntegrityNoMd5file": "O check de integridade do arquivo não pode ser completado enquanto estiver faltando a função md5_file().", diff --git a/lang/ru.json b/lang/ru.json index e11ba77b41740e63dce671fe5bf6cba3b2f6d3c0..18ba18e860e9a8c4a84b39cba55c01f151c99374 100644 --- a/lang/ru.json +++ b/lang/ru.json @@ -7,9 +7,11 @@ "Add": "Добавить", "AfterEntry": "поÑле захода Ñюда", "All": "Ð’Ñе", + "AllowPiwikArchivingToTriggerBrowser": "Ðрхив отчетов при проÑмотре в браузере", "AllWebsitesDashboard": "СтатиÑтика вÑех Ñайтов", "And": "и", "API": "API-функции", + "Apply": "Применить", "ArchivingInlineHelp": "Ð”Ð»Ñ Ñайтов Ñо Ñредней или выÑокой нагрузкой рекомендуетÑÑ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ архивирование данных при входе в веб-аналитику через браузер. ВмеÑто Ñтого лучше назначить cron-задачу, чтобы Piwik автоматичеÑки формировал отчеты каждый чаÑ.", "ArchivingTriggerDescription": "Ð”Ð»Ñ Ñайтов Ñ Ð²Ñ‹Ñокой нагрузкой наÑтоÑтельно рекомендуетÑÑ %sназначить cron-задачу%s, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚ формировать отчеты автоматичеÑки.", "AuthenticationMethodSmtp": "Метод аутентификации SMTP", @@ -97,6 +99,7 @@ "DateRange": "Временной период:", "DateRangeFrom": "От", "DateRangeFromTo": "С %s по %s", + "DateRangeInPeriodList": "диапазон дат:", "DateRangeTo": "До", "DaysHours": "%1$s дн. %2$s чаÑ", "DaysSinceFirstVisit": "Дней прошло Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð° первого поÑещениÑ", @@ -236,6 +239,7 @@ "NotDefined": "%s - не определено", "Note": "Заметка", "NotInstalled": "Ðе уÑтановлено", + "NotRecommended": "не рекомендуетÑÑ", "NotValid": "%s неверный", "NumberOfVisits": "КоличеÑтво поÑещений", "NUsers": "%s пользователей", @@ -291,6 +295,7 @@ "Quantity": "КоличеÑтво", "RangeReports": "Другие периоды", "ReadThisToLearnMore": "%1$sПрочтите Ñто, чтобы узнать больше.%2$s", + "Recommended": "РекомендуетÑÑ", "RecordsToPlot": "ЗапиÑи Ð´Ð»Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ Ð³Ñ€Ð°Ñ„Ð¸ÐºÐ°", "Refresh": "Обновить", "RefreshPage": "Обновить Ñтраницу", @@ -301,6 +306,8 @@ "ReportGeneratedFrom": "Ðтот отчет был Ñформирован Ñ Ð¸Ñпользованием данных: %s.", "ReportRatioTooltip": "'%1$s' предÑтавлÑет %2$s из %3$s %4$s Ñ %5$s.", "Reports": "Отчеты", + "ReportsContainingTodayWillBeProcessedAtMostEvery": "Ðрхив отчетов на каждые Ð¥ Ñекунд", + "RearchiveTimeIntervalOnlyForTodayReports": "Ðто влиÑет только на отчеты (или другие Диапазоны Дат Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ ÑегоднÑ)", "ReportsWillBeProcessedAtMostEveryHour": "Следовательно, отчеты обрабатываютÑÑ ÐºÐ°Ð¶Ð´Ñ‹Ð¹ чаÑ.", "RequestTimedOut": "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸ запроÑе данных к %s иÑтекло. ПожалуйÑта, попробуйте Ñнова.", "Required": "%s необходимо", @@ -338,10 +345,12 @@ "TagCloud": "Теги", "Tax": "Ðалог (комиÑÑиÑ)", "TimeAgo": "%s назад", + "TimeFormat": "Формат времени", "TimeOnPage": "ВремÑ, проведенное на Ñтранице", "Total": "Ð’Ñего", "TotalRatioTooltip": "Ðто %1$s из вÑех %2$s %3$s.", "TotalRevenue": "ÐžÐ±Ñ‰Ð°Ñ Ð¿Ñ€Ð¸Ð±Ñ‹Ð»ÑŒ", + "TotalVisitsPageviewsActionsRevenue": "(Ð’Ñего: %s визиты, %s проÑмотры Ñтраниц, %s дейÑтвиÑ, %s выручка)", "TransitionsRowActionTooltip": "ПоÑмотрите, что поÑетители делали до и поÑле проÑмотра Ñтой Ñтраницы", "TransitionsRowActionTooltipTitle": "Открыть переходы", "TranslatorName": "Ademaro, <a href=\"http:\/\/jokerintertactive.ru\/\">Joker Interactive<\/a>, <a href=\"http:\/\/codax.ru\/\">Важенин Ð˜Ð»ÑŒÑ (ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Codax)<\/a>, Nelde Maxim, Andrey, Vadim Nekhai", @@ -367,10 +376,11 @@ "Visitors": "ПоÑетители", "VisitsWith": "ПоÑÐµÑ‰ÐµÐ½Ð¸Ñ Ñ %s", "VisitorSettings": "ÐаÑтройки поÑетителей", + "VisitType": "Тип визита", "VisitTypeExample": "Ðапример, чтобы выбрать вÑех поÑетителей, которые вернулиÑть на Ñайт, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ñ‚ÐµÑ…, кто уже купил что-то в Ñвои предыдущие визиты, API-Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð±ÑƒÐ´ÐµÑ‚ Ñодержать: %s", "Warning": "Внимание", "WarningPhpVersionXIsTooOld": "ВерÑÐ¸Ñ PHP %s, которую вы иÑпользуете, завершила Ñвой жизненый цикл (EOL). ÐаÑтоÑтельно рекомендуем обновитьÑÑ Ð´Ð¾ текущей верÑии, Ñ‚. к. иÑпользование уÑтаревшей верÑии подвергает Ð²Ð°Ñ ÑƒÑзвимоÑÑ‚Ñм в безопаÑноÑти и ошибкам, которые уÑтранены в более Ñвежей верÑии PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik будет прекращать поддержку Ñтой верÑии PHP в %s. Обновите верÑию PHP пока не Ñлишком поздно!", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik прекратит поддержку PHP %1$s в Ñледующей верÑии. Обновите ваш PHP, по крайней мере, до верÑии PHP %2$s !", "WarningFileIntegrityNoManifest": "Проверка целоÑтноÑти не может быть проведена из-за отÑутÑÑ‚Ð²Ð¸Ñ manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "ЕÑли вы делаете деплой Piwik из Git, Ñто Ñообщение ÑвлÑетÑÑ Ð½Ð¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¼.", "WarningFileIntegrityNoMd5file": "Проверка целоÑтноÑти не может быть проведена из-за отÑутÑÑ‚Ð²Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ md5_file().", @@ -389,6 +399,7 @@ "YearsDays": "%1$s г. %2$s дн.", "Yes": "Да", "YouAreCurrentlyUsing": "Ð’Ñ‹ иÑпользуете верÑию Piwik %s.", + "YouAreViewingDemoShortMessage": "Ð’Ñ‹ проÑматриваете Piwik в демо режиме", "YouMustBeLoggedIn": "Ð’Ñ‹ должны зайти на Ñайт, чтобы получить доÑтуп к Ñтому функционалу.", "YourChangesHaveBeenSaved": "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñохранены." }, diff --git a/lang/sk.json b/lang/sk.json index 574122d94ce265c681b23ed783f267688b5bd44a..6593349188d48aa1893fe875e6bcc753d239a276 100644 --- a/lang/sk.json +++ b/lang/sk.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "12 hodinový Äas", + "24HourClock": "24 hodinový Äas", "AbandonedCarts": "Opustené koÅ¡Ãky", "AboutPiwikX": "O Piwiku %s", "Action": "Akcia", @@ -7,9 +9,11 @@ "Add": "PridaÅ¥", "AfterEntry": "po zadanà sem", "All": "VÅ¡etko", + "AllowPiwikArchivingToTriggerBrowser": "ArchivovaÅ¥ reporty, keÄ sú prezerané v prehliadaÄi", "AllWebsitesDashboard": "Nástenka pre vÅ¡etky weby", "And": "a", "API": "API", + "Apply": "PoužiÅ¥", "ArchivingInlineHelp": "Pre stredné až vysoké návÅ¡tevnosti webových stránok, sa odporúÄa vypnúť v Piwiku archiváciu spúšťanú prezeranÃm z prehliadaÄa. Namiesto toho odporúÄame nastaviÅ¥ cron úlohu na spracovanie Piwik reportov každú hodinu.", "ArchivingTriggerDescription": "OdporúÄa sa pre väÄÅ¡ie inÅ¡talácie Piwiku, musÃte %s nastaviÅ¥ cron %s aby spracovával reporty automaticky.", "AuthenticationMethodSmtp": "Metóda overovania pre SMTP", @@ -97,6 +101,7 @@ "DateRange": "ÄŒasové obdobie:", "DateRangeFrom": "Od", "DateRangeFromTo": "Od %s do %s", + "DateRangeInPeriodList": "dátumový rozsah", "DateRangeTo": "Do", "DaysHours": "%1$s dnà %2$s hodÃn", "DaysSinceFirstVisit": "Dnà od prvej návÅ¡tevy", @@ -306,6 +311,8 @@ "ReportGeneratedFrom": "Tento report bol vytvorený s použitÃm dát z %s.", "ReportRatioTooltip": "'%1$s' reprezentuje %2$s z %3$s %4$s s %5$s.", "Reports": "Správy", + "ReportsContainingTodayWillBeProcessedAtMostEvery": "ArchivovaÅ¥ reporty každých X sekúnd", + "RearchiveTimeIntervalOnlyForTodayReports": "Toto ovplyvnà len dneÅ¡né reporty (alebo akýkoľvek iný dátumový rozsah ktorý bude obsahovaÅ¥ dneÅ¡ný deň)", "ReportsWillBeProcessedAtMostEveryHour": "Reporty budú budú preto spracované nanajvýš každú hodinu.", "RequestTimedOut": "ÄŒas %sS vyprÅ¡al. ProsÃm skúste to znova.", "Required": "%s požadované", @@ -343,10 +350,12 @@ "TagCloud": "Oblak znaÄiek", "Tax": "Daň", "TimeAgo": "pred %s", + "TimeFormat": "ÄŒasový formát", "TimeOnPage": "Doba na stránke", "Total": "Celkom", "TotalRatioTooltip": "Toto je %1$s z celkového %2$s %3$s.", "TotalRevenue": "Celkový prÃjem", + "TotalVisitsPageviewsActionsRevenue": "(Celkom: %s návÅ¡tev, %s zobrazenÃ, %s akciÃ, tržby: %s)", "TransitionsRowActionTooltip": "Pozrite si Äo robili návÅ¡tevnÃci pred a po prezretà si tejto stránky.", "TransitionsRowActionTooltipTitle": "Otvorené zmeny", "TranslatorName": "Miroslav Habara, Zdenko Podobný, Juraj \"Lup0\" ViktorÃn, Ivanka", @@ -372,14 +381,16 @@ "Visitors": "NávÅ¡tevnÃci", "VisitsWith": "NávÅ¡tevy s %s", "VisitorSettings": "Nastavenia návÅ¡tevnÃkov", + "VisitType": "Typ návÅ¡tevy", "VisitTypeExample": "NaprÃklad: Pre výber vÅ¡etkých návÅ¡tevnÃkov, ktorà sa vrátili na web, vrátane tých, ktorà nieÄo nakúpili poÄas prechádzajúcej návÅ¡tevy by API požiadavka obsahovala %s", "Warning": "Varovanie", "WarningPhpVersionXIsTooOld": "PHP verzia %s, ktorú použÃvate, práve dospela do svojho konca (EOL). Nutne ju potrebujete aktualizovaÅ¥ na najnovÅ¡iu verziu , pretože použÃvanie tejto verzie Vás môže vystaviÅ¥ bezpeÄnostnému riziku a chybám, ktoré boli odstránené v novÅ¡Ãch verziách PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik prestane podporovaÅ¥ túto verziu PHP v %s. Aktualizujte PHP skôr ako bude prÃliÅ¡ neskoro!", + "WarningPiwikWillStopSupportingPHPVersion": "Piwik ukonÄà podporu PHP %1$s pri nasledujúcej hlavnej verziÃ. Aktualizujte svoje PHP aspoň na verziu %2$s skôr než bude neskoro!", "WarningFileIntegrityNoManifest": "Súbor kontrola integrity nemohla byÅ¥ vykonaná z dôvodu chýbajúcich manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Ak nasadzujete Piwik z Git-u, tak toto je normálna správa.", "WarningFileIntegrityNoMd5file": "Súbor kontrola integrity nemožno dokonÄiÅ¥ z dôvodu chýbajúcich md5_file () funkcie.", "WarningPasswordStored": "%sVarovanie:%s Toto heslo bude uložené v konfiguraÄnom súbore viditeľné pre vÅ¡etkých, ako prÃstup.", + "WarningDebugOnDemandEnabled": "Je povolený režim sledovaÄa (tracker) %s. Z bezpeÄnostných dôvodov by mal byÅ¥ povolený len veľmi krátky Äas. Na jeho ukonÄenie nastavte %s na %s v %s", "Website": "Web", "Weekly": "Týždenne", "WeeklyReport": "týždenne", @@ -394,6 +405,7 @@ "YearsDays": "%1$s rokov %2$s dnÃ", "Yes": "Ãno", "YouAreCurrentlyUsing": "Aktuálne použÃvate Piwik %s.", + "YouAreViewingDemoShortMessage": "Prezeráte si Piwik demo", "YouMustBeLoggedIn": "MusÃte byÅ¥ prihlásený pre prÃstup k tejto functionnality.", "YourChangesHaveBeenSaved": "VaÅ¡e zmeny boli uložené." }, diff --git a/lang/sl.json b/lang/sl.json index 1c2a4fc2590dba949b582699401cdd62d198b942..52d6a42ee08b1dde9dc154f358158562516ace98 100644 --- a/lang/sl.json +++ b/lang/sl.json @@ -1,5 +1,7 @@ { "General": { + "12HourClock": "12-urni prikaz Äasa", + "24HourClock": "24-urni prikaz Äasa", "AbandonedCarts": "OpuÅ¡Äeni VoziÄki", "AboutPiwikX": "O Piwik %s", "Action": "Dejanje", @@ -11,6 +13,7 @@ "AllWebsitesDashboard": "Vse nadzorne ploÅ¡Äe spletnih strani", "And": "in", "API": "API", + "Apply": "Uveljavi", "ArchivingInlineHelp": "Za srednje velike in velike spletne strani izklopite arhiviranje preko spletnega brskalnika. Namesto tega vam priporoÄamo, da nastavite \"cron job\" tako, da bodo poroÄila ustvarjena vsako uro.", "ArchivingTriggerDescription": "PriporoÄamo za veÄje namestitve. %sNastavite \"cron job\"%s za avtomatsko procesiranje.", "AuthenticationMethodSmtp": "Metoda potrditve verodostojnosti za SMTP", @@ -370,7 +373,6 @@ "VisitTypeExample": "Na primer, Äe želite zbrati vse obiskovalce, ki so se vrnili na spletno stran, vkljuÄno s tistimi, ki so v prejÅ¡njih obiskih kaj kupili, bi API zahteva vsebovala %s", "Warning": "Opozorilo", "WarningPhpVersionXIsTooOld": "RazliÄica PHP %s, ki jo uporabljate, ni veÄ podprta! PriporoÄamo Äim prejÅ¡njo nadgradnjo na zadnjo stabilno razliÄico, saj ste z nadaljnjo uporabo trenutne razliÄice lahko izpostavljeni varnostnim ranljivostim in napakam, ki so odpravljene v novejÅ¡ih razliÄicah PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Ta razliÄica PHP ne bo veÄ podprta v Piwiku %s. ÄŒim prej nadgradite PHP!", "WarningFileIntegrityNoManifest": "Pregleda integritete datotek ni bilo mogoÄe izvesti, saj manjka manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "ÄŒe nameÅ¡Äate Piwik iz Git repozitorija, je to sporoÄilo normalno.", "WarningFileIntegrityNoMd5file": "Ne morem preveriti integritete datoteke, ker manjka funkcija md5_file().", @@ -436,6 +438,7 @@ "NoWebsitesShort": "Ni spletnih mest", "PullDownToRefresh": "Potegnite navzdol za osvežitev...", "PossibleSslError": "Možna napaka SSL certifikata", + "PossibleSslErrorExplanation": "PriÅ¡lo je do napake. Vzrok zanjo je lahko neveljavno ali samopodpisano digitalno potrdilo: \"%s\". Prijava je vseeno mogoÄa, Äe prezrete SSL preverjanje, vendar je manj varna. SSL preverjanje lahko vkljuÄite\/izkljuÄite kadarkoli v nastavitvah vaÅ¡ega brskalnika.", "IgnoreSslError": "Prezri SSL napako", "RatingDontRemindMe": "Ne spomni me", "RatingNotNow": "Ne zdaj", diff --git a/lang/sq.json b/lang/sq.json index 80902db077d16ac467a4844005a0bdff62ef8945..acf1e9822eb4af2b6546e941a6d8897d7ff17dd4 100644 --- a/lang/sq.json +++ b/lang/sq.json @@ -379,7 +379,6 @@ "VisitTypeExample": "Për shembull, për përzgjedhjen e krejt vizitorëve që janë rikthyer te sajti, përfshi ata që kanë blerë diçka gjatë vizitash të mëparshme, kërkesa API do të duhej të përmbante %s", "Warning": "Sinjalizim", "WarningPhpVersionXIsTooOld": "Versioni PHP %s që po përdorni ka mbërritur në fund të ciklit të vet (EOL). Ftoheni me forcë ta përmirësoni me një version të tanishëm, ngaqë përdorimi i këtij versioni mund t’ju lërë zbuluar kundrejt cenimesh sigurie dhe të metash që janë ndrequr në versione më të rinj të PHP-së.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik-u do të reshtë mbulimin e këtij versioni të PHP-së në %s. Përmirësoni versionin e PHP-së tuaj, para se të jetë tepër vonë!", "WarningFileIntegrityNoManifest": "Kontrolli i pacenueshmërisë së kartelës s’u krye dot, për shkak të mungesës së manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Nëse po krijoni një instalim të Piwik-ut prej Git-i, ky mesazh është normal.", "WarningFileIntegrityNoMd5file": "Kontrolli i pacenueshmërisë së kartelës s’u plotësua dot, për shkak të mungesës së funksionit md5_file().", diff --git a/lang/sr.json b/lang/sr.json index f50bda84606c6bef71e3dd53491b9e2f857833a0..acea21bac6c9345125fdb229b71d8328e27d07d4 100644 --- a/lang/sr.json +++ b/lang/sr.json @@ -379,7 +379,6 @@ "VisitTypeExample": "Na primer, kako biste obeležili sve posetioce koji su se vratili na sajt, ukljuÄujući i one koji su već neÅ¡to kupili, API zahtev bi sadržao %s", "Warning": "Upozorenje", "WarningPhpVersionXIsTooOld": "PHP verzija %s koju koristite je zastarela. Molimo vas da hitno nadogradite PHP na najnoviju verziju jer ukoliko nastavite da koristite postojeću, izlažete se sigurnosnim rizicima i bagovima koji su već ispravljeni u novijim verzijama PHP-a.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik će prestati sa podrÅ¡kom ove PHP verzije %s. Nadogradite vaÅ¡ PHP pre nego Å¡to postane kasno!", "WarningFileIntegrityNoManifest": "Proveru integriteta datoteka nije moguće sprovesti zato Å¡to nedostaje datoteka manifest.inc.php.", "WarningFileIntegrityNoManifestDeployingFromGit": "Ukoliko podižete Piwik iz Git-a, ova poruka je sasvim prirodna.", "WarningFileIntegrityNoMd5file": "Proveru integriteta datoteka nije moguće okonÄati zato Å¡to nedostaje funkcija md5_file().", diff --git a/lang/sv.json b/lang/sv.json index 4c38a0691b1acabace884321729c236ebcff88d0..25326597ab0afa120a0b7a2a6180c3cd17d8d1ac 100644 --- a/lang/sv.json +++ b/lang/sv.json @@ -379,7 +379,6 @@ "VisitTypeExample": "Till exempel, för att markera alla besökare som har Ã¥tervänt till webbplatsen, inklusive de som har köpt nÃ¥got i sina tidigare besök, sÃ¥ skulle API-begäran innehÃ¥lla %s", "Warning": "Varning", "WarningPhpVersionXIsTooOld": "Den version av PHP du använder, %s, har nÃ¥tt End of Life (EOL). Du bör uppgradera till en aktuell version eftersom den nuvarande versionen kan innehÃ¥lla säkerhetsluckor och buggar som har fixats i en senare version av PHP.", - "WarningPiwikWillStopSupportingPHPVersion": "Piwik kommer inte längre stödja den här versionen av PHP om %s. Uppgradera din PHP-version innan det är för sent.", "WarningFileIntegrityNoManifest": "Filintegriteten kunde inte kontrolleras eftersom att filen manifest.inc.php saknades.", "WarningFileIntegrityNoManifestDeployingFromGit": "Om du utvecklar Piwik frÃ¥n Git, är det här meddelandet normalt.", "WarningFileIntegrityNoMd5file": "Filintegriteten kunde inte slutföras eftersom att funktionen md5_file() saknas.", diff --git a/lang/tr.json b/lang/tr.json index ff8ee3fbc21eb11ba82b7d046b67e1a5cb97143b..93fdace4ae2d11a36c4dcd9817a73cb1fd4d7591 100644 --- a/lang/tr.json +++ b/lang/tr.json @@ -10,6 +10,7 @@ "AllWebsitesDashboard": "Tüm Websitelerin Panosu", "And": "ve", "API": "API", + "Apply": "Uygula", "AuthenticationMethodSmtp": "SMTP için kimlik doÄŸrulama yöntemi", "AverageOrderValue": "Ortalama SipariÅŸ DeÄŸeri", "AveragePrice": "Ortalama Fiyat", @@ -258,9 +259,11 @@ "TagCloud": "Etiket bulutu", "Tax": "Vergi", "TimeAgo": "%s önce", + "TimeFormat": "Zaman formatı", "TimeOnPage": "Sayfadaki süre", "Total": "Toplam", "TotalRevenue": "Toplam Kazanç", + "TotalVisitsPageviewsActionsRevenue": "(Toplam: %s ziyaretçiler, %s sayfa görüntülemeler, %s aksiyonlar, %s geliri)", "TransitionsRowActionTooltipTitle": "Açık GeçiÅŸler", "TranslatorName": "Fabian Becker, Emre Yazici, Emre SaraçoÄŸlu, <a href=\"http:\/\/www.ugureskici.com\">UÄŸur Eskici<\/a>", "UniquePurchases": "Tekil Satın Alımlar", @@ -308,18 +311,23 @@ "AnonymousAccess": "İsimsiz eriÅŸim", "AnonymousTracking": "İsimsiz izleme", "ChooseHttpTimeout": "HTTP zamanaşımı deÄŸerini seçin", + "ChooseReport": "Rapor seçin", + "ConfirmRemoveAccount": "Bu hesabı kaldırmak istediÄŸinizden emin misiniz?", "DefaultReportDate": "Rapor tarihi", "HowtoDeleteAnAccount": "Bir hesabı silmek için uzun basın.", "HowtoDeleteAnAccountOniOS": "Bir hesabı silmek için saÄŸdan sola kaydırın.", "HttpTimeout": "HTTP Zamanaşımı", "LastUpdated": "Son Güncelleme: %s", + "LoadingReport": "Yükleniyor %s", "LoginUseHttps": "https kullan", "NavigationBack": "Geri", "NetworkError": "AÄŸ Hatası", + "NetworkErrorWithStatusCodeShort": "AÄŸ Hatası %s", "NetworkNotReachable": "AÄŸa eriÅŸilemiyor", "NoDataShort": "Veri Yok", "NoPiwikAccount": "Piwik Hesabınız yok mu?", "NoVisitorFound": "Hiç ziyaretçi bulunamadı", + "PullDownToRefresh": "Yenilemek için aÅŸağı çekin...", "PossibleSslError": "Muhtemel SSL sertifika hatası", "IgnoreSslError": "SSL Hatasını yoksay", "RatingDontRemindMe": "Tekrar hatırlatma", diff --git a/libs/PiwikTracker b/libs/PiwikTracker index 9a70fe37a1ce23cbd64b7cde00a6030e30942b75..ac3e26bb3e2c8a428ccbf6ca663c2ef37fa47a5e 160000 --- a/libs/PiwikTracker +++ b/libs/PiwikTracker @@ -1 +1 @@ -Subproject commit 9a70fe37a1ce23cbd64b7cde00a6030e30942b75 +Subproject commit ac3e26bb3e2c8a428ccbf6ca663c2ef37fa47a5e diff --git a/misc/log-analytics b/misc/log-analytics index 11957e29646d348ae8ab238ef84cbe23d728cef6..aa600c9a20049db05443c1ebd69f681908702479 160000 --- a/misc/log-analytics +++ b/misc/log-analytics @@ -1 +1 @@ -Subproject commit 11957e29646d348ae8ab238ef84cbe23d728cef6 +Subproject commit aa600c9a20049db05443c1ebd69f681908702479 diff --git a/piwik.js b/piwik.js index dc2a967e7ebd781390c953527a4deeeca7220e17..e16b81c991592e1d11688ac10cd8a59d36f61bbc 100644 --- a/piwik.js +++ b/piwik.js @@ -8,7 +8,7 @@ * @license http://piwik.org/free-software/bsd/ BSD-3 Clause (also in js/LICENSE.txt) * @license magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt BSD-3-Clause */ -if(typeof JSON2!=="object"&&window.JSON){JSON2=window.JSON}else{(function(){var a={}; +if(typeof JSON2!=="object"&&typeof window.JSON==="object"&&window.JSON.stringify&&window.JSON.parse){JSON2=window.JSON}else{(function(){var a={}; /*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ (function(){var c=typeof define==="function"&&define.amd;var e={"function":true,object:true};var h=e[typeof a]&&a&&!a.nodeType&&a;var i=e[typeof window]&&window||this,b=h&&e[typeof module]&&module&&!module.nodeType&&typeof global=="object"&&global;if(b&&(b.global===b||b.window===b||b.self===b)){i=b}function j(ab,V){ab||(ab=i.Object());V||(V=i.Object());var K=ab.Number||i.Number,R=ab.String||i.String,x=ab.Object||i.Object,S=ab.Date||i.Date,T=ab.SyntaxError||i.SyntaxError,aa=ab.TypeError||i.TypeError,J=ab.Math||i.Math,Y=ab.JSON||i.JSON; if(typeof Y=="object"&&Y){V.stringify=Y.stringify;V.parse=Y.parse}var n=x.prototype,u=n.toString,r,m,L;var B=new S(-3509827334573292);try{B=B.getUTCFullYear()==-109252&&B.getUTCMonth()===0&&B.getUTCDate()===1&&B.getUTCHours()==10&&B.getUTCMinutes()==37&&B.getUTCSeconds()==6&&B.getUTCMilliseconds()==708}catch(v){}function o(ac){if(o[ac]!==L){return o[ac]}var ad;if(ac=="bug-string-char-index"){ad="a"[0]!="a"}else{if(ac=="json"){ad=o("json-stringify")&&o("json-parse")}else{var ak,ah='{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';if(ac=="json-stringify"){var ai=V.stringify,aj=typeof ai=="function"&&B;if(aj){(ak=function(){return 1}).toJSON=ak;try{aj=ai(0)==="0"&&ai(new K())==="0"&&ai(new R())=='""'&&ai(u)===L&&ai(L)===L&&ai()===L&&ai(ak)==="1"&&ai([ak])=="[1]"&&ai([L])=="[null]"&&ai(null)=="null"&&ai([L,u,null])=="[null,null,null]"&&ai({a:[ak,true,false,null,"\x00\b\n\f\r\t"]})==ah&&ai(null,ak)==="1"&&ai([1,2],null,1)=="[\n 1,\n 2\n]"&&ai(new S(-8640000000000000))=='"-271821-04-20T00:00:00.000Z"'&&ai(new S(8640000000000000))=='"+275760-09-13T00:00:00.000Z"'&&ai(new S(-62198755200000))=='"-000001-01-01T00:00:00.000Z"'&&ai(new S(-1))=='"1969-12-31T23:59:59.999Z"' @@ -18,46 +18,49 @@ var I="000000";var t=function(ac,ad){return(I+(ad||0)).slice(-ac)};var z="\\u00" }else{at=null}}else{if(typeof at.toJSON=="function"&&((ae!=N&&ae!=O&&ae!=E)||r.call(at,"toJSON"))){at=at.toJSON(ai)}}}if(ag){at=ag.call(aA,ai,at)}if(at===null){return"null"}ae=u.call(at);if(ae==A){return""+at}else{if(ae==N){return at>-1/0&&at<1/0?""+at:"null"}else{if(ae==O){return C(""+at)}}}if(typeof at=="object"){for(af=aj.length;af--;){if(aj[af]===at){throw aa()}}aj.push(at);ar=[];av=ac;ac+=ax;if(ae==E){for(ah=0,af=at.length;ah<af;ah++){ad=p(ah,at,ag,al,ax,ac,aj);ar.push(ad===L?"null":ad)}ao=ar.length?(ax?"[\n"+ac+ar.join(",\n"+ac)+"\n"+av+"]":("["+ar.join(",")+"]")):"[]"}else{m(al||at,function(aC){var aB=p(aC,at,ag,al,ax,ac,aj);if(aB!==L){ar.push(C(aC)+":"+(ax?" ":"")+aB)}});ao=ar.length?(ax?"{\n"+ac+ar.join(",\n"+ac)+"\n"+av+"}":("{"+ar.join(",")+"}")):"{}"}aj.pop();return ao}};V.stringify=function(ac,ae,af){var ad,al,aj,ai;if(e[typeof ae]&&ae){if((ai=u.call(ae))==U){al=ae}else{if(ai==E){aj={};for(var ah=0,ag=ae.length,ak;ah<ag;ak=ae[ah++],((ai=u.call(ak)),ai==O||ai==N)&&(aj[ak]=1)){}}}}if(af){if((ai=u.call(af))==N){if((af-=af%1)>0){for(ad="",af>10&&(af=10); ad.length<af;ad+=" "){}}}else{if(ai==O){ad=af.length<=10?af:af.slice(0,10)}}}return p("",(ak={},ak[""]=ac,ak),al,aj,ad,"",[])}}if(!o("json-parse")){var M=R.fromCharCode;var l={92:"\\",34:'"',47:"/",98:"\b",116:"\t",110:"\n",102:"\f",114:"\r"};var G,X;var H=function(){G=X=null;throw T()};var y=function(){var ah=X,af=ah.length,ag,ae,ac,ai,ad;while(G<af){ad=ah.charCodeAt(G);switch(ad){case 9:case 10:case 13:case 32:G++;break;case 123:case 125:case 91:case 93:case 58:case 44:ag=F?ah.charAt(G):ah[G];G++;return ag;case 34:for(ag="@",G++;G<af;){ad=ah.charCodeAt(G);if(ad<32){H()}else{if(ad==92){ad=ah.charCodeAt(++G);switch(ad){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:ag+=l[ad];G++;break;case 117:ae=++G;for(ac=G+4;G<ac;G++){ad=ah.charCodeAt(G);if(!(ad>=48&&ad<=57||ad>=97&&ad<=102||ad>=65&&ad<=70)){H()}}ag+=M("0x"+ah.slice(ae,G));break;default:H()}}else{if(ad==34){break}ad=ah.charCodeAt(G);ae=G;while(ad>=32&&ad!=92&&ad!=34){ad=ah.charCodeAt(++G)}ag+=ah.slice(ae,G)}}}if(ah.charCodeAt(G)==34){G++; return ag}H();default:ae=G;if(ad==45){ai=true;ad=ah.charCodeAt(++G)}if(ad>=48&&ad<=57){if(ad==48&&((ad=ah.charCodeAt(G+1)),ad>=48&&ad<=57)){H()}ai=false;for(;G<af&&((ad=ah.charCodeAt(G)),ad>=48&&ad<=57);G++){}if(ah.charCodeAt(G)==46){ac=++G;for(;ac<af&&((ad=ah.charCodeAt(ac)),ad>=48&&ad<=57);ac++){}if(ac==G){H()}G=ac}ad=ah.charCodeAt(G);if(ad==101||ad==69){ad=ah.charCodeAt(++G);if(ad==43||ad==45){G++}for(ac=G;ac<af&&((ad=ah.charCodeAt(ac)),ad>=48&&ad<=57);ac++){}if(ac==G){H()}G=ac}return +ah.slice(ae,G)}if(ai){H()}if(ah.slice(G,G+4)=="true"){G+=4;return true}else{if(ah.slice(G,G+5)=="false"){G+=5;return false}else{if(ah.slice(G,G+4)=="null"){G+=4;return null}}}H()}}return"$"};var W=function(ad){var ac,ae;if(ad=="$"){H()}if(typeof ad=="string"){if((F?ad.charAt(0):ad[0])=="@"){return ad.slice(1)}if(ad=="["){ac=[];for(;;ae||(ae=true)){ad=y();if(ad=="]"){break}if(ae){if(ad==","){ad=y();if(ad=="]"){H()}}else{H()}}if(ad==","){H()}ac.push(W(ad))}return ac}else{if(ad=="{"){ac={};for(;;ae||(ae=true)){ad=y(); -if(ad=="}"){break}if(ae){if(ad==","){ad=y();if(ad=="}"){H()}}else{H()}}if(ad==","||typeof ad!="string"||(F?ad.charAt(0):ad[0])!="@"||y()!=":"){H()}ac[ad.slice(1)]=W(y())}return ac}}H()}return ad};var P=function(ae,ad,af){var ac=w(ae,ad,af);if(ac===L){delete ae[ad]}else{ae[ad]=ac}};var w=function(af,ae,ag){var ad=af[ae],ac;if(typeof ad=="object"&&ad){if(u.call(ad)==E){for(ac=ad.length;ac--;){P(ad,ac,ag)}}else{m(ad,function(ah){P(ad,ah,ag)})}}return ag.call(af,ae,ad)};V.parse=function(ae,af){var ac,ad;G=0;X=""+ae;ac=W(y());if(y()!="$"){H()}G=X=null;return af&&u.call(af)==U?w((ad={},ad[""]=ac,ad),"",af):ac}}}V.runInContext=j;return V}if(h&&!c){j(i,h)}else{var f=i.JSON,k=i.JSON3,d=false;var g=j(i,(i.JSON3={noConflict:function(){if(!d){d=true;i.JSON=f;i.JSON3=k;f=k=null}return g}}));i.JSON={parse:g.parse,stringify:g.stringify}}if(c){define(function(){return g})}}).call(this);JSON2=a})()}if(typeof _paq!=="object"){_paq=[]}if(typeof Piwik!=="object"){Piwik=(function(){var k,a={},v=document,e=navigator,L=screen,H=window,f=H.performance||H.mozPerformance||H.msPerformance||H.webkitPerformance,q=false,F=[],m=H.encodeURIComponent,G=H.decodeURIComponent,h=unescape,M,u,d; -function j(X){try{return G(X)}catch(Y){return unescape(X)}}function x(Y){var X=typeof Y;return X!=="undefined"}function r(X){return typeof X==="function"}function K(X){return typeof X==="object"}function o(X){return typeof X==="string"||X instanceof String}function S(){var X,Z,Y;for(X=0;X<arguments.length;X+=1){Y=arguments[X];Z=Y.shift();if(o(Z)){M[Z].apply(M,Y)}else{Z.apply(M,Y)}}}function W(aa,Z,Y,X){if(aa.addEventListener){aa.addEventListener(Z,Y,X);return true}if(aa.attachEvent){return aa.attachEvent("on"+Z,Y)}aa["on"+Z]=Y}function P(Y,ab){var X="",aa,Z;for(aa in a){if(Object.prototype.hasOwnProperty.call(a,aa)){Z=a[aa][Y];if(r(Z)){X+=Z(ab)}}}return X}function T(){var X;P("unload");if(k){do{X=new Date()}while(X.getTimeAlias()<k)}}function Q(){var X;if(!q){q=true;P("load");for(X=0;X<F.length;X++){F[X]()}}return true}function p(){var Y;if(v.addEventListener){W(v,"DOMContentLoaded",function X(){v.removeEventListener("DOMContentLoaded",X,false);Q()})}else{if(v.attachEvent){v.attachEvent("onreadystatechange",function X(){if(v.readyState==="complete"){v.detachEvent("onreadystatechange",X); -Q()}});if(v.documentElement.doScroll&&H===H.top){(function X(){if(!q){try{v.documentElement.doScroll("left")}catch(Z){setTimeout(X,0);return}Q()}}())}}}if((new RegExp("WebKit")).test(e.userAgent)){Y=setInterval(function(){if(q||/loaded|complete/.test(v.readyState)){clearInterval(Y);Q()}},10)}W(H,"load",Q,false)}function i(Z,Y){var X=v.createElement("script");X.type="text/javascript";X.src=Z;if(X.readyState){X.onreadystatechange=function(){var aa=this.readyState;if(aa==="loaded"||aa==="complete"){X.onreadystatechange=null;Y()}}}else{X.onload=Y}v.getElementsByTagName("head")[0].appendChild(X)}function y(){var X="";try{X=H.top.document.referrer}catch(Z){if(H.parent){try{X=H.parent.document.referrer}catch(Y){X=""}}}if(X===""){X=v.referrer}return X}function l(X){var Z=new RegExp("^([a-z]+):"),Y=Z.exec(X);return Y?Y[1]:null}function c(X){var Z=new RegExp("^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)"),Y=Z.exec(X);return Y?Y[1]:X}function J(Z,Y){var X="[\\?&#]"+Y+"=([^&#]*)";var ab=new RegExp(X); -var aa=ab.exec(Z);return aa?G(aa[1]):""}function t(X){return unescape(m(X))}function V(am){var Z=function(at,ar){return(at<<ar)|(at>>>(32-ar))},an=function(av){var at="",au,ar;for(au=7;au>=0;au--){ar=(av>>>(au*4))&15;at+=ar.toString(16)}return at},ac,ap,ao,Y=[],ag=1732584193,ae=4023233417,ad=2562383102,ab=271733878,aa=3285377520,al,ak,aj,ai,ah,aq,X,af=[];am=t(am);X=am.length;for(ap=0;ap<X-3;ap+=4){ao=am.charCodeAt(ap)<<24|am.charCodeAt(ap+1)<<16|am.charCodeAt(ap+2)<<8|am.charCodeAt(ap+3);af.push(ao)}switch(X&3){case 0:ap=2147483648;break;case 1:ap=am.charCodeAt(X-1)<<24|8388608;break;case 2:ap=am.charCodeAt(X-2)<<24|am.charCodeAt(X-1)<<16|32768;break;case 3:ap=am.charCodeAt(X-3)<<24|am.charCodeAt(X-2)<<16|am.charCodeAt(X-1)<<8|128;break}af.push(ap);while((af.length&15)!==14){af.push(0)}af.push(X>>>29);af.push((X<<3)&4294967295);for(ac=0;ac<af.length;ac+=16){for(ap=0;ap<16;ap++){Y[ap]=af[ac+ap]}for(ap=16;ap<=79;ap++){Y[ap]=Z(Y[ap-3]^Y[ap-8]^Y[ap-14]^Y[ap-16],1)}al=ag;ak=ae;aj=ad;ai=ab;ah=aa; -for(ap=0;ap<=19;ap++){aq=(Z(al,5)+((ak&aj)|(~ak&ai))+ah+Y[ap]+1518500249)&4294967295;ah=ai;ai=aj;aj=Z(ak,30);ak=al;al=aq}for(ap=20;ap<=39;ap++){aq=(Z(al,5)+(ak^aj^ai)+ah+Y[ap]+1859775393)&4294967295;ah=ai;ai=aj;aj=Z(ak,30);ak=al;al=aq}for(ap=40;ap<=59;ap++){aq=(Z(al,5)+((ak&aj)|(ak&ai)|(aj&ai))+ah+Y[ap]+2400959708)&4294967295;ah=ai;ai=aj;aj=Z(ak,30);ak=al;al=aq}for(ap=60;ap<=79;ap++){aq=(Z(al,5)+(ak^aj^ai)+ah+Y[ap]+3395469782)&4294967295;ah=ai;ai=aj;aj=Z(ak,30);ak=al;al=aq}ag=(ag+al)&4294967295;ae=(ae+ak)&4294967295;ad=(ad+aj)&4294967295;ab=(ab+ai)&4294967295;aa=(aa+ah)&4294967295}aq=an(ag)+an(ae)+an(ad)+an(ab)+an(aa);return aq.toLowerCase()}function O(Z,X,Y){if(Z==="translate.googleusercontent.com"){if(Y===""){Y=X}X=J(X,"u");Z=c(X)}else{if(Z==="cc.bingj.com"||Z==="webcache.googleusercontent.com"||Z.slice(0,5)==="74.6."){X=v.links[0].href;Z=c(X)}}return[Z,X,Y]}function z(Y){var X=Y.length;if(Y.charAt(--X)==="."){Y=Y.slice(0,X)}if(Y.slice(0,2)==="*."){Y=Y.slice(1)}return Y}function U(Y){Y=Y&&Y.text?Y.text:Y; -if(!o(Y)){var X=v.getElementsByTagName("title");if(X&&x(X[0])){Y=X[0].text}}return Y}function D(X){if(!X){return[]}if(!x(X.children)&&x(X.childNodes)){return X.children}if(x(X.children)){return X.children}return[]}function I(Y,X){if(!Y||!X){return false}if(Y.contains){return Y.contains(X)}if(Y===X){return true}if(Y.compareDocumentPosition){return !!(Y.compareDocumentPosition(X)&16)}return false}function A(Z,aa){if(Z&&Z.indexOf){return Z.indexOf(aa)}if(!x(Z)||Z===null){return -1}if(!Z.length){return -1}var X=Z.length;if(X===0){return -1}var Y=0;while(Y<X){if(Z[Y]===aa){return Y}Y++}return -1}function g(Z){if(!Z){return false}function X(ab,ac){if(H.getComputedStyle){return v.defaultView.getComputedStyle(ab,null)[ac]}if(ab.currentStyle){return ab.currentStyle[ac]}}function aa(ab){ab=ab.parentNode;while(ab){if(ab===v){return true}ab=ab.parentNode}return false}function Y(ad,aj,ab,ag,ae,ah,af){var ac=ad.parentNode,ai=1;if(!aa(ad)){return false}if(9===ac.nodeType){return true}if("0"===X(ad,"opacity")||"none"===X(ad,"display")||"hidden"===X(ad,"visibility")){return false -}if(!x(aj)||!x(ab)||!x(ag)||!x(ae)||!x(ah)||!x(af)){aj=ad.offsetTop;ae=ad.offsetLeft;ag=aj+ad.offsetHeight;ab=ae+ad.offsetWidth;ah=ad.offsetWidth;af=ad.offsetHeight}if(Z===ad&&(0===af||0===ah)&&"hidden"===X(ad,"overflow")){return false}if(ac){if(("hidden"===X(ac,"overflow")||"scroll"===X(ac,"overflow"))){if(ae+ai>ac.offsetWidth+ac.scrollLeft||ae+ah-ai<ac.scrollLeft||aj+ai>ac.offsetHeight+ac.scrollTop||aj+af-ai<ac.scrollTop){return false}}if(ad.offsetParent===ac){ae+=ac.offsetLeft;aj+=ac.offsetTop}return Y(ac,aj,ab,ag,ae,ah,af)}return true}return Y(Z)}var R={htmlCollectionToArray:function(Z){var X=[],Y;if(!Z||!Z.length){return X}for(Y=0;Y<Z.length;Y++){X.push(Z[Y])}return X},find:function(X){if(!document.querySelectorAll||!X){return[]}var Y=document.querySelectorAll(X);return this.htmlCollectionToArray(Y)},findMultiple:function(Z){if(!Z||!Z.length){return[]}var Y,aa;var X=[];for(Y=0;Y<Z.length;Y++){aa=this.find(Z[Y]);X=X.concat(aa)}X=this.makeNodesUnique(X);return X},findNodesByTagName:function(Y,X){if(!Y||!X||!Y.getElementsByTagName){return[] -}var Z=Y.getElementsByTagName(X);return this.htmlCollectionToArray(Z)},makeNodesUnique:function(X){var ac=[].concat(X);X.sort(function(ae,ad){if(ae===ad){return 0}var ag=A(ac,ae);var af=A(ac,ad);if(ag===af){return 0}return ag>af?-1:1});if(X.length<=1){return X}var Y=0;var aa=0;var ab=[];var Z;Z=X[Y++];while(Z){if(Z===X[Y]){aa=ab.push(Y)}Z=X[Y++]||null}while(aa--){X.splice(ab[aa],1)}return X},getAttributeValueFromNode:function(ab,Z){if(!this.hasNodeAttribute(ab,Z)){return}if(ab&&ab.getAttribute){return ab.getAttribute(Z)}if(!ab||!ab.attributes){return}var aa=(typeof ab.attributes[Z]);if("undefined"===aa){return}if(ab.attributes[Z].value){return ab.attributes[Z].value}if(ab.attributes[Z].nodeValue){return ab.attributes[Z].nodeValue}var Y;var X=ab.attributes;if(!X){return}for(Y=0;Y<X.length;Y++){if(X[Y].nodeName===Z){return X[Y].nodeValue}}return null},hasNodeAttributeWithValue:function(Y,X){var Z=this.getAttributeValueFromNode(Y,X);return !!Z},hasNodeAttribute:function(Z,X){if(Z&&Z.hasAttribute){return Z.hasAttribute(X) -}if(Z&&Z.attributes){var Y=(typeof Z.attributes[X]);return"undefined"!==Y}return false},hasNodeCssClass:function(Z,X){if(Z&&X&&Z.className){var Y=typeof Z.className==="string"?Z.className.split(" "):[];if(-1!==A(Y,X)){return true}}return false},findNodesHavingAttribute:function(ab,Z,X){if(!X){X=[]}if(!ab||!Z){return X}var aa=D(ab);if(!aa||!aa.length){return X}var Y,ac;for(Y=0;Y<aa.length;Y++){ac=aa[Y];if(this.hasNodeAttribute(ac,Z)){X.push(ac)}X=this.findNodesHavingAttribute(ac,Z,X)}return X},findFirstNodeHavingAttribute:function(Z,Y){if(!Z||!Y){return}if(this.hasNodeAttribute(Z,Y)){return Z}var X=this.findNodesHavingAttribute(Z,Y);if(X&&X.length){return X[0]}},findFirstNodeHavingAttributeWithValue:function(aa,Z){if(!aa||!Z){return}if(this.hasNodeAttributeWithValue(aa,Z)){return aa}var X=this.findNodesHavingAttribute(aa,Z);if(!X||!X.length){return}var Y;for(Y=0;Y<X.length;Y++){if(this.getAttributeValueFromNode(X[Y],Z)){return X[Y]}}},findNodesHavingCssClass:function(ab,aa,X){if(!X){X=[] -}if(!ab||!aa){return X}if(ab.getElementsByClassName){var ac=ab.getElementsByClassName(aa);return this.htmlCollectionToArray(ac)}var Z=D(ab);if(!Z||!Z.length){return[]}var Y,ad;for(Y=0;Y<Z.length;Y++){ad=Z[Y];if(this.hasNodeCssClass(ad,aa)){X.push(ad)}X=this.findNodesHavingCssClass(ad,aa,X)}return X},findFirstNodeHavingClass:function(Z,Y){if(!Z||!Y){return}if(this.hasNodeCssClass(Z,Y)){return Z}var X=this.findNodesHavingCssClass(Z,Y);if(X&&X.length){return X[0]}},isLinkElement:function(Y){if(!Y){return false}var X=String(Y.nodeName).toLowerCase();var aa=["a","area"];var Z=A(aa,X);return Z!==-1},setAnyAttribute:function(Y,X,Z){if(!Y||!X){return}if(Y.setAttribute){Y.setAttribute(X,Z)}else{Y[X]=Z}}};var n={CONTENT_ATTR:"data-track-content",CONTENT_CLASS:"piwikTrackContent",CONTENT_NAME_ATTR:"data-content-name",CONTENT_PIECE_ATTR:"data-content-piece",CONTENT_PIECE_CLASS:"piwikContentPiece",CONTENT_TARGET_ATTR:"data-content-target",CONTENT_TARGET_CLASS:"piwikContentTarget",CONTENT_IGNOREINTERACTION_ATTR:"data-content-ignoreinteraction",CONTENT_IGNOREINTERACTION_CLASS:"piwikContentIgnoreInteraction",location:undefined,findContentNodes:function(){var Y="."+this.CONTENT_CLASS; -var X="["+this.CONTENT_ATTR+"]";var Z=R.findMultiple([Y,X]);return Z},findContentNodesWithinNode:function(aa){if(!aa){return[]}var Y=R.findNodesHavingCssClass(aa,this.CONTENT_CLASS);var X=R.findNodesHavingAttribute(aa,this.CONTENT_ATTR);if(X&&X.length){var Z;for(Z=0;Z<X.length;Z++){Y.push(X[Z])}}if(R.hasNodeAttribute(aa,this.CONTENT_ATTR)){Y.push(aa)}else{if(R.hasNodeCssClass(aa,this.CONTENT_CLASS)){Y.push(aa)}}Y=R.makeNodesUnique(Y);return Y},findParentContentNode:function(Y){if(!Y){return}var Z=Y;var X=0;while(Z&&Z!==v&&Z.parentNode){if(R.hasNodeAttribute(Z,this.CONTENT_ATTR)){return Z}if(R.hasNodeCssClass(Z,this.CONTENT_CLASS)){return Z}Z=Z.parentNode;if(X>1000){break}X++}},findPieceNode:function(Y){var X;X=R.findFirstNodeHavingAttribute(Y,this.CONTENT_PIECE_ATTR);if(!X){X=R.findFirstNodeHavingClass(Y,this.CONTENT_PIECE_CLASS)}if(X){return X}return Y},findTargetNodeNoDefault:function(X){if(!X){return}var Y=R.findFirstNodeHavingAttributeWithValue(X,this.CONTENT_TARGET_ATTR);if(Y){return Y -}Y=R.findFirstNodeHavingAttribute(X,this.CONTENT_TARGET_ATTR);if(Y){return Y}Y=R.findFirstNodeHavingClass(X,this.CONTENT_TARGET_CLASS);if(Y){return Y}},findTargetNode:function(X){var Y=this.findTargetNodeNoDefault(X);if(Y){return Y}return X},findContentName:function(Y){if(!Y){return}var ab=R.findFirstNodeHavingAttributeWithValue(Y,this.CONTENT_NAME_ATTR);if(ab){return R.getAttributeValueFromNode(ab,this.CONTENT_NAME_ATTR)}var X=this.findContentPiece(Y);if(X){return this.removeDomainIfIsInLink(X)}if(R.hasNodeAttributeWithValue(Y,"title")){return R.getAttributeValueFromNode(Y,"title")}var Z=this.findPieceNode(Y);if(R.hasNodeAttributeWithValue(Z,"title")){return R.getAttributeValueFromNode(Z,"title")}var aa=this.findTargetNode(Y);if(R.hasNodeAttributeWithValue(aa,"title")){return R.getAttributeValueFromNode(aa,"title")}},findContentPiece:function(Y){if(!Y){return}var aa=R.findFirstNodeHavingAttributeWithValue(Y,this.CONTENT_PIECE_ATTR);if(aa){return R.getAttributeValueFromNode(aa,this.CONTENT_PIECE_ATTR) -}var X=this.findPieceNode(Y);var Z=this.findMediaUrlInNode(X);if(Z){return this.toAbsoluteUrl(Z)}},findContentTarget:function(Z){if(!Z){return}var aa=this.findTargetNode(Z);if(R.hasNodeAttributeWithValue(aa,this.CONTENT_TARGET_ATTR)){return R.getAttributeValueFromNode(aa,this.CONTENT_TARGET_ATTR)}var Y;if(R.hasNodeAttributeWithValue(aa,"href")){Y=R.getAttributeValueFromNode(aa,"href");return this.toAbsoluteUrl(Y)}var X=this.findPieceNode(Z);if(R.hasNodeAttributeWithValue(X,"href")){Y=R.getAttributeValueFromNode(X,"href");return this.toAbsoluteUrl(Y)}},isSameDomain:function(X){if(!X||!X.indexOf){return false}if(0===X.indexOf(this.getLocation().origin)){return true}var Y=X.indexOf(this.getLocation().host);if(8>=Y&&0<=Y){return true}return false},removeDomainIfIsInLink:function(Z){var Y="^https?://[^/]+";var X="^.*//[^/]+";if(Z&&Z.search&&-1!==Z.search(new RegExp(Y))&&this.isSameDomain(Z)){Z=Z.replace(new RegExp(X),"");if(!Z){Z="/"}}return Z},findMediaUrlInNode:function(ab){if(!ab){return}var Z=["img","embed","video","audio"]; -var X=ab.nodeName.toLowerCase();if(-1!==A(Z,X)&&R.findFirstNodeHavingAttributeWithValue(ab,"src")){var aa=R.findFirstNodeHavingAttributeWithValue(ab,"src");return R.getAttributeValueFromNode(aa,"src")}if(X==="object"&&R.hasNodeAttributeWithValue(ab,"data")){return R.getAttributeValueFromNode(ab,"data")}if(X==="object"){var ac=R.findNodesByTagName(ab,"param");if(ac&&ac.length){var Y;for(Y=0;Y<ac.length;Y++){if("movie"===R.getAttributeValueFromNode(ac[Y],"name")&&R.hasNodeAttributeWithValue(ac[Y],"value")){return R.getAttributeValueFromNode(ac[Y],"value")}}}var ad=R.findNodesByTagName(ab,"embed");if(ad&&ad.length){return this.findMediaUrlInNode(ad[0])}}},trim:function(X){if(X&&String(X)===X){return X.replace(/^\s+|\s+$/g,"")}return X},isOrWasNodeInViewport:function(ac){if(!ac||!ac.getBoundingClientRect||ac.nodeType!==1){return true}var ab=ac.getBoundingClientRect();var aa=v.documentElement||{};var Z=ab.top<0;if(Z&&ac.offsetTop){Z=(ac.offsetTop+ab.height)>0}var Y=aa.clientWidth;if(H.innerWidth&&Y>H.innerWidth){Y=H.innerWidth -}var X=aa.clientHeight;if(H.innerHeight&&X>H.innerHeight){X=H.innerHeight}return((ab.bottom>0||Z)&&ab.right>0&&ab.left<Y&&((ab.top<X)||Z))},isNodeVisible:function(Y){var X=g(Y);var Z=this.isOrWasNodeInViewport(Y);return X&&Z},buildInteractionRequestParams:function(X,Y,Z,aa){var ab="";if(X){ab+="c_i="+m(X)}if(Y){if(ab){ab+="&"}ab+="c_n="+m(Y)}if(Z){if(ab){ab+="&"}ab+="c_p="+m(Z)}if(aa){if(ab){ab+="&"}ab+="c_t="+m(aa)}return ab},buildImpressionRequestParams:function(X,Y,Z){var aa="c_n="+m(X)+"&c_p="+m(Y);if(Z){aa+="&c_t="+m(Z)}return aa},buildContentBlock:function(Z){if(!Z){return}var X=this.findContentName(Z);var Y=this.findContentPiece(Z);var aa=this.findContentTarget(Z);X=this.trim(X);Y=this.trim(Y);aa=this.trim(aa);return{name:X||"Unknown",piece:Y||"Unknown",target:aa||""}},collectContent:function(aa){if(!aa||!aa.length){return[]}var Z=[];var X,Y;for(X=0;X<aa.length;X++){Y=this.buildContentBlock(aa[X]);if(x(Y)){Z.push(Y)}}return Z},setLocation:function(X){this.location=X},getLocation:function(){var X=this.location||H.location; -if(!X.origin){X.origin=X.protocol+"//"+X.hostname+(X.port?":"+X.port:"")}return X},toAbsoluteUrl:function(Y){if((!Y||String(Y)!==Y)&&Y!==""){return Y}if(""===Y){return this.getLocation().href}if(Y.search(/^\/\//)!==-1){return this.getLocation().protocol+Y}if(Y.search(/:\/\//)!==-1){return Y}if(0===Y.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+Y}if(0===Y.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+Y}if(0===Y.search("^[a-zA-Z]{2,11}:")){return Y}if(Y.search(/^\//)!==-1){return this.getLocation().origin+Y}var X="(.*/)";var Z=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(X))[0];return Z+Y},isUrlToCurrentDomain:function(Y){var Z=this.toAbsoluteUrl(Y);if(!Z){return false}var X=this.getLocation().origin;if(X===Z){return true}if(0===String(Z).indexOf(X)){if(":"===String(Z).substr(X.length,1)){return false}return true}return false},setHrefAttribute:function(Y,X){if(!Y||!X){return}R.setAnyAttribute(Y,"href",X)},shouldIgnoreInteraction:function(Z){var Y=R.hasNodeAttribute(Z,this.CONTENT_IGNOREINTERACTION_ATTR); -var X=R.hasNodeCssClass(Z,this.CONTENT_IGNOREINTERACTION_CLASS);return Y||X}};function C(X,Y){if(Y){return Y}if(X.slice(-9)==="piwik.php"){X=X.slice(0,X.length-9)}return X}function B(ab){var X="Piwik_Overlay";var ae=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)$");var Z=ae.exec(v.referrer);if(Z){var aa=Z[1];if(aa!==String(ab)){return false}var ad=Z[2],Y=Z[3];H.name=X+"###"+ad+"###"+Y}var ac=H.name.split("###");return ac.length===3&&ac[0]===X}function N(Y,ad,aa){var ac=H.name.split("###"),ab=ac[1],X=ac[2],Z=C(Y,ad);i(Z+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(Z,aa,ab,X)})}function E(aJ,by){var ae=O(v.domain,H.location.href,y()),bY=z(ae[0]),cj=j(ae[1]),bG=j(ae[2]),cn=false,bC="GET",bE=bC,bj="application/x-www-form-urlencoded; charset=UTF-8",aP=bj,ab=aJ||"",az="",bA="",b5=by||"",aO="",a7="",bd,aX=v.title,aZ=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],bB=[bY],aj=[],bp=[],aH=[],bz=500,ak,b3,br,al,ao,a3=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],aU=["pk_kwd","piwik_kwd","utm_term"],ch="_pk_",ar,ci,ap=false,b9,a5,ba,ay=33955200000,aE=1800000,bh=15768000000,a6=true,aM=0,bc=false,ah=false,av,bq={},ac={},ca=200,bR={},b6={},ai=[],aB=false,bg=false,bK=false,b7=false,bN=false,bo=null,bb,bu,au,a2=V,bJ; -function bT(cw,ct,cs,cv,cr,cu){if(ap){return}var cq;if(cs){cq=new Date();cq.setTime(cq.getTime()+cs)}v.cookie=cw+"="+m(ct)+(cs?";expires="+cq.toGMTString():"")+";path="+(cv||"/")+(cr?";domain="+cr:"")+(cu?";secure":"")}function aw(cs){if(ap){return 0}var cq=new RegExp("(^|;)[ ]*"+cs+"=([^;]*)"),cr=cq.exec(v.cookie);return cr?G(cr[2]):0}function cd(cq){var cr;if(al){cr=new RegExp("#.*");return cq.replace(cr,"")}return cq}function bX(cs,cq){var ct=l(cq),cr;if(ct){return cq}if(cq.slice(0,1)==="/"){return l(cs)+"://"+c(cs)+cq}cs=cd(cs);cr=cs.indexOf("?");if(cr>=0){cs=cs.slice(0,cr)}cr=cs.lastIndexOf("/");if(cr!==cs.length-1){cs=cs.slice(0,cr+1)}return cs+cq}function bD(ct){var cr,cq,cs;for(cr=0;cr<bB.length;cr++){cq=z(bB[cr].toLowerCase());if(ct===cq){return true}if(cq.slice(0,1)==="."){if(ct===cq.slice(1)){return true}cs=ct.length-cq.length;if((cs>0)&&(ct.slice(cs)===cq)){return true}}}return false}function cp(cq,cs){var cr=new Image(1,1);cr.onload=function(){u=0;if(typeof cs==="function"){cs() -}};cr.src=ab+(ab.indexOf("?")<0?"?":"&")+cq}function bU(cr,cu,cq){if(!x(cq)||null===cq){cq=true}try{var ct=H.XMLHttpRequest?new H.XMLHttpRequest():H.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;ct.open("POST",ab,true);ct.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)&&cq){cp(cr,cu)}else{if(typeof cu==="function"){cu()}}};ct.setRequestHeader("Content-Type",aP);ct.send(cr)}catch(cs){if(cq){cp(cr,cu)}}}function cc(cr){var cq=new Date();var cs=cq.getTime()+cr;if(!k||cs>k){k=cs}}function aC(cq){if(bb||!b3){return}bb=setTimeout(function cr(){bb=null;if(br()){return}var cs=new Date(),ct=b3-(cs.getTime()-bo);ct=Math.min(b3,ct);aC(ct)},cq||b3)}function be(){if(!bb){return}clearTimeout(bb);bb=null}function ax(){if(br()){return}aC()}function bm(){be()}function bF(){if(bN||!b3){return}bN=true;W(H,"focus",ax);W(H,"blur",bm);aC()}function aI(cu){var cr=new Date();var cq=cr.getTime();bo=cq;if(bg&&cq<bg){var cs=bg-cq;setTimeout(cu,cs);cc(cs+50);bg+=50; -return}if(bg===false){var ct=800;bg=cq+ct}cu()}function a4(cr,cq,cs){if(!b9&&cr){aI(function(){if(bE==="POST"){bU(cr,cs)}else{cp(cr,cs)}cc(cq)})}if(!bN){bF()}else{aC()}}function bi(cq){if(b9){return false}return(cq&&cq.length)}function aq(cs,cq){if(!bi(cs)){return}var cr='{"requests":["?'+cs.join('","?')+'"]}';aI(function(){bU(cr,null,false);cc(cq)})}function bS(cq){return ch+cq+"."+b5+"."+bJ}function af(){if(ap){return"0"}if(!x(e.cookieEnabled)){var cq=bS("testcookie");bT(cq,"1");return aw(cq)==="1"?"1":"0"}return e.cookieEnabled?"1":"0"}function bv(){bJ=a2((ar||bY)+(ci||"/")).slice(0,4)}function at(){var cr=bS("cvar"),cq=aw(cr);if(cq.length){cq=JSON2.parse(cq);if(K(cq)){return cq}}return{}}function aa(){if(ah===false){ah=at()}}function cf(){return a2((e.userAgent||"")+(e.platform||"")+JSON2.stringify(b6)+(new Date()).getTime()+Math.random()).slice(0,16)}function Z(){var cs=new Date(),cq=Math.round(cs.getTime()/1000),cr=bS("id"),cv=aw(cr),cu,ct;if(cv){cu=cv.split(".");cu.unshift("0");if(a7.length){cu[1]=a7 -}return cu}if(a7.length){ct=a7}else{if("0"===af()){ct=""}else{ct=cf()}}cu=["1",ct,cq,0,cq,"",""];return cu}function bM(){var cx=Z(),ct=cx[0],cu=cx[1],cr=cx[2],cq=cx[3],cv=cx[4],cs=cx[5];if(!x(cx[6])){cx[6]=""}var cw=cx[6];return{newVisitor:ct,uuid:cu,createTs:cr,visitCount:cq,currentVisitTs:cv,lastVisitTs:cs,lastEcommerceOrderTs:cw}}function aQ(){var ct=new Date(),cr=ct.getTime(),cu=bM().createTs;var cq=parseInt(cu,10);var cs=(cq*1000)+ay-cr;return cs}function an(cq){if(!b5){return}var cs=new Date(),cr=Math.round(cs.getTime()/1000);if(!x(cq)){cq=bM()}var ct=cq.uuid+"."+cq.createTs+"."+cq.visitCount+"."+cr+"."+cq.lastVisitTs+"."+cq.lastEcommerceOrderTs;bT(bS("id"),ct,aQ(),ci,ar)}function Y(){var cq=aw(bS("ref"));if(cq.length){try{cq=JSON2.parse(cq);if(K(cq)){return cq}}catch(cr){}}return["","",0,""]}function b4(cs,cr,cq){bT(cs,"",-86400,cr,cq)}function bn(cr){var cq="testvalue";bT("test",cq,10000,null,cr);if(aw("test")===cq){b4("test",null,cr);return true}return false}function X(){var cs=ap; -ap=false;var cq=["id","ses","cvar","ref"];var cr,ct;for(cr=0;cr<cq.length;cr++){ct=bS(cq[cr]);if(0!==aw(ct)){b4(ct,ci,ar)}}ap=cs}function cm(cq){b5=cq;an()}function b2(cu){if(!cu||!K(cu)){return}var ct=[];var cs;for(cs in cu){if(Object.prototype.hasOwnProperty.call(cu,cs)){ct.push(cs)}}var cv={};ct.sort();var cq=ct.length;var cr;for(cr=0;cr<cq;cr++){cv[ct[cr]]=cu[ct[cr]]}return cv}function a9(){bT(bS("ses"),"*",aE,ci,ar)}function aY(cs,cL,cM,ct){var cK,cr=new Date(),cz=Math.round(cr.getTime()/1000),cw,cJ,cu=1024,cQ,cA,cH=ah,cv=bS("ses"),cF=bS("ref"),cC=bS("cvar"),cD=aw(cv),cI=Y(),cO=bd||cj,cx,cq;if(ap){X()}if(b9){return""}var cE=bM();if(!x(ct)){ct=""}var cB=v.characterSet||v.charset;if(!cB||cB.toLowerCase()==="utf-8"){cB=null}cx=cI[0];cq=cI[1];cw=cI[2];cJ=cI[3];if(!cD){var cN=aE/1000;if(!cE.lastVisitTs||(cz-cE.lastVisitTs)>cN){cE.visitCount++;cE.lastVisitTs=cE.currentVisitTs}if(!ba||!cx.length){for(cK in a3){if(Object.prototype.hasOwnProperty.call(a3,cK)){cx=J(cO,a3[cK]);if(cx.length){break -}}}for(cK in aU){if(Object.prototype.hasOwnProperty.call(aU,cK)){cq=J(cO,aU[cK]);if(cq.length){break}}}}cQ=c(bG);cA=cJ.length?c(cJ):"";if(cQ.length&&!bD(cQ)&&(!ba||!cA.length||bD(cA))){cJ=bG}if(cJ.length||cx.length){cw=cz;cI=[cx,cq,cw,cd(cJ.slice(0,cu))];bT(cF,JSON2.stringify(cI),bh,ci,ar)}}cs+="&idsite="+b5+"&rec=1&r="+String(Math.random()).slice(2,8)+"&h="+cr.getHours()+"&m="+cr.getMinutes()+"&s="+cr.getSeconds()+"&url="+m(cd(cO))+(bG.length?"&urlref="+m(cd(bG)):"")+((aO&&aO.length)?"&uid="+m(aO):"")+"&_id="+cE.uuid+"&_idts="+cE.createTs+"&_idvc="+cE.visitCount+"&_idn="+cE.newVisitor+(cx.length?"&_rcn="+m(cx):"")+(cq.length?"&_rck="+m(cq):"")+"&_refts="+cw+"&_viewts="+cE.lastVisitTs+(String(cE.lastEcommerceOrderTs).length?"&_ects="+cE.lastEcommerceOrderTs:"")+(String(cJ).length?"&_ref="+m(cd(cJ.slice(0,cu))):"")+(cB?"&cs="+m(cB):"")+"&send_image=0";for(cK in b6){if(Object.prototype.hasOwnProperty.call(b6,cK)){cs+="&"+cK+"="+b6[cK]}}if(cL){cs+="&data="+m(JSON2.stringify(cL))}else{if(ao){cs+="&data="+m(JSON2.stringify(ao)) -}}function cy(cR,cS){var cT=JSON2.stringify(cR);if(cT.length>2){return"&"+cS+"="+m(cT)}return""}var cP=b2(bq);var cG=b2(ac);cs+=cy(cP,"cvar");cs+=cy(cG,"e_cvar");if(ah){cs+=cy(ah,"_cvar");for(cK in cH){if(Object.prototype.hasOwnProperty.call(cH,cK)){if(ah[cK][0]===""||ah[cK][1]===""){delete ah[cK]}}}if(bc){bT(cC,JSON2.stringify(ah),aE,ci,ar)}}if(a6){if(aM){cs+=">_ms="+aM}else{if(f&&f.timing&&f.timing.requestStart&&f.timing.responseEnd){cs+=">_ms="+(f.timing.responseEnd-f.timing.requestStart)}}}cE.lastEcommerceOrderTs=x(ct)&&String(ct).length?ct:cE.lastEcommerceOrderTs;an(cE);a9();cs+=P(cM);if(bA.length){cs+="&"+bA}if(r(av)){cs=av(cs)}return cs}br=function bw(){var cq=new Date();if(bo+b3<=cq.getTime()){var cr=aY("ping=1",null,"ping");a4(cr,bz);return true}return false};function bW(ct,cs,cx,cu,cq,cA){var cv="idgoal=0",cw,cr=new Date(),cy=[],cz;if(String(ct).length){cv+="&ec_id="+m(ct);cw=Math.round(cr.getTime()/1000)}cv+="&revenue="+cs;if(String(cx).length){cv+="&ec_st="+cx}if(String(cu).length){cv+="&ec_tx="+cu -}if(String(cq).length){cv+="&ec_sh="+cq}if(String(cA).length){cv+="&ec_dt="+cA}if(bR){for(cz in bR){if(Object.prototype.hasOwnProperty.call(bR,cz)){if(!x(bR[cz][1])){bR[cz][1]=""}if(!x(bR[cz][2])){bR[cz][2]=""}if(!x(bR[cz][3])||String(bR[cz][3]).length===0){bR[cz][3]=0}if(!x(bR[cz][4])||String(bR[cz][4]).length===0){bR[cz][4]=1}cy.push(bR[cz])}}cv+="&ec_items="+m(JSON2.stringify(cy))}cv=aY(cv,ao,"ecommerce",cw);a4(cv,bz)}function bV(cq,cu,ct,cs,cr,cv){if(String(cq).length&&x(cu)){bW(cq,cu,ct,cs,cr,cv)}}function cg(cq){if(x(cq)){bW("",cq,"","","","")}}function bl(cs,ct){var cq=new Date(),cr=aY("action_name="+m(U(cs||aX)),ct,"log");a4(cr,bz)}function aL(cs,cr){var ct,cq="(^| )(piwik[_-]"+cr;if(cs){for(ct=0;ct<cs.length;ct++){cq+="|"+cs[ct]}}cq+=")( |$)";return new RegExp(cq)}function bP(cq){return(ab&&cq&&0===String(cq).indexOf(ab))}function b1(cu,cq,cv,cr){if(bP(cq)){return 0}var ct=aL(bp,"download"),cs=aL(aH,"link"),cw=new RegExp("\\.("+aZ.join("|")+")([?&#]|$)","i");if(cs.test(cu)){return"link" -}if(cr||ct.test(cu)||cw.test(cq)){return"download"}if(cv){return 0}return"link"}function bf(cr){var cq;cq=cr.parentNode;while(cq!==null&&x(cq)){if(R.isLinkElement(cr)){break}cr=cq;cq=cr.parentNode}return cr}function bt(cu){cu=bf(cu);if(!R.hasNodeAttribute(cu,"href")){return}if(!x(cu.href)){return}var ct=R.getAttributeValueFromNode(cu,"href");if(bP(ct)){return}var cv=cu.hostname||c(cu.href);var cw=cv.toLowerCase();var cr=cu.href.replace(cv,cw);var cs=new RegExp("^(javascript|vbscript|jscript|mocha|livescript|ecmascript|mailto):","i");if(!cs.test(cr)){var cq=b1(cu.className,cr,bD(cw),R.hasNodeAttribute(cu,"download"));if(cq){return{type:cq,href:cr}}}}function cl(cq,cr,cs,ct){var cu=n.buildInteractionRequestParams(cq,cr,cs,ct);if(!cu){return}return aY(cu,null,"contentInteraction")}function ck(cs,ct,cx,cq,cr){if(!x(cs)){return}if(bP(cs)){return cs}var cv=n.toAbsoluteUrl(cs);var cu="redirecturl="+m(cv)+"&";cu+=cl(ct,cx,cq,(cr||cs));var cw="&";if(ab.indexOf("?")<0){cw="?"}return ab+cw+cu}function a8(cq,cr){if(!cq||!cr){return false -}var cs=n.findTargetNode(cq);if(n.shouldIgnoreInteraction(cs)){return false}cs=n.findTargetNodeNoDefault(cq);if(cs&&!I(cs,cr)){return false}return true}function aW(cs,cr,cu){if(!cs){return}var cq=n.findParentContentNode(cs);if(!cq){return}if(!a8(cq,cs)){return}var ct=n.buildContentBlock(cq);if(!ct){return}if(!ct.target&&cu){ct.target=cu}return n.buildInteractionRequestParams(cr,ct.name,ct.piece,ct.target)}function aT(cr){if(!ai||!ai.length){return false}var cq,cs;for(cq=0;cq<ai.length;cq++){cs=ai[cq];if(cs&&cs.name===cr.name&&cs.piece===cr.piece&&cs.target===cr.target){return true}}return false}function ad(ct){if(!ct){return false}var cw=n.findTargetNode(ct);if(!cw||n.shouldIgnoreInteraction(cw)){return false}var cx=bt(cw);if(b7&&cx&&cx.type){return false}if(R.isLinkElement(cw)&&R.hasNodeAttributeWithValue(cw,"href")){var cq=String(R.getAttributeValueFromNode(cw,"href"));if(0===cq.indexOf("#")){return false}if(bP(cq)){return true}if(!n.isUrlToCurrentDomain(cq)){return false}var cu=n.buildContentBlock(ct); -if(!cu){return}var cs=cu.name;var cy=cu.piece;var cv=cu.target;if(!R.hasNodeAttributeWithValue(cw,n.CONTENT_TARGET_ATTR)||cw.wasContentTargetAttrReplaced){cw.wasContentTargetAttrReplaced=true;cv=n.toAbsoluteUrl(cq);R.setAnyAttribute(cw,n.CONTENT_TARGET_ATTR,cv)}var cr=ck(cq,"click",cs,cy,cv);n.setHrefAttribute(cw,cr);return true}return false}function ag(cr){if(!cr||!cr.length){return}var cq;for(cq=0;cq<cr.length;cq++){ad(cr[cq])}}function bs(cq){return function(cr){if(!cq){return}var cu=n.findParentContentNode(cq);var cv;if(cr){cv=cr.target||cr.srcElement}if(!cv){cv=cq}if(!a8(cu,cv)){return}cc(bz);if(R.isLinkElement(cq)&&R.hasNodeAttributeWithValue(cq,"href")&&R.hasNodeAttributeWithValue(cq,n.CONTENT_TARGET_ATTR)){var cs=R.getAttributeValueFromNode(cq,"href");if(!bP(cs)&&cq.wasContentTargetAttrReplaced){R.setAnyAttribute(cq,n.CONTENT_TARGET_ATTR,"")}}var cz=bt(cq);if(bK&&cz&&cz.type){return cz.type}if(ad(cu)){return"href"}var cw=n.buildContentBlock(cu);if(!cw){return}var ct=cw.name;var cA=cw.piece; -var cy=cw.target;var cx=cl("click",ct,cA,cy);a4(cx,bz);return cx}}function aK(cs){if(!cs||!cs.length){return}var cq,cr;for(cq=0;cq<cs.length;cq++){cr=n.findTargetNode(cs[cq]);if(cr&&!cr.contentInteractionTrackingSetupDone){cr.contentInteractionTrackingSetupDone=true;W(cr,"click",bs(cr))}}}function aG(cs,ct){if(!cs||!cs.length){return[]}var cq,cr;for(cq=0;cq<cs.length;cq++){if(aT(cs[cq])){cs.splice(cq,1);cq--}else{ai.push(cs[cq])}}if(!cs||!cs.length){return[]}ag(ct);aK(ct);var cu=[];for(cq=0;cq<cs.length;cq++){cr=aY(n.buildImpressionRequestParams(cs[cq].name,cs[cq].piece,cs[cq].target),undefined,"contentImpressions");cu.push(cr)}return cu}function a1(cr){var cq=n.collectContent(cr);return aG(cq,cr)}function bO(cr){if(!cr||!cr.length){return[]}var cq;for(cq=0;cq<cr.length;cq++){if(!n.isNodeVisible(cr[cq])){cr.splice(cq,1);cq--}}if(!cr||!cr.length){return[]}return a1(cr)}function bZ(cs,cq,cr){var ct=n.buildImpressionRequestParams(cs,cq,cr);return aY(ct,null,"contentImpression")}function a0(ct,cr){if(!ct){return -}var cq=n.findParentContentNode(ct);var cs=n.buildContentBlock(cq);if(!cs){return}if(!cr){cr="Unknown"}return cl(cr,cs.name,cs.piece,cs.target)}function bI(cr,ct,cq,cs){return"e_c="+m(cr)+"&e_a="+m(ct)+(x(cq)?"&e_n="+m(cq):"")+(x(cs)?"&e_v="+m(cs):"")}function am(cs,cu,cq,ct,cv){if(String(cs).length===0||String(cu).length===0){return false}var cr=aY(bI(cs,cu,cq,ct),cv,"event");a4(cr,bz)}function aS(cq,ct,cr,cu){var cs=aY("search="+m(cq)+(ct?"&search_cat="+m(ct):"")+(x(cr)?"&search_count="+cr:""),cu,"sitesearch");a4(cs,bz)}function bx(cq,ct,cs){var cr=aY("idgoal="+cq+(ct?"&revenue="+ct:""),cs,"goal");a4(cr,bz)}function b0(ct,cq,cx,cw,cs){var cv=cq+"="+m(cd(ct));var cr=aW(cs,"click",ct);if(cr){cv+="&"+cr}var cu=aY(cv,cx,"link");a4(cu,(cw?0:bz),cw)}function b8(cr,cq){if(cr!==""){return cr+cq.charAt(0).toUpperCase()+cq.slice(1)}return cq}function aR(cv){var cu,cq,ct=["","webkit","ms","moz"],cs;if(!a5){for(cq=0;cq<ct.length;cq++){cs=ct[cq];if(Object.prototype.hasOwnProperty.call(v,b8(cs,"hidden"))){if(v[b8(cs,"visibilityState")]==="prerender"){cu=true -}break}}}if(cu){W(v,cs+"visibilitychange",function cr(){v.removeEventListener(cs+"visibilitychange",cr,false);cv()});return}cv()}function aV(cq){if(v.readyState==="complete"){cq()}else{if(H.addEventListener){H.addEventListener("load",cq)}else{if(H.attachEvent){H.attachEvent("onLoad",cq)}}}}function aF(cr){var cq=false;if(v.attachEvent){cq=v.readyState==="complete"}else{cq=v.readyState!=="loading"}if(cq){cr()}else{if(v.addEventListener){v.addEventListener("DOMContentLoaded",cr)}else{if(v.attachEvent){v.attachEvent("onreadystatechange",cr)}}}}function bQ(cq){var cr=bt(cq);if(cr&&cr.type){cr.href=j(cr.href);b0(cr.href,cr.type,undefined,null,cq)}}function aN(){return v.all&&!v.addEventListener}function aD(cq){var cs=cq.which;var cr=(typeof cq.button);if(!cs&&cr!=="undefined"){if(aN()){if(cq.button&1){cs=1}else{if(cq.button&2){cs=3}else{if(cq.button&4){cs=2}}}}else{if(cq.button===0||cq.button==="0"){cs=1}else{if(cq.button&1){cs=2}else{if(cq.button&2){cs=3}}}}}return cs}function aA(cq){switch(aD(cq)){case 1:return"left"; -case 2:return"middle";case 3:return"right"}}function cb(cq){return cq.target||cq.srcElement}function co(cq){return function(ct){ct=ct||H.event;var cs=aA(ct);var cu=cb(ct);if(ct.type==="click"){var cr=false;if(cq&&cs==="middle"){cr=true}if(cu&&!cr){bQ(cu)}}else{if(ct.type==="mousedown"){if(cs==="middle"&&cu){bu=cs;au=cu}else{bu=au=null}}else{if(ct.type==="mouseup"){if(cs===bu&&cu===au){bQ(cu)}bu=au=null}else{if(ct.type==="contextmenu"){bQ(cu)}}}}}}function bL(cr,cq){W(cr,"click",co(cq),false);if(cq){W(cr,"mouseup",co(cq),false);W(cr,"mousedown",co(cq),false);W(cr,"contextmenu",co(cq),false)}}function bk(cr){if(!bK){bK=true;var cs,cq=aL(aj,"ignore"),ct=v.links;if(ct){for(cs=0;cs<ct.length;cs++){if(!cq.test(ct[cs].className)){bL(ct[cs],cr)}}}}}function bH(cs,cu,cv){if(aB){return true}aB=true;var cw=false;var ct,cr;function cq(){cw=true}aV(function(){function cx(cz){setTimeout(function(){if(!aB){return}cw=false;cv.trackVisibleContentImpressions();cx(cz)},cz)}function cy(cz){setTimeout(function(){if(!aB){return -}if(cw){cw=false;cv.trackVisibleContentImpressions()}cy(cz)},cz)}if(cs){ct=["scroll","resize"];for(cr=0;cr<ct.length;cr++){if(v.addEventListener){v.addEventListener(ct[cr],cq)}else{H.attachEvent("on"+ct[cr],cq)}}cy(100)}if(cu&&cu>0){cu=parseInt(cu,10);cx(cu)}})}function ce(){var cr,cs,ct={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",dir:"application/x-director",fla:"application/x-shockwave-flash",java:"application/x-java-vm",gears:"application/x-googlegears",ag:"application/x-silverlight"},cq=H.devicePixelRatio||1;if(!((new RegExp("MSIE")).test(e.userAgent))){if(e.mimeTypes&&e.mimeTypes.length){for(cr in ct){if(Object.prototype.hasOwnProperty.call(ct,cr)){cs=e.mimeTypes[ct[cr]];b6[cr]=(cs&&cs.enabledPlugin)?"1":"0"}}}if(typeof navigator.javaEnabled!=="unknown"&&x(e.javaEnabled)&&e.javaEnabled()){b6.java="1"}if(r(H.GearsFactory)){b6.gears="1"}b6.cookie=af()}b6.res=L.width*cq+"x"+L.height*cq}ce();bv();an();return{getVisitorId:function(){return bM().uuid -},getVisitorInfo:function(){return Z()},getAttributionInfo:function(){return Y()},getAttributionCampaignName:function(){return Y()[0]},getAttributionCampaignKeyword:function(){return Y()[1]},getAttributionReferrerTimestamp:function(){return Y()[2]},getAttributionReferrerUrl:function(){return Y()[3]},setTrackerUrl:function(cq){ab=cq},getTrackerUrl:function(){return ab},getSiteId:function(){return b5},setSiteId:function(cq){cm(cq)},setUserId:function(cq){if(!x(cq)||!cq.length){return}aO=cq;a7=a2(aO).substr(0,16)},getUserId:function(){return aO},setCustomData:function(cq,cr){if(K(cq)){ao=cq}else{if(!ao){ao={}}ao[cq]=cr}},getCustomData:function(){return ao},setCustomRequestProcessing:function(cq){av=cq},appendToTrackingUrl:function(cq){bA=cq},getRequest:function(cq){return aY(cq)},addPlugin:function(cq,cr){a[cq]=cr},setCustomVariable:function(cr,cq,cu,cs){var ct;if(!x(cs)){cs="visit"}if(!x(cq)){return}if(!x(cu)){cu=""}if(cr>0){cq=!o(cq)?String(cq):cq;cu=!o(cu)?String(cu):cu;ct=[cq.slice(0,ca),cu.slice(0,ca)]; -if(cs==="visit"||cs===2){aa();ah[cr]=ct}else{if(cs==="page"||cs===3){bq[cr]=ct}else{if(cs==="event"){ac[cr]=ct}}}}},getCustomVariable:function(cr,cs){var cq;if(!x(cs)){cs="visit"}if(cs==="page"||cs===3){cq=bq[cr]}else{if(cs==="event"){cq=ac[cr]}else{if(cs==="visit"||cs===2){aa();cq=ah[cr]}}}if(!x(cq)||(cq&&cq[0]==="")){return false}return cq},deleteCustomVariable:function(cq,cr){if(this.getCustomVariable(cq,cr)){this.setCustomVariable(cq,"","",cr)}},storeCustomVariablesInCookie:function(){bc=true},setLinkTrackingTimer:function(cq){bz=cq},setDownloadExtensions:function(cq){if(o(cq)){cq=cq.split("|")}aZ=cq},addDownloadExtensions:function(cr){var cq;if(o(cr)){cr=cr.split("|")}for(cq=0;cq<cr.length;cq++){aZ.push(cr[cq])}},removeDownloadExtensions:function(cs){var cr,cq=[];if(o(cs)){cs=cs.split("|")}for(cr=0;cr<aZ.length;cr++){if(A(cs,aZ[cr])===-1){cq.push(aZ[cr])}}aZ=cq},setDomains:function(cq){bB=o(cq)?[cq]:cq;bB.push(bY)},setIgnoreClasses:function(cq){aj=o(cq)?[cq]:cq},setRequestMethod:function(cq){bE=cq||bC -},setRequestContentType:function(cq){aP=cq||bj},setReferrerUrl:function(cq){bG=cq},setCustomUrl:function(cq){bd=bX(cj,cq)},setDocumentTitle:function(cq){aX=cq},setAPIUrl:function(cq){az=cq},setDownloadClasses:function(cq){bp=o(cq)?[cq]:cq},setLinkClasses:function(cq){aH=o(cq)?[cq]:cq},setCampaignNameKey:function(cq){a3=o(cq)?[cq]:cq},setCampaignKeywordKey:function(cq){aU=o(cq)?[cq]:cq},discardHashTag:function(cq){al=cq},setCookieNamePrefix:function(cq){ch=cq;ah=at()},setCookieDomain:function(cq){var cr=z(cq);if(bn(cr)){ar=cr;bv()}},setCookiePath:function(cq){ci=cq;bv()},setVisitorCookieTimeout:function(cq){ay=cq*1000},setSessionCookieTimeout:function(cq){aE=cq*1000},setReferralCookieTimeout:function(cq){bh=cq*1000},setConversionAttributionFirstReferrer:function(cq){ba=cq},disableCookies:function(){ap=true;b6.cookie="0";if(b5){X()}},deleteCookies:function(){X()},setDoNotTrack:function(cr){var cq=e.doNotTrack||e.msDoNotTrack;b9=cr&&(cq==="yes"||cq==="1");if(b9){this.disableCookies()}},addListener:function(cr,cq){bL(cr,cq) -},enableLinkTracking:function(cq){b7=true;if(q){bk(cq)}else{F.push(function(){bk(cq)})}},enableJSErrorTracking:function(){if(cn){return}cn=true;var cq=H.onerror;H.onerror=function(cv,ct,cs,cu,cr){aR(function(){var cw="JavaScript Errors";var cx=ct+":"+cs;if(cu){cx+=":"+cu}am(cw,cx,cv)});if(cq){return cq(cv,ct,cs,cu,cr)}return false}},disablePerformanceTracking:function(){a6=false},setGenerationTimeMs:function(cq){aM=parseInt(cq,10)},enableHeartBeatTimer:function(cq){cq=Math.max(cq,1);b3=(cq||15)*1000;if(bo!==null){bF()}},killFrame:function(){if(H.location!==H.top.location){H.top.location=H.location}},redirectFile:function(cq){if(H.location.protocol==="file:"){H.location=cq}},setCountPreRendered:function(cq){a5=cq},trackGoal:function(cq,cs,cr){aR(function(){bx(cq,cs,cr)})},trackLink:function(cr,cq,ct,cs){aR(function(){b0(cr,cq,ct,cs)})},trackPageView:function(cq,cr){ai=[];if(B(b5)){aR(function(){N(ab,az,b5)})}else{aR(function(){bl(cq,cr)})}},trackAllContentImpressions:function(){if(B(b5)){return -}aR(function(){aF(function(){var cq=n.findContentNodes();var cr=a1(cq);aq(cr,bz)})})},trackVisibleContentImpressions:function(cq,cr){if(B(b5)){return}if(!x(cq)){cq=true}if(!x(cr)){cr=750}bH(cq,cr,this);aR(function(){aV(function(){var cs=n.findContentNodes();var ct=bO(cs);aq(ct,bz)})})},trackContentImpression:function(cs,cq,cr){if(B(b5)){return}if(!cs){return}cq=cq||"Unknown";aR(function(){var ct=bZ(cs,cq,cr);a4(ct,bz)})},trackContentImpressionsWithinNode:function(cq){if(B(b5)||!cq){return}aR(function(){if(aB){aV(function(){var cr=n.findContentNodesWithinNode(cq);var cs=bO(cr);aq(cs,bz)})}else{aF(function(){var cr=n.findContentNodesWithinNode(cq);var cs=a1(cr);aq(cs,bz)})}})},trackContentInteraction:function(cs,ct,cq,cr){if(B(b5)){return}if(!cs||!ct){return}cq=cq||"Unknown";aR(function(){var cu=cl(cs,ct,cq,cr);a4(cu,bz)})},trackContentInteractionNode:function(cr,cq){if(B(b5)||!cr){return}aR(function(){var cs=a0(cr,cq);a4(cs,bz)})},logAllContentBlocksOnPage:function(){var cr=n.findContentNodes(); -var cq=n.collectContent(cr);if(console!==undefined&&console&&console.log){console.log(cq)}},trackEvent:function(cr,ct,cq,cs){aR(function(){am(cr,ct,cq,cs)})},trackSiteSearch:function(cq,cs,cr){aR(function(){aS(cq,cs,cr)})},setEcommerceView:function(ct,cq,cs,cr){if(!x(cs)||!cs.length){cs=""}else{if(cs instanceof Array){cs=JSON2.stringify(cs)}}bq[5]=["_pkc",cs];if(x(cr)&&String(cr).length){bq[2]=["_pkp",cr]}if((!x(ct)||!ct.length)&&(!x(cq)||!cq.length)){return}if(x(ct)&&ct.length){bq[3]=["_pks",ct]}if(!x(cq)||!cq.length){cq=""}bq[4]=["_pkn",cq]},addEcommerceItem:function(cu,cq,cs,cr,ct){if(cu.length){bR[cu]=[cu,cq,cs,cr,ct]}},trackEcommerceOrder:function(cq,cu,ct,cs,cr,cv){bV(cq,cu,ct,cs,cr,cv)},trackEcommerceCartUpdate:function(cq){cg(cq)}}}function w(){return{push:S}}function b(ac,ab){var ad={};var Z,aa;for(Z=0;Z<ab.length;Z++){var X=ab[Z];ad[X]=1;for(aa=0;aa<ac.length;aa++){if(ac[aa]&&ac[aa][0]){var Y=ac[aa][0];if(X===Y){S(ac[aa]);delete ac[aa];if(ad[Y]>1){if(console!==undefined&&console&&console.error){console.error("The method "+Y+' is registered more than once in "paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: http://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers') -}}ad[Y]++}}}}return ac}W(H,"beforeunload",T,false);p();Date.prototype.getTimeAlias=Date.prototype.getTime;M=new E();var s=["disableCookies","setTrackerUrl","setAPIUrl","setCookiePath","setCookieDomain","setUserId","setSiteId","enableLinkTracking"];_paq=b(_paq,s);for(u=0;u<_paq.length;u++){if(_paq[u]){S(_paq[u])}}_paq=new w();d={addPlugin:function(X,Y){a[X]=Y},getTracker:function(X,Y){if(!x(Y)){Y=this.getAsyncTracker().getSiteId()}if(!x(X)){X=this.getAsyncTracker().getTrackerUrl()}return new E(X,Y)},getAsyncTracker:function(){return M}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return d})}return d}())}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g); +if(ad=="}"){break}if(ae){if(ad==","){ad=y();if(ad=="}"){H()}}else{H()}}if(ad==","||typeof ad!="string"||(F?ad.charAt(0):ad[0])!="@"||y()!=":"){H()}ac[ad.slice(1)]=W(y())}return ac}}H()}return ad};var P=function(ae,ad,af){var ac=w(ae,ad,af);if(ac===L){delete ae[ad]}else{ae[ad]=ac}};var w=function(af,ae,ag){var ad=af[ae],ac;if(typeof ad=="object"&&ad){if(u.call(ad)==E){for(ac=ad.length;ac--;){P(ad,ac,ag)}}else{m(ad,function(ah){P(ad,ah,ag)})}}return ag.call(af,ae,ad)};V.parse=function(ae,af){var ac,ad;G=0;X=""+ae;ac=W(y());if(y()!="$"){H()}G=X=null;return af&&u.call(af)==U?w((ad={},ad[""]=ac,ad),"",af):ac}}}V.runInContext=j;return V}if(h&&!c){j(i,h)}else{var f=i.JSON,k=i.JSON3,d=false;var g=j(i,(i.JSON3={noConflict:function(){if(!d){d=true;i.JSON=f;i.JSON3=k;f=k=null}return g}}));i.JSON={parse:g.parse,stringify:g.stringify}}if(c){define(function(){return g})}}).call(this);JSON2=a})()}if(typeof _paq!=="object"){_paq=[]}if(typeof Piwik!=="object"){Piwik=(function(){var k,a={},w=document,e=navigator,M=screen,I=window,f=I.performance||I.mozPerformance||I.msPerformance||I.webkitPerformance,q=false,G=[],m=I.encodeURIComponent,H=I.decodeURIComponent,h=unescape,N,v,d; +function j(Y){try{return H(Y)}catch(Z){return unescape(Y)}}function y(Z){var Y=typeof Z;return Y!=="undefined"}function r(Y){return typeof Y==="function"}function L(Y){return typeof Y==="object"}function o(Y){return typeof Y==="string"||Y instanceof String}function s(Z){if(!Z){return true}var Y;var aa=true;for(Y in Z){if(Object.prototype.hasOwnProperty.call(Z,Y)){aa=false}}return aa}function T(){var Y,aa,Z;for(Y=0;Y<arguments.length;Y+=1){Z=arguments[Y];aa=Z.shift();if(o(aa)){N[aa].apply(N,Z)}else{aa.apply(N,Z)}}}function X(ab,aa,Z,Y){if(ab.addEventListener){ab.addEventListener(aa,Z,Y);return true}if(ab.attachEvent){return ab.attachEvent("on"+aa,Z)}ab["on"+aa]=Z}function Q(Z,ac){var Y="",ab,aa;for(ab in a){if(Object.prototype.hasOwnProperty.call(a,ab)){aa=a[ab][Z];if(r(aa)){Y+=aa(ac)}}}return Y}function U(){var Y;Q("unload");if(k){do{Y=new Date()}while(Y.getTimeAlias()<k)}}function R(){var Y;if(!q){q=true;Q("load");for(Y=0;Y<G.length;Y++){G[Y]()}}return true}function p(){var Z;if(w.addEventListener){X(w,"DOMContentLoaded",function Y(){w.removeEventListener("DOMContentLoaded",Y,false); +R()})}else{if(w.attachEvent){w.attachEvent("onreadystatechange",function Y(){if(w.readyState==="complete"){w.detachEvent("onreadystatechange",Y);R()}});if(w.documentElement.doScroll&&I===I.top){(function Y(){if(!q){try{w.documentElement.doScroll("left")}catch(aa){setTimeout(Y,0);return}R()}}())}}}if((new RegExp("WebKit")).test(e.userAgent)){Z=setInterval(function(){if(q||/loaded|complete/.test(w.readyState)){clearInterval(Z);R()}},10)}X(I,"load",R,false)}function i(aa,Z){var Y=w.createElement("script");Y.type="text/javascript";Y.src=aa;if(Y.readyState){Y.onreadystatechange=function(){var ab=this.readyState;if(ab==="loaded"||ab==="complete"){Y.onreadystatechange=null;Z()}}}else{Y.onload=Z}w.getElementsByTagName("head")[0].appendChild(Y)}function z(){var Y="";try{Y=I.top.document.referrer}catch(aa){if(I.parent){try{Y=I.parent.document.referrer}catch(Z){Y=""}}}if(Y===""){Y=w.referrer}return Y}function l(Y){var aa=new RegExp("^([a-z]+):"),Z=aa.exec(Y);return Z?Z[1]:null}function c(Y){var aa=new RegExp("^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)"),Z=aa.exec(Y); +return Z?Z[1]:Y}function K(aa,Z){var Y="[\\?&#]"+Z+"=([^&#]*)";var ac=new RegExp(Y);var ab=ac.exec(aa);return ab?H(ab[1]):""}function u(Y){return unescape(m(Y))}function W(an){var aa=function(au,at){return(au<<at)|(au>>>(32-at))},ao=function(aw){var au="",av,at;for(av=7;av>=0;av--){at=(aw>>>(av*4))&15;au+=at.toString(16)}return au},ad,aq,ap,Z=[],ah=1732584193,af=4023233417,ae=2562383102,ac=271733878,ab=3285377520,am,al,ak,aj,ai,ar,Y,ag=[];an=u(an);Y=an.length;for(aq=0;aq<Y-3;aq+=4){ap=an.charCodeAt(aq)<<24|an.charCodeAt(aq+1)<<16|an.charCodeAt(aq+2)<<8|an.charCodeAt(aq+3);ag.push(ap)}switch(Y&3){case 0:aq=2147483648;break;case 1:aq=an.charCodeAt(Y-1)<<24|8388608;break;case 2:aq=an.charCodeAt(Y-2)<<24|an.charCodeAt(Y-1)<<16|32768;break;case 3:aq=an.charCodeAt(Y-3)<<24|an.charCodeAt(Y-2)<<16|an.charCodeAt(Y-1)<<8|128;break}ag.push(aq);while((ag.length&15)!==14){ag.push(0)}ag.push(Y>>>29);ag.push((Y<<3)&4294967295);for(ad=0;ad<ag.length;ad+=16){for(aq=0;aq<16;aq++){Z[aq]=ag[ad+aq]}for(aq=16; +aq<=79;aq++){Z[aq]=aa(Z[aq-3]^Z[aq-8]^Z[aq-14]^Z[aq-16],1)}am=ah;al=af;ak=ae;aj=ac;ai=ab;for(aq=0;aq<=19;aq++){ar=(aa(am,5)+((al&ak)|(~al&aj))+ai+Z[aq]+1518500249)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}for(aq=20;aq<=39;aq++){ar=(aa(am,5)+(al^ak^aj)+ai+Z[aq]+1859775393)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}for(aq=40;aq<=59;aq++){ar=(aa(am,5)+((al&ak)|(al&aj)|(ak&aj))+ai+Z[aq]+2400959708)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}for(aq=60;aq<=79;aq++){ar=(aa(am,5)+(al^ak^aj)+ai+Z[aq]+3395469782)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}ah=(ah+am)&4294967295;af=(af+al)&4294967295;ae=(ae+ak)&4294967295;ac=(ac+aj)&4294967295;ab=(ab+ai)&4294967295}ar=ao(ah)+ao(af)+ao(ae)+ao(ac)+ao(ab);return ar.toLowerCase()}function P(aa,Y,Z){if(!aa){aa=""}if(!Y){Y=""}if(aa==="translate.googleusercontent.com"){if(Z===""){Z=Y}Y=K(Y,"u");aa=c(Y)}else{if(aa==="cc.bingj.com"||aa==="webcache.googleusercontent.com"||aa.slice(0,5)==="74.6."){Y=w.links[0].href;aa=c(Y)}}return[aa,Y,Z] +}function A(Z){var Y=Z.length;if(Z.charAt(--Y)==="."){Z=Z.slice(0,Y)}if(Z.slice(0,2)==="*."){Z=Z.slice(1)}if(Z.indexOf("/")!==-1){Z=Z.substr(0,Z.indexOf("/"))}return Z}function V(Z){Z=Z&&Z.text?Z.text:Z;if(!o(Z)){var Y=w.getElementsByTagName("title");if(Y&&y(Y[0])){Z=Y[0].text}}return Z}function E(Y){if(!Y){return[]}if(!y(Y.children)&&y(Y.childNodes)){return Y.children}if(y(Y.children)){return Y.children}return[]}function J(Z,Y){if(!Z||!Y){return false}if(Z.contains){return Z.contains(Y)}if(Z===Y){return true}if(Z.compareDocumentPosition){return !!(Z.compareDocumentPosition(Y)&16)}return false}function B(aa,ab){if(aa&&aa.indexOf){return aa.indexOf(ab)}if(!y(aa)||aa===null){return -1}if(!aa.length){return -1}var Y=aa.length;if(Y===0){return -1}var Z=0;while(Z<Y){if(aa[Z]===ab){return Z}Z++}return -1}function g(aa){if(!aa){return false}function Y(ac,ad){if(I.getComputedStyle){return w.defaultView.getComputedStyle(ac,null)[ad]}if(ac.currentStyle){return ac.currentStyle[ad]}}function ab(ac){ac=ac.parentNode; +while(ac){if(ac===w){return true}ac=ac.parentNode}return false}function Z(ae,ak,ac,ah,af,ai,ag){var ad=ae.parentNode,aj=1;if(!ab(ae)){return false}if(9===ad.nodeType){return true}if("0"===Y(ae,"opacity")||"none"===Y(ae,"display")||"hidden"===Y(ae,"visibility")){return false}if(!y(ak)||!y(ac)||!y(ah)||!y(af)||!y(ai)||!y(ag)){ak=ae.offsetTop;af=ae.offsetLeft;ah=ak+ae.offsetHeight;ac=af+ae.offsetWidth;ai=ae.offsetWidth;ag=ae.offsetHeight}if(aa===ae&&(0===ag||0===ai)&&"hidden"===Y(ae,"overflow")){return false}if(ad){if(("hidden"===Y(ad,"overflow")||"scroll"===Y(ad,"overflow"))){if(af+aj>ad.offsetWidth+ad.scrollLeft||af+ai-aj<ad.scrollLeft||ak+aj>ad.offsetHeight+ad.scrollTop||ak+ag-aj<ad.scrollTop){return false}}if(ae.offsetParent===ad){af+=ad.offsetLeft;ak+=ad.offsetTop}return Z(ad,ak,ac,ah,af,ai,ag)}return true}return Z(aa)}var S={htmlCollectionToArray:function(aa){var Y=[],Z;if(!aa||!aa.length){return Y}for(Z=0;Z<aa.length;Z++){Y.push(aa[Z])}return Y},find:function(Y){if(!document.querySelectorAll||!Y){return[] +}var Z=document.querySelectorAll(Y);return this.htmlCollectionToArray(Z)},findMultiple:function(aa){if(!aa||!aa.length){return[]}var Z,ab;var Y=[];for(Z=0;Z<aa.length;Z++){ab=this.find(aa[Z]);Y=Y.concat(ab)}Y=this.makeNodesUnique(Y);return Y},findNodesByTagName:function(Z,Y){if(!Z||!Y||!Z.getElementsByTagName){return[]}var aa=Z.getElementsByTagName(Y);return this.htmlCollectionToArray(aa)},makeNodesUnique:function(Y){var ad=[].concat(Y);Y.sort(function(af,ae){if(af===ae){return 0}var ah=B(ad,af);var ag=B(ad,ae);if(ah===ag){return 0}return ah>ag?-1:1});if(Y.length<=1){return Y}var Z=0;var ab=0;var ac=[];var aa;aa=Y[Z++];while(aa){if(aa===Y[Z]){ab=ac.push(Z)}aa=Y[Z++]||null}while(ab--){Y.splice(ac[ab],1)}return Y},getAttributeValueFromNode:function(ac,aa){if(!this.hasNodeAttribute(ac,aa)){return}if(ac&&ac.getAttribute){return ac.getAttribute(aa)}if(!ac||!ac.attributes){return}var ab=(typeof ac.attributes[aa]);if("undefined"===ab){return}if(ac.attributes[aa].value){return ac.attributes[aa].value +}if(ac.attributes[aa].nodeValue){return ac.attributes[aa].nodeValue}var Z;var Y=ac.attributes;if(!Y){return}for(Z=0;Z<Y.length;Z++){if(Y[Z].nodeName===aa){return Y[Z].nodeValue}}return null},hasNodeAttributeWithValue:function(Z,Y){var aa=this.getAttributeValueFromNode(Z,Y);return !!aa},hasNodeAttribute:function(aa,Y){if(aa&&aa.hasAttribute){return aa.hasAttribute(Y)}if(aa&&aa.attributes){var Z=(typeof aa.attributes[Y]);return"undefined"!==Z}return false},hasNodeCssClass:function(aa,Y){if(aa&&Y&&aa.className){var Z=typeof aa.className==="string"?aa.className.split(" "):[];if(-1!==B(Z,Y)){return true}}return false},findNodesHavingAttribute:function(ac,aa,Y){if(!Y){Y=[]}if(!ac||!aa){return Y}var ab=E(ac);if(!ab||!ab.length){return Y}var Z,ad;for(Z=0;Z<ab.length;Z++){ad=ab[Z];if(this.hasNodeAttribute(ad,aa)){Y.push(ad)}Y=this.findNodesHavingAttribute(ad,aa,Y)}return Y},findFirstNodeHavingAttribute:function(aa,Z){if(!aa||!Z){return}if(this.hasNodeAttribute(aa,Z)){return aa}var Y=this.findNodesHavingAttribute(aa,Z); +if(Y&&Y.length){return Y[0]}},findFirstNodeHavingAttributeWithValue:function(ab,aa){if(!ab||!aa){return}if(this.hasNodeAttributeWithValue(ab,aa)){return ab}var Y=this.findNodesHavingAttribute(ab,aa);if(!Y||!Y.length){return}var Z;for(Z=0;Z<Y.length;Z++){if(this.getAttributeValueFromNode(Y[Z],aa)){return Y[Z]}}},findNodesHavingCssClass:function(ac,ab,Y){if(!Y){Y=[]}if(!ac||!ab){return Y}if(ac.getElementsByClassName){var ad=ac.getElementsByClassName(ab);return this.htmlCollectionToArray(ad)}var aa=E(ac);if(!aa||!aa.length){return[]}var Z,ae;for(Z=0;Z<aa.length;Z++){ae=aa[Z];if(this.hasNodeCssClass(ae,ab)){Y.push(ae)}Y=this.findNodesHavingCssClass(ae,ab,Y)}return Y},findFirstNodeHavingClass:function(aa,Z){if(!aa||!Z){return}if(this.hasNodeCssClass(aa,Z)){return aa}var Y=this.findNodesHavingCssClass(aa,Z);if(Y&&Y.length){return Y[0]}},isLinkElement:function(Z){if(!Z){return false}var Y=String(Z.nodeName).toLowerCase();var ab=["a","area"];var aa=B(ab,Y);return aa!==-1},setAnyAttribute:function(Z,Y,aa){if(!Z||!Y){return +}if(Z.setAttribute){Z.setAttribute(Y,aa)}else{Z[Y]=aa}}};var n={CONTENT_ATTR:"data-track-content",CONTENT_CLASS:"piwikTrackContent",CONTENT_NAME_ATTR:"data-content-name",CONTENT_PIECE_ATTR:"data-content-piece",CONTENT_PIECE_CLASS:"piwikContentPiece",CONTENT_TARGET_ATTR:"data-content-target",CONTENT_TARGET_CLASS:"piwikContentTarget",CONTENT_IGNOREINTERACTION_ATTR:"data-content-ignoreinteraction",CONTENT_IGNOREINTERACTION_CLASS:"piwikContentIgnoreInteraction",location:undefined,findContentNodes:function(){var Z="."+this.CONTENT_CLASS;var Y="["+this.CONTENT_ATTR+"]";var aa=S.findMultiple([Z,Y]);return aa},findContentNodesWithinNode:function(ab){if(!ab){return[]}var Z=S.findNodesHavingCssClass(ab,this.CONTENT_CLASS);var Y=S.findNodesHavingAttribute(ab,this.CONTENT_ATTR);if(Y&&Y.length){var aa;for(aa=0;aa<Y.length;aa++){Z.push(Y[aa])}}if(S.hasNodeAttribute(ab,this.CONTENT_ATTR)){Z.push(ab)}else{if(S.hasNodeCssClass(ab,this.CONTENT_CLASS)){Z.push(ab)}}Z=S.makeNodesUnique(Z);return Z},findParentContentNode:function(Z){if(!Z){return +}var aa=Z;var Y=0;while(aa&&aa!==w&&aa.parentNode){if(S.hasNodeAttribute(aa,this.CONTENT_ATTR)){return aa}if(S.hasNodeCssClass(aa,this.CONTENT_CLASS)){return aa}aa=aa.parentNode;if(Y>1000){break}Y++}},findPieceNode:function(Z){var Y;Y=S.findFirstNodeHavingAttribute(Z,this.CONTENT_PIECE_ATTR);if(!Y){Y=S.findFirstNodeHavingClass(Z,this.CONTENT_PIECE_CLASS)}if(Y){return Y}return Z},findTargetNodeNoDefault:function(Y){if(!Y){return}var Z=S.findFirstNodeHavingAttributeWithValue(Y,this.CONTENT_TARGET_ATTR);if(Z){return Z}Z=S.findFirstNodeHavingAttribute(Y,this.CONTENT_TARGET_ATTR);if(Z){return Z}Z=S.findFirstNodeHavingClass(Y,this.CONTENT_TARGET_CLASS);if(Z){return Z}},findTargetNode:function(Y){var Z=this.findTargetNodeNoDefault(Y);if(Z){return Z}return Y},findContentName:function(Z){if(!Z){return}var ac=S.findFirstNodeHavingAttributeWithValue(Z,this.CONTENT_NAME_ATTR);if(ac){return S.getAttributeValueFromNode(ac,this.CONTENT_NAME_ATTR)}var Y=this.findContentPiece(Z);if(Y){return this.removeDomainIfIsInLink(Y) +}if(S.hasNodeAttributeWithValue(Z,"title")){return S.getAttributeValueFromNode(Z,"title")}var aa=this.findPieceNode(Z);if(S.hasNodeAttributeWithValue(aa,"title")){return S.getAttributeValueFromNode(aa,"title")}var ab=this.findTargetNode(Z);if(S.hasNodeAttributeWithValue(ab,"title")){return S.getAttributeValueFromNode(ab,"title")}},findContentPiece:function(Z){if(!Z){return}var ab=S.findFirstNodeHavingAttributeWithValue(Z,this.CONTENT_PIECE_ATTR);if(ab){return S.getAttributeValueFromNode(ab,this.CONTENT_PIECE_ATTR)}var Y=this.findPieceNode(Z);var aa=this.findMediaUrlInNode(Y);if(aa){return this.toAbsoluteUrl(aa)}},findContentTarget:function(aa){if(!aa){return}var ab=this.findTargetNode(aa);if(S.hasNodeAttributeWithValue(ab,this.CONTENT_TARGET_ATTR)){return S.getAttributeValueFromNode(ab,this.CONTENT_TARGET_ATTR)}var Z;if(S.hasNodeAttributeWithValue(ab,"href")){Z=S.getAttributeValueFromNode(ab,"href");return this.toAbsoluteUrl(Z)}var Y=this.findPieceNode(aa);if(S.hasNodeAttributeWithValue(Y,"href")){Z=S.getAttributeValueFromNode(Y,"href"); +return this.toAbsoluteUrl(Z)}},isSameDomain:function(Y){if(!Y||!Y.indexOf){return false}if(0===Y.indexOf(this.getLocation().origin)){return true}var Z=Y.indexOf(this.getLocation().host);if(8>=Z&&0<=Z){return true}return false},removeDomainIfIsInLink:function(aa){var Z="^https?://[^/]+";var Y="^.*//[^/]+";if(aa&&aa.search&&-1!==aa.search(new RegExp(Z))&&this.isSameDomain(aa)){aa=aa.replace(new RegExp(Y),"");if(!aa){aa="/"}}return aa},findMediaUrlInNode:function(ac){if(!ac){return}var aa=["img","embed","video","audio"];var Y=ac.nodeName.toLowerCase();if(-1!==B(aa,Y)&&S.findFirstNodeHavingAttributeWithValue(ac,"src")){var ab=S.findFirstNodeHavingAttributeWithValue(ac,"src");return S.getAttributeValueFromNode(ab,"src")}if(Y==="object"&&S.hasNodeAttributeWithValue(ac,"data")){return S.getAttributeValueFromNode(ac,"data")}if(Y==="object"){var ad=S.findNodesByTagName(ac,"param");if(ad&&ad.length){var Z;for(Z=0;Z<ad.length;Z++){if("movie"===S.getAttributeValueFromNode(ad[Z],"name")&&S.hasNodeAttributeWithValue(ad[Z],"value")){return S.getAttributeValueFromNode(ad[Z],"value") +}}}var ae=S.findNodesByTagName(ac,"embed");if(ae&&ae.length){return this.findMediaUrlInNode(ae[0])}}},trim:function(Y){if(Y&&String(Y)===Y){return Y.replace(/^\s+|\s+$/g,"")}return Y},isOrWasNodeInViewport:function(ad){if(!ad||!ad.getBoundingClientRect||ad.nodeType!==1){return true}var ac=ad.getBoundingClientRect();var ab=w.documentElement||{};var aa=ac.top<0;if(aa&&ad.offsetTop){aa=(ad.offsetTop+ac.height)>0}var Z=ab.clientWidth;if(I.innerWidth&&Z>I.innerWidth){Z=I.innerWidth}var Y=ab.clientHeight;if(I.innerHeight&&Y>I.innerHeight){Y=I.innerHeight}return((ac.bottom>0||aa)&&ac.right>0&&ac.left<Z&&((ac.top<Y)||aa))},isNodeVisible:function(Z){var Y=g(Z);var aa=this.isOrWasNodeInViewport(Z);return Y&&aa},buildInteractionRequestParams:function(Y,Z,aa,ab){var ac="";if(Y){ac+="c_i="+m(Y)}if(Z){if(ac){ac+="&"}ac+="c_n="+m(Z)}if(aa){if(ac){ac+="&"}ac+="c_p="+m(aa)}if(ab){if(ac){ac+="&"}ac+="c_t="+m(ab)}return ac},buildImpressionRequestParams:function(Y,Z,aa){var ab="c_n="+m(Y)+"&c_p="+m(Z);if(aa){ab+="&c_t="+m(aa) +}return ab},buildContentBlock:function(aa){if(!aa){return}var Y=this.findContentName(aa);var Z=this.findContentPiece(aa);var ab=this.findContentTarget(aa);Y=this.trim(Y);Z=this.trim(Z);ab=this.trim(ab);return{name:Y||"Unknown",piece:Z||"Unknown",target:ab||""}},collectContent:function(ab){if(!ab||!ab.length){return[]}var aa=[];var Y,Z;for(Y=0;Y<ab.length;Y++){Z=this.buildContentBlock(ab[Y]);if(y(Z)){aa.push(Z)}}return aa},setLocation:function(Y){this.location=Y},getLocation:function(){var Y=this.location||I.location;if(!Y.origin){Y.origin=Y.protocol+"//"+Y.hostname+(Y.port?":"+Y.port:"")}return Y},toAbsoluteUrl:function(Z){if((!Z||String(Z)!==Z)&&Z!==""){return Z}if(""===Z){return this.getLocation().href}if(Z.search(/^\/\//)!==-1){return this.getLocation().protocol+Z}if(Z.search(/:\/\//)!==-1){return Z}if(0===Z.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+Z}if(0===Z.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+Z}if(0===Z.search("^[a-zA-Z]{2,11}:")){return Z +}if(Z.search(/^\//)!==-1){return this.getLocation().origin+Z}var Y="(.*/)";var aa=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(Y))[0];return aa+Z},isUrlToCurrentDomain:function(Z){var aa=this.toAbsoluteUrl(Z);if(!aa){return false}var Y=this.getLocation().origin;if(Y===aa){return true}if(0===String(aa).indexOf(Y)){if(":"===String(aa).substr(Y.length,1)){return false}return true}return false},setHrefAttribute:function(Z,Y){if(!Z||!Y){return}S.setAnyAttribute(Z,"href",Y)},shouldIgnoreInteraction:function(aa){var Z=S.hasNodeAttribute(aa,this.CONTENT_IGNOREINTERACTION_ATTR);var Y=S.hasNodeCssClass(aa,this.CONTENT_IGNOREINTERACTION_CLASS);return Z||Y}};function D(Y,Z){if(Z){return Z}if(Y.slice(-9)==="piwik.php"){Y=Y.slice(0,Y.length-9)}return Y}function C(ae){var ag="Piwik_Overlay";var Z=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=.*)?$");var aa=Z.exec(w.referrer);if(aa){var ac=aa[1];if(ac!==String(ae)){return false +}var ad=aa[2],Y=aa[3],ab=aa[4];if(!ab){ab=""}else{if(ab.indexOf("&segment=")===0){ab=ab.substr("&segment=".length)}}I.name=ag+"###"+ad+"###"+Y+"###"+ab}var af=I.name.split("###");return af.length===4&&af[0]===ag}function O(Z,af,ab){var ae=I.name.split("###"),ad=ae[1],Y=ae[2],ac=ae[3],aa=D(Z,af);i(aa+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(aa,ab,ad,Y,ac)})}function F(bH,bB){var bx=P(w.domain,I.location.href,z()),cf=A(bx[0]),bh=j(bx[1]),aW=j(bx[2]),cd=false,bL="GET",cs=bL,am="application/x-www-form-urlencoded; charset=UTF-8",bX=am,ai=bH||"",bc="",cj="",bz=bB||"",a5="",bi="",aG,aS=w.title,cp=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],ae=[cf],a6=[],bf=[],aJ=[],bd=500,b6,aH,bl,bj,Y,bT=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],bb=["pk_kwd","piwik_kwd","utm_term"],aT="_pk_",ch,aY,aU=false,cb,aQ,a2,b7=33955200000,bR=1800000,co=15768000000,aE=true,bP=0,bk=false,at=false,bE,bp={},bO={},aV={},a1=200,ck={},cq={},bD=[],bI=false,b0=false,Z=false,cr=false,aq=false,ci=null,bF,au,a7,bA=W,aX; +function cv(cF,cC,cB,cE,cA,cD){if(aU){return}var cz;if(cB){cz=new Date();cz.setTime(cz.getTime()+cB)}w.cookie=cF+"="+m(cC)+(cB?";expires="+cz.toGMTString():"")+";path="+(cE||"/")+(cA?";domain="+cA:"")+(cD?";secure":"")}function ah(cB){if(aU){return 0}var cz=new RegExp("(^|;)[ ]*"+cB+"=([^;]*)"),cA=cz.exec(w.cookie);return cA?H(cA[2]):0}function bv(cz){var cA;if(bj){cA=new RegExp("#.*");return cz.replace(cA,"")}return cz}function bo(cB,cz){var cC=l(cz),cA;if(cC){return cz}if(cz.slice(0,1)==="/"){return l(cB)+"://"+c(cB)+cz}cB=bv(cB);cA=cB.indexOf("?");if(cA>=0){cB=cB.slice(0,cA)}cA=cB.lastIndexOf("/");if(cA!==cB.length-1){cB=cB.slice(0,cA+1)}return cB+cz}function b4(cB,cz){var cA;cB=String(cB).toLowerCase();cz=String(cz).toLowerCase();if(cB===cz){return true}if(cz.slice(0,1)==="."){if(cB===cz.slice(1)){return true}cA=cB.length-cz.length;if((cA>0)&&(cB.slice(cA)===cz)){return true}}return false}function cm(cA,cz){cA=String(cA);return cA.indexOf(cz,cA.length-cz.length)!==-1}function aP(cA,cz){cA=String(cA); +return cA.substr(0,cA.length-cz)}function bN(cz){var cA=document.createElement("a");if(cz.indexOf("//")!==0&&cz.indexOf("http")!==0){cz="http://"+cz}cA.href=n.toAbsoluteUrl(cz);if(cA.pathname){return cA.pathname}return""}function aF(cA,cz){var cB=(!cz||cz==="/");if(cB){return true}if(cA===cz){return true}if(!cA){return false}cz=String(cz).toLowerCase();cA=String(cA).toLowerCase();if(!cm(cA,"/")){cA+="/"}if(!cm(cz,"/")){cz+="/"}return cA.indexOf(cz)===0}function ab(cD,cF){var cA,cz,cB,cC,cE;for(cA=0;cA<ae.length;cA++){cC=A(ae[cA]);cE=bN(ae[cA]);if(b4(cD,cC)&&aF(cF,cE)){return true}}return false}function ay(cC){var cA,cz,cB;for(cA=0;cA<ae.length;cA++){cz=A(ae[cA].toLowerCase());if(cC===cz){return true}if(cz.slice(0,1)==="."){if(cC===cz.slice(1)){return true}cB=cC.length-cz.length;if((cB>0)&&(cC.slice(cB)===cz)){return true}}}return false}function bS(cz,cB){var cA=new Image(1,1);cA.onload=function(){v=0;if(typeof cB==="function"){cB()}};cA.src=ai+(ai.indexOf("?")<0?"?":"&")+cz}function cn(cA,cD,cz){if(!y(cz)||null===cz){cz=true +}try{var cC=I.XMLHttpRequest?new I.XMLHttpRequest():I.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;cC.open("POST",ai,true);cC.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)&&cz){bS(cA,cD)}else{if(typeof cD==="function"){cD()}}};cC.setRequestHeader("Content-Type",bX);cC.send(cA)}catch(cB){if(cz){bS(cA,cD)}}}function bJ(cA){var cz=new Date();var cB=cz.getTime()+cA;if(!k||cB>k){k=cB}}function bQ(cz){if(bF||!aH){return}bF=setTimeout(function cA(){bF=null;if(bl()){return}var cB=new Date(),cC=aH-(cB.getTime()-ci);cC=Math.min(aH,cC);bQ(cC)},cz||aH)}function be(){if(!bF){return}clearTimeout(bF);bF=null}function aM(){if(bl()){return}bQ()}function af(){be()}function cx(){if(aq||!aH){return}aq=true;X(I,"focus",aM);X(I,"blur",af);bQ()}function b1(cD){var cA=new Date();var cz=cA.getTime();ci=cz;if(b0&&cz<b0){var cB=b0-cz;setTimeout(cD,cB);bJ(cB+50);b0+=50;return}if(b0===false){var cC=800;b0=cz+cC}cD()}function ba(cA,cz,cB){if(!cb&&cA){b1(function(){if(cs==="POST"){cn(cA,cB) +}else{bS(cA,cB)}bJ(cz)})}if(!aq){cx()}else{bQ()}}function bM(cz){if(cb){return false}return(cz&&cz.length)}function cw(cB,cz){if(!bM(cB)){return}var cA='{"requests":["?'+cB.join('","?')+'"]}';b1(function(){cn(cA,null,false);bJ(cz)})}function aw(cz){return aT+cz+"."+bz+"."+aX}function by(){if(aU){return"0"}if(!y(e.cookieEnabled)){var cz=aw("testcookie");cv(cz,"1");return ah(cz)==="1"?"1":"0"}return e.cookieEnabled?"1":"0"}function aR(){aX=bA((ch||cf)+(aY||"/")).slice(0,4)}function bq(){var cA=aw("cvar"),cz=ah(cA);if(cz.length){cz=JSON2.parse(cz);if(L(cz)){return cz}}return{}}function b2(){if(at===false){at=bq()}}function cc(){return bA((e.userAgent||"")+(e.platform||"")+JSON2.stringify(cq)+(new Date()).getTime()+Math.random()).slice(0,16)}function b9(){var cB=new Date(),cz=Math.round(cB.getTime()/1000),cA=aw("id"),cE=ah(cA),cD,cC;if(cE){cD=cE.split(".");cD.unshift("0");if(bi.length){cD[1]=bi}return cD}if(bi.length){cC=bi}else{if("0"===by()){cC=""}else{cC=cc()}}cD=["1",cC,cz,0,cz,"",""];return cD +}function aA(){var cG=b9(),cC=cG[0],cD=cG[1],cA=cG[2],cz=cG[3],cE=cG[4],cB=cG[5];if(!y(cG[6])){cG[6]=""}var cF=cG[6];return{newVisitor:cC,uuid:cD,createTs:cA,visitCount:cz,currentVisitTs:cE,lastVisitTs:cB,lastEcommerceOrderTs:cF}}function al(){var cC=new Date(),cA=cC.getTime(),cD=aA().createTs;var cz=parseInt(cD,10);var cB=(cz*1000)+b7-cA;return cB}function ao(cz){if(!bz){return}var cB=new Date(),cA=Math.round(cB.getTime()/1000);if(!y(cz)){cz=aA()}var cC=cz.uuid+"."+cz.createTs+"."+cz.visitCount+"."+cA+"."+cz.lastVisitTs+"."+cz.lastEcommerceOrderTs;cv(aw("id"),cC,al(),aY,ch)}function bg(){var cz=ah(aw("ref"));if(cz.length){try{cz=JSON2.parse(cz);if(L(cz)){return cz}}catch(cA){}}return["","",0,""]}function br(cB,cA,cz){cv(cB,"",-86400,cA,cz)}function a3(cA){var cz="testvalue";cv("test",cz,10000,null,cA);if(ah("test")===cz){br("test",null,cA);return true}return false}function aj(){var cB=aU;aU=false;var cz=["id","ses","cvar","ref"];var cA,cC;for(cA=0;cA<cz.length;cA++){cC=aw(cz[cA]);if(0!==ah(cC)){br(cC,aY,ch) +}}aU=cB}function bw(cz){bz=cz;ao()}function cy(cD){if(!cD||!L(cD)){return}var cC=[];var cB;for(cB in cD){if(Object.prototype.hasOwnProperty.call(cD,cB)){cC.push(cB)}}var cE={};cC.sort();var cz=cC.length;var cA;for(cA=0;cA<cz;cA++){cE[cC[cA]]=cD[cC[cA]]}return cE}function bG(){cv(aw("ses"),"*",bR,aY,ch)}function bU(cB,cW,cX,cC){var cV,cA=new Date(),cJ=Math.round(cA.getTime()/1000),cG,cU,cD=1024,c2,cK,cS=at,cE=aw("ses"),cQ=aw("ref"),cN=aw("cvar"),cO=ah(cE),cT=bg(),cZ=aG||bh,cH,cz;if(aU){aj()}if(cb){return""}var cP=aA();if(!y(cC)){cC=""}var cM=w.characterSet||w.charset;if(!cM||cM.toLowerCase()==="utf-8"){cM=null}cH=cT[0];cz=cT[1];cG=cT[2];cU=cT[3];if(!cO){var cY=bR/1000;if(!cP.lastVisitTs||(cJ-cP.lastVisitTs)>cY){cP.visitCount++;cP.lastVisitTs=cP.currentVisitTs}if(!a2||!cH.length){for(cV in bT){if(Object.prototype.hasOwnProperty.call(bT,cV)){cH=K(cZ,bT[cV]);if(cH.length){break}}}for(cV in bb){if(Object.prototype.hasOwnProperty.call(bb,cV)){cz=K(cZ,bb[cV]);if(cz.length){break}}}}c2=c(aW);cK=cU.length?c(cU):""; +if(c2.length&&!ay(c2)&&(!a2||!cK.length||ay(cK))){cU=aW}if(cU.length||cH.length){cG=cJ;cT=[cH,cz,cG,bv(cU.slice(0,cD))];cv(cQ,JSON2.stringify(cT),co,aY,ch)}}cB+="&idsite="+bz+"&rec=1&r="+String(Math.random()).slice(2,8)+"&h="+cA.getHours()+"&m="+cA.getMinutes()+"&s="+cA.getSeconds()+"&url="+m(bv(cZ))+(aW.length?"&urlref="+m(bv(aW)):"")+((a5&&a5.length)?"&uid="+m(a5):"")+"&_id="+cP.uuid+"&_idts="+cP.createTs+"&_idvc="+cP.visitCount+"&_idn="+cP.newVisitor+(cH.length?"&_rcn="+m(cH):"")+(cz.length?"&_rck="+m(cz):"")+"&_refts="+cG+"&_viewts="+cP.lastVisitTs+(String(cP.lastEcommerceOrderTs).length?"&_ects="+cP.lastEcommerceOrderTs:"")+(String(cU).length?"&_ref="+m(bv(cU.slice(0,cD))):"")+(cM?"&cs="+m(cM):"")+"&send_image=0";for(cV in cq){if(Object.prototype.hasOwnProperty.call(cq,cV)){cB+="&"+cV+"="+cq[cV]}}var c1=[];if(cW){for(cV in cW){if(Object.prototype.hasOwnProperty.call(cW,cV)&&/^dimension\d+$/.test(cV)){var cF=cV.replace("dimension","");c1.push(parseInt(cF,10));c1.push(String(cF));cB+="&"+cV+"="+cW[cV]; +delete cW[cV]}}}if(cW&&s(cW)){cW=null}for(cV in aV){if(Object.prototype.hasOwnProperty.call(aV,cV)){var cL=(-1===c1.indexOf(cV));if(cL){cB+="&dimension"+cV+"="+aV[cV]}}}if(cW){cB+="&data="+m(JSON2.stringify(cW))}else{if(Y){cB+="&data="+m(JSON2.stringify(Y))}}function cI(c3,c4){var c5=JSON2.stringify(c3);if(c5.length>2){return"&"+c4+"="+m(c5)}return""}var c0=cy(bp);var cR=cy(bO);cB+=cI(c0,"cvar");cB+=cI(cR,"e_cvar");if(at){cB+=cI(at,"_cvar");for(cV in cS){if(Object.prototype.hasOwnProperty.call(cS,cV)){if(at[cV][0]===""||at[cV][1]===""){delete at[cV]}}}if(bk){cv(cN,JSON2.stringify(at),bR,aY,ch)}}if(aE){if(bP){cB+=">_ms="+bP}else{if(f&&f.timing&&f.timing.requestStart&&f.timing.responseEnd){cB+=">_ms="+(f.timing.responseEnd-f.timing.requestStart)}}}cP.lastEcommerceOrderTs=y(cC)&&String(cC).length?cC:cP.lastEcommerceOrderTs;ao(cP);bG();cB+=Q(cX);if(cj.length){cB+="&"+cj}if(r(bE)){cB=bE(cB)}return cB}bl=function aI(){var cz=new Date();if(ci+aH<=cz.getTime()){var cA=bU("ping=1",null,"ping"); +ba(cA,bd);return true}return false};function aZ(cC,cB,cG,cD,cz,cJ){var cE="idgoal=0",cF,cA=new Date(),cH=[],cI;if(String(cC).length){cE+="&ec_id="+m(cC);cF=Math.round(cA.getTime()/1000)}cE+="&revenue="+cB;if(String(cG).length){cE+="&ec_st="+cG}if(String(cD).length){cE+="&ec_tx="+cD}if(String(cz).length){cE+="&ec_sh="+cz}if(String(cJ).length){cE+="&ec_dt="+cJ}if(ck){for(cI in ck){if(Object.prototype.hasOwnProperty.call(ck,cI)){if(!y(ck[cI][1])){ck[cI][1]=""}if(!y(ck[cI][2])){ck[cI][2]=""}if(!y(ck[cI][3])||String(ck[cI][3]).length===0){ck[cI][3]=0}if(!y(ck[cI][4])||String(ck[cI][4]).length===0){ck[cI][4]=1}cH.push(ck[cI])}}cE+="&ec_items="+m(JSON2.stringify(cH))}cE=bU(cE,Y,"ecommerce",cF);ba(cE,bd)}function bs(cz,cD,cC,cB,cA,cE){if(String(cz).length&&y(cD)){aZ(cz,cD,cC,cB,cA,cE)}}function a0(cz){if(y(cz)){aZ("",cz,"","","","")}}function bt(cB,cC){var cz=new Date(),cA=bU("action_name="+m(V(cB||aS)),cC,"log");ba(cA,bd)}function aC(cB,cA){var cC,cz="(^| )(piwik[_-]"+cA;if(cB){for(cC=0;cC<cB.length; +cC++){cz+="|"+cB[cC]}}cz+=")( |$)";return new RegExp(cz)}function ax(cz){return(ai&&cz&&0===String(cz).indexOf(ai))}function bV(cD,cz,cE,cA){if(ax(cz)){return 0}var cC=aC(bf,"download"),cB=aC(aJ,"link"),cF=new RegExp("\\.("+cp.join("|")+")([?&#]|$)","i");if(cB.test(cD)){return"link"}if(cA||cC.test(cD)||cF.test(cz)){return"download"}if(cE){return 0}return"link"}function ac(cA){var cz;cz=cA.parentNode;while(cz!==null&&y(cz)){if(S.isLinkElement(cA)){break}cA=cz;cz=cA.parentNode}return cA}function ct(cE){cE=ac(cE);if(!S.hasNodeAttribute(cE,"href")){return}if(!y(cE.href)){return}var cD=S.getAttributeValueFromNode(cE,"href");if(ax(cD)){return}var cA=cE.pathname||bN(cE.href);var cF=cE.hostname||c(cE.href);var cG=cF.toLowerCase();var cB=cE.href.replace(cF,cG);var cC=new RegExp("^(javascript|vbscript|jscript|mocha|livescript|ecmascript|mailto):","i");if(!cC.test(cB)){var cz=bV(cE.className,cB,ab(cG,cA),S.hasNodeAttribute(cE,"download"));if(cz){return{type:cz,href:cB}}}}function ar(cz,cA,cB,cC){var cD=n.buildInteractionRequestParams(cz,cA,cB,cC); +if(!cD){return}return bU(cD,null,"contentInteraction")}function b8(cB,cC,cG,cz,cA){if(!y(cB)){return}if(ax(cB)){return cB}var cE=n.toAbsoluteUrl(cB);var cD="redirecturl="+m(cE)+"&";cD+=ar(cC,cG,cz,(cA||cB));var cF="&";if(ai.indexOf("?")<0){cF="?"}return ai+cF+cD}function aN(cz,cA){if(!cz||!cA){return false}var cB=n.findTargetNode(cz);if(n.shouldIgnoreInteraction(cB)){return false}cB=n.findTargetNodeNoDefault(cz);if(cB&&!J(cB,cA)){return false}return true}function bW(cB,cA,cD){if(!cB){return}var cz=n.findParentContentNode(cB);if(!cz){return}if(!aN(cz,cB)){return}var cC=n.buildContentBlock(cz);if(!cC){return}if(!cC.target&&cD){cC.target=cD}return n.buildInteractionRequestParams(cA,cC.name,cC.piece,cC.target)}function az(cA){if(!bD||!bD.length){return false}var cz,cB;for(cz=0;cz<bD.length;cz++){cB=bD[cz];if(cB&&cB.name===cA.name&&cB.piece===cA.piece&&cB.target===cA.target){return true}}return false}function a9(cC){if(!cC){return false}var cF=n.findTargetNode(cC);if(!cF||n.shouldIgnoreInteraction(cF)){return false +}var cG=ct(cF);if(cr&&cG&&cG.type){return false}if(S.isLinkElement(cF)&&S.hasNodeAttributeWithValue(cF,"href")){var cz=String(S.getAttributeValueFromNode(cF,"href"));if(0===cz.indexOf("#")){return false}if(ax(cz)){return true}if(!n.isUrlToCurrentDomain(cz)){return false}var cD=n.buildContentBlock(cC);if(!cD){return}var cB=cD.name;var cH=cD.piece;var cE=cD.target;if(!S.hasNodeAttributeWithValue(cF,n.CONTENT_TARGET_ATTR)||cF.wasContentTargetAttrReplaced){cF.wasContentTargetAttrReplaced=true;cE=n.toAbsoluteUrl(cz);S.setAnyAttribute(cF,n.CONTENT_TARGET_ATTR,cE)}var cA=b8(cz,"click",cB,cH,cE);n.setHrefAttribute(cF,cA);return true}return false}function ap(cA){if(!cA||!cA.length){return}var cz;for(cz=0;cz<cA.length;cz++){a9(cA[cz])}}function aB(cz){return function(cA){if(!cz){return}var cD=n.findParentContentNode(cz);var cE;if(cA){cE=cA.target||cA.srcElement}if(!cE){cE=cz}if(!aN(cD,cE)){return}bJ(bd);if(S.isLinkElement(cz)&&S.hasNodeAttributeWithValue(cz,"href")&&S.hasNodeAttributeWithValue(cz,n.CONTENT_TARGET_ATTR)){var cB=S.getAttributeValueFromNode(cz,"href"); +if(!ax(cB)&&cz.wasContentTargetAttrReplaced){S.setAnyAttribute(cz,n.CONTENT_TARGET_ATTR,"")}}var cI=ct(cz);if(Z&&cI&&cI.type){return cI.type}if(a9(cD)){return"href"}var cF=n.buildContentBlock(cD);if(!cF){return}var cC=cF.name;var cJ=cF.piece;var cH=cF.target;var cG=ar("click",cC,cJ,cH);ba(cG,bd);return cG}}function bu(cB){if(!cB||!cB.length){return}var cz,cA;for(cz=0;cz<cB.length;cz++){cA=n.findTargetNode(cB[cz]);if(cA&&!cA.contentInteractionTrackingSetupDone){cA.contentInteractionTrackingSetupDone=true;X(cA,"click",aB(cA))}}}function a4(cB,cC){if(!cB||!cB.length){return[]}var cz,cA;for(cz=0;cz<cB.length;cz++){if(az(cB[cz])){cB.splice(cz,1);cz--}else{bD.push(cB[cz])}}if(!cB||!cB.length){return[]}ap(cC);bu(cC);var cD=[];for(cz=0;cz<cB.length;cz++){cA=bU(n.buildImpressionRequestParams(cB[cz].name,cB[cz].piece,cB[cz].target),undefined,"contentImpressions");cD.push(cA)}return cD}function bZ(cA){var cz=n.collectContent(cA);return a4(cz,cA)}function aL(cA){if(!cA||!cA.length){return[]}var cz; +for(cz=0;cz<cA.length;cz++){if(!n.isNodeVisible(cA[cz])){cA.splice(cz,1);cz--}}if(!cA||!cA.length){return[]}return bZ(cA)}function ak(cB,cz,cA){var cC=n.buildImpressionRequestParams(cB,cz,cA);return bU(cC,null,"contentImpression")}function cu(cC,cA){if(!cC){return}var cz=n.findParentContentNode(cC);var cB=n.buildContentBlock(cz);if(!cB){return}if(!cA){cA="Unknown"}return ar(cA,cB.name,cB.piece,cB.target)}function ca(cA,cC,cz,cB){return"e_c="+m(cA)+"&e_a="+m(cC)+(y(cz)?"&e_n="+m(cz):"")+(y(cB)?"&e_v="+m(cB):"")}function ad(cB,cD,cz,cC,cE){if(String(cB).length===0||String(cD).length===0){return false}var cA=bU(ca(cB,cD,cz,cC),cE,"event");ba(cA,bd)}function bC(cz,cC,cA,cD){var cB=bU("search="+m(cz)+(cC?"&search_cat="+m(cC):"")+(y(cA)?"&search_count="+cA:""),cD,"sitesearch");ba(cB,bd)}function ce(cz,cC,cB){var cA=bU("idgoal="+cz+(cC?"&revenue="+cC:""),cB,"goal");ba(cA,bd)}function cl(cC,cz,cG,cF,cB){var cE=cz+"="+m(bv(cC));var cA=bW(cB,"click",cC);if(cA){cE+="&"+cA}var cD=bU(cE,cG,"link");ba(cD,(cF?0:bd),cF) +}function bm(cA,cz){if(cA!==""){return cA+cz.charAt(0).toUpperCase()+cz.slice(1)}return cz}function bK(cE){var cD,cz,cC=["","webkit","ms","moz"],cB;if(!aQ){for(cz=0;cz<cC.length;cz++){cB=cC[cz];if(Object.prototype.hasOwnProperty.call(w,bm(cB,"hidden"))){if(w[bm(cB,"visibilityState")]==="prerender"){cD=true}break}}}if(cD){X(w,cB+"visibilitychange",function cA(){w.removeEventListener(cB+"visibilitychange",cA,false);cE()});return}cE()}function an(cz){if(w.readyState==="complete"){cz()}else{if(I.addEventListener){I.addEventListener("load",cz)}else{if(I.attachEvent){I.attachEvent("onLoad",cz)}}}}function aO(cA){var cz=false;if(w.attachEvent){cz=w.readyState==="complete"}else{cz=w.readyState!=="loading"}if(cz){cA()}else{if(w.addEventListener){w.addEventListener("DOMContentLoaded",cA)}else{if(w.attachEvent){w.attachEvent("onreadystatechange",cA)}}}}function b5(cz){var cA=ct(cz);if(cA&&cA.type){cA.href=j(cA.href);cl(cA.href,cA.type,undefined,null,cz)}}function bY(){return w.all&&!w.addEventListener +}function cg(cz){var cB=cz.which;var cA=(typeof cz.button);if(!cB&&cA!=="undefined"){if(bY()){if(cz.button&1){cB=1}else{if(cz.button&2){cB=3}else{if(cz.button&4){cB=2}}}}else{if(cz.button===0||cz.button==="0"){cB=1}else{if(cz.button&1){cB=2}else{if(cz.button&2){cB=3}}}}}return cB}function bn(cz){switch(cg(cz)){case 1:return"left";case 2:return"middle";case 3:return"right"}}function aD(cz){return cz.target||cz.srcElement}function ag(cz){return function(cC){cC=cC||I.event;var cB=bn(cC);var cD=aD(cC);if(cC.type==="click"){var cA=false;if(cz&&cB==="middle"){cA=true}if(cD&&!cA){b5(cD)}}else{if(cC.type==="mousedown"){if(cB==="middle"&&cD){au=cB;a7=cD}else{au=a7=null}}else{if(cC.type==="mouseup"){if(cB===au&&cD===a7){b5(cD)}au=a7=null}else{if(cC.type==="contextmenu"){b5(cD)}}}}}}function aa(cA,cz){X(cA,"click",ag(cz),false);if(cz){X(cA,"mouseup",ag(cz),false);X(cA,"mousedown",ag(cz),false);X(cA,"contextmenu",ag(cz),false)}}function a8(cA){if(!Z){Z=true;var cB,cz=aC(a6,"ignore"),cC=w.links;if(cC){for(cB=0; +cB<cC.length;cB++){if(!cz.test(cC[cB].className)){aa(cC[cB],cA)}}}}}function av(cB,cD,cE){if(bI){return true}bI=true;var cF=false;var cC,cA;function cz(){cF=true}an(function(){function cG(cI){setTimeout(function(){if(!bI){return}cF=false;cE.trackVisibleContentImpressions();cG(cI)},cI)}function cH(cI){setTimeout(function(){if(!bI){return}if(cF){cF=false;cE.trackVisibleContentImpressions()}cH(cI)},cI)}if(cB){cC=["scroll","resize"];for(cA=0;cA<cC.length;cA++){if(w.addEventListener){w.addEventListener(cC[cA],cz)}else{I.attachEvent("on"+cC[cA],cz)}}cH(100)}if(cD&&cD>0){cD=parseInt(cD,10);cG(cD)}})}function aK(cD,cF){var cE=bN(cD);var cC=bN(cF);if(!cE||cE==="/"||!cC||cC==="/"){return}var cB=A(cD);if(ab(cB,"/")){return}if(cm(cE,"/")){cE=aP(cE,1)}var cG=cE.split("/");var cA;for(cA=2;cA<cG.length;cA++){var cz=cG.slice(0,cA).join("/");if(ab(cB,cz)){cE=cz;break}}if(!aF(cC,cE)){return}return cE}function b3(){var cA,cB,cC={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",dir:"application/x-director",fla:"application/x-shockwave-flash",java:"application/x-java-vm",gears:"application/x-googlegears",ag:"application/x-silverlight"},cz=I.devicePixelRatio||1; +if(!((new RegExp("MSIE")).test(e.userAgent))){if(e.mimeTypes&&e.mimeTypes.length){for(cA in cC){if(Object.prototype.hasOwnProperty.call(cC,cA)){cB=e.mimeTypes[cC[cA]];cq[cA]=(cB&&cB.enabledPlugin)?"1":"0"}}}if(typeof navigator.javaEnabled!=="unknown"&&y(e.javaEnabled)&&e.javaEnabled()){cq.java="1"}if(r(I.GearsFactory)){cq.gears="1"}cq.cookie=by()}cq.res=M.width*cz+"x"+M.height*cz}b3();aR();ao();return{getVisitorId:function(){return aA().uuid},getVisitorInfo:function(){return b9()},getAttributionInfo:function(){return bg()},getAttributionCampaignName:function(){return bg()[0]},getAttributionCampaignKeyword:function(){return bg()[1]},getAttributionReferrerTimestamp:function(){return bg()[2]},getAttributionReferrerUrl:function(){return bg()[3]},setTrackerUrl:function(cz){ai=cz},getTrackerUrl:function(){return ai},getSiteId:function(){return bz},setSiteId:function(cz){bw(cz)},setUserId:function(cz){if(!y(cz)||!cz.length){return}a5=cz;bi=bA(a5).substr(0,16)},getUserId:function(){return a5},setCustomData:function(cz,cA){if(L(cz)){Y=cz +}else{if(!Y){Y={}}Y[cz]=cA}},getCustomData:function(){return Y},setCustomRequestProcessing:function(cz){bE=cz},appendToTrackingUrl:function(cz){cj=cz},getRequest:function(cz){return bU(cz)},addPlugin:function(cz,cA){a[cz]=cA},setCustomDimension:function(cz,cA){cz=parseInt(cz,10);if(cz>0){if(!y(cA)){cA=""}if(!o(cA)){cA=String(cA)}aV[cz]=cA}},getCustomDimension:function(cz){cz=parseInt(cz,10);if(cz>0&&Object.prototype.hasOwnProperty.call(aV,cz)){return aV[cz]}},deleteCustomDimension:function(cz){cz=parseInt(cz,10);if(cz>0){delete aV[cz]}},setCustomVariable:function(cA,cz,cD,cB){var cC;if(!y(cB)){cB="visit"}if(!y(cz)){return}if(!y(cD)){cD=""}if(cA>0){cz=!o(cz)?String(cz):cz;cD=!o(cD)?String(cD):cD;cC=[cz.slice(0,a1),cD.slice(0,a1)];if(cB==="visit"||cB===2){b2();at[cA]=cC}else{if(cB==="page"||cB===3){bp[cA]=cC}else{if(cB==="event"){bO[cA]=cC}}}}},getCustomVariable:function(cA,cB){var cz;if(!y(cB)){cB="visit"}if(cB==="page"||cB===3){cz=bp[cA]}else{if(cB==="event"){cz=bO[cA]}else{if(cB==="visit"||cB===2){b2(); +cz=at[cA]}}}if(!y(cz)||(cz&&cz[0]==="")){return false}return cz},deleteCustomVariable:function(cz,cA){if(this.getCustomVariable(cz,cA)){this.setCustomVariable(cz,"","",cA)}},storeCustomVariablesInCookie:function(){bk=true},setLinkTrackingTimer:function(cz){bd=cz},setDownloadExtensions:function(cz){if(o(cz)){cz=cz.split("|")}cp=cz},addDownloadExtensions:function(cA){var cz;if(o(cA)){cA=cA.split("|")}for(cz=0;cz<cA.length;cz++){cp.push(cA[cz])}},removeDownloadExtensions:function(cB){var cA,cz=[];if(o(cB)){cB=cB.split("|")}for(cA=0;cA<cp.length;cA++){if(B(cB,cp[cA])===-1){cz.push(cp[cA])}}cp=cz},setDomains:function(cz){ae=o(cz)?[cz]:cz;var cB=false,cA;for(cA in ae){if(Object.prototype.hasOwnProperty.call(ae,cA)&&b4(cf,A(String(ae[cA])))){cB=true;if(!aY){var cC=aK(ae[cA],bh);if(cC){this.setCookiePath(cC)}break}}}if(!cB){ae.push(cf)}},setIgnoreClasses:function(cz){a6=o(cz)?[cz]:cz},setRequestMethod:function(cz){cs=cz||bL},setRequestContentType:function(cz){bX=cz||am},setReferrerUrl:function(cz){aW=cz +},setCustomUrl:function(cz){aG=bo(bh,cz)},setDocumentTitle:function(cz){aS=cz},setAPIUrl:function(cz){bc=cz},setDownloadClasses:function(cz){bf=o(cz)?[cz]:cz},setLinkClasses:function(cz){aJ=o(cz)?[cz]:cz},setCampaignNameKey:function(cz){bT=o(cz)?[cz]:cz},setCampaignKeywordKey:function(cz){bb=o(cz)?[cz]:cz},discardHashTag:function(cz){bj=cz},setCookieNamePrefix:function(cz){aT=cz;at=bq()},setCookieDomain:function(cz){var cA=A(cz);if(a3(cA)){ch=cA;aR()}},setCookiePath:function(cz){aY=cz;aR()},setVisitorCookieTimeout:function(cz){b7=cz*1000},setSessionCookieTimeout:function(cz){bR=cz*1000},setReferralCookieTimeout:function(cz){co=cz*1000},setConversionAttributionFirstReferrer:function(cz){a2=cz},disableCookies:function(){aU=true;cq.cookie="0";if(bz){aj()}},deleteCookies:function(){aj()},setDoNotTrack:function(cA){var cz=e.doNotTrack||e.msDoNotTrack;cb=cA&&(cz==="yes"||cz==="1");if(cb){this.disableCookies()}},addListener:function(cA,cz){aa(cA,cz)},enableLinkTracking:function(cz){cr=true;if(q){a8(cz) +}else{G.push(function(){a8(cz)})}},enableJSErrorTracking:function(){if(cd){return}cd=true;var cz=I.onerror;I.onerror=function(cE,cC,cB,cD,cA){bK(function(){var cF="JavaScript Errors";var cG=cC+":"+cB;if(cD){cG+=":"+cD}ad(cF,cG,cE)});if(cz){return cz(cE,cC,cB,cD,cA)}return false}},disablePerformanceTracking:function(){aE=false},setGenerationTimeMs:function(cz){bP=parseInt(cz,10)},enableHeartBeatTimer:function(cz){cz=Math.max(cz,1);aH=(cz||15)*1000;if(ci!==null){cx()}},killFrame:function(){if(I.location!==I.top.location){I.top.location=I.location}},redirectFile:function(cz){if(I.location.protocol==="file:"){I.location=cz}},setCountPreRendered:function(cz){aQ=cz},trackGoal:function(cz,cB,cA){bK(function(){ce(cz,cB,cA)})},trackLink:function(cA,cz,cC,cB){bK(function(){cl(cA,cz,cC,cB)})},trackPageView:function(cz,cA){bD=[];if(C(bz)){bK(function(){O(ai,bc,bz)})}else{bK(function(){bt(cz,cA)})}},trackAllContentImpressions:function(){if(C(bz)){return}bK(function(){aO(function(){var cz=n.findContentNodes(); +var cA=bZ(cz);cw(cA,bd)})})},trackVisibleContentImpressions:function(cz,cA){if(C(bz)){return}if(!y(cz)){cz=true}if(!y(cA)){cA=750}av(cz,cA,this);bK(function(){an(function(){var cB=n.findContentNodes();var cC=aL(cB);cw(cC,bd)})})},trackContentImpression:function(cB,cz,cA){if(C(bz)){return}if(!cB){return}cz=cz||"Unknown";bK(function(){var cC=ak(cB,cz,cA);ba(cC,bd)})},trackContentImpressionsWithinNode:function(cz){if(C(bz)||!cz){return}bK(function(){if(bI){an(function(){var cA=n.findContentNodesWithinNode(cz);var cB=aL(cA);cw(cB,bd)})}else{aO(function(){var cA=n.findContentNodesWithinNode(cz);var cB=bZ(cA);cw(cB,bd)})}})},trackContentInteraction:function(cB,cC,cz,cA){if(C(bz)){return}if(!cB||!cC){return}cz=cz||"Unknown";bK(function(){var cD=ar(cB,cC,cz,cA);ba(cD,bd)})},trackContentInteractionNode:function(cA,cz){if(C(bz)||!cA){return}bK(function(){var cB=cu(cA,cz);ba(cB,bd)})},logAllContentBlocksOnPage:function(){var cA=n.findContentNodes();var cz=n.collectContent(cA);if(console!==undefined&&console&&console.log){console.log(cz) +}},trackEvent:function(cA,cC,cz,cB,cD){bK(function(){ad(cA,cC,cz,cB,cD)})},trackSiteSearch:function(cz,cB,cA,cC){bK(function(){bC(cz,cB,cA,cC)})},setEcommerceView:function(cC,cz,cB,cA){if(!y(cB)||!cB.length){cB=""}else{if(cB instanceof Array){cB=JSON2.stringify(cB)}}bp[5]=["_pkc",cB];if(y(cA)&&String(cA).length){bp[2]=["_pkp",cA]}if((!y(cC)||!cC.length)&&(!y(cz)||!cz.length)){return}if(y(cC)&&cC.length){bp[3]=["_pks",cC]}if(!y(cz)||!cz.length){cz=""}bp[4]=["_pkn",cz]},addEcommerceItem:function(cD,cz,cB,cA,cC){if(cD.length){ck[cD]=[cD,cz,cB,cA,cC]}},trackEcommerceOrder:function(cz,cD,cC,cB,cA,cE){bs(cz,cD,cC,cB,cA,cE)},trackEcommerceCartUpdate:function(cz){a0(cz)}}}function x(){return{push:T}}function b(ad,ac){var ae={};var aa,ab;for(aa=0;aa<ac.length;aa++){var Y=ac[aa];ae[Y]=1;for(ab=0;ab<ad.length;ab++){if(ad[ab]&&ad[ab][0]){var Z=ad[ab][0];if(Y===Z){T(ad[ab]);delete ad[ab];if(ae[Z]>1){if(console!==undefined&&console&&console.error){console.error("The method "+Z+' is registered more than once in "paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: http://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers') +}}ae[Z]++}}}}return ad}X(I,"beforeunload",U,false);p();Date.prototype.getTimeAlias=Date.prototype.getTime;N=new F();var t=["disableCookies","setTrackerUrl","setAPIUrl","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","enableLinkTracking"];_paq=b(_paq,t);for(v=0;v<_paq.length;v++){if(_paq[v]){T(_paq[v])}}_paq=new x();d={addPlugin:function(Y,Z){a[Y]=Z},getTracker:function(Y,Z){if(!y(Z)){Z=this.getAsyncTracker().getSiteId()}if(!y(Y)){Y=this.getAsyncTracker().getTrackerUrl()}return new F(Y,Z)},getAsyncTracker:function(){return N}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return d})}return d}())}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g); c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}; /*! @license-end */ }; \ No newline at end of file diff --git a/plugins/API/API.php b/plugins/API/API.php index 8dcaf0186b512ec6cc0d2e9d7c94083b1bbefb55..4eab2c63fd7f8c447218580cbcd88b7119a562cf 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -91,8 +91,9 @@ class API extends \Piwik\Plugin\API * are not visible in the UI and not present in the API meta data. These columns are * translated here. * @return array + * @deprecated since Piwik 2.15.1 */ - public static function getDefaultMetricTranslations() + public function getDefaultMetricTranslations() { return Metrics::getDefaultMetricTranslations(); } @@ -105,6 +106,8 @@ class API extends \Piwik\Plugin\API */ public function getAvailableMeasurableTypes() { + Piwik::checkUserHasSomeViewAccess(); + $typeManager = new TypeManager(); $types = $typeManager->getAllTypes(); @@ -123,11 +126,17 @@ class API extends \Piwik\Plugin\API public function getSegmentsMetadata($idSites = array(), $_hideImplementationData = true) { - $isAuthenticatedWithViewAccess = Piwik::isUserHasViewAccess($idSites) && !Piwik::isUserIsAnonymous(); + if (empty($idSites)) { + Piwik::checkUserHasSomeViewAccess(); + } else { + Piwik::checkUserHasViewAccess($idSites); + } + + $isNotAnonymous = !Piwik::isUserIsAnonymous(); $sites = (is_array($idSites) ? implode('.', $idSites) : (int) $idSites); $cache = Cache::getTransientCache(); - $cachKey = 'API.getSegmentsMetadata' . $sites . '_' . (int) $_hideImplementationData . '_' . (int) $isAuthenticatedWithViewAccess; + $cachKey = 'API.getSegmentsMetadata' . $sites . '_' . (int) $_hideImplementationData . '_' . (int) $isNotAnonymous; $cachKey = CacheId::pluginAware($cachKey); if ($cache->contains($cachKey)) { @@ -135,7 +144,7 @@ class API extends \Piwik\Plugin\API } $metadata = new SegmentMetadata(); - $segments = $metadata->getSegmentsMetadata($idSites, $_hideImplementationData, $isAuthenticatedWithViewAccess); + $segments = $metadata->getSegmentsMetadata($idSites, $_hideImplementationData, $isNotAnonymous); $cache->save($cachKey, $segments); @@ -164,6 +173,7 @@ class API extends \Piwik\Plugin\API * * @param bool $pathOnly If true, returns path relative to doc root. Otherwise, returns a URL. * @return string + * @deprecated since Piwik 2.15.1 */ public function getLogoUrl($pathOnly = false) { @@ -176,6 +186,7 @@ class API extends \Piwik\Plugin\API * * @param bool $pathOnly If true, returns path relative to doc root. Otherwise, returns a URL. * @return string + * @deprecated since Piwik 2.15.1 */ public function getHeaderLogoUrl($pathOnly = false) { @@ -214,6 +225,8 @@ class API extends \Piwik\Plugin\API public function getMetadata($idSite, $apiModule, $apiAction, $apiParameters = array(), $language = false, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false) { + Piwik::checkUserHasViewAccess($idSite); + if ($language) { /** @var Translator $translator */ $translator = StaticContainer::get('Piwik\Translation\Translator'); @@ -239,6 +252,8 @@ class API extends \Piwik\Plugin\API public function getReportMetadata($idSites = '', $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false) { + Piwik::checkUserHasViewAccess($idSites); + $reporter = new ProcessedReport(); $metadata = $reporter->getReportMetadata($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports); return $metadata; @@ -247,11 +262,13 @@ class API extends \Piwik\Plugin\API public function getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment = false, $apiParameters = false, $idGoal = false, $language = false, $showTimer = true, $hideMetricsDoc = false, $idSubtable = false, $showRawMetrics = false, - $format_metrics = null) + $format_metrics = null, $idDimension = false) { + Piwik::checkUserHasViewAccess($idSite); + $reporter = new ProcessedReport(); $processed = $reporter->getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment, - $apiParameters, $idGoal, $language, $showTimer, $hideMetricsDoc, $idSubtable, $showRawMetrics, $format_metrics); + $apiParameters, $idGoal, $language, $showTimer, $hideMetricsDoc, $idSubtable, $showRawMetrics, $format_metrics, $idDimension); return $processed; } @@ -296,6 +313,8 @@ class API extends \Piwik\Plugin\API */ public function get($idSite, $period, $date, $segment = false, $columns = false) { + Piwik::checkUserHasViewAccess($idSite); + $columns = Piwik::getArrayFromApiParameter($columns); // build columns map for faster checks later on @@ -376,13 +395,16 @@ class API extends \Piwik\Plugin\API * @param bool|int $idGoal * @param bool|string $legendAppendMetric * @param bool|string $labelUseAbsoluteUrl + * @param bool|int $idDimension * @return array */ - public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true) + public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true, $idDimension = false) { + Piwik::checkUserHasViewAccess($idSite); + $rowEvolution = new RowEvolution(); return $rowEvolution->getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label, $segment, $column, - $language, $idGoal, $legendAppendMetric, $labelUseAbsoluteUrl); + $language, $idGoal, $legendAppendMetric, $labelUseAbsoluteUrl, $idDimension); } /** @@ -442,30 +464,20 @@ class API extends \Piwik\Plugin\API if (empty(Config::getInstance()->General['enable_segment_suggested_values'])) { return array(); } + Piwik::checkUserHasViewAccess($idSite); $maxSuggestionsToReturn = 30; - $segmentsMetadata = $this->getSegmentsMetadata($idSite, $_hideImplementationData = false); - - $segmentFound = false; - foreach ($segmentsMetadata as $segmentMetadata) { - if ($segmentMetadata['segment'] == $segmentName) { - $segmentFound = $segmentMetadata; - break; - } - } - if (empty($segmentFound)) { - throw new \Exception("Requested segment not found."); - } + $segment = $this->findSegment($segmentName, $idSite); // if segment has suggested values callback then return result from it instead $suggestedValuesCallbackRequiresTable = false; - if (isset($segmentFound['suggestedValuesCallback'])) { + if (isset($segment['suggestedValuesCallback'])) { $suggestedValuesCallbackRequiresTable = $this->doesSuggestedValuesCallbackNeedData( - $segmentFound['suggestedValuesCallback']); + $segment['suggestedValuesCallback']); if (!$suggestedValuesCallbackRequiresTable) { - return call_user_func($segmentFound['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn); + return call_user_func($segment['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn); } } @@ -474,6 +486,57 @@ class API extends \Piwik\Plugin\API return array(); } + if (!empty($segment['unionOfSegments'])) { + $values = array(); + foreach ($segment['unionOfSegments'] as $unionSegmentName) { + $unionSegment = $this->findSegment($unionSegmentName, $idSite); + + try { + $result = $this->getSuggestedValuesForSegmentName($idSite, $unionSegment, $maxSuggestionsToReturn); + if (!empty($result)) { + $values = array_merge($result, $values); + } + } catch (\Exception $e) { + // we ignore if there was no data found for $unionSegmentName + } + } + + if (empty($values)) { + throw new \Exception("There was no data to suggest for $segmentName"); + } + + } else { + $values = $this->getSuggestedValuesForSegmentName($idSite, $segment, $maxSuggestionsToReturn); + } + + $values = $this->getMostFrequentValues($values); + $values = array_slice($values, 0, $maxSuggestionsToReturn); + $values = array_map(array('Piwik\Common', 'unsanitizeInputValue'), $values); + + return $values; + } + + private function findSegment($segmentName, $idSite) + { + $segmentsMetadata = $this->getSegmentsMetadata($idSite, $_hideImplementationData = false); + + $segmentFound = false; + foreach ($segmentsMetadata as $segmentMetadata) { + if ($segmentMetadata['segment'] == $segmentName) { + $segmentFound = $segmentMetadata; + break; + } + } + + if (empty($segmentFound)) { + throw new \Exception("Requested segment $segmentName not found."); + } + + return $segmentFound; + } + + private function getSuggestedValuesForSegmentName($idSite, $segment, $maxSuggestionsToReturn) + { $startDate = Date::now()->subDay(60)->toString(); $requestLastVisits = "method=Live.getLastVisitsDetails &idSite=$idSite @@ -483,6 +546,8 @@ class API extends \Piwik\Plugin\API &serialize=0 &flat=1"; + $segmentName = $segment['segment']; + // Select non empty fields only // Note: this optimization has only a very minor impact $requestLastVisits .= "&segment=$segmentName" . urlencode('!='); @@ -497,22 +562,18 @@ class API extends \Piwik\Plugin\API $request = new Request($requestLastVisits); $table = $request->process(); + if (empty($table)) { throw new \Exception("There was no data to suggest for $segmentName"); } - if ($suggestedValuesCallbackRequiresTable) { - $values = call_user_func($segmentFound['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn, $table); + if (isset($segment['suggestedValuesCallback']) && + $this->doesSuggestedValuesCallbackNeedData($segment['suggestedValuesCallback'])) { + $values = call_user_func($segment['suggestedValuesCallback'], $idSite, $maxSuggestionsToReturn, $table); } else { $values = $this->getSegmentValuesFromVisitorLog($segmentName, $table); } - $values = $this->getMostFrequentValues($values); - - $values = array_slice($values, 0, $maxSuggestionsToReturn); - - $values = array_map(array('Piwik\Common', 'unsanitizeInputValue'), $values); - return $values; } diff --git a/plugins/API/ProcessedReport.php b/plugins/API/ProcessedReport.php index 65b59a205196475b132a90449e34961a7f6e224c..8a9a96b5370cc2f19feea50d8f91a8be4effaf9e 100644 --- a/plugins/API/ProcessedReport.php +++ b/plugins/API/ProcessedReport.php @@ -298,17 +298,25 @@ class ProcessedReport public function getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment = false, $apiParameters = false, $idGoal = false, $language = false, $showTimer = true, $hideMetricsDoc = false, $idSubtable = false, $showRawMetrics = false, - $formatMetrics = null) + $formatMetrics = null, $idDimension = false) { $timer = new Timer(); if (empty($apiParameters)) { $apiParameters = array(); } + if (!empty($idGoal) && empty($apiParameters['idGoal']) ) { $apiParameters['idGoal'] = $idGoal; } + + if (!empty($idDimension) + && empty($apiParameters['idDimension']) + ) { + $apiParameters['idDimension'] = (int) $idDimension; + } + // Is this report found in the Metadata available reports? $reportMetadata = $this->getMetadata($idSite, $apiModule, $apiAction, $apiParameters, $language, $period, $date, $hideMetricsDoc, $showSubtableReports = true); diff --git a/plugins/API/RowEvolution.php b/plugins/API/RowEvolution.php index c7086080896ef4260e6ba1a3b6fcd301b378eaff..711a48316ca5823a5c14615021d745a923055698 100644 --- a/plugins/API/RowEvolution.php +++ b/plugins/API/RowEvolution.php @@ -37,7 +37,7 @@ class RowEvolution 'getPageUrl' ); - public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true) + public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true, $idDimension = false) { // validation of requested $period & $date if ($period == 'range') { @@ -52,9 +52,9 @@ class RowEvolution $label = DataTablePostProcessor::unsanitizeLabelParameter($label); $labels = Piwik::getArrayFromApiParameter($label); - $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal); + $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal, $idDimension); - $dataTable = $this->loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $idGoal); + $dataTable = $this->loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $idGoal, $idDimension); if (empty($labels)) { $labels = $this->getLabelsFromDataTable($dataTable, $labels); @@ -249,7 +249,7 @@ class RowEvolution * @throws Exception * @return DataTable\Map|DataTable */ - private function loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $idGoal = false) + private function loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $idGoal = false, $idDimension = false) { if (!is_array($label)) { $label = array($label); @@ -266,6 +266,7 @@ class RowEvolution 'serialize' => '0', 'segment' => $segment, 'idGoal' => $idGoal, + 'idDimension' => $idDimension, // data for row evolution should NOT be limited 'filter_limit' => -1, @@ -310,12 +311,15 @@ class RowEvolution * @throws Exception * @return array */ - private function getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal = false) + private function getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal = false, $idDimension = false) { $apiParameters = array(); if (!empty($idGoal) && $idGoal > 0) { $apiParameters = array('idGoal' => $idGoal); } + if (!empty($idDimension) && $idDimension > 0) { + $apiParameters = array('idDimension' => (int) $idDimension); + } $reportMetadata = API::getInstance()->getMetadata($idSite, $apiModule, $apiAction, $apiParameters, $language, $period, $date, $hideMetricsDoc = false, $showSubtableReports = true); diff --git a/plugins/API/lang/cs.json b/plugins/API/lang/cs.json index 68c93a8e58da43985b4227393fb2e93c89dd33f5..32d7dcba79c2b72f79151ebe7724e86488e2baf1 100644 --- a/plugins/API/lang/cs.json +++ b/plugins/API/lang/cs.json @@ -4,9 +4,9 @@ "KeepTokenSecret": "Tento token_auth je tajný jako vaÅ¡e uživatelské jméno a heslo, %s neÅ™Ãkejte jej nikomu jinému %s!", "LoadedAPIs": "ÚspěšnÄ› naÄteno %s API", "MoreInformation": "Pro vÃce informacà o API Piwiku se podÃvejte na %s Úvod do API Piwiku %s a %s Referenci API Piwiku %s", - "PluginDescription": "VÅ¡echna data v Piwiku jsou dostupná pomocà jednoduchých API. Tento zásuvný modul je vstupnÃm bodem tÄ›chto webových služeb, který vám umožňuje zÃskat vaÅ¡e analitická data jako XML, JSON, CSV, PHP atd.", + "PluginDescription": "VÅ¡echna data v Piwiku jsou dostupná pomocà jednoduchých API. Tento zásuvný modul je vstupnÃm bodem tÄ›chto webových služeb, který vám umožňuje zÃskat vaÅ¡e analytická data jako XML, JSON, CSV, PHP atd.", "ReportingApiReference": "Reference API hlášenÃ", - "TopLinkTooltip": "ZpÅ™ÃstupnÄ›te VaÅ¡e Webové analýzy programovÄ› skrze jednoduché API pomocà json, xml a dalÅ¡Ãch.", + "TopLinkTooltip": "ZpÅ™ÃstupnÄ›te svoje Webové analýzy programovÄ› skrze jednoduché API pomocà json, xml a dalÅ¡Ãch.", "UserAuthentication": "Autentifikace uživatele", "UsingTokenAuth": "Pokud chcete %s naÄÃst data ze skriptu, cronu, atd. %s PotÅ™ebujete pÅ™idat parametr %s k volánÃm API, které vyžadujà pÅ™ihlášenÃ", "Glossary": "Glosář", diff --git a/plugins/API/lang/ja.json b/plugins/API/lang/ja.json index 7e65064104725213cef090499a4834c628e4aea4..f32bf15992133ef40ab447218369c19a8cf3b3e3 100644 --- a/plugins/API/lang/ja.json +++ b/plugins/API/lang/ja.json @@ -5,8 +5,11 @@ "LoadedAPIs": "%s API ãŒæ£å¸¸ã«èªã¿è¾¼ã¾ã‚Œã¾ã—ãŸ", "MoreInformation": "Piwik API ã®è©³ç´°ã«ã¤ã„ã¦ã¯ã€%sIntroduction to Piwik API%s ã‚„ %sPiwik API Reference%s ã‚’å‚ç…§ã—ã¦ãã ã•ã„。", "PluginDescription": "Pwik ã®å…¨ã¦ã®ãƒ‡ãƒ¼ã‚¿ã¯ç°¡å˜ãª API を通ã—ã¦åˆ©ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“ã®ãƒ—ラグインã¯ã‚¦ã‚§ãƒ–サービスã®å…¥ã‚Šå£ã§ã€xml , json , php , csv ãªã©ã®ã‚ãªãŸã®ã‚¦ã‚§ãƒ–分æžãƒ‡ãƒ¼ã‚¿ã‚’入手ã™ã‚‹ãŸã‚ã«å‘¼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã™ã€‚", + "ReportingApiReference": "API ãƒªãƒ•ã‚¡ãƒ¬ãƒ³ã‚¹ã‚’å ±å‘Š", "TopLinkTooltip": "jsopnã€xmlç‰ã‚·ãƒ³ãƒ—ルãªAPIを介ã—ã¦ã€ãƒ—ãƒã‚°ãƒ©ãƒ ã§åˆ†æžãƒ‡ãƒ¼ã‚¿ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™", "UserAuthentication": "ユーザーèªè¨¼", - "UsingTokenAuth": "%sスクリプト(crontab ç‰ï¼‰ã§ãƒªã‚¯ã‚¨ã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿ã‚’å¾—ãŸã„å ´åˆ%sã¯ã€API をコールã™ã‚‹ URL(èªè¨¼ãŒå¿…è¦ï¼‰ã«ãƒ‘ラメータ %s ã‚’ä»˜åŠ ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + "UsingTokenAuth": "%sスクリプト(crontab ç‰ï¼‰ã§ãƒªã‚¯ã‚¨ã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿ã‚’å¾—ãŸã„å ´åˆ%sã¯ã€API をコールã™ã‚‹ URL(èªè¨¼ãŒå¿…è¦ï¼‰ã«ãƒ‘ラメータ %s ã‚’ä»˜åŠ ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚", + "Glossary": "用語集", + "LearnAboutCommonlyUsedTerms": "Piwik Analytics ã®æœ€ã‚‚よã使ã‚れる用語ã«ã¤ã„ã¦: %s 㨠%s" } } \ No newline at end of file diff --git a/plugins/API/lang/ko.json b/plugins/API/lang/ko.json index c2c86579601eea0ef208c49e9b598270b9812ed0..2f0405137876aa88fd50bf66fb137529e7ec46b7 100644 --- a/plugins/API/lang/ko.json +++ b/plugins/API/lang/ko.json @@ -5,7 +5,9 @@ "LoadedAPIs": "성공ì 으로 %s API를 불러옴", "MoreInformation": "Piwik APIì— ëŒ€í•œ ìžì„¸í•œ ë‚´ìš©ì€ %sIntroduction to Piwik API %s 문서와 %sPiwik API Reference%s 문서를 참조하세요.", "TopLinkTooltip": "JSON, XML ë“±ì˜ ê°„ë‹¨í•œ API를 통해 í”„ë¡œê·¸ëž˜ë° ë°©ì‹ìœ¼ë¡œ 웹 로그 ë¶„ì„ ë°ì´í„°ì— ì ‘ê·¼í• ìˆ˜ 있습니다.", - "UserAuthentication": "ìš©ìž ì¸ì¦", - "UsingTokenAuth": "%s 스í¬ë¦½íЏ (crontab 등)ì—서 ìš”ì² ë°ì´í„°ë¥¼ ì–»ê³ ì‹¶ë‹¤ë©´ %s는 API를 호출하는 URL (ì¸ì¦ í•„ìš”)ì— ë§¤ê°œ 변수 %s를 추가해야합니다." + "UserAuthentication": "ì‚¬ìš©ìž ì¸ì¦", + "UsingTokenAuth": "%s 스í¬ë¦½íЏ (crontab 등)ì—서 ìš”ì² ë°ì´í„°ë¥¼ ì–»ê³ ì‹¶ë‹¤ë©´ %s는 API를 호출하는 URL (ì¸ì¦ í•„ìš”)ì— ë§¤ê°œ 변수 %s를 추가해야합니다.", + "Glossary": "용어", + "LearnAboutCommonlyUsedTerms": "Piwik ë¶„ì„ì— ìžˆì–´ ìžì£¼ 사용ë˜ëŠ” 용어 %s 와 %s 배우기" } } \ No newline at end of file diff --git a/plugins/API/lang/nb.json b/plugins/API/lang/nb.json index 7cde5b4d1cb7089ac10f4040a9e809e5fb01c9e9..cd56984f85788bee7269ccbe604ba05ce67b5cc9 100644 --- a/plugins/API/lang/nb.json +++ b/plugins/API/lang/nb.json @@ -1,6 +1,7 @@ { "API": { "LoadedAPIs": "Lastet %s API", - "UserAuthentication": "Brukerautentisering" + "UserAuthentication": "Brukerautentisering", + "Glossary": "Ordliste" } } \ No newline at end of file diff --git a/plugins/Actions/Actions.php b/plugins/Actions/Actions.php index bca43962710e95cd80df61f960839edc0b9ba62c..b42ccf25393a5eba03922d1095291a4e8ce24855 100644 --- a/plugins/Actions/Actions.php +++ b/plugins/Actions/Actions.php @@ -106,6 +106,7 @@ class Actions extends \Piwik\Plugin public function getJsFiles(&$jsFiles) { $jsFiles[] = "plugins/Actions/javascripts/actionsDataTable.js"; + $jsFiles[] = "plugins/Actions/javascripts/rowactions.js"; } public function isSiteSearchEnabled($idSites, $idSite) diff --git a/plugins/Actions/Archiver.php b/plugins/Actions/Archiver.php index 5110130b849f8ada78b2469c57582c26067615a8..7610e973ef9bacc4b3ceeaa7aa071703aad90a65 100644 --- a/plugins/Actions/Archiver.php +++ b/plugins/Actions/Archiver.php @@ -149,10 +149,7 @@ class Archiver extends \Piwik\Plugin\Archiver $select = "log_action.name, log_action.type, log_action.idaction, - log_action.url_prefix, - count(distinct log_link_visit_action.idvisit) as `" . PiwikMetrics::INDEX_NB_VISITS . "`, - count(distinct log_link_visit_action.idvisitor) as `" . PiwikMetrics::INDEX_NB_UNIQ_VISITORS . "`, - count(*) as `" . PiwikMetrics::INDEX_PAGE_NB_HITS . "`"; + log_action.url_prefix"; $select = $this->addMetricsToSelect($select, $metricsConfig); @@ -178,8 +175,7 @@ class Archiver extends \Piwik\Plugin\Archiver $rankingQuery = new RankingQuery($rankingQueryLimit); $rankingQuery->setOthersLabel(DataTable::LABEL_SUMMARY_ROW); $rankingQuery->addLabelColumn(array('idaction', 'name')); - $rankingQuery->addColumn(array('url_prefix', PiwikMetrics::INDEX_NB_UNIQ_VISITORS)); - $rankingQuery->addColumn(array(PiwikMetrics::INDEX_PAGE_NB_HITS, PiwikMetrics::INDEX_NB_VISITS), 'sum'); + $rankingQuery->addColumn('url_prefix'); if ($this->isSiteSearchEnabled()) { $rankingQuery->addColumn(PiwikMetrics::INDEX_SITE_SEARCH_HAS_NO_RESULT, 'min'); diff --git a/plugins/Actions/ArchivingHelper.php b/plugins/Actions/ArchivingHelper.php index b5735225b856954bae6cbc8c1c16413bd5230eb5..192a3089ba31b6fcf10ceecc1a70e0da7cc3a35c 100644 --- a/plugins/Actions/ArchivingHelper.php +++ b/plugins/Actions/ArchivingHelper.php @@ -53,7 +53,7 @@ class ArchivingHelper unset($row[PiwikMetrics::INDEX_SITE_SEARCH_HAS_NO_RESULT]); } - if ($row['type'] == Action::TYPE_CONTENT) { + if (in_array($row['type'], array(Action::TYPE_CONTENT, Action::TYPE_EVENT))) { continue; } diff --git a/plugins/Actions/Columns/ActionType.php b/plugins/Actions/Columns/ActionType.php new file mode 100644 index 0000000000000000000000000000000000000000..3d6e9b599aa4f15c50a642286f4681cd41321ce6 --- /dev/null +++ b/plugins/Actions/Columns/ActionType.php @@ -0,0 +1,70 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Actions\Columns; + +use Piwik\Piwik; +use Piwik\Plugin\Dimension\ActionDimension; +use Piwik\Plugins\Actions\Segment; +use Piwik\Tracker\Action; +use Exception; + +/** + * This example dimension only defines a name and does not track any data. It's supposed to be only used in reports. + * + * See {@link http://developer.piwik.org/api-reference/Piwik/Columns\Dimension} for more information. + */ +class ActionType extends ActionDimension +{ + private $types = array( + Action::TYPE_PAGE_URL => 'pageviews', + Action::TYPE_CONTENT => 'contents', + Action::TYPE_SITE_SEARCH => 'sitesearches', + Action::TYPE_EVENT => 'events', + Action::TYPE_OUTLINK => 'outlinks', + Action::TYPE_DOWNLOAD => 'downloads' + ); + + /** + * The name of the dimension which will be visible for instance in the UI of a related report and in the mobile app. + * @return string + */ + public function getName() + { + return Piwik::translate('Actions_ActionType'); + } + + protected function configureSegments() + { + $types = $this->types; + + $segment = new Segment(); + $segment->setSegment('actionType'); + $segment->setName('Actions_ActionType'); + $segment->setSqlSegment('log_action.type'); + $segment->setType(Segment::TYPE_METRIC); + $segment->setAcceptedValues(sprintf('A type of action, such as: %s', implode(', ', $types))); + $segment->setSqlFilter(function ($type) use ($types) { + if (array_key_exists($type, $types)) { + return $type; + } + + $index = array_search(strtolower(trim(urldecode($type))), $types); + + if ($index === false) { + throw new Exception("actionType must be one of: " . implode(', ', $types)); + } + + return $index; + }); + $segment->setSuggestedValuesCallback(function ($idSite, $maxSuggestionsToReturn) use ($types) { + return array_slice(array_values($types), 0, $maxSuggestionsToReturn); + }); + $this->addSegment($segment); + } +} \ No newline at end of file diff --git a/plugins/Actions/Columns/ActionUrl.php b/plugins/Actions/Columns/ActionUrl.php new file mode 100644 index 0000000000000000000000000000000000000000..5fa80d1efa744a68f6ef6b1ce7802788f2bda8c6 --- /dev/null +++ b/plugins/Actions/Columns/ActionUrl.php @@ -0,0 +1,32 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Actions\Columns; + +use Piwik\Piwik; +use Piwik\Plugin\Dimension\ActionDimension; +use Piwik\Plugins\Actions\Segment; + +class ActionUrl extends ActionDimension +{ + public function getName() + { + return Piwik::translate('Actions_ColumnActionURL'); + } + + protected function configureSegments() + { + $segment = new Segment(); + $segment->setSegment('actionUrl'); + $segment->setName('Actions_ColumnActionURL'); + $segment->setUnionOfSegments(array('pageUrl', 'downloadUrl', 'outlinkUrl')); + + $this->addSegment($segment); + } + +} diff --git a/plugins/Actions/Metrics.php b/plugins/Actions/Metrics.php index 83b1c7370aeecb2270ac338f96e07ddd17282191..006fd6043dd633f6039cafa3ac60969627a464ab 100644 --- a/plugins/Actions/Metrics.php +++ b/plugins/Actions/Metrics.php @@ -50,6 +50,18 @@ class Metrics public static function getActionMetrics() { $metricsConfig = array( + PiwikMetrics::INDEX_NB_VISITS => array( + 'aggregation' => 'sum', + 'query' => "count(distinct log_link_visit_action.idvisit)" + ), + PiwikMetrics::INDEX_NB_UNIQ_VISITORS => array( + 'aggregation' => false, + 'query' => "count(distinct log_link_visit_action.idvisitor)" + ), + PiwikMetrics::INDEX_PAGE_NB_HITS => array( + 'aggregation' => 'sum', + 'query' => "count(*)" + ), PiwikMetrics::INDEX_PAGE_SUM_TIME_GENERATION => array( 'aggregation' => 'sum', 'query' => "sum( diff --git a/plugins/Actions/Reports/GetPageUrls.php b/plugins/Actions/Reports/GetPageUrls.php index 2c850a5339d5fd78d74e4e3942827b60e00de8b9..004d11ba88283be04207f949233e903ac986c2a7 100644 --- a/plugins/Actions/Reports/GetPageUrls.php +++ b/plugins/Actions/Reports/GetPageUrls.php @@ -39,7 +39,6 @@ class GetPageUrls extends Base new AveragePageGenerationTime() ); - $this->segmentSql = 'log_visit.visit_entry_idaction_url'; $this->subcategoryId = 'General_Pages'; } diff --git a/plugins/Actions/config/config.php b/plugins/Actions/config/config.php deleted file mode 100644 index 293acee476975129481a710b649bd7dd36672373..0000000000000000000000000000000000000000 --- a/plugins/Actions/config/config.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php - -return array( - - 'tracker.request.processors' => DI\add(array( - DI\get('Piwik\Plugins\Actions\Tracker\ActionsRequestProcessor'), - )), - -); diff --git a/plugins/Actions/javascripts/rowactions.js b/plugins/Actions/javascripts/rowactions.js new file mode 100644 index 0000000000000000000000000000000000000000..33050b90edf1f37790260fff863c1912e7518a46 --- /dev/null +++ b/plugins/Actions/javascripts/rowactions.js @@ -0,0 +1,65 @@ +$(function () { + + function isActionsModule(params) + { + return params.module == 'Actions'; + } + + function isPageUrlReport(params) { + var action = params.action; + + return isActionsModule(params) && + (action == 'getPageUrls' || action == 'getEntryPageUrls' || action == 'getExitPageUrls' || action == 'getPageUrlsFollowingSiteSearch'); + }; + + function isPageTitleReport(params) { + var action = params.action; + + return isActionsModule(params) && (action == 'getPageTitles' || action == 'getPageTitlesFollowingSiteSearch'); + }; + + function getLinkForTransitionAndOverlayPopover(tr) + { + var link = tr.find('> td:first > a').attr('href'); + link = $('<textarea>').html(link).val(); // remove html entities + return link; + } + + DataTable_RowActions_Transitions.registerReport({ + isAvailableOnReport: function (dataTableParams) { + return isPageUrlReport(dataTableParams); + }, + isAvailableOnRow: function (dataTableParams, tr) { + return isPageUrlReport(dataTableParams) && tr.find('> td:first span.label').parent().is('a') + }, + trigger: function (tr, e, subTableLabel) { + var link = getLinkForTransitionAndOverlayPopover(tr); + this.openPopover('url:' + link); + } + }); + + DataTable_RowActions_Transitions.registerReport({ + isAvailableOnReport: function (dataTableParams) { + return isPageTitleReport(dataTableParams); + }, + isAvailableOnRow: function (dataTableParams, tr) { + return isPageTitleReport(dataTableParams); + }, + trigger: function (tr, e, subTableLabel) { + DataTable_RowAction.prototype.trigger.apply(this, [tr, e, subTableLabel]); + } + }); + + DataTable_RowActions_Overlay.registerReport({ + isAvailableOnReport: function (dataTableParams) { + return isPageUrlReport(dataTableParams); + }, + onClick: function (actionA, tr, e) { + return { + link: getLinkForTransitionAndOverlayPopover(tr), + segment: null + } + } + }); + +}); \ No newline at end of file diff --git a/plugins/Actions/lang/cs.json b/plugins/Actions/lang/cs.json index 1c68478b02ee07370f2ef41359a026af9a34ca32..5b63d05d6002000ecd0b438582938af58e99d483 100644 --- a/plugins/Actions/lang/cs.json +++ b/plugins/Actions/lang/cs.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "PrůmÄ›r dle %s pÅ™Ãstupů %s mezi %s a %s", "ColumnClickedURL": "URL prokliku", + "ColumnActionURL": "URL akce", "ColumnClicks": "Prokliků", "ColumnClicksDocumentation": "PoÄet kliknutà na odkaz v závislosti na Äase.", "ColumnDownloadURL": "URL staženÃ", @@ -32,17 +33,17 @@ "ExitPagesReportDocumentation": "Toto hlášenà obsahuje informace o výstupnÃch stránkách, které se vyskytly v daném obdobÃ. Výstupnà stránka je poslednà stránkou, kterou uživatel zobrazà bÄ›hem své návÅ¡tÄ›vy. %s URL výstupnÃch stránek jsou zobrazeny jako strom složek.", "ExitPageTitles": "Titulky výstupnÃch stránek", "ExitPageTitlesReportDocumentation": "Toto hlášenà obsahuje informace o titulcÃch výstupnÃch stránek za dané obdobÃ.", - "LearnMoreAboutSiteSearchLink": "ZjistÄ›te vÃce o sledovánà toho, jak návÅ¡tÄ›vnÃci použÃvaà váš vyhledávaÄ.", + "LearnMoreAboutSiteSearchLink": "ZjistÄ›te vÃce o sledovánà toho, jak návÅ¡tÄ›vnÃci použÃvajà váš vyhledávaÄ.", "OneSearch": "1 VyhledávánÃ", "OutlinkDocumentation": "Externà odkaz je odkaz, který vede z vaÅ¡ich stránek na jinou domén.", "OutlinksReportDocumentation": "Toto hlášenà zobrazuje hyerarchický seznam URL externÃch odkazů, na které vaÅ¡i návÅ¡tÄ›vnÃci klikli.", "PagesReportDocumentation": "Toto hlášenà obsahuje informace o URL navÅ¡tÃvených. %s Tabulka je organizována hyerarchicky jako strom složek.", "PageTitlesReportDocumentation": "Toto hlášenà obsahuje informace o titulcÃch navÅ¡tÃvených stránek. %s Titulek je HTML tag %s, který vÄ›tÅ¡ina prohlÞeÄů zobrazuje v titulku okna.", "PageUrls": "URL stránky", - "PluginDescription": "Podává hlášenà o zobrazenà a titulcÃch stránek. Umožňuje vám měřit váš internà vyhledávaÄ. Automaticky sleduje kliky na externà odkazy a soubory ke staženÃ.", + "PluginDescription": "Podává hlášenà o zobrazenà a titulcÃch stránek. Umožňuje měřit váš internà vyhledávaÄ. Automaticky sleduje kliky na externà odkazy a soubory ke staženÃ.", "SiteSearchCategories1": "Toto hlášenà shrnuje kategorie, které návÅ¡tÄ›vnÃci vybrali pÅ™i vyhledávánà na stránkách.", "SiteSearchCategories2": "NapÅ™Ãklad elektronické obchody mÃvajà filtr kategoriÃ, aby mohli uzákaznÃci zvolit, ve které kategorii bude provedeno hledánÃ.", - "SiteSearchFollowingPagesDoc": "Když návÅ¡tÄ›vnÃci hledajà na vaÅ¡ich stránkách, snažà se nalézt urÄitou stránku, obhsa, produkt, nebo službu. Toto hlášenà zobrazuje stránky, na které bylo klikáno nejÄastÄ›ji po internÃm vyhledávánÃ. Jinak Å™eÄeno, jedná se o stránky, které byly nejvÃce hledány návÅ¡tÄ›vnÃky, kteřà už byli na vaÅ¡ich stránkách.", + "SiteSearchFollowingPagesDoc": "Když návÅ¡tÄ›vnÃci hledajà na vaÅ¡ich stránkách, snažà se nalézt urÄitou stránku, obsah, produkt, nebo službu. Toto hlášenà zobrazuje stránky, na které bylo klikáno nejÄastÄ›ji po internÃm vyhledávánÃ. Jinak Å™eÄeno, jedná se o stránky, které byly nejvÃce hledány návÅ¡tÄ›vnÃky, kteřà už byli na vaÅ¡ich stránkách.", "SiteSearchIntro": "Sledovánà vyhledávánà na vaÅ¡ich stránkách je velmi efektivnà způsob, jak se dozvÄ›dÄ›t vÃce o tom, co vaÅ¡i návÅ¡tÄ›vnÃci na stránkách hledajÃ, jaký obsah by je mohl zajÃmat, jaké produkty by si mohli chtÃt koupit, a jak jim obecnÄ› zpÅ™Ãjemnit pobyt na vaÅ¡ich stránkách.", "SiteSearchKeyword": "KlÃÄová slova (VyhledávánÃ)", "SiteSearchKeywordsDocumentation": "Toto hlášenà shrnuje klÃÄová slova, která byla použita návÅ¡tÄ›vnÃky pÅ™i hledánà pomocà internÃho vyhledávaÄe.", diff --git a/plugins/Actions/lang/de.json b/plugins/Actions/lang/de.json index f52aaabfbe39ae6a840e982c66268019abfe6543..ffefdf14be14fa6f94b90548eaec87f992961e54 100644 --- a/plugins/Actions/lang/de.json +++ b/plugins/Actions/lang/de.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "Durchschnitt basierend auf %s Aufruf(en) %s zwischen %s und %s", "ColumnClickedURL": "Angeklickte URL", + "ColumnActionURL": "Aktions-URL", "ColumnClicks": "Klicks", "ColumnClicksDocumentation": "Anzahl der Klicks auf diesen Link.", "ColumnDownloadURL": "Download-URL", diff --git a/plugins/Actions/lang/el.json b/plugins/Actions/lang/el.json index edc949a3f35b9cb05498b8f4e01703fb388597ee..a495f92138fa1961961d3887c99f39d111bc87aa 100644 --- a/plugins/Actions/lang/el.json +++ b/plugins/Actions/lang/el.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "ΜÎσος ÏŒÏος βάσει των %s επισκÎψεων %s Î¼ÎµÏ„Î±Î¾Ï %s και %s", "ColumnClickedURL": "URL επιλογής", + "ColumnActionURL": "ΔιεÏθυνση URL ενÎÏγειας", "ColumnClicks": "Κλικ", "ColumnClicksDocumentation": "Οι φοÏÎÏ‚ που πατήθηκε αυτός ο σÏνδεσμος.", "ColumnDownloadURL": "URL λήψης", diff --git a/plugins/Actions/lang/en.json b/plugins/Actions/lang/en.json index 5a31efee342ce08a981119f979d53e13ff5a0a00..f176db870d00315684c7a758eaf243916b1eb8a6 100644 --- a/plugins/Actions/lang/en.json +++ b/plugins/Actions/lang/en.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "Average based on %s hit(s) %s between %s and %s", "ColumnClickedURL": "Clicked URL", + "ColumnActionURL": "Action URL", "ColumnClicks": "Clicks", "ColumnClicksDocumentation": "The number of times this link was clicked.", "ColumnDownloadURL": "Download URL", @@ -60,6 +61,7 @@ "WidgetPageUrlsFollowingSearch": "Pages Following a Site Search", "WidgetSearchCategories": "Search Categories", "WidgetSearchKeywords": "Site Search Keywords", - "WidgetSearchNoResultKeywords": "Search Keywords with No Results" + "WidgetSearchNoResultKeywords": "Search Keywords with No Results", + "ActionType": "Action Type" } } \ No newline at end of file diff --git a/plugins/Actions/lang/it.json b/plugins/Actions/lang/it.json index 013467699f02b399b4b04694319689c2966bc29e..d727a00bbcfb4b7430fd87f1d0c623fb74612358 100644 --- a/plugins/Actions/lang/it.json +++ b/plugins/Actions/lang/it.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "Media basata su %s hits %s tra %s e %s", "ColumnClickedURL": "URL Cliccate", + "ColumnActionURL": "URL dell'azione", "ColumnClicks": "Click", "ColumnClicksDocumentation": "Numero di volte che questo link è stato cliccato.", "ColumnDownloadURL": "URL Download", diff --git a/plugins/Actions/lang/ja.json b/plugins/Actions/lang/ja.json index 2d9e44354e7f6545561369f427b1ef2dcd539bec..c752f0ece44f24a4ff1fd21c9c5ed77d0449f7da 100644 --- a/plugins/Actions/lang/ja.json +++ b/plugins/Actions/lang/ja.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "%s ~ %s ã®é–“ã® %s ã®ãƒ’ット %s ã«åŸºã¥ãå¹³å‡", "ColumnClickedURL": "クリックã•れ㟠URL", + "ColumnActionURL": "アクション URL", "ColumnClicks": "クリック数", "ColumnClicksDocumentation": "ã“ã®ãƒªãƒ³ã‚¯ãŒã‚¯ãƒªãƒƒã‚¯ã•れãŸå›žæ•°", "ColumnDownloadURL": "ダウンãƒãƒ¼ãƒ‰ URL", @@ -39,6 +40,7 @@ "PagesReportDocumentation": "ã“れã¯è¨ªå•ã•れãŸãƒšãƒ¼ã‚¸URLã«ã¤ã„ã¦ã®ãƒªãƒãƒ¼ãƒˆã§ã™ã€‚%s 表ã¯éšŽå±¤æ§‹é€ ã«ãªã£ã¦ãŠã‚Šã€URLã¯ãƒ•ォルダーã®éšŽå±¤ã§è¡¨ç¤ºã•れã¦ã„ã¾ã™ã€‚", "PageTitlesReportDocumentation": "ã“れã¯è¨ªå•ã•れãŸãƒšãƒ¼ã‚¸ã‚¿ã‚¤ãƒˆãƒ«ã«ã¤ã„ã¦ã®ãƒªãƒãƒ¼ãƒˆã§ã™ã€‚%s ページタイトルã¯å¤šãã®ãƒ–ラウザã§ã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦ã®ã‚¿ã‚¤ãƒˆãƒ«ã«è¡¨ç¤ºã•れるHTMLã® %s ã‚¿ã‚°ã§ã™ã€‚", "PageUrls": "ページURL", + "PluginDescription": "ページ ビューã¨ãƒšãƒ¼ã‚¸ã®ã‚¿ã‚¤ãƒˆãƒ«ã«ã¤ã„ã¦ãƒ¬ãƒãƒ¼ãƒˆã—ã¾ã™ã€‚内部ã®ã‚¦ã‚§ãƒ–ã‚µã‚¤ãƒˆã®æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³ã‚’測定ã§ãã¾ã™ã€‚自動的ã«å¤–部リンクã¨ãƒ•ァイルã®ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã®ã‚¯ãƒªãƒƒã‚¯ã‚’追跡ã—ã¾ã™ã€‚", "SiteSearchCategories1": "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã¯ã€è¨ªå•者ãŒã‚µã‚¤ãƒˆã§æ¤œç´¢ã—ãŸæ™‚ã«é¸æŠžã—ãŸã‚«ãƒ†ã‚´ãƒªã®ä¸€è¦§ã§ã™ã€‚", "SiteSearchCategories2": "例ãˆã°ã€eコマースサイトã¯ä¸€èˆ¬çš„ã«\"カテゴリー\"ã®ã‚»ãƒ¬ã‚¯ãƒˆã‚’æŒã£ã¦ã„ã¦ã€è¨ªå•者ã¯è£½å“ã®æ¤œç´¢çµæžœã‚’特定ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã«çµžã‚Šè¾¼ã¿ã§ãã¾ã™ã€‚", "SiteSearchFollowingPagesDoc": "訪å•者ã¯ã€ç‰¹å®šã®ãƒšãƒ¼ã‚¸ã€ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã€è£½å“ã€ã¾ãŸã¯ã‚µãƒ¼ãƒ“スを見ã¤ã‘よã†ã¨ã—ã¦ã€ã‚µã‚¤ãƒˆå†…ã§æ¤œç´¢ã‚’行ã„ã¾ã™ã€‚ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã¯ã€ã‚µã‚¤ãƒˆå†…ã§æ¤œç´¢ã—ã¦ã‹ã‚‰æœ€ã‚‚多ãクリックã•れãŸãƒšãƒ¼ã‚¸ã®ä¸€è¦§ã§ã™ã€‚è¨€ã„æ›ãˆã‚Œã°ã€ã‚µã‚¤ãƒˆå†…ã§è¨ªå•è€…ãŒæœ€ã‚‚検索ã—ãŸãƒšãƒ¼ã‚¸ã®ä¸€è¦§ã¨ã„ã†ã“ã¨ã§ã™ã€‚", diff --git a/plugins/Actions/lang/ko.json b/plugins/Actions/lang/ko.json index b5ec63216b555a1967464ce2f0da390b968c45e6..fa9f7d2257fbd895f55c51d520821bf705d93acd 100644 --- a/plugins/Actions/lang/ko.json +++ b/plugins/Actions/lang/ko.json @@ -1,6 +1,7 @@ { "Actions": { "ColumnClickedURL": "조회한 URL", + "ColumnActionURL": "í™œë™ URL", "ColumnClicks": "조회수", "ColumnClicksDocumentation": "ì´ ë§í¬ë¥¼ í´ë¦ 한 횟수입니다.", "ColumnDownloadURL": "다운로드 URL", @@ -32,15 +33,18 @@ "ExitPageTitles": "ì´íƒˆ 페ì´ì§€ ì œëª©", "ExitPageTitlesReportDocumentation": "ì´ ë³´ê³ ì„œëŠ” ê¸°ê°„ì˜ ì´íƒˆ 페ì´ì§€ ì œëª©ì— ëŒ€í•œ ì •ë³´ìž…ë‹ˆë‹¤.", "LearnMoreAboutSiteSearchLink": "방문ìžê°€ ê²€ìƒ‰ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ëŠ” ê²ƒì„ ì¶”ì 하는 ë°©ë²•ì— ëŒ€í•´ ìžì„¸ížˆ 알아보세요.", + "OneSearch": "검색 1", "OutlinkDocumentation": "외부 ë§í¬ëŠ” 사ì´íЏ ë‚´ì—서 외부 사ì´íЏ(다른 ë„ë©”ì¸)ë¡œì˜ ë§í¬ìž…니다.", "OutlinksReportDocumentation": "ì´ ë³´ê³ ì„œëŠ” 방문ìžê°€ í´ë¦ 한 외부 ë§í¬ì˜ URLì„ ê³„ì¸µ 구조 목ë¡ìœ¼ë¡œ 표시합니다.", "PagesReportDocumentation": "ì´ ë³´ê³ ì„œëŠ” 방문한 페ì´ì§€ URLì— ëŒ€í•œ ì •ë³´ìž…ë‹ˆë‹¤. %s í…Œì´ë¸”ì€ ê³„ì¸µ 구조로 ë˜ì–´ 있으며, URLì€ í´ë” 구조로 표시ë©ë‹ˆë‹¤.", "PageTitlesReportDocumentation": "ì´ ë³´ê³ ì„œëŠ” 방문한 페ì´ì§€ ì œëª©ì— ëŒ€í•œ ì •ë³´ìž…ë‹ˆë‹¤. %s 페ì´ì§€ ì œëª©ì€ ëŒ€ë¶€ë¶„ì˜ ë¸Œë¼ìš°ì € 윈ë„ìš°ì˜ ì œëª©ì— í‘œì‹œë˜ëŠ” HTML %s 태그입니다.", "PageUrls": "페ì´ì§€ URL", + "PluginDescription": "페ì´ì§€ 뷰와 ì œëª©ì— ëŒ€í•œ ë³´ê³ ì„œ. ë‚´ë¶€ 웹사ì´íЏ 검색 ì—”ì§„ì„ ì¸¡ì •í• ìˆ˜ 있습니다. 외부 ë§í¬ í´ë¦ ë° íŒŒì¼ ë‹¤ìš´ë¡œë“œì— ëŒ€í•´ì„œë„ ìžë™ìœ¼ë¡œ ì¶”ì 합니다.", "SiteSearchCategories1": "ì´ ë³´ê³ ì„œëŠ” 웹사ì´íЏì—서 ê²€ìƒ‰í–ˆì„ ë•Œ 방문ìžê°€ ì„ íƒí•œ ì¹´í…Œê³ ë¦¬ë¥¼ 나열합니다.", "SiteSearchCategories2": "예를 들면, ì¼ë°˜ì ì¸ ì „ìžìƒê±°ëž˜ 사ì´íŠ¸ëŠ” 'ì¹´í…Œê³ ë¦¬'를 ì œê³µí•˜ëŠ”ë° ë°©ë¬¸ìžëŠ” íŠ¹ì • ì¹´í…Œê³ ë¦¬ì˜ ëª¨ë“ ì œí’ˆì„ ê²€ìƒ‰í•˜ëŠ” 것으로 범위를 ì¶•ì†Œí• ìˆ˜ 있습니다.", "SiteSearchFollowingPagesDoc": "방문ìžëŠ” íŠ¹ì • 페ì´ì§€, 콘í…ì¸ , ì œí’ˆ ë˜ëŠ” 서비스를 ì°¾ìœ¼ë ¤ê³ ì›¹ì‚¬ì´íЏì—서 ê²€ìƒ‰ì„ ì‹œë„합니다. ì´ ë³´ê³ ì„œëŠ” 사ì´íЏ ë‚´ë¶€ì—서 ê²€ìƒ‰ì‹œë„ í›„ 가장 ë§Žì´ í´ë¦í•œ 페ì´ì§€ 목ë¡ìž…니다. 즉, ì´ íŽ˜ì´ì§€ 목ë¡ì€ ëŒ€ë¶€ë¶„ì˜ ë°©ë¬¸ìžê°€ 사ì´íŠ¸ë‚´ ê²€ìƒ‰ì— ì˜í•´ 방문한 것입니다.", "SiteSearchIntro": "방문ìžì˜ ê²€ìƒ‰ì„ ì¶”ì 하는 ê²ƒì€ ë‹¹ì‹ ì˜ ì›¹ì‚¬ì´íŠ¸ë¥¼ 좋게 만드는 매우 효과ì ì¸ ë°©ë²•ìž…ë‹ˆë‹¤. ìž ìž¬ ê³ ê°ì´ ë¬´ì—‡ì„ ì°¾ê³ ìžˆëŠ”ì§€ì— ëŒ€í•´ ìžì„¸ížˆ 알 수 ìžˆê³ , ì´ê²ƒìœ¼ë¡œ 새로운 콘í…ì¸ ì— ëŒ€í•œ ì•„ì´ë””어를 찾는 ë° ë„ì›€ì„ ë°›ê²Œ ë˜ë©°, ìž ìž¬ ê³ ê°ì´ 찾는 새로운 ì „ìžìƒê±°ëž˜ ì œí’ˆì„ ì œê³µí• ìˆ˜ 있게 ë©ë‹ˆë‹¤. ê·¸ë¦¬ê³ ë°©ë¬¸ìžì˜ 웹사ì´íЏ 사용 ê²½í—˜ì„ ëŒ€í í–¥ìƒì‹œí‚µë‹ˆë‹¤.", + "SiteSearchKeyword": "키워드 (사ì´íЏ 검색)", "SiteSearchKeywordsDocumentation": "ì´ ë³´ê³ ì„œì—서는 방문ìžê°€ ë‚´ë¶€ 검색 엔진ì—서 검색한 검색어를 나열합니다.", "SiteSearchKeywordsNoResultDocumentation": "ì´ ë³´ê³ ì„œëŠ” 검색 결과를 반환하지 ì•Šì€ ê²€ìƒ‰ì–´ë¥¼ 나열합니다: 어쩌면 검색 엔진 ì•Œê³ ë¦¬ì¦˜ì„ í–¥ìƒ ì‹œí‚¤ê±°ë‚˜ 방문ìžê°€ ë‹¹ì‹ ì˜ ì›¹ì‚¬ì´íŠ¸ì— (ì•„ì§)없는 콘í…ì¸ ë¥¼ ì°¾ê³ ìžˆëŠ” 것ì´ê² ì£ ?", "SubmenuPagesEntry": "ì§„ìž… 페ì´ì§€", diff --git a/plugins/Actions/lang/nb.json b/plugins/Actions/lang/nb.json index bf3f0ea718d1cb9508f5db21b729b87eb404733d..18ab7471b986af2657ef6cabb7908dd0a2be72cc 100644 --- a/plugins/Actions/lang/nb.json +++ b/plugins/Actions/lang/nb.json @@ -1,41 +1,63 @@ { "Actions": { "AvgGenerationTimeTooltip": "Gjennomsnitt basert pÃ¥ %s treff %s mellom %s og %s", - "ColumnClickedURL": "URL for klikk", + "ColumnClickedURL": "Klikket URL", "ColumnClicks": "Klikk", "ColumnClicksDocumentation": "Antall klikk pÃ¥ denne lenken", - "ColumnDownloadURL": "URL for nedlasting", - "ColumnEntryPageTitle": "Tittel for inngangsside", - "ColumnEntryPageURL": "URL for inngangsside", - "ColumnExitPageTitle": "Tittel for utgangsside", - "ColumnExitPageURL": "URL for utgangsside", + "ColumnDownloadURL": "Nedlastings-URL", + "ColumnEntryPageTitle": "Tittel pÃ¥ inngangsside", + "ColumnEntryPageURL": "URL pÃ¥ inngangsside", + "ColumnExitPageTitle": "Tittel pÃ¥ utgangsside", + "ColumnExitPageURL": "URL pÃ¥ utgangsside", "ColumnNoResultKeyword": "Nøkkelord uten søkeresultat", "ColumnPageName": "Sidenavn", - "ColumnPagesPerSearch": "Søkeresultater", - "ColumnPageURL": "URL for side", + "ColumnPagesPerSearch": "Søkeresultatsider", + "ColumnPagesPerSearchDocumentation": "Brukere vil søke pÃ¥ ditt nettsted, og noen ganger klikke «neste» for Ã¥ se flere resultater. Dette er det gjennomsnittlige antallet søkeresultatsider for dette nøkkelordet.", + "ColumnPageURL": "Side-URL", "ColumnSearchCategory": "Søkekategori", "ColumnSearches": "Søk", - "ColumnSearchesDocumentation": "Antall besøkende som søkte etter dette nøkkelordet i din søkemotor.", + "ColumnSearchesDocumentation": "Antall besøkende som søkte etter dette nøkkelordet i ditt nettsteds søkemotor.", + "ColumnSearchExits": "% Utganger fra søk", "ColumnSearchExitsDocumentation": "Antall besøkende som forlot nettsiden etter Ã¥ ha søkt etter dette nøkkelordet.", "ColumnSearchResultsCount": "Antall søkeresultater", "ColumnSiteSearchKeywords": "Unike nøkkelord", "ColumnUniqueClicks": "Unike klikk", + "ColumnUniqueClicksDocumentation": "Antall besøk som involverte et klikk pÃ¥ denne lenken. Hvis lenken ble klikket flere ganger i løpet av et besøk, blir det kun talt én gang.", "ColumnUniqueDownloads": "Unike nedlastinger", "ColumnUniqueOutlinks": "Unike utlenker", "DownloadsReportDocumentation": "I denne rapporten kan du se hvilke filer de besøkende har lastet ned. %s Hva Piwik teller som en nedlasting, er klikket pÃ¥ en nedlastingslink. Om nedlastingen ble fullført eller ikke er ikke kjent for Piwik.", + "EntryPagesReportDocumentation": "Denne rapporten inneholder informasjon om inngangssidene som ble brukt i løpet av den angitte perioden. En inngangsside er den første siden en bruker ser i løpet av besøket. %s Inngangs-URLen vises som en mappestruktur.", + "EntryPageTitles": "Inngangssidetitler", + "EntryPageTitlesReportDocumentation": "Denne rapporten inneholder informasjon om titler pÃ¥ inngangssider som ble brukt i løpet av den angitte perioden.", + "ExitPagesReportDocumentation": "Denne rapporten inneholder informasjon om utgangssidene som ble brukt i den angitte perioden. En utgangsside er den siste siden en bruker ser i løpet av besøket. %s Utgangs-URLene vises som en mappestruktur.", + "ExitPageTitles": "Titler pÃ¥ utgangssider", + "ExitPageTitlesReportDocumentation": "Denne rapporten inneholder informasjon om titler pÃ¥ utgangssider som ble brukt i den angitte perioden.", + "LearnMoreAboutSiteSearchLink": "Lær mer om hvordan du kan spore hvordan besøkere bruker din søkemotor.", "OneSearch": "1 søk", + "OutlinkDocumentation": "En utlenke er en lenke som leder besøkeren bort fra ditt nettsted (til et annet domene).", + "OutlinksReportDocumentation": "Denne rapporten viser en hierarkisk liste av utlenkers URL-er som ble klikket av dine besøkere.", + "PagesReportDocumentation": "Denne rapporten inneholder informasjon om side-URLer som har blitt besøkt. %s Tabellen er organisert hierarkisk, URL-ene vises som en mappestruktur.", + "PageTitlesReportDocumentation": "Denne rapporten inneholder informasjon om titler pÃ¥ sider som har blitt besøkt. %s Sidetittelen er HTML-taggen %s som de fleste nettlesere viser i vindustittelen.", + "PageUrls": "Side-URLer", + "PluginDescription": "Rapporter om sidevisninger org sidetitler. Lar deg mÃ¥le ditt nettsteds interne søkemotor. Sporer klikk pÃ¥ eksterne lenker og nedlastinger automatisk.", + "SiteSearchCategories1": "Denne rapporten viser kategorier som besøkere velger nÃ¥r de søker pÃ¥ ditt nettsted.", + "SiteSearchCategories2": "For eksempel: e-handelsnettsteder har typisk en «kategori»-velger slik at besøkere kan begrense sine søk til kun produkter i en spesifikk kategori.", + "SiteSearchFollowingPagesDoc": "NÃ¥r besøkere søker pÃ¥ ditt nettsted, leter de etter en bestemt side, innhold, produkt eller tjeneste. Denne rapporten lister opp sider som ble klikket mest etter et internt søk. Med andre ord, det er listen over sider som blir mest søkt etter av besøkere som allerede er pÃ¥ nettstedet.", + "SiteSearchIntro": "Ã… spore søk som besøkere gjør pÃ¥ dine nettsteder er en effektiv mÃ¥te Ã¥ lære mer om hva din mÃ¥lgruppe leter etter. Det kan hjelpe deg Ã¥ finne ideer til nytt innhold, nye produkter og generelt Ã¥ øke kvaliteten pÃ¥ dine besøkeres opplevelse av ditt nettsted.", "SiteSearchKeyword": "Nøkkelord (Sidesøk)", + "SiteSearchKeywordsDocumentation": "Denne rapporten lister opp nøkkelord som besøkere har søkt etter i nettstedets interne søkemotor.", + "SiteSearchKeywordsNoResultDocumentation": "Denne rapporten lister opp nøkkelord som ikke ga noen søkeresultater. Kanskje søkealgoritmen kan forbedres, eller kanskje dine besøkere ser etter innhold som ikke er pÃ¥ ditt nettsted (ennÃ¥)?", "SubmenuPagesEntry": "Inngangssider", "SubmenuPagesExit": "Utgangssider", "SubmenuPageTitles": "Sidetitler", "SubmenuSitesearch": "Sidesøk", - "WidgetEntryPageTitles": "Inngangssiders tittel", - "WidgetExitPageTitles": "Utgangs Side Tittler", + "WidgetEntryPageTitles": "Titler pÃ¥ inngangssider", + "WidgetExitPageTitles": "Titler pÃ¥ utgangssider", "WidgetPagesEntry": "Inngangssider", "WidgetPagesExit": "Utgangssider", - "WidgetPageTitles": "Side Tittler", - "WidgetPageTitlesFollowingSearch": "Side Tittel fulgt av ett sidesøk", - "WidgetPageUrlsFollowingSearch": "Sider etter et nettstedssøk", + "WidgetPageTitles": "Sidetitler", + "WidgetPageTitlesFollowingSearch": "Sidetittel fulgt av ett nettstedssøk", + "WidgetPageUrlsFollowingSearch": "Sider som følger etter et nettstedssøk", "WidgetSearchCategories": "Søkekategorier", "WidgetSearchKeywords": "Nøkkelord for sidesøk", "WidgetSearchNoResultKeywords": "Nøkkelord uten resultater" diff --git a/plugins/Actions/lang/pt-br.json b/plugins/Actions/lang/pt-br.json index 99baab291c7f5c134dad6232b4103181854071e9..41d3f88a934c1238eafeebc028740e31b01c2982 100644 --- a/plugins/Actions/lang/pt-br.json +++ b/plugins/Actions/lang/pt-br.json @@ -2,6 +2,7 @@ "Actions": { "AvgGenerationTimeTooltip": "Média baseada em %s visita(s) %s entre %s e %s", "ColumnClickedURL": "URL clicado", + "ColumnActionURL": "URL Ação", "ColumnClicks": "Cliques", "ColumnClicksDocumentation": "O número de vezes que link foi clicado.", "ColumnDownloadURL": "URL do Download", diff --git a/plugins/AnonymousPiwikUsageMeasurement b/plugins/AnonymousPiwikUsageMeasurement index 02dfdc4b8e744cf432fdcb91e3613d0f04ccc59d..5ba37193bba2be01df462b61c724c212657c449f 160000 --- a/plugins/AnonymousPiwikUsageMeasurement +++ b/plugins/AnonymousPiwikUsageMeasurement @@ -1 +1 @@ -Subproject commit 02dfdc4b8e744cf432fdcb91e3613d0f04ccc59d +Subproject commit 5ba37193bba2be01df462b61c724c212657c449f diff --git a/plugins/Contents/lang/cs.json b/plugins/Contents/lang/cs.json index 596ee07a0363c469d32f7e5340e215e44d767c4a..7cbe4e44888def064cad1afd105d0d228d8a9ca2 100644 --- a/plugins/Contents/lang/cs.json +++ b/plugins/Contents/lang/cs.json @@ -8,6 +8,9 @@ "ContentName": "Jméno obsahu", "ContentPiece": "Část obsahu", "ContentTarget": "CÃl obsahu", - "Contents": "Obsah" + "Contents": "Obsah", + "InteractionsMetricDocumentation": "Kolikrát bylo s blokem obsahu interagováno (t. j. kliknuto na banner nebo reklamu).", + "ImpressionsMetricDocumentation": "PoÄet zobrazenà banneru nebo reklamy na stránkách.", + "InteractionRateMetricDocumentation": "PomÄ›r impresà obsahu k interakcÃm." } } \ No newline at end of file diff --git a/plugins/Contents/lang/de.json b/plugins/Contents/lang/de.json index cc42a8d6bbd65573c97ebe1e294ebbab972a5623..61cb4074fa2f7b584342a153533829d3e502c367 100644 --- a/plugins/Contents/lang/de.json +++ b/plugins/Contents/lang/de.json @@ -8,6 +8,9 @@ "ContentName": "Inhaltsname", "ContentPiece": "Inhaltsteil", "ContentTarget": "Inhaltsziel", - "Contents": "Inhalte" + "Contents": "Inhalte", + "InteractionsMetricDocumentation": "Die Anzahl, wie häufig mit einem Inhalt interagiert wurde (z.B. durch einen Klick auf ein Banner oder eine Anzeige).", + "ImpressionsMetricDocumentation": "Die Anzahl, wie häufig ein Inhalt, z.b. ein Banner oder eine Anzeige, auf der Seite angezeigt wurden.", + "InteractionRateMetricDocumentation": "Verhältnis zwischen Impressionen des Inhalts und Interaktionen." } } \ No newline at end of file diff --git a/plugins/Contents/lang/ja.json b/plugins/Contents/lang/ja.json index 56af2f6ea7541588eab154ee27936c7fb656f151..a15de7b0421af07bc6e80073c3c6891e5a85de6e 100644 --- a/plugins/Contents/lang/ja.json +++ b/plugins/Contents/lang/ja.json @@ -1,5 +1,6 @@ { "Contents": { + "PluginDescription": "コンテンツやãƒãƒŠãƒ¼ã®è¿½è·¡ã§ã¯ã€ãƒšãƒ¼ã‚¸ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®ä»»æ„ã®éƒ¨åˆ†(ãƒãƒŠãƒ¼åºƒå‘Šã€ã‚¤ãƒ¡ãƒ¼ã‚¸ã€ä»»æ„é …ç›®) ã®ãƒ‘フォーマンス(ビューã€ã‚¯ãƒªãƒƒã‚¯æ•°ã€CTR )を測定ã§ãã¾ã™ã€‚", "Impressions": "インプレッション", "Interactions": "インタラクション", "Interaction": "インタラクション", @@ -7,6 +8,9 @@ "ContentName": "コンテンツå", "ContentPiece": "コンテンツè¦ç´ ", "ContentTarget": "コンテンツターゲット", - "Contents": "内容" + "Contents": "内容", + "InteractionsMetricDocumentation": "( 例ãˆã°ã€ãƒãƒŠãƒ¼ã‚„広告を「クリックã€ã¨ã„ã†ã‚ˆã†ãª ) 相互作用をコンテンツブãƒãƒƒã‚¯ãŒå—ã‘ãŸå›žæ•°ã€‚", + "ImpressionsMetricDocumentation": "広告やãƒãƒŠãƒ¼ãªã©ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ブãƒãƒƒã‚¯ãŒãƒšãƒ¼ã‚¸ã«è¡¨ç¤ºã•れãŸå›žæ•°ã€‚", + "InteractionRateMetricDocumentation": "相互作用ã«å¯¾ã™ã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®è¡¨ç¤ºå›žæ•°ã®æ¯”率。" } } \ No newline at end of file diff --git a/plugins/Contents/lang/ko.json b/plugins/Contents/lang/ko.json new file mode 100644 index 0000000000000000000000000000000000000000..121856bf06897d499e47783b8d1b8b0456deb449 --- /dev/null +++ b/plugins/Contents/lang/ko.json @@ -0,0 +1,11 @@ +{ + "Contents": { + "Interactions": "ìƒí˜¸ 작용들", + "Interaction": "ìƒí˜¸ 작용", + "InteractionRate": "ìƒí˜¸ 작용 비율", + "ContentName": "콘í…ì¸ ì´ë¦„", + "ContentPiece": "콘í…ì¸ ì¡°ê°", + "ContentTarget": "콘í…ì¸ ëª©í‘œ", + "Contents": "콘í…ì¸ " + } +} \ No newline at end of file diff --git a/plugins/CoreAdminHome/Commands/DeleteLogsData.php b/plugins/CoreAdminHome/Commands/DeleteLogsData.php index df4141edbb34b23542aa8fd06c36b8a1353c7aa0..a504ed2c9cb675ac32b5e00a6ed9c11a0df98869 100644 --- a/plugins/CoreAdminHome/Commands/DeleteLogsData.php +++ b/plugins/CoreAdminHome/Commands/DeleteLogsData.php @@ -168,6 +168,10 @@ class DeleteLogsData extends ConsoleCommand private function askForDeleteConfirmation(InputInterface $input, OutputInterface $output) { + if ($input->getOption('no-interaction')) { + return true; + } + $helper = $this->getHelper('question'); $question = new ConfirmationQuestion('<comment>You are about to delete log data. This action cannot be undone, are you sure you want to continue? (Y/N)</comment> ', false); @@ -194,4 +198,4 @@ class DeleteLogsData extends ConsoleCommand $this->writeSuccessMessage($output, array("Table optimization finished.")); } -} \ No newline at end of file +} diff --git a/plugins/CoreAdminHome/CoreAdminHome.php b/plugins/CoreAdminHome/CoreAdminHome.php index 305506038a53234ebe979512c75e695f26bcdf94..0f9bf6070230ae7c83316517274ff1bd744c0ca1 100644 --- a/plugins/CoreAdminHome/CoreAdminHome.php +++ b/plugins/CoreAdminHome/CoreAdminHome.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\CoreAdminHome; use Piwik\Db; use Piwik\Piwik; +use Piwik\ProxyHttp; use Piwik\Settings\UserSetting; /** @@ -26,7 +27,9 @@ class CoreAdminHome extends \Piwik\Plugin 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles', 'AssetManager.getJavaScriptFiles' => 'getJsFiles', 'UsersManager.deleteUser' => 'cleanupUser', - 'API.DocumentationGenerator.@hideExceptForSuperUser' => 'displayOnlyForSuperUser' + 'API.DocumentationGenerator.@hideExceptForSuperUser' => 'displayOnlyForSuperUser', + 'Template.jsGlobalVariables' => 'addJsGlobalVariables', + 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys' ); } @@ -57,10 +60,28 @@ class CoreAdminHome extends \Piwik\Plugin $jsFiles[] = "plugins/CoreAdminHome/javascripts/generalSettings.js"; $jsFiles[] = "plugins/CoreHome/javascripts/donate.js"; $jsFiles[] = "plugins/CoreAdminHome/javascripts/pluginSettings.js"; + $jsFiles[] = "plugins/CoreAdminHome/javascripts/protocolCheck.js"; } public function displayOnlyForSuperUser(&$hide) { $hide = !Piwik::hasUserSuperUserAccess(); } + + public function addJsGlobalVariables(&$out) + { + if (ProxyHttp::isHttps()) { + $isHttps = 'true'; + } else { + $isHttps = 'false'; + } + + $out .= "piwik.hasServerDetectedHttps = $isHttps;\n"; + } + + public function getClientSideTranslationKeys(&$translationKeys) + { + $translationKeys[] = 'CoreAdminHome_ProtocolNotDetectedCorrectly'; + $translationKeys[] = 'CoreAdminHome_ProtocolNotDetectedCorrectlySolution'; + } } diff --git a/plugins/CoreAdminHome/Menu.php b/plugins/CoreAdminHome/Menu.php index b4621e2f5e356e4fedc86531c03ade9666e7bd0a..a149baa39981dd131871b805fdfc7554703cc03b 100644 --- a/plugins/CoreAdminHome/Menu.php +++ b/plugins/CoreAdminHome/Menu.php @@ -61,7 +61,7 @@ class Menu extends \Piwik\Plugin\Menu if (!Piwik::isUserIsAnonymous()) { $menu->addManageItem('CoreAdminHome_TrackingCode', $this->urlForAction('trackingCodeGenerator'), - $order = 10); + $order = 20); if (SettingsManager::hasUserPluginsSettingsForCurrentUser()) { $menu->addPersonalItem('CoreAdminHome_PluginSettings', diff --git a/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js b/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js index 87b053e980fc0c48dbea36cc1d6c456bc2414ea0..3c983deca80732d3038ab7e23e185825eaa412ad 100644 --- a/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js +++ b/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js @@ -302,7 +302,7 @@ $('#javascript-text>textarea,#image-tracking-text>textarea').click(function () { $(this).select(); }); - + // initial generation getSiteData( $('#js-tracker-website').attr('siteid'), diff --git a/plugins/CoreAdminHome/javascripts/protocolCheck.js b/plugins/CoreAdminHome/javascripts/protocolCheck.js new file mode 100644 index 0000000000000000000000000000000000000000..5bd4148e101319b17bf82de49d7bfed81c2c0805 --- /dev/null +++ b/plugins/CoreAdminHome/javascripts/protocolCheck.js @@ -0,0 +1,43 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +$(document).ready(function () { + + if (!piwik || !location.protocol) { + return; + } + + if (!piwik.hasSuperUserAccess) { + // we show a potential notification only to super users + return; + } + + if (piwik.hasServerDetectedHttps) { + // https was detected, not needed to show a message + return; + } + + var isHttpsUsed = 0 === location.protocol.indexOf('https'); + + if (!isHttpsUsed) { + // not using https anyway, we do not show a message + return; + } + + var params = [ + '"config/config.ini.php"', + '"assume_secure_protocol=1"', + '"[General]"', + '<a href="?module=Proxy&action=redirect&url=https://piwik.org/faq/how-to-install/faq_98/" target="_blank">', + '</a>' + ]; + var message = _pk_translate('CoreAdminHome_ProtocolNotDetectedCorrectly') + " " + _pk_translate('CoreAdminHome_ProtocolNotDetectedCorrectlySolution', params); + + var UI = require('piwik/UI'); + var notification = new UI.Notification(); + notification.show(message, {context: 'warning'}); +}); diff --git a/plugins/CoreAdminHome/lang/cs.json b/plugins/CoreAdminHome/lang/cs.json index 8233b15931b40b381ad4a39381a488156c1e66f7..136ef9770aa88d71f9bfc9304c0b5a50d3b40271 100644 --- a/plugins/CoreAdminHome/lang/cs.json +++ b/plugins/CoreAdminHome/lang/cs.json @@ -8,9 +8,9 @@ "ClickHereToOptIn": "KliknÄ›te zde pro pÅ™ihlášenÃ.", "ClickHereToOptOut": "KliknÄ›te zde pro vylouÄenÃ.", "CustomLogoFeedbackInfo": "Pokud pÅ™izpůsobÃte logo Piwiku, možná by vás zajÃmalo, jak skrýt odkaz %s v hornÃm menu, Pokud to chcete provést, zakažte plugin zpÄ›tné vazby na stránce %sSpravovat zásuvné moduly%s.", - "CustomLogoHelpText": "Můžete pÅ™izpůsobit logo Piwiku, které bude zobrazeno v uživatelském rozhranà a v e-mailových hlášenÃch.", + "CustomLogoHelpText": "Můžete pÅ™izpůsobit logo Piwiku, které bude zobrazeno v uživatelském rozhranà a v emailových hlášenÃch.", "DevelopmentProcess": "PÅ™estože náš %sproces vývoje%s zahrnuje tisÃce automatizovaných testů, beta testeÅ™i hrajà klÃÄovou roli v našà politice nevýskytu chyb.", - "EmailServerSettings": "Nastavenà e-mailového serveru", + "EmailServerSettings": "Nastavenà emailového serveru", "ForBetaTestersOnly": "Pouze pro beta testery", "ImageTracking": "Sledovánà obrázkem", "ImageTrackingIntro1": "Pokud má návÅ¡tÄ›vnÃk vypnutý JavaScript nebo nemůže být JavaScript použit, můžete využÃt obrázku k měřenà a sledovánà Vašà návÅ¡tÄ›vnosti.", @@ -58,7 +58,7 @@ "MenuDevelopment": "Vývoj", "OptOutComplete": "VylouÄenà hotovo. VaÅ¡e návÅ¡tÄ›vy nebudou sledovány nástrojem webové analýzy.", "OptOutCompleteBis": "Poznámka: pokud smažete cookie, odstranÃte vyluÄovacà cookie nebo zmmÄ›nÃte poÄÃtaÄ nebo prohlÞeÄ, budete muset provést proceduru vylouÄenà znovu.", - "OptOutDntFound": "Nejste sledováni, protože váš prohlÞeÄ hlásÃ, že si to nepÅ™ejete. Jedná se o nastavenà prohlÞeÄe, takže se nebudete moct pÅ™ihlásit, dokud nezakážete funkci nesledovat.", + "OptOutDntFound": "Nejste sledováni, protože váš prohlÞeÄ hlásÃ, že si to nepÅ™ejete. Jedná se o nastavenà prohlÞeÄe, takže se nebudete moci pÅ™ihlásit, dokud nezakážete funkci nesledovat.", "OptOutExplanation": "Piwik se zaměřuje na poskytovánà soukromà na internetu. Pokud chcete dát svým návÅ¡tÄ›vnÃkům možnost, aby byli vylouÄeni z webové analýzy Piwikem, můžete na nÄ›jakou stránku (tÅ™eba stránku o soukromÃ) umÃstit následujÃcà HTML kód.", "OptOutExplanationBis": "Tento kód zobrazà iframe s odkazem, který nastavà u návÅ¡tÄ›vnÃka vynechávacà cookie. %s KliknÄ›te zde%s pro zobrazenà obsahu iframe.", "OptOutForYourVisitors": "Piwik vylouÄenà pro VaÅ¡e návÅ¡tÄ›vnÃky", @@ -70,8 +70,8 @@ "PluginSettingsIntro": "Zde můžete zmÄ›nit nastavenà pro následujÃcà zásuvné moduly tÅ™etÃch stran:", "PluginSettingsValueNotAllowed": "Hodnota pro pole \"%s\" zásuvného modulu \"%s\" nenà povolena", "PluginSettingsSaveFailed": "NepodaÅ™ilo se uložit nastavenà zásuvného modulu", - "SendPluginUpdateCommunication": "Pokud bude k dispozici aktualizace pluginu, odeslat e-mail.", - "SendPluginUpdateCommunicationHelp": "Super uživatelům bude odeslán e-mail, když bude k dispozici aktualizace zásuvného modulu.", + "SendPluginUpdateCommunication": "Pokud bude k dispozici aktualizace pluginu, odeslat email.", + "SendPluginUpdateCommunicationHelp": "Super uživatelům bude odeslán email, pokud bude k dispozici aktualizace zásuvného modulu.", "StableReleases": "Piwik je důležitý nástroj pro měřenÃ, doporuÄujeme vždy použÃvat nejnovÄ›jšà vydánÃ. Pokud použÃváte nejnovÄ›jšà beta verzi a naÅ¡li jste chyby, prosÃme o jejich nahlášenà %spÅ™Ãmo zde %s.", "LtsReleases": "LTS (verze s dlouhodobou podporou) dostávajà pouze bezpeÄnostnà a jiné opravy chyb.", "SystemPluginSettings": "Systémová nastavenà zásuvných modulů", @@ -84,9 +84,9 @@ "ValidPiwikHostname": "Platné jméno hostitele Piwiku", "WithOptionalRevenue": "s volitelným pÅ™Ãjmem", "YouAreOptedIn": "AktuálnÄ› nejste vylouÄen.", - "YouAreOptedOut": "AktuálnÄ› jste vylouÄen.", - "YouMayOptOut": "Zde se můžete rozhodnout, zda se smà ve VaÅ¡em prohlÞeÄi ukládat jedineÄná analytická data “ Cookies†, a zda umožnÃte provozovateli webové stránky shromažÄovat a analyzovat různé statistické údaje.", - "YouMayOptOutBis": "Pokud jste se rozhodli že ne, kliknÄ›te na pÅ™iložený odkaz pro uloženà deaktivaÄnÃho Cookie ve VaÅ¡em prohlÞeÄi.", + "YouAreOptedOut": "AktuálnÄ› jste vylouÄeni.", + "YouMayOptOut": "Zde se můžete zakázat uloženà cookie s identifikaÄnÃm ÄÃslem pÅ™idÄ›leným vaÅ¡emu poÄÃtaÄi a tÃm zamezit provozovateli této webové stránky shromažÄovat a analyzovat statistické údaje.", + "YouMayOptOutBis": "Pokud jste se rozhodli že ne, kliknÄ›te na pÅ™iložený odkaz pro uloženà deaktivaÄnÃho cookie ve svém prohlÞeÄi.", "OptingYouOut": "VyluÄovánÃ, prosÃm Äekejte..." } } \ No newline at end of file diff --git a/plugins/CoreAdminHome/lang/en.json b/plugins/CoreAdminHome/lang/en.json index 5fe5d64d3945d32eee480b579c75b6721ab49590..25a85f6475a8c3094e0fedfe174cf1019be06caf 100644 --- a/plugins/CoreAdminHome/lang/en.json +++ b/plugins/CoreAdminHome/lang/en.json @@ -87,6 +87,8 @@ "YouAreOptedOut": "You are currently opted out.", "YouMayOptOut": "You may choose not to have a unique web analytics cookie identification number assigned to your computer to avoid the aggregation and analysis of data collected on this website.", "YouMayOptOutBis": "To make that choice, please click below to receive an opt-out cookie.", - "OptingYouOut": "Opting you out, please wait..." + "OptingYouOut": "Opting you out, please wait...", + "ProtocolNotDetectedCorrectly": "You are currently viewing Piwik over a secure SSL connection (using https), but Piwik could only detect a non secure connection on the server. ", + "ProtocolNotDetectedCorrectlySolution": "To make sure Piwik securely requests and serves your content over HTTPS, you may edit your %s file and either configure your proxy settings, or you may add the line %s below the %s section. %sLearn more%s" } } diff --git a/plugins/CoreAdminHome/lang/it.json b/plugins/CoreAdminHome/lang/it.json index a8692d08a60533548c3e82c3f2aa2f9cd4425b65..d453a6252c8c0f5b082eadb23981be7a0ebc2d30 100644 --- a/plugins/CoreAdminHome/lang/it.json +++ b/plugins/CoreAdminHome/lang/it.json @@ -56,7 +56,7 @@ "MenuGeneralSettings": "Impostazioni generali", "MenuManage": "Gestione", "MenuDevelopment": "Sviluppo", - "OptOutComplete": "Opt-out completato; le tue visite a questo sito non verranno registrate dallo strumento di Web Analytics.", + "OptOutComplete": "Opt-out completato. Le tue visite a questo sito non verranno registrate dallo strumento di Web Analytics.", "OptOutCompleteBis": "Nota che se cancelli i tuoi cookie, cancelli anche il cookie di opt-out, e se cambi computer o browser web, devi fare la procedura di opt-out nuovamente.", "OptOutDntFound": "Non vieni tracciato poiché il tuo browser comunica che non lo desideri. Questa è un'impostazione del tuo browser, dunque non potrai effettuare l'opt-in finchè non disabiliti la funzionalità \"Non Tracciare\".", "OptOutExplanation": "Piwik è impegnato ad assicurare la riservatezza su Internet. Per dare ai tuoi ospiti la possibilità di escludersi dalle Statistiche Web Piwik, è possibile aggiungere il seguente codice HTML in una pagina del tuo sito web, ad esempio in una pagina sulla privacy.", diff --git a/plugins/CoreAdminHome/lang/ja.json b/plugins/CoreAdminHome/lang/ja.json index 782ccc1ad796199d911c470be090d9e1529c7d88..a40ab8e3b8e5d4b9d4cf739141c78bc3bcc65275 100644 --- a/plugins/CoreAdminHome/lang/ja.json +++ b/plugins/CoreAdminHome/lang/ja.json @@ -1,8 +1,10 @@ { "CoreAdminHome": { + "AddNewTrustedHost": "æ–°ã—ã„ä¿¡é ¼ã§ãã‚‹ãƒ›ã‚¹ãƒˆã‚’è¿½åŠ ã—ã¾ã™ã€‚", "Administration": "管ç†", "ArchivingSettings": "アーカイブè¨å®š", "BrandingSettings": "ブランディングè¨å®š", + "ReleaseChannel": "リリース ãƒãƒ£ãƒãƒ«", "ClickHereToOptIn": "クリックã—ã¦ã‚ªãƒ—トイン。", "ClickHereToOptOut": "クリックã—ã¦ã‚ªãƒ—トアウト。", "CustomLogoFeedbackInfo": "Piwikã®ãƒã‚´ã‚’カスタマイズã™ã‚‹å ´åˆã€ãƒˆãƒƒãƒ—メニュー㮠%s ã®ãƒªãƒ³ã‚¯ã‚‚éš ã—ãŸã„ã¨æ€ã†ã‹ã‚‚ã—れã¾ã›ã‚“。ãれã«ã¯ %sプラグインã®ç®¡ç†%s ã®ãƒšãƒ¼ã‚¸ã§ãƒ•ィードãƒãƒƒã‚¯ãƒ—ラグインを無効ã«ã—ã¾ã™ã€‚", @@ -68,8 +70,10 @@ "PluginSettingsIntro": "ã“ã“ã§ã¯ã€æ¬¡ã®ã‚µãƒ¼ãƒ‰ãƒ‘ーティã®ãƒ—ラグインã®è¨å®šå¤‰æ›´ãŒã§ãã¾ã™", "PluginSettingsValueNotAllowed": "\"%s\" プラグイン㮠\"%s\" フィールドã®å€¤ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“。", "PluginSettingsSaveFailed": "プラグインã®è¨å®šã‚’ä¿å˜ã§ãã¾ã›ã‚“ã§ã—ãŸ", + "SendPluginUpdateCommunication": "ãƒ—ãƒ©ã‚°ã‚¤ãƒ³ã®æ›´æ–°ãŒåˆ©ç”¨å¯èƒ½ãªã¨ãã«ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã™ã€‚", "SendPluginUpdateCommunicationHelp": "使用å¯èƒ½ãªæ–°ã—ã„プラグインã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒã‚ã‚‹å ´åˆã€ç®¡ç†è€…ユーザーã¸ãƒ¡ãƒ¼ãƒ«ãŒé€šçŸ¥ã•れã¾ã™ã€‚", "StableReleases": "PiwikãŒãƒ“ジãƒã‚¹ã®é‡è¦ãªä¸€éƒ¨ã§ã‚ã‚‹å ´åˆã€æœ€æ–°ã®å®‰å®šç‰ˆã‚’使用ã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚ã¾ãŸã€æœ€æ–°ã®ãƒ™ãƒ¼ã‚¿ç‰ˆã‚’使用ã—ã€ãƒã‚°ã‚’見ã¤ã‘ãŸã‚Šã€ææ¡ˆãŒã‚れã°ã€%sã“ã¡ã‚‰ã‚’ã”覧ãã ã•ã„%s。", + "LtsReleases": "LTS (長期サãƒãƒ¼ãƒˆ) ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€ã‚»ã‚ュリティã¨ãƒã‚°ä¿®æ£ã®ã¿å—ä¿¡ã—ã¾ã™ã€‚", "SystemPluginSettings": "システムプラグインè¨å®š", "TrackAGoal": "目標ã®è¿½è·¡", "TrackingCode": "トラッã‚ングコード", diff --git a/plugins/CoreAdminHome/lang/ko.json b/plugins/CoreAdminHome/lang/ko.json index d44b2797a7795529e538fc6b46080f11d87e7fcc..d51f4e43be5934d2ce60b84cc34b4d26898a5721 100644 --- a/plugins/CoreAdminHome/lang/ko.json +++ b/plugins/CoreAdminHome/lang/ko.json @@ -8,22 +8,40 @@ "ClickHereToOptOut": "í´ë¦í•˜ì—¬ 차단합니다.", "CustomLogoFeedbackInfo": "Piwik ë¡œê³ ë¥¼ 변경하거나 ìƒë‹¨ ë©”ë‰´ì˜ %s ë§í¬ë„ 숨길 수 있습니다. %s í”ŒëŸ¬ê·¸ì¸ ê´€ë¦¬ %s 페ì´ì§€ì—서 피드백 플러그ì¸ì„ 비활성화세요.", "CustomLogoHelpText": "Piwik ë¡œê³ ë¥¼ 사용ìžì •ì˜í•˜ì—¬ ì‚¬ìš©ìž ì¸í„°íŽ˜ì´ìФ 화면과 ì´ë©”ì¼ ë³´ê³ ì„œë¥¼ ë³¼ 수 있습니다.", + "DevelopmentProcess": "Piwikì˜ %s개발 ê³¼ì •%sì•ˆì— ìˆ˜ë§Žì€ ìžë™ 검사를 수행하지만, Piwikì˜ \"무버그 ì •ì±…\"ì„ ë§Œì¡±ì‹œí‚¤ê¸° 위해 ë² íƒ€ 테스터가 ìƒë‹¹ížˆ 중요합니다.", "EmailServerSettings": "ë©”ì¼ ì„œë²„ ì„¤ì •", + "ForBetaTestersOnly": "ë² íƒ€ 테스터 ì „ìš©", "ImageTracking": "ì´ë¯¸ì§€ ì¶”ì ", "ImageTrackingLink": "ì´ë¯¸ì§€ ì¶”ì ë§í¬", "ImportingServerLogs": "서버 로그 ê°€ì ¸ì˜¤ê¸°", "JavaScriptTracking": "ìžë°”스í¬ë¦½íЏ ì¶”ì ", + "JSTracking_CampaignKwdParam": "ìº íŽ˜ì¸ í‚¤ì›Œë“œ 파ë¼ë©”í„°", + "JSTracking_CampaignNameParam": "ìº íŽ˜ì¸ ì´ë¦„ 파ë¼ë©”í„°", + "JSTracking_CodeNote": "아래 코드는 ë‹¹ì‹ ì˜ ì›¹ì‚¬ì´íЏì—서 ëª¨ë“ íŽ˜ì´ì§€ì˜ %1$s 태그 바로 ì•žì— ìœ„ì¹˜í•´ì•¼ 합니다.", + "JSTracking_CustomCampaignQueryParamDesc": "중요: %1$s Piwik는 ìžë™ìœ¼ë¡œ 구글 ë¶„ì„ íŒŒë¼ë©”터를 ê°ì§€í•©ë‹ˆë‹¤.%2$s", + "JSTracking_EnableDoNotTrack": "í´ë¼ì´ì–¸íЏì—서 DoNotTrack íƒì§€ 활성화", + "JSTrackingIntro3": "ëŒ€ë¶€ë¶„ì˜ ì›¹ì‚¬ì´íЏ, 블로그, CMS 등ì—서 쉽게 ì‚¬ìš©í• ìˆ˜ 있ë„ë¡ í”ŒëŸ¬ê·¸ì¸ í˜•íƒœë¡œ ì œê³µë˜ê³ 있습니다. (%1$sPiwik 통합 í”ŒëŸ¬ê·¸ì¸ ë¦¬ìŠ¤íŠ¸%2$s 보기) 만약 플러그ì¸ì´ ì œê³µë˜ì§€ 않는다면, 웹사ì´íЏ í…œí”Œë¦¿ì„ ê³ ì³ \"footer\" 파ì¼ì— 해당 코드를 넣어 í•´ê²°í• ìˆ˜ 있습니다.", + "JSTrackingIntro5": "만약 페ì´ì§€ ë·°ì— ëŒ€í•œ 것 ì´ìƒì„ ì›í• 경우, %1$sPiwik ìžë°”스í¬ë¦½íЏ 트래킹 문서%2$s ë‚´ 여러 가능한 함수 리스트를 ì°¸ê³ í•˜ì„¸ìš”. ì´ í•¨ìˆ˜ë“¤ì„ í†µí•´ 목표나 맞춤 변수, ìƒê±°ëž˜ 주문 ë° ë‹´ê²¨ì ¸ìžˆê¸°ë§Œ 한 카트 ë“±ì„ ì¶”ì í• ìˆ˜ 있습니다.", "LogoUpload": "업로드 í• ë¡œê³ ì„ íƒ", + "FaviconUpload": "업로드 í• íŒŒë¹„ì½˜ ì„ íƒ", "MenuDiagnostic": "진단", "MenuGeneralSettings": "ì¼ë°˜ ì„¤ì •", "MenuManage": "관리", + "MenuDevelopment": "개발", "OptOutComplete": "차단 완료; ë‹¹ì‹ ì˜ ë°©ë¬¸í•œ ì´ ì›¹ì‚¬ì´íŠ¸ëŠ” ì´ì œ 웹 ë¶„ì„ ë„êµ¬ì— ê¸°ë¡ë˜ì§€ 않습니다.", "OptOutCompleteBis": "Cookie를 ì‚ì œí•˜ì—¬ 차단 Cookie를 ì‚ì œí•˜ê±°ë‚˜ 컴퓨터 ë˜ëŠ” 브ë¼ìš°ì €ë¥¼ 변경 한 경우는 차단 ì ˆì°¨ë¥¼ 다시 수행해야 한다는 ì ìœ ì˜í•˜ì„¸ìš”.", "OptOutExplanation": "Piwikì€ ì¸í„°ë„·ì—서 ê°œì¸ ì •ë³´ ì œê³µì— ìµœì„ ì„ ë‹¤í•˜ê³ ìžˆìŠµë‹ˆë‹¤. 방문ìžì— Piwik 웹 ë¶„ì„ì˜ ì°¨ë‹¨ ì˜µì…˜ì„ ì œê³µí•˜ê¸° 위해 웹 사ì´íŠ¸ì˜ 1페ì´ì§€ (ê°œì¸ ì •ë³´ 보호 ì •ì±… 페ì´ì§€ 등)ì— ë‹¤ìŒ HTML 코드를 추가 í• ìˆ˜ 있습니다.", "OptOutExplanationBis": "HTML 코드는 방문ìžì˜ 브ë¼ìš°ì €ì— 차단 Cookie를 ì„¤ì •í•˜ëŠ” Piwik 차단 ë§í¬ë¥¼ ​​í¬í•¨ iFrameì„ í‘œì‹œí•©ë‹ˆë‹¤. iFrameì—서 표시ë˜ëŠ” ë‚´ìš©ì„ í‘œì‹œí•˜ë ¤ë©´ %s여기를 í´ë¦%s합니다.", "OptOutForYourVisitors": "방문ìžì˜ Piwik 차단", "PiwikIsInstalledAt": "Piwikê°€ 설치ë˜ì–´ 있습니다", + "PersonalPluginSettings": "ë‚˜ë§Œì˜ í”ŒëŸ¬ê·¸ì¸ ì„¤ì •", "PluginSettings": "í”ŒëŸ¬ê·¸ì¸ ì„¤ì •", + "PluginSettingsIntro": "ë‹¤ìŒ ë‚˜ì—´ëœ ì„œë“œ 파티 플러그ì¸ì˜ ì„¤ì •ì„ ë°”ê¿€ 수 있다:", + "PluginSettingsSaveFailed": "í”ŒëŸ¬ê·¸ì¸ ì„¤ì • ì €ìž¥ 실패", + "SendPluginUpdateCommunication": "í”ŒëŸ¬ê·¸ì¸ ì—…ë°ì´íŠ¸ê°€ ê°€ëŠ¥í• ë•Œ ì´ë©”ì¼ ì•Œë¦¼", + "SendPluginUpdateCommunicationHelp": "플러그ì¸ì˜ 새로운 ë²„ì „ì´ ë‚˜íƒ€ë‚ ê²½ìš° ìˆ˜í¼ ìœ ì €ì—게 ë©”ì¼ë¡œ ì•Œë ¤ì§‘ë‹ˆë‹¤.", + "StableReleases": "만약 Piwikê°€ ë‹¹ì‹ ì˜ ë¹„ì§€ë‹ˆìŠ¤ì— ìƒë‹¹ížˆ 중요한 요소ë¼ë©´ 최근 ì•ˆì • ë²„ì „ì„ ì‚¬ìš©í•˜ì‹œëŠ” ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤. 만약 최근 ë² íƒ€ ë²„ì „ì„ ì‚¬ìš© 중 버그를 찾으셨거나 ì œì•ˆí•˜ì‹¤ 사í•ì´ ìžˆìœ¼ì‹œë‹¤ë©´, %s여기를 ë´ì£¼ì„¸ìš”%s.", + "LtsReleases": "LTS (Long Term Support, 오랜 기간ë™ì•ˆ ì§€ì›ë¨) ë²„ì „ì€ ë³´ì•ˆ ë° ë²„ê·¸ í•´ê²°ë§Œ 받습니다.", "SystemPluginSettings": "시스템 í”ŒëŸ¬ê·¸ì¸ ì„¤ì •", "TrackAGoal": "목표 ì¶”ì ", "TrackingCode": "ì¶”ì 코드", diff --git a/plugins/CoreAdminHome/lang/nb.json b/plugins/CoreAdminHome/lang/nb.json index d0fa1a793a9b40ce3ae02bf1e8855b9c64380412..cb4c8f07e11ca5be9a2d8c4cb813d194d914d1af 100644 --- a/plugins/CoreAdminHome/lang/nb.json +++ b/plugins/CoreAdminHome/lang/nb.json @@ -1,15 +1,26 @@ { "CoreAdminHome": { + "AddNewTrustedHost": "Legg til en ny trygg tjener", "Administration": "Administrasjon", "ArchivingSettings": "Arkiveringsinnstillinger", "BrandingSettings": "Innstillinger for profilering", + "ReleaseChannel": "Versjonskanal", "ClickHereToOptIn": "Trykk her for Ã¥ delta.", "ClickHereToOptOut": "Trykk her for Ã¥ ikke delta.", + "CustomLogoFeedbackInfo": "Hvis du tilpasser Piwik-logoen vil du kanskje ogsÃ¥ skjule %s-lenken i toppmenyen. For Ã¥ gjøre det mÃ¥ du deaktivere Feedback-utvidelsen i %sAdministrasjon av utvidelser%s-siden.", + "CustomLogoHelpText": "Du kan tilpasse Piwik-logoen som vises i brukergrensesnittet og i e-postrapporter.", + "DevelopmentProcess": "Selv om vÃ¥r %sutviklingsprosess%s inkluderer tusener av automatiske testser, spiller betatestere en viktig rolle for Ã¥ at vi skal kunne etterleve vÃ¥rt mÃ¥l om Ã¥ ikke ha noen feil.", "EmailServerSettings": "Innstillinger for e-posttjener", "ForBetaTestersOnly": "Kun for beta testere", "ImageTracking": "Bildesporing", - "ImageTrackingLink": "Sporings lenke for bilde", + "ImageTrackingIntro1": "NÃ¥r en bruker har deaktivert JavaScript, eller nÃ¥r JavaScript ikke kan brukes, kan du bruke en bildesporingslenke for Ã¥ spore besøkere.", + "ImageTrackingIntro2": "Generer lenken under og kopier den genererte HTML-koden til ditt nettsted. Hvis du bruker dette som en fallback for JavaScript-sporing, kan du bruke %1$s-tagger rundt koden.", + "ImageTrackingIntro3": "For hele listen med valg du kan bruke med en bildesporingslenke, se %1$sDokumentasjonen for sporings-API%2$s.", + "ImageTrackingLink": "Bildesporingslenke", "ImportingServerLogs": "Importerer serverlogger", + "ImportingServerLogsDesc": "Som et alternativ til Ã¥ spore besøkere gjennom nettleseren (enten via JavaScript eller bildesporingslenke), kan du importere serverlogger regelmessig. %1$sLær mer serverlogganalyse her.%2$s", + "InvalidPluginsWarning": "De følgende utvidelsene er ikke kompatible med %1$s og kunne ikke lastes inn: %2$s.", + "InvalidPluginsYouCanUninstall": "Du kan oppdatere eller avinstallere disse utvidelsene pÃ¥ %1$sAdministrer utvidelser%2$s-siden.", "JavaScriptTracking": "JavaScript-sporing", "JSTracking_EnableDoNotTrack": "Aktiver klientside DoNotTrack-gjenkjenning", "LogoUpload": "Velg en logo for Ã¥ laste opp", diff --git a/plugins/CoreAdminHome/lang/pt-br.json b/plugins/CoreAdminHome/lang/pt-br.json index bda01821fc7c969032cd63c97599c31466f2f8a5..dd8298be318b90d10db6634b35950820aac7f1d7 100644 --- a/plugins/CoreAdminHome/lang/pt-br.json +++ b/plugins/CoreAdminHome/lang/pt-br.json @@ -48,10 +48,10 @@ "JSTrackingIntro4": "Se você não quiser usar JavaScript para monitorar visitantes, %1$sgere abaixo, um link para rastreamento por imagem%2$s.", "JSTrackingIntro5": "Se você deseja mais do que apenas monitorar exibições de página, porfavor verifique a %1$sdocumentação do rastreamento por javascript do Piwik%2$s para uma lista de funcões disponÃveis. Usando essas funções você pode acompanhar objetivos, variáveis ​​personalizadas, ordens de comércio eletrônico, compras abandonadas e muito mais.", "LogoNotWriteableInstruction": "Para usar um logotipo cutomizado ao invés do logo padrão Piwiki, dê permissão de escrita para esse diretório: %1$s Piwiki precisa de acesso de escrita para seus logotipos armazenados no arquivo %2$s.", - "FileUploadDisabled": "O envio de arquivos não está habilitado na sua configuração do PHP. Para enviar uma logomarca customizada defina %s no php.ini e reinicie seu servidor web.", + "FileUploadDisabled": "O carregamento de arquivos não está habilitado na sua configuração do PHP. Para carregar uma logomarca customizada defina %s no php.ini e reinicie seu servidor web.", "LogoUpload": "Selecione um logotipo para carregar", - "FaviconUpload": "Selecione um Favicon para fazer upload", - "LogoUploadHelp": "Por favor faça o upload de um arquivo nos formatos %s com uma altura mÃnima de %s pixels.", + "FaviconUpload": "Selecione um Favicon para carregar", + "LogoUploadHelp": "Por favor carregue um arquivo nos formatos %s com uma altura mÃnima de %s pixels.", "MenuDiagnostic": "Diagnostico", "MenuGeneralSettings": "Configurações Gerais", "MenuManage": "Gerenciar", diff --git a/plugins/CoreAdminHome/lang/tr.json b/plugins/CoreAdminHome/lang/tr.json index 1a4116f46e1a50f76335dc27da79cd8ccf95858f..8a412db6af3957bcb772648b30f6d578de75eb6a 100644 --- a/plugins/CoreAdminHome/lang/tr.json +++ b/plugins/CoreAdminHome/lang/tr.json @@ -50,8 +50,12 @@ "OptOutForYourVisitors": "ziyaretciniz için Piwiki devre dışı bırakmak", "PiwikIsInstalledAt": "Piwikde yüklenir", "PluginSettingChangeNotAllowed": "Bu ayarların \"%s\" deÄŸerlerini deÄŸiÅŸtirmek için \"%s\" eklentisinde gerekli izniniz yok.", + "PluginSettings": "Eklenti Ayarları", "PluginSettingsIntro": "Buradan aÅŸağıdaki 3. parti eklentiler için ayarları deÄŸiÅŸtirebilirsiniz:", + "PluginSettingsSaveFailed": "Eklenti ayarları kaydedilemedi", + "SendPluginUpdateCommunication": "Eklenti güncellemesi olduÄŸunda e-posta gönder", "StableReleases": "EÄŸer Piwik iÅŸiniz için kritik bir parçaysa, son ve stabil olan versiyonu kullanmanızı öneririz. EÄŸer en son güncel betayı kullanıyorsanız ve bir hata bulur ya da öneriniz olursa, lütfen ÅŸuraya%s bakın%s.", + "SystemPluginSettings": "Sistem Eklenti Ayarları", "TrackAGoal": "Bir hedef izleme", "TrackingCode": "İzleme Kodu", "TrustedHostConfirm": "Güvenilir alan adınızı deÄŸiÅŸtirmek istediÄŸinizden emin misiniz?", diff --git a/plugins/CoreAdminHome/stylesheets/generalSettings.less b/plugins/CoreAdminHome/stylesheets/generalSettings.less index 9d232f789b65bf2229115a06f3a0478328674229..dde1da48edb97d8d0238c3ac7d22f99f693569cf 100644 --- a/plugins/CoreAdminHome/stylesheets/generalSettings.less +++ b/plugins/CoreAdminHome/stylesheets/generalSettings.less @@ -8,7 +8,7 @@ } // hide PHP is deprecated notification in UI test -.uiTest [notification-id="PHP53VersionCheck"] { +.uiTest [notification-id="DeprecatedPHPVersionCheck"] { display: none !important; } diff --git a/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig b/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig index 25d03527330ba62818a5b61232b977c240ee35ef..6d66695552e55ac7b1d71eb55b633c813c4aed03 100644 --- a/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig +++ b/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig @@ -75,7 +75,7 @@ {{ 'CoreAdminHome_JSTracking_MergeAliasesDesc'|translate("<span class='current-site-alias'>"~defaultReportSiteAlias~"</span>")|raw }} </div> <label class="checkbox"> - <input type="checkbox" id="javascript-tracking-all-aliases"/> + <input type="checkbox" checked="checked" id="javascript-tracking-all-aliases"/> {{ 'CoreAdminHome_JSTracking_MergeAliases'|translate }} <span class='current-site-name'>{{ defaultReportSiteName|raw }}</span> </label> diff --git a/plugins/CoreConsole/Commands/GenerateArchiver.php b/plugins/CoreConsole/Commands/GenerateArchiver.php index bbbdb85dfce5c90b315d49f6262992b14ef58c83..29bcee7bb6fa7ebd67067be41fc6ae1b24968c9e 100644 --- a/plugins/CoreConsole/Commands/GenerateArchiver.php +++ b/plugins/CoreConsole/Commands/GenerateArchiver.php @@ -30,7 +30,7 @@ class GenerateArchiver extends GeneratePluginBase $this->checkAndUpdateRequiredPiwikVersion($pluginName, $output); $exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin'; - $replace = array('ExamplePlugin' => ucfirst($pluginName), 'EXAMPLEPLUGIN' => strtoupper($pluginName)); + $replace = array('ExamplePlugin' => $pluginName, 'EXAMPLEPLUGIN' => strtoupper($pluginName)); $whitelistFiles = array('/Archiver.php'); $this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles); diff --git a/plugins/CoreConsole/Commands/GeneratePlugin.php b/plugins/CoreConsole/Commands/GeneratePlugin.php index c42d7a619bdfaeec1703bbc4a94cc788596798e8..bf83889305e793d3be703a210b3900d044dda4e2 100644 --- a/plugins/CoreConsole/Commands/GeneratePlugin.php +++ b/plugins/CoreConsole/Commands/GeneratePlugin.php @@ -12,6 +12,7 @@ namespace Piwik\Plugins\CoreConsole\Commands; use Piwik\Filesystem; use Piwik\Plugins\ExamplePlugin\ExamplePlugin; use Piwik\Version; +use Piwik\Plugin; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -28,7 +29,8 @@ class GeneratePlugin extends GeneratePluginBase ->setDescription('Generates a new plugin/theme including all needed files') ->addOption('name', null, InputOption::VALUE_REQUIRED, 'Plugin name ([a-Z0-9_-])') ->addOption('description', null, InputOption::VALUE_REQUIRED, 'Plugin description, max 150 characters') - ->addOption('pluginversion', null, InputOption::VALUE_OPTIONAL, 'Plugin version'); + ->addOption('pluginversion', null, InputOption::VALUE_OPTIONAL, 'Plugin version') + ->addOption('overwrite', null, InputOption::VALUE_NONE, 'Generate even if plugin directory already exists.'); } protected function execute(InputInterface $input, OutputInterface $output) @@ -115,20 +117,24 @@ class GeneratePlugin extends GeneratePluginBase */ protected function getPluginName(InputInterface $input, OutputInterface $output) { + $overwrite = $input->getOption('overwrite'); + $self = $this; - $validate = function ($pluginName) use ($self) { + $validate = function ($pluginName) use ($self, $overwrite) { if (empty($pluginName)) { throw new \RuntimeException('You have to enter a plugin name'); } - if (!Filesystem::isValidFilename($pluginName)) { - throw new \RuntimeException(sprintf('The plugin name %s is not valid', $pluginName)); + if (!Plugin\Manager::getInstance()->isValidPluginName($pluginName)) { + throw new \RuntimeException(sprintf('The plugin name %s is not valid. The name must start with a letter and is only allowed to contain numbers and letters.', $pluginName)); } $pluginPath = $self->getPluginPath($pluginName); - if (file_exists($pluginPath)) { + if (file_exists($pluginPath) + && !$overwrite + ) { throw new \RuntimeException('A plugin with this name already exists'); } diff --git a/plugins/CoreConsole/Commands/GeneratePluginBase.php b/plugins/CoreConsole/Commands/GeneratePluginBase.php index c3fce493dc02ffdae690366508402bd1a6ca2550..9012839943265ae24f0e839c15b75709c1377ff3 100644 --- a/plugins/CoreConsole/Commands/GeneratePluginBase.php +++ b/plugins/CoreConsole/Commands/GeneratePluginBase.php @@ -31,7 +31,7 @@ abstract class GeneratePluginBase extends ConsoleCommand private function getRelativePluginPath($pluginName) { - return '/plugins/' . ucfirst($pluginName); + return '/plugins/' . $pluginName; } private function createFolderWithinPluginIfNotExists($pluginNameOrCore, $folder) @@ -325,8 +325,6 @@ abstract class GeneratePluginBase extends ConsoleCommand $validate($pluginName); } - $pluginName = ucfirst($pluginName); - return $pluginName; } diff --git a/plugins/CoreHome/Columns/UserId.php b/plugins/CoreHome/Columns/UserId.php index bbe7e44c8ffa7aa0691f9fbcb32100d0683a8e83..a611ca8def39837e143e2bb8d0b0ddea839c7bb5 100644 --- a/plugins/CoreHome/Columns/UserId.php +++ b/plugins/CoreHome/Columns/UserId.php @@ -11,6 +11,7 @@ namespace Piwik\Plugins\CoreHome\Columns; use Piwik\Cache; use Piwik\DataTable; use Piwik\DataTable\Map; +use Piwik\Metrics; use Piwik\Period\Range; use Piwik\Piwik; use Piwik\Plugin\Dimension\VisitDimension; @@ -124,7 +125,14 @@ class UserId extends VisitDimension return false; } - $numUsers = $result->getColumn('nb_users'); + $firstRow = $result->getFirstRow(); + if ($firstRow instanceof DataTable\Row && $firstRow->hasColumn(Metrics::INDEX_NB_USERS)) { + $metric = Metrics::INDEX_NB_USERS; + } else { + $metric = 'nb_users'; + } + + $numUsers = $result->getColumn($metric); $numUsers = array_sum($numUsers); return !empty($numUsers); diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php index 519891acb043ff2da7d3c8242dbb0739e04b3832..c1f88e035c1de5751ba940cf561888e8bfb9a3a9 100644 --- a/plugins/CoreHome/CoreHome.php +++ b/plugins/CoreHome/CoreHome.php @@ -143,6 +143,8 @@ class CoreHome extends \Piwik\Plugin $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/trim.js"; $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/pretty-url.js"; $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/escape.js"; + $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/htmldecode.js"; + $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/ucfirst.js"; $jsFiles[] = "plugins/CoreHome/angularjs/common/directives/directive.module.js"; $jsFiles[] = "plugins/CoreHome/angularjs/common/directives/autocomplete-matched.js"; @@ -207,7 +209,6 @@ class CoreHome extends \Piwik\Plugin $translationKeys[] = 'General_Show'; $translationKeys[] = 'General_Hide'; $translationKeys[] = 'General_Website'; - $translationKeys[] = 'General_ChooseWebsite'; $translationKeys[] = 'Intl_Year_Short'; $translationKeys[] = 'General_MultiSitesSummary'; $translationKeys[] = 'General_SearchNoResults'; @@ -278,6 +279,7 @@ class CoreHome extends \Piwik\Plugin $translationKeys[] = 'Intl_Day_Min_StandAlone_6'; $translationKeys[] = 'Intl_Day_Min_StandAlone_7'; $translationKeys[] = 'General_And'; + $translationKeys[] = 'General_All'; $translationKeys[] = 'General_Search'; $translationKeys[] = 'General_Clear'; $translationKeys[] = 'General_MoreDetails'; @@ -304,5 +306,6 @@ class CoreHome extends \Piwik\Plugin $translationKeys[] = 'CoreHome_Segments'; $translationKeys[] = 'CoreHome_MenuEntries'; $translationKeys[] = 'SitesManager_Sites'; + $translationKeys[] = 'CoreHome_ChangeCurrentWebsite'; } } diff --git a/plugins/CoreHome/DataTableRowAction/RowEvolution.php b/plugins/CoreHome/DataTableRowAction/RowEvolution.php index d73c5c21580c7620240d70bac2ff108409d5f682..106685edf7a32e2de4b2b587e22b6fba658d430f 100644 --- a/plugins/CoreHome/DataTableRowAction/RowEvolution.php +++ b/plugins/CoreHome/DataTableRowAction/RowEvolution.php @@ -91,7 +91,7 @@ class RowEvolution if (!is_array($this->label)) { throw new Exception("Expected label to be an array, got instead: " . $this->label); } - $this->label = $this->label[0]; + $this->label = Common::unsanitizeInputValue($this->label[0]); if ($this->label === '') throw new Exception("Parameter label not set."); diff --git a/plugins/CoreHome/Menu.php b/plugins/CoreHome/Menu.php index 20d9ac8eb8ba9d10801eb54db2f44ea38593b851..c9331e4470a8f81d79734a35df85d5c3f5a1caba 100644 --- a/plugins/CoreHome/Menu.php +++ b/plugins/CoreHome/Menu.php @@ -35,12 +35,13 @@ class Menu extends \Piwik\Plugin\Menu if (Piwik::isUserIsAnonymous()) { if (Plugin\Manager::getInstance()->isPluginActivated('ScheduledReports')) { - $menu->addItem($login, null, array('module' => 'ScheduledReports', 'action' => 'index'), 970, $login); + $menu->addItem($login, null, array('module' => 'ScheduledReports', 'action' => 'index'), 970, Piwik::translate('ScheduledReports_PersonalEmailReports')); } else { - $menu->addItem($login, null, array('module' => 'API', 'action' => 'listAllAPI'), 970, $login); + $menu->addItem($login, null, array('module' => 'API', 'action' => 'listAllAPI'), 970, Piwik::translate('API_ReportingApiReference')); } } else { - $menu->addItem($login, null, array('module' => 'UsersManager', 'action' => 'userSettings'), 970, $login); + $tooltip = sprintf('%s: %s', Piwik::translate('UsersManager_PersonalSettings'), $login); + $menu->addItem($login, null, array('module' => 'UsersManager', 'action' => 'userSettings'), 970, $tooltip); } $module = $this->getLoginModule(); diff --git a/plugins/CoreHome/angularjs/common/filters/htmldecode.js b/plugins/CoreHome/angularjs/common/filters/htmldecode.js new file mode 100644 index 0000000000000000000000000000000000000000..c3e81079312bcc260e931053a89a0d225e682386 --- /dev/null +++ b/plugins/CoreHome/angularjs/common/filters/htmldecode.js @@ -0,0 +1,26 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +(function () { + angular.module('piwikApp.filter').filter('htmldecode', htmldecode); + + htmldecode.$inject = ['piwik']; + + /** + * Be aware that this filter can cause XSS so only use it when you're sure it is safe. + * Eg it should be safe when it is afterwards escaped by angular sanitize again. + */ + function htmldecode(piwik) { + + return function(text) { + if (text && text.length) { + return piwik.helper.htmlDecode(text); + } + + return text; + }; + } +})(); diff --git a/plugins/CoreHome/angularjs/common/filters/ucfirst.js b/plugins/CoreHome/angularjs/common/filters/ucfirst.js new file mode 100644 index 0000000000000000000000000000000000000000..34b3460be89f52064ce5efa022be112f9ac8dce0 --- /dev/null +++ b/plugins/CoreHome/angularjs/common/filters/ucfirst.js @@ -0,0 +1,21 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +(function () { + angular.module('piwikApp.filter').filter('ucfirst', ucfirst); + + function ucfirst() { + + return function(value) { + if (!value) { + return value; + } + + var firstLetter = (value + '').charAt(0).toUpperCase(); + return firstLetter + value.substr(1); + }; + } +})(); diff --git a/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.directive.html b/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.directive.html index 8cf6a9a67b9a60c38c58a52c6452eccd1ce0d06c..93371a03bf007bf9c8878111b2a03506d9607989 100644 --- a/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.directive.html +++ b/plugins/CoreHome/angularjs/reporting-menu/reportingmenu.directive.html @@ -1,6 +1,7 @@ -<ul class="navbar"> +<ul class="navbar"role="menu"> <li ng-repeat="category in menuModel.menu" class="menuTab" + role="menuitem" ng-class="{'active': category.active}"> <a class="item" href="" @@ -10,8 +11,9 @@ {{ 'CoreHome_Menu'|translate }} </span> </a> - <ul> + <ul role="menu"> <li ng-repeat="subcategory in category.subcategories" + role="menuitem" ng-class="{'active': subcategory.active}"> <div ng-if="subcategory.isGroup" piwik-menudropdown show-search="true" menu-title="{{ subcategory.name|escape }}"> <a class="item" diff --git a/plugins/CoreHome/angularjs/siteselector/siteselector.directive.html b/plugins/CoreHome/angularjs/siteselector/siteselector.directive.html index 9ee493216324f92a0cd9fd88801c58e9b0c4975f..e4e46a676aabd1070a1acaabd5a65f09d283701d 100644 --- a/plugins/CoreHome/angularjs/siteselector/siteselector.directive.html +++ b/plugins/CoreHome/angularjs/siteselector/siteselector.directive.html @@ -16,7 +16,7 @@ <a ng-click="view.showSitesList=!view.showSitesList; view.showSitesList && !model.isLoading && model.loadInitialSites();" piwik-onenter="view.showSitesList=!view.showSitesList; view.showSitesList && !model.isLoading && model.loadInitialSites();" href="javascript:void(0)" - title="{{ 'General_ChooseWebsite'|translate }}" + title="{{ 'CoreHome_ChangeCurrentWebsite'|translate:((selectedSite.name || model.firstSiteName)|htmldecode) }}" ng-class="{'loading': model.isLoading}" class="title"> <span class="icon icon-arrow-bottom" @@ -37,6 +37,7 @@ ng-hide="!showSelectedSite && activeSiteId==site.idsite"> <a piwik-ignore-click href="{{ getUrlForSiteId(site.idsite) }}" piwik-autocomplete-matched="view.searchTerm" + title="{{ site.name|htmldecode }}" ng-bind-html="site.name"></a> </li> </ul> diff --git a/plugins/CoreHome/config/config.php b/plugins/CoreHome/config/config.php index 3c646cbd887d08602362a34f5495c528ce6ae366..39236b62c53c92f57d63ea865971a2eb15077840 100644 --- a/plugins/CoreHome/config/config.php +++ b/plugins/CoreHome/config/config.php @@ -3,10 +3,6 @@ return array( 'Piwik\Plugins\CoreHome\Tracker\VisitRequestProcessor' => DI\object() - ->constructorParameter('visitStandardLength', DI\get('ini.Tracker.visit_standard_length')), - - 'tracker.request.processors' => DI\add(array( - DI\get('Piwik\Plugins\CoreHome\Tracker\VisitRequestProcessor'), - )), + ->constructorParameter('visitStandardLength', DI\get('ini.Tracker.visit_standard_length')) ); diff --git a/plugins/CoreHome/javascripts/broadcast.js b/plugins/CoreHome/javascripts/broadcast.js index 3d5fb0432c1f7c306be5f8034ae4c676e9b1b760..30b21f46af077c2dc2c2a83f6a95118814920889 100644 --- a/plugins/CoreHome/javascripts/broadcast.js +++ b/plugins/CoreHome/javascripts/broadcast.js @@ -214,6 +214,10 @@ var broadcast = { currentHashStr = broadcast.updateParamValue('idDashboard=', currentHashStr); } + if (module != 'CustomDimensions') { + currentHashStr = broadcast.updateParamValue('idDimension=', currentHashStr); + } + if (disableHistory) { var newLocation = window.location.href.split('#')[0] + '#?' + currentHashStr; // window.location.replace changes the current url without pushing it on the browser's history stack @@ -451,7 +455,8 @@ var broadcast = { broadcast.getParamValue('action', urlAjax), { idGoal: broadcast.getParamValue('idGoal', urlAjax), - idDashboard: broadcast.getParamValue('idDashboard', urlAjax) + idDashboard: broadcast.getParamValue('idDashboard', urlAjax), + idDimension: broadcast.getParamValue('idDimension', urlAjax) } ); }); diff --git a/plugins/CoreHome/javascripts/dataTable.js b/plugins/CoreHome/javascripts/dataTable.js index 9a7f34cd4c8fab43e2c188a30c6f48b3f90fe3a0..2ec3fb16d8b755da220cba28a6c70d3ecd3286ef 100644 --- a/plugins/CoreHome/javascripts/dataTable.js +++ b/plugins/CoreHome/javascripts/dataTable.js @@ -508,13 +508,20 @@ $.extend(DataTable.prototype, UIControl.prototype, { }; } + function getFilterLimitAsString(limit) { + if (limit == '-1') { + return _pk_translate('General_All').toLowerCase(); + } + return limit; + } + // setup limit control - $('.limitSelection', domElem).append('<div><span>' + self.param[limitParamName] + '</span></div><ul></ul>'); + $('.limitSelection', domElem).append('<div><span value="'+ self.param[limitParamName] +'">' + getFilterLimitAsString(self.param[limitParamName]) + '</span></div><ul></ul>'); if (self.props.show_limit_control) { $('.limitSelection ul', domElem).hide(); for (var i = 0; i < numbers.length; i++) { - $('.limitSelection ul', domElem).append('<li value="' + numbers[i] + '"><span>' + numbers[i] + '</span></li>'); + $('.limitSelection ul', domElem).append('<li value="' + numbers[i] + '"><span>' + getFilterLimitAsString(numbers[i]) + '</span></li>'); } $('.limitSelection ul li:last', domElem).addClass('last'); @@ -537,12 +544,12 @@ $.extend(DataTable.prototype, UIControl.prototype, { $('.limitSelection', domElem).is('.visible') ? hide() : show(); }); $('.limitSelection ul li', domElem).on('click', function (event) { - var limit = parseInt($(event.target).text()); + var limit = parseInt($(event.target).closest('li').attr('value')); hide(); if (limit != self.param[limitParamName]) { setLimitValue(self.param, limit); - $('.limitSelection>div>span', domElem).text(limit); + $('.limitSelection>div>span', domElem).text( getFilterLimitAsString(limit)).attr('value', limit); self.reloadAjaxDataTable(); var data = {}; @@ -1047,7 +1054,7 @@ $.extend(DataTable.prototype, UIControl.prototype, { $(this).attr('href', function () { var url = $(this).attr('href') + '&token_auth=' + piwik.token_auth; - var limit = $('.limitSelection>div>span', domElem).text(); + var limit = $('.limitSelection>div>span', domElem).attr('value'); var defaultLimit = $(this).attr('filter_limit'); if (!limit || 'undefined' === limit || defaultLimit == -1) { limit = defaultLimit; @@ -1071,6 +1078,7 @@ $.extend(DataTable.prototype, UIControl.prototype, { var segment = self.param.segment; var label = self.param.label; var idGoal = self.param.idGoal; + var idDimension = self.param.idDimension; var param_date = self.param.date; var date = $(this).attr('date'); if (typeof date != 'undefined') { @@ -1139,6 +1147,11 @@ $.extend(DataTable.prototype, UIControl.prototype, { && idGoal != '-1') { str += '&idGoal=' + idGoal; } + // Export Dimension specific reports + if (typeof idDimension != 'undefined' + && idDimension != '-1') { + str += '&idDimension=' + idDimension; + } if (label) { label = label.split(','); diff --git a/plugins/CoreHome/javascripts/dataTable_rowactions.js b/plugins/CoreHome/javascripts/dataTable_rowactions.js index 004e27e3b67694e7da304620e92911baf81e2a85..e7308fb93f450d02c8b53f56ebaa46f33fcfd010 100644 --- a/plugins/CoreHome/javascripts/dataTable_rowactions.js +++ b/plugins/CoreHome/javascripts/dataTable_rowactions.js @@ -386,6 +386,17 @@ DataTable_RowActions_RowEvolution.prototype.showRowEvolution = function (apiMeth requestParams.action = 'getRowEvolutionPopover'; requestParams.colors = JSON.stringify(piwik.getSparklineColors()); + var idDimension; + if (broadcast.getValueFromUrl('module') === 'Widgetize') { + idDimension = broadcast.getValueFromUrl('idDimension'); + } else { + idDimension = broadcast.getValueFromHash('idDimension'); + } + + if (idDimension) { + requestParams.idDimension = parseInt(idDimension, 10); + } + $.extend(requestParams, extraParams); var ajaxRequest = new ajaxHelper(); diff --git a/plugins/CoreHome/javascripts/notification.js b/plugins/CoreHome/javascripts/notification.js index e6c3f017f2ebf6484e945f7212768676cfb8f35a..527c845d8724fd1cfd523527f37d75d450cec1b1 100644 --- a/plugins/CoreHome/javascripts/notification.js +++ b/plugins/CoreHome/javascripts/notification.js @@ -54,6 +54,16 @@ this.$node = placeNotification(template, options); }; + /** + * Removes a previously shown notification having the given notification id. + * + * + * @param {string} notificationId The id of a notification that was previously registered. + */ + Notification.prototype.remove = function (notificationId) { + $('[piwik-notification][notification-id=' + notificationId + ']').remove(); + }; + Notification.prototype.scrollToNotification = function () { if (this.$node) { piwikHelper.lazyScrollTo(this.$node, 250); diff --git a/plugins/CoreHome/javascripts/popover.js b/plugins/CoreHome/javascripts/popover.js index aff7ed7ff9544e2146c421b9772a683b68311888..f6947698218f82e8df0a952cf2f266880d23ab02 100644 --- a/plugins/CoreHome/javascripts/popover.js +++ b/plugins/CoreHome/javascripts/popover.js @@ -142,7 +142,17 @@ var Piwik_Popover = (function () { /** Set the title of the popover */ setTitle: function (titleHtml) { + var titleText = piwikHelper.htmlDecode(titleHtml); + if (titleText.length > 60) { + titleHtml = $('<span>').attr('class', 'tooltip').attr('title', titleText).html(titleHtml); + } container.dialog('option', 'title', titleHtml); + try { + $('.tooltip', container.parentNode).tooltip('destroy'); + } catch (e) {} + if (titleText.length > 60) { + $('.tooltip', container.parentNode).tooltip({track: true, items: '.tooltip'}); + } }, /** Set inner HTML of the popover */ diff --git a/plugins/CoreHome/lang/cs.json b/plugins/CoreHome/lang/cs.json index b2a02bb644d80688392c91bafa00bb86c79456c5..aba489871a67dc9db6cabdb1ca287e87e282b563 100644 --- a/plugins/CoreHome/lang/cs.json +++ b/plugins/CoreHome/lang/cs.json @@ -20,7 +20,7 @@ "IncludeRowsWithLowPopulation": "Řádky s nÃzkou populacà jsou skryty %s Zobrazit vÅ¡echny řádky", "InjectedHostEmailBody": "Ahoj. Dnes jsem se snažil dostat do \\Piwiku a dostal jsem varovánà o neznámém ménu hostitele.", "InjectedHostEmailSubject": "K piwiku bylo pÅ™istupováno s neznámým jménem hostitele %s", - "InjectedHostNonSuperUserWarning": "%1$sKliknÄ›te zde pro bezpeÄný pÅ™Ãstup k Piwiku%2$s a odstranÄ›nà tohoto varovánÃ. Pokud chcete upozornit administrátora na tento problém, %3$skliknÄ›te zde pro odeslánà e-mailu%4$s.", + "InjectedHostNonSuperUserWarning": "%1$sKliknÄ›te zde pro bezpeÄný pÅ™Ãstup k Piwiku%2$s a odstranÄ›nà tohoto varovánÃ. Pokud chcete upozornit administrátora na tento problém, %3$skliknÄ›te zde pro odeslánà emailu%4$s.", "InjectedHostSuperUserWarning": "Piwik může být Å¡patnÄ› nakonfigurován, napÅ™Ãklad pokud byl pÅ™esunut na nový server nebo URL. Můžete %1$skliknout zde a pÅ™idat %2$s jako platné jméno hostitele Piwiku (pokud mu důvěřujete)%3$s, nebo %4$s kliknÄ›te zde%5$s pro bezpeÄný pÅ™Ãstup k Piwiku%6$s.", "InjectedHostWarningIntro": "Nynà pÅ™istupujete k Piwiku z %1$s, ale byl nakonfigurován, aby naslouchal na následujÃcà adrese: %2$s.", "JavascriptDisabled": "MusÃte mÃt zapnutý JavaScript, jinak Piwik nezobrazÃte.<br \/> Nebo jen nenà Váš prohlÞeÄ mezi podporovanými.<br \/>Pro běžné zobrazenà zapnÄ›te JavaScript ve svém prohlÞeÄi, poté %1$szkuste znovu%2$s.<br \/>", @@ -48,6 +48,11 @@ "YouAreUsingTheLatestVersion": "PoužÃváte nejnovÄ›jšà verzi Piwiku.", "ClickRowToExpandOrContract": "KliknÄ›te na tento řádek pro rozbalenà nebo zbalenà podtabulky.", "UndoPivotBySubtable": "Toto hlášenà bylo zaměřeno %s Vrátit zpÄ›t", - "PivotBySubtable": "Toto hlášenà nenà zaměřené %s Zaměřit na %s" + "PivotBySubtable": "Toto hlášenà nenà zaměřené %s Zaměřit na %s", + "QuickAccessTitle": "NajÃt zástupce %s: Pro hledánà stisknÄ›te 'f'.", + "MenuEntries": "Položky menu", + "Segments": "Segmenty", + "AdblockIsMaybeUsed": "Pokud použÃváte blokovaÄ reklam, zakažte ho pro tyto stránky, aby Piwik správnÄ› fungoval.", + "ChangeCurrentWebsite": "Vybrat webovou stránku, aktuálnÄ› vybraná stránka: %s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/de.json b/plugins/CoreHome/lang/de.json index 4c744998ebcb6a7916bb6f652ceeada4a2cbf0dc..a80015d88d42272a45125c0b5f09063f19162b93 100644 --- a/plugins/CoreHome/lang/de.json +++ b/plugins/CoreHome/lang/de.json @@ -52,6 +52,7 @@ "QuickAccessTitle": "Suche nach %s. Tastenkürzel: Drücken Sie 'f' um zu suchen.", "MenuEntries": "Menüeinträge", "Segments": "Segmente", - "AdblockIsMaybeUsed": "Für den Fall, dass Sie einen Ad-Blocker verwenden, deaktivieren Sie diesen bitte für diese Seite um sicherzustellen, dass Piwik problemlos läuft." + "AdblockIsMaybeUsed": "Für den Fall, dass Sie einen Ad-Blocker verwenden, deaktivieren Sie diesen bitte für diese Seite um sicherzustellen, dass Piwik problemlos läuft.", + "ChangeCurrentWebsite": "Wählen Sie eine Webseite, aktuell gewählte Webseite: %s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/el.json b/plugins/CoreHome/lang/el.json index 242a7af9e6f3a8333c4e00409a3da17ee14f1ed1..ed3ae34bb24a09f3f7cfc9377d975a40bbced79d 100644 --- a/plugins/CoreHome/lang/el.json +++ b/plugins/CoreHome/lang/el.json @@ -52,6 +52,7 @@ "QuickAccessTitle": "Αναζήτηση για το %s. ΠλήκτÏο συντόμευσης: Πατήστε 'f' για αναζήτηση.", "MenuEntries": "ΚαταχωÏήσεις μενοÏ", "Segments": "Τμήματα", - "AdblockIsMaybeUsed": "Σε πεÏίπτωση που χÏησιμοποιείτε κάποια Ï€ÏόγÏαμμα που μπλοκάÏει τις διαφημίσεις, παÏακαλοÏμε απενεÏγοποιήστε το για αυτόν τον ιστοτόπο για να είστε σίγουÏοι ότι το Piwik δουλεÏει σωστά." + "AdblockIsMaybeUsed": "Σε πεÏίπτωση που χÏησιμοποιείτε κάποια Ï€ÏόγÏαμμα που μπλοκάÏει τις διαφημίσεις, παÏακαλοÏμε απενεÏγοποιήστε το για αυτόν τον ιστοτόπο για να είστε σίγουÏοι ότι το Piwik δουλεÏει σωστά.", + "ChangeCurrentWebsite": "ΕπιλÎξτε Îνα ιστοτόπο, επιλεγμÎνος ιστοτόπος αυτή τη στιγμή: %s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/en.json b/plugins/CoreHome/lang/en.json index 6e38e1d0f28b64ab132e42723d35ad18aedefe4f..75566a08f2ad68f1a0f3bc5a941eeb1fc1229380 100644 --- a/plugins/CoreHome/lang/en.json +++ b/plugins/CoreHome/lang/en.json @@ -53,6 +53,7 @@ "QuickAccessTitle": "Search for %s. Shortcut: Press 'f' to search.", "MenuEntries": "Menu entries", "Segments": "Segments", - "AdblockIsMaybeUsed": "In case you are using an ad blocker, please disable it for this site to make sure Piwik works without any issues." + "AdblockIsMaybeUsed": "In case you are using an ad blocker, please disable it for this site to make sure Piwik works without any issues.", + "ChangeCurrentWebsite": "Choose a website, currently selected website: %s" } } diff --git a/plugins/CoreHome/lang/fr.json b/plugins/CoreHome/lang/fr.json index dc5980c3355ec133fd04fef6bda81428f6c760de..c63eb35c23db207880c88c67cf1133dfb0abd85e 100644 --- a/plugins/CoreHome/lang/fr.json +++ b/plugins/CoreHome/lang/fr.json @@ -48,6 +48,7 @@ "YouAreUsingTheLatestVersion": "Vous utilisez la dernière version de Piwik!", "ClickRowToExpandOrContract": "Cliquez sur cette rangée pour afficher ou masquer le sous-tableau", "UndoPivotBySubtable": "Ce rapport a été pivoté %s Annuler le pivot", - "PivotBySubtable": "Ce rapport n'a pas été pivoté %s Pivoter par %s" + "PivotBySubtable": "Ce rapport n'a pas été pivoté %s Pivoter par %s", + "Segments": "Segments" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/it.json b/plugins/CoreHome/lang/it.json index 1d1513c8dea9f4a6c45a5ff4d871bdc0df4ee67d..37c9c5fc1ab7932011f5f81f70f010562ddcb4d4 100644 --- a/plugins/CoreHome/lang/it.json +++ b/plugins/CoreHome/lang/it.json @@ -52,6 +52,7 @@ "QuickAccessTitle": "Cerca %s. Shortcut: Premi 'f' per la ricerca.", "MenuEntries": "Ingressi da menù", "Segments": "Segmenti", - "AdblockIsMaybeUsed": "Se stai utilizzando un plugin di blocco della pubblicità , disabilitalo per questo sito, per essere sicuro che Piwik lavori senza problemi." + "AdblockIsMaybeUsed": "Se stai utilizzando un plugin di blocco della pubblicità , disabilitalo per questo sito, per essere sicuro che Piwik lavori senza problemi.", + "ChangeCurrentWebsite": "Scegli un sito, attualmente è selezionato: %s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/ja.json b/plugins/CoreHome/lang/ja.json index 6efb5237e9abc9350d37ddcb1e9b608e243b9d41..d328182c53945b25c5c5b6a80114a677a925d262 100644 --- a/plugins/CoreHome/lang/ja.json +++ b/plugins/CoreHome/lang/ja.json @@ -48,6 +48,11 @@ "YouAreUsingTheLatestVersion": "Piwik ã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’使用ã—ã¦ã„ã¾ã™ ï¼", "ClickRowToExpandOrContract": "サブテーブルを拡大ã¾ãŸã¯ç¸®å°ã™ã‚‹ã«ã¯ã€ã“ã®åˆ—をクリックã—ã¦ãã ã•ã„。", "UndoPivotBySubtable": "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã¯ã€%s å…ƒã«æˆ»ã™ãƒ”ボットを旋回ã—ã¾ã—ãŸã€‚", - "PivotBySubtable": "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã¯ã€%s ㌠%s ピボット を旋回ã—ã¦ã„ã¾ã›ã‚“。" + "PivotBySubtable": "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã¯ã€%s ㌠%s ピボット を旋回ã—ã¦ã„ã¾ã›ã‚“。", + "QuickAccessTitle": "%s を検索。ショートカット: ' f' ã‚ーを押ã—ã¦æ¤œç´¢ã—ã¾ã™ã€‚", + "MenuEntries": "メニュー エントリー", + "Segments": "セグメント", + "AdblockIsMaybeUsed": "広告ブãƒãƒƒã‚«ãƒ¼ã‚’使用ã—ã¦ã„ã‚‹å ´åˆã«ã¯ã€Piwik ãŒå•題ãªã動作ã™ã‚‹ã“ã¨ã‚’確èªã™ã‚‹ãŸã‚ã«ã€ã“ã®ã‚µã‚¤ãƒˆã§ãれを無効ã«ã—ã¦ãã ã•ã„。", + "ChangeCurrentWebsite": "ウェブサイトをé¸ã¶ã€€ç¾åœ¨é¸æŠžã•れã¦ã„ã‚‹Webサイト:%s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/ko.json b/plugins/CoreHome/lang/ko.json index f43ee7f5aec342d069aed985408c1bf2d67da0e0..aee10161d2d3aebd3ba04f1c3765d20bbfc0ddaa 100644 --- a/plugins/CoreHome/lang/ko.json +++ b/plugins/CoreHome/lang/ko.json @@ -3,6 +3,7 @@ "CategoryNoData": "ì´ ì¹´í…Œê³ ë¦¬ ì•ˆì— ë°ì´í„°ê°€ 없습니다. \"ëª¨ë“ ì§‘ë‹¨ í¬í•¨\"ì„ ì‹œë„해보세요.", "CheckForUpdates": "ì—…ë°ì´íЏ 확ì¸", "CheckPiwikOut": "Piwik 출시 확ì¸!", + "ClickToEditX": "%s ìˆ˜ì •í•˜ê¸°", "CloseWidgetDirections": "ìœ„ì ¯ì˜ ìƒë‹¨ì—있는 'X'ì•„ì´ì½˜ì„ í´ë¦í•˜ì—¬ ì´ ìœ„ì ¯ì„ ë‹«ì„ ìˆ˜ 있습니다.", "DataForThisReportHasBeenPurged": "ì´ ë³´ê³ ì„œì˜ ë°ì´í„°ëŠ” %s 개월 ì´ìƒ ë˜ì—ˆê¸° ë•Œë¬¸ì— ì œê±°ë˜ì—ˆìŠµë‹ˆë‹¤.", "DataTableExcludeAggregateRows": "요약 í–‰ 표시 %s 숨기기", @@ -13,6 +14,7 @@ "DonateCall3": "Piwikì´ ë‹¹ì‹ ì˜ ì—…ë¬´ë‚˜ 시ë„하는 ì¼ì— 특별한 가치를 ë”í•´ì¤€ë‹¤ê³ ëŠë¼ì‹ 다면, %1$s기부해 주세요!%2$s", "DonateFormInstructions": "슬ë¼ì´ë”를 í´ë¦í•˜ì—¬ ê¸ˆì•¡ì„ ì„ íƒí•˜ê³ , ê¸°ë¶€ì— ê¸°ëª…ì„ í´ë¦í•©ë‹ˆë‹¤.", "ExcludeRowsWithLowPopulation": "ëª¨ë“ í–‰ì„ í‘œì‹œ %s ì ì€ ëŸ‰ì˜ í•ëª©ì€ ì œì™¸", + "ExternalHelp": "ë„ì›€ë§ (새로운 íƒì— 열기)", "FlattenDataTable": "ì´ ë³´ê³ ì„œëŠ” 계층형입니다. %s 펼치기", "HowMuchIsPiwikWorth": "ë‹¹ì‹ ì—게 Piwikì˜ ê°€ì¹˜ëŠ” 얼마ì¸ê°€ìš”?", "IncludeRowsWithLowPopulation": "수가 ì ì€ ì¤„ 숨기기 %s ëª¨ë“ í–‰ì„ í‘œì‹œ", @@ -24,7 +26,9 @@ "JavascriptDisabled": "Piwikì˜ í‘œì¤€ë³´ê¸°ë¥¼ ì´ìš©í•˜ë ¤ë©´ JavaScript가가 활성화ë˜ì–´ 있어야 합니다.<br \/>하지만, ë‹¹ì‹ ì˜ ë¸Œë¼ìš°ì €ëŠ” 활성화ë˜ì–´ìžˆì§€ 않거나 ì§€ì›ë˜ì§€ 않는 것 같습니다.<br \/>표준보기를 ì´ìš©í•˜ë ¤ë©´ 브ë¼ìš°ì € ì˜µì…˜ì„ ë³€ê²½í•˜ì—¬ JavaScript를 í™œì„±í™”í•˜ê³ <br \/> %1$s다시 시ë„하세요%2$s.<br \/>", "MakeADifference": "개발 ì§€ì›: Piwik 2.0ì— %1$s기부해 주세요%2$s!", "MakeOneTimeDonation": "ë˜ëŠ”, 한 번만 기부합니다.", + "Menu": "메뉴", "NoPrivilegesAskPiwikAdmin": "'%s'로 로그ì¸ë˜ì—ˆì§€ë§Œ ê¶Œí•œì´ ì„¤ì •ë˜ì–´ 있지 않습니다. %s Piwik 관리ìž(í´ë¦ ì´ë©”ì¼) %sì— '보기'ê¶Œí•œì„ ë¶€ì—¬ 받으세요.", + "OnlyForSuperUserAccess": "해당 ìœ„ì ¯ì€ ìœ ì €ê°€ ìˆ˜í¼ ìœ ì €ì¼ ê²½ìš°ì—ë§Œ 나타납니다.", "PageOf": "%1$s \/ %2$s", "PeriodRange": "기간", "ReportGeneratedOn": "%sì— ìƒì„±ëœ ë³´ê³ ì„œ", @@ -33,12 +37,20 @@ "SharePiwikShort": "Piwikì€ ì˜¤í”ˆì†ŒìŠ¤ê¸°ë°˜ 무료 웹 ë¶„ì„ ë„구입니다. ì´ì œ 소중한 ì •ë³´ë¥¼ ì†Œìœ í•˜ì„¸ìš”!", "ShareThis": "ê³µìœ í•˜ê¸°", "ShowJSCode": "ì‚½ìž…í• ìžë°”스í¬ë¦½íЏ 코드 보기", + "SkipToContent": "ë‚´ìš© 건너뛰기", "SubscribeAndBecomePiwikSupporter": "Piwikì˜ í›„ì›ìžê°€ ë˜ê¸° 위해서 보안 ì‹ ìš©ì¹´ë“œ ê²°ì œ 페ì´ì§€ (페ì´íŒ”)로 ì´ë™í•©ë‹ˆë‹¤!", "SupportPiwik": "Piwik ì§€ì›!", + "TableNoData": "ì´ í…Œì´ë¸”ì— ë°ì´í„°ê°€ 없습니다.", "ThereIsNoDataForThisReport": "ì´ ë³´ê³ ì„œì—는 ë°ì´í„°ê°€ 없습니다.", "UnFlattenDataTable": "ë³´ê³ ì„œê°€ 펼ì³ì ¸ 있습니다 %s 계층으로 표시하기", "ViewAllPiwikVideoTutorials": "ëª¨ë“ ë¹„ë””ì˜¤ íŠœí† ë¦¬ì–¼ 보기", "WebAnalyticsReports": "웹 ë¶„ì„ ë³´ê³ ì„œ", - "YouAreUsingTheLatestVersion": "Piwik ìµœì‹ ë²„ì „ì„ ì‚¬ìš©í•˜ê³ ìžˆìŠµë‹ˆë‹¤!" + "YouAreUsingTheLatestVersion": "Piwik ìµœì‹ ë²„ì „ì„ ì‚¬ìš©í•˜ê³ ìžˆìŠµë‹ˆë‹¤!", + "ClickRowToExpandOrContract": "하위 í…Œì´ë¸”ì˜ í–‰ì„ í™•ìž¥í•˜ê±°ë‚˜ 축소하기 위해 í´ë¦í•˜ì„¸ìš”.", + "QuickAccessTitle": "%s 검색하기. 단축키: ê²€ìƒ‰ì„ í•˜ë ¤ë©´ 'f'를 누르세요.", + "MenuEntries": "메뉴", + "Segments": "세그멘트", + "AdblockIsMaybeUsed": "Piwikê°€ ë¬¸ì œ ì—†ì´ ë™ìž‘하기 위해서 ê´‘ê³ ì°¨ë‹¨ê¸°ëŠ¥ì´ ìžˆëŠ” 플러그ì¸ì„ 꺼주시길 ë°”ëžë‹ˆë‹¤.", + "ChangeCurrentWebsite": "웹사ì´íŠ¸ë¥¼ ì„ íƒí•˜ì„¸ìš”, 현재 ì„ íƒëœ 웹사ì´íЏ: %s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/lt.json b/plugins/CoreHome/lang/lt.json index f0b88807bff015d96e7782cda2c27ddbc15d50dd..907f1bf17816bf4bacc7eb20c2359785d224e941 100644 --- a/plugins/CoreHome/lang/lt.json +++ b/plugins/CoreHome/lang/lt.json @@ -3,6 +3,7 @@ "CategoryNoData": "Å ioje kategorijoje duomenų nÄ—ra. Pabandykite \"Ä®traukti visÄ… populiacijÄ…\"", "JavascriptDisabled": "JavaScript turi bÅ«ti įjungta, kad bÅ«tų galima naudoti standartinÄ™ Piwik iÅ¡vaizdÄ….<br \/>TaÄiau panaÅ¡u, kad JavaScript yra arba iÅ¡jungta, arba nepalaikoma JÅ«sų narÅ¡yklÄ—s.<br \/>NorÄ—dami matyti standartinÄ™ iÅ¡vaizdÄ…, įjunkite JavaScript keisdami savo narÅ¡yklÄ—s nustatymus, tada %1$sbandykite dar kartÄ…%2$s.<br \/>", "PageOf": "%1$s iÅ¡ %2$s", + "SharePiwikShort": "Piwik! Nemokama\/laisva saityno analitika. BÅ«kite savo duomenų savininkais.", "ShowJSCode": "Parodyti JavaScript kodÄ… įvedimui", "ThereIsNoDataForThisReport": "NÄ—ra duomenų Å¡iai ataskaitai.", "WebAnalyticsReports": "Žiniatinklio analizÄ—s sprendimo ataskaitos" diff --git a/plugins/CoreHome/lang/nb.json b/plugins/CoreHome/lang/nb.json index 91308236ff812021ad56c7c5a6a56b562b62eae3..33cc4649d0063ae415543ce46cc56e248dcb347c 100644 --- a/plugins/CoreHome/lang/nb.json +++ b/plugins/CoreHome/lang/nb.json @@ -1,12 +1,12 @@ { "CoreHome": { - "CategoryNoData": "Ingen data i denne kategorien. Prøv Ã¥ velge \"Inkluder hele populasjon\".", + "CategoryNoData": "Ingen data i denne kategorien. Prøv Ã¥ velge «Inkluder hele populasjonen».", "CheckForUpdates": "Se etter oppdateringer", "CheckPiwikOut": "Sjekk ut Piwik!", "ClickToEditX": "Klikk for Ã¥ redigere %s", - "CloseWidgetDirections": "Du kan lukke dette elementet ved Ã¥ klikke pÃ¥ X-ikonet pÃ¥ toppen av elementet.", + "CloseWidgetDirections": "Du kan lukke dette elementet ved Ã¥ klikke pÃ¥ X-ikonet over widgeten.", "DataForThisReportHasBeenPurged": "Dataene for denne rapporten er mer enn %s mÃ¥neder gamle og har blitt fjernet.", - "DataTableExcludeAggregateRows": "Aggregerte rader er vist som %s Skjul dem", + "DataTableExcludeAggregateRows": "Aggregerte rader vises %s Skjul dem", "DataTableIncludeAggregateRows": "Aggregerte rader er skjult %s Vi dem", "Default": "standard", "DonateCall1": "Det vil aldri koste noe Ã¥ bruke Piwik, men det betyr ikke at det ikke koster oss noe Ã¥ lage.", @@ -20,7 +20,7 @@ "IncludeRowsWithLowPopulation": "Rader med lav populasjon er skjult %s Vis alle rader", "InjectedHostEmailBody": "Hei, jeg prøvde Ã¥ fÃ¥ tilgang til Piwik i dag og ble møtt av «ukjent vertsnavn»-advarselen.", "InjectedHostEmailSubject": "Piwik ble Ã¥pnet med et ukjent vertsnavn: %s", - "InjectedHostNonSuperUserWarning": "%1$sKlikk her for Ã¥ fÃ¥ sikker tilgang til Piwik%2$s og for Ã¥ fjerne denne advarselen. Du ømsker kanskje ogsÃ¥ Ã¥ kontakte din Piwik-administrator for Ã¥ varsle dem om dette problemet (%3$sklikk her for Ã¥ sende epost%4$s).", + "InjectedHostNonSuperUserWarning": "%1$sKlikk her for Ã¥ fÃ¥ sikker tilgang til Piwik%2$s og for Ã¥ fjerne denne advarselen. Du vil kanskje ogsÃ¥ kontakte din Piwik-administrator for Ã¥ varsle dem om dette problemet (%3$sklikk her for Ã¥ sende e-post%4$s).", "InjectedHostSuperUserWarning": "Piwik kan være feilkonfigurert (for eksempel hvis Piwik nylig var flyttet til en ny tjener eller ny URL). Du kan enten %1$sklikke her og legge til %2$s som et gyldig Piwik-vertsnavn (hvis du stoler pÃ¥ det)%3$s eller %4$sklikk her og gÃ¥ til %5$s for sikker tilgang til Piwik%6$s.", "InjectedHostWarningIntro": "Du har tilgang til Piwik fra %1$s, men Piwik er konfigurert til Ã¥ kjøre pÃ¥ adressen: %2$s", "JavascriptDisabled": "JavaScript mÃ¥ være aktivert for at du skal kunne bruke Piwik i standardvisning.<br \/>Det ser ut til at JavaScript enten er deaktivert eller ikke støttet av din nettleser.<br \/>For Ã¥ bruke standardvisning, mÃ¥ du aktivere JavaScript i nettleserinnstillingene og deretter %1$sprøve igjen%2$s.<br \/>", @@ -28,13 +28,13 @@ "MakeOneTimeDonation": "Bidra med en engangsdonasjon i stedet.", "Menu": "Meny", "NoPrivilegesAskPiwikAdmin": "Du er logget inn som «%s», men det ser ut til at du ikke har noen rettigheter satt i Piwik. %s Be din Piwik-administrator (klikk for Ã¥ sende e-post)%s Ã¥ gi deg «vis»-tilgang til et nettsted.", - "OnlyForSuperUserAccess": "Dette elementet er vises kun til brukere som har superbruker-tilgang.", + "OnlyForSuperUserAccess": "Denne widgeten vises kun til brukere som har superbruker-tilgang.", "PageOf": "%1$s av %2$s", - "PeriodRange": "OmrÃ¥de", + "PeriodRange": "Periode", "ReportGeneratedOn": "Rapport generert %s", "ReportGeneratedXAgo": "Rapport generert %s siden", "SharePiwikLong": "Hei! Jeg har nettopp funnet et bra stykke fri programvare: Piwik!\n\nPiwik lar deg spore besøkende pÃ¥ ditt nettsted gratis. Du bør definitivt prøve det ut.", - "SharePiwikShort": "Piwik! Gratis og Ã¥pen kildekode web analyse. Du eier dataene.", + "SharePiwikShort": "Piwik! Gratis og Ã¥pen kildekode for nettstatistikk. Du eier dataene.", "ShareThis": "Del dette", "ShowJSCode": "Vis JavaScript-koden til Ã¥ sette inn pÃ¥ din nettside.", "SkipToContent": "Hopp til innhold", @@ -48,6 +48,11 @@ "YouAreUsingTheLatestVersion": "Du bruker den nyeste versjonen av Piwik!", "ClickRowToExpandOrContract": "Klikk denne raden for utvide eller slÃ¥ sammen undertabellen.", "UndoPivotBySubtable": "Denne rapporten er pivotert %s Angre pivot", - "PivotBySubtable": "Denne rapporten er ikke pivotert %s Pivot etter %s" + "PivotBySubtable": "Denne rapporten er ikke pivotert %s Pivot etter %s", + "QuickAccessTitle": "Søk etter %s. Snarvei: Trykk «f» for Ã¥ søke.", + "MenuEntries": "Menyvalg", + "Segments": "Segmenter", + "AdblockIsMaybeUsed": "Hvis du bruker en ad-blocker, vennligst deaktiver den for dette nettstedet for Ã¥ forsikre deg om at Piwik fungerer som det skal.", + "ChangeCurrentWebsite": "Velg et nettsted. Nettstedet som nÃ¥ er valgt er: %s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/pt-br.json b/plugins/CoreHome/lang/pt-br.json index 69f02cb1ad21a4c09fad202018f9829c68b57e88..b7522980e0e08c380abc4eb52f97611fa732b54f 100644 --- a/plugins/CoreHome/lang/pt-br.json +++ b/plugins/CoreHome/lang/pt-br.json @@ -52,6 +52,7 @@ "QuickAccessTitle": "Buscar por %s. Atalho: Tecle 'f' para buscar.", "MenuEntries": "Itens do menu", "Segments": "Segmentos", - "AdblockIsMaybeUsed": "Caso você esteja usando um bloqueador de anúncios, por favor desative-o para este site, pois assim poderá certificar-se de que o Piwik funciona sem qualquer problema." + "AdblockIsMaybeUsed": "Caso você esteja usando um bloqueador de anúncios, por favor desative-o para este site, pois assim poderá certificar-se de que o Piwik funciona sem qualquer problema.", + "ChangeCurrentWebsite": "Escolha um website; website atualmente selecionado: %s" } } \ No newline at end of file diff --git a/plugins/CoreHome/lang/tr.json b/plugins/CoreHome/lang/tr.json index 572a8f8459ba56ca421f9f776f91517e067a9eed..eddff9951ebaa22116711566514ab08efd1103bf 100644 --- a/plugins/CoreHome/lang/tr.json +++ b/plugins/CoreHome/lang/tr.json @@ -31,7 +31,7 @@ "ShowJSCode": "Eklenecek JavaScript kodu göster", "SubscribeAndBecomePiwikSupporter": "Piwik Destekçisi olmak için güvenli bir kredi kartı ödeme sayfasına (Paypal) geçin!", "SupportPiwik": "Piwike destek ol", - "TableNoData": "Bu tablo için bir data yok.", + "TableNoData": "Bu tablo için bir veri yok.", "ThereIsNoDataForThisReport": "Bu rapor için veri yok.", "ViewAllPiwikVideoTutorials": "Tüm Piwik Yardım Videolarına Bak", "WebAnalyticsReports": "Web Analiz Raporları", diff --git a/plugins/CoreHome/stylesheets/coreHome.less b/plugins/CoreHome/stylesheets/coreHome.less index 9be7d148797ceb272db1949ece74388731923402..ab4b749b024af42d03257db148c6e48dfc748798 100644 --- a/plugins/CoreHome/stylesheets/coreHome.less +++ b/plugins/CoreHome/stylesheets/coreHome.less @@ -177,28 +177,24 @@ div.pk-emptyGraph { } .Piwik_Popover_Error_Title { - color: @theme-color-link; - font-weight: bold; font-size: 16px; } .Piwik_Popover_Error_Title span { - color: #222; font-weight: normal; font-size: 16px; } .Piwik_Popover_Error_Message { - color: #7e7363; padding: 20px 0 0 0; - font-size: 14px; + font-size: 13px; } a.Piwik_Popover_Error_Back { display: block; margin: 20px 0 0 0; - color: #1D3256; - font-size: 14px; + font-size: 13px; + text-decoration: underline; } #alert.ui-confirm input { diff --git a/plugins/CoreHome/stylesheets/layout.less b/plugins/CoreHome/stylesheets/layout.less index 5cffdf3be85d28234a9ffddb9d6c50311dcbd98f..a398657c7c203dce2b86575aecf43e1181ee60f6 100644 --- a/plugins/CoreHome/stylesheets/layout.less +++ b/plugins/CoreHome/stylesheets/layout.less @@ -30,7 +30,7 @@ height: 100%; transition: background-color 150ms linear; - &:hover { + &:hover, &:focus { background-color: @theme-color-menu-contrast-background; } @@ -59,7 +59,7 @@ .navbar { a { text-decoration: none; - &:hover, &:focus, &:active { + &:hover, &:focus { text-decoration: none; } } @@ -244,7 +244,7 @@ > .item { cursor: default; font-weight: bold; - &:hover { + &:hover, &:focus { text-decoration: none; } } @@ -257,7 +257,7 @@ padding: 11px 22px 11px 45px; decoration: none; transition: background-color 200ms linear; - &:hover { + &:hover, &:focus { text-decoration: none; color: @theme-color-menu-contrast-textActive; } @@ -300,7 +300,7 @@ font-size: 13px; font-weight: normal; - &:hover { + &:hover, &:focus { color: @theme-color-menu-contrast-textActive; } @@ -325,7 +325,7 @@ > .item { cursor: pointer; - &:hover { + &:hover, &:focus { color: @theme-color-menu-contrast-textActive; } } @@ -388,7 +388,7 @@ border: 1px solid @theme-color-background-tinyContrast; transition: box-shadow 150ms linear; &.expanded, - &:hover { + &:hover, &:focus { box-shadow: 0 1px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); } } diff --git a/plugins/CoreHome/templates/_dataTable.twig b/plugins/CoreHome/templates/_dataTable.twig index 6bc35bca9e32ee3011c49d9d3e8fcbd64ca0f038..697af2c9b6c8dffb9ea6551ca334e7adeb7053e2 100644 --- a/plugins/CoreHome/templates/_dataTable.twig +++ b/plugins/CoreHome/templates/_dataTable.twig @@ -12,7 +12,7 @@ data-params="{% if clientSideParameters is empty %}{}{% else %}{{ clientSideParameters|json_encode }}{% endif %}"> <div class="reportDocumentation"> {% if properties.documentation|default is not empty %}<p>{{ properties.documentation|raw }}</p>{% endif %} - {% if reportLastUpdatedMessage is defined %}<span class='helpDate'>{{ reportLastUpdatedMessage }}</span>{% endif %} + {% if reportLastUpdatedMessage is defined %}<span class='helpDate'>{{ reportLastUpdatedMessage|raw }}</span>{% endif %} </div> <div class="dataTableWrapper"> {% if error is defined %} diff --git a/plugins/CoreHome/templates/_menu.twig b/plugins/CoreHome/templates/_menu.twig index 51b87bc30166e284654cc033ef2dbb7af503bece..94321a033f8d40ffbebce26715636ddc34790d58 100644 --- a/plugins/CoreHome/templates/_menu.twig +++ b/plugins/CoreHome/templates/_menu.twig @@ -1,10 +1,9 @@ - {% macro menu(menu, anchorlink, cssClass, currentModule, currentAction) %} <div id="secondNavBar" class="{{ cssClass }}"> <div id="search" ng-cloak> <div piwik-quick-access class="borderedControl"></div> </div> - <ul class="navbar"> + <ul class="navbar" role="menu"> {% for level1,level2 in menu %} {% set hasSubmenuItem = false %} @@ -15,7 +14,7 @@ {% endfor %} {% if hasSubmenuItem %} - <li class="menuTab"> + <li class="menuTab" role="menuitem"> <a class="item"> <span class="menu-icon {{ level2._icon|default('icon-arrow-right') }}"></span>{{ level1|translate }} @@ -23,12 +22,14 @@ {{ 'CoreHome_Menu'|translate }} </span> </a> - <ul> + <ul role="menu"> {% for name,urlParameters in level2 %} {% if name|slice(0,1) != '_' %} <li {% if urlParameters._url.module is defined and urlParameters._url.module == currentModule and urlParameters._url.action is defined and urlParameters._url.action == currentAction %}class="active"{% endif %} - > + role="menuitem" + > <a class="item" + title="{{ urlParameters._tooltip|default(name)|translate|e('html_attr') }}" href="index.php?{{ urlParameters._url|urlRewriteWithParameters|slice(1) }}"> {{ name|translate }} </a> diff --git a/plugins/CoreHome/templates/_siteSelectHeader.twig b/plugins/CoreHome/templates/_siteSelectHeader.twig index 7353e2e07a794f2c2138a403d56fcd4c11265865..beacabd8494ef812ae2d0fc5bca68fabea80c0ac 100644 --- a/plugins/CoreHome/templates/_siteSelectHeader.twig +++ b/plugins/CoreHome/templates/_siteSelectHeader.twig @@ -1,3 +1,3 @@ <div class="top_bar_sites_selector piwikTopControl"> - <div piwik-siteselector class="sites_autocomplete"></div> + <div piwik-siteselector show-selected-site="true" class="sites_autocomplete"></div> </div> \ No newline at end of file diff --git a/plugins/CoreHome/templates/_topBar.twig b/plugins/CoreHome/templates/_topBar.twig index e69e9c1978b840c8b8fb669d1a3ba601693f1350..c1158f46bba4268c77b745d4f7c0387f7bda8649 100644 --- a/plugins/CoreHome/templates/_topBar.twig +++ b/plugins/CoreHome/templates/_topBar.twig @@ -1,5 +1,5 @@ {{ postEvent("Template.beforeTopBar", userAlias, userLogin, topMenu, userMenu) }} -<ul class="navbar-right"> +<ul role="menubar" class="navbar-right"> {% macro menuItemLabel(label, icon) %} {% if icon is defined and icon and icon starts with 'icon-' %} @@ -27,7 +27,7 @@ {% spaceless %} {% for label,menu in topMenu %} - <li>{{ _self.topMenuItem(label, menu, topMenuModule, topMenuAction) }}</li> + <li role="menuitem">{{ _self.topMenuItem(label, menu, topMenuModule, topMenuAction) }}</li> {% endfor %} {% endspaceless %} diff --git a/plugins/CoreHome/tests/Integration/Column/UserIdTest.php b/plugins/CoreHome/tests/Integration/Column/UserIdTest.php index 33c268afaec61258bab703a8e4ece0980726bac3..70715a4dc2d6761e1bd35924a6ee5152e017cac3 100644 --- a/plugins/CoreHome/tests/Integration/Column/UserIdTest.php +++ b/plugins/CoreHome/tests/Integration/Column/UserIdTest.php @@ -12,6 +12,7 @@ use Piwik\Access; use Piwik\Cache; use Piwik\DataAccess\ArchiveTableCreator; use Piwik\Db; +use Piwik\Metrics; use Piwik\Plugin\Manager; use Piwik\Plugins\CoreHome\Columns\UserId; use Piwik\Tests\Framework\Fixture; @@ -164,6 +165,17 @@ class UserIdTest extends IntegrationTestCase $this->assertDataTableHasUsers($this->getDataTableWithUsers()); } + public function test_hasDataTableUsers_shouldBeAbleToDetectIfNbUsersMetricIdIsused() + { + $table = $this->getDataTableWithZeroUsers(); + $table->renameColumn('nb_users', Metrics::INDEX_NB_USERS); + $this->assertNotDataTableHasUsers($table); + + $table = $this->getDataTableWithUsers(); + $table->renameColumn('nb_users', Metrics::INDEX_NB_USERS); + $this->assertDataTableHasUsers($this->getDataTableWithUsers()); + } + private function getDataTableWithoutUsersColumn() { $tableWithoutUsers = new DataTable(); diff --git a/plugins/CorePluginsAdmin/Controller.php b/plugins/CorePluginsAdmin/Controller.php index ea9a386ced9511cd012d11210c8f5ef774d13853..c9b4a48a7cd4a4fc91a5be09838da66d68f3c163 100644 --- a/plugins/CorePluginsAdmin/Controller.php +++ b/plugins/CorePluginsAdmin/Controller.php @@ -247,7 +247,7 @@ class Controller extends Plugin\ControllerAdmin $view->deactivateNonce = Nonce::getNonce(static::DEACTIVATE_NONCE); $view->pluginsInfo = $this->getPluginsInfo($themesOnly); - $users = \Piwik\Plugins\UsersManager\API::getInstance()->getUsers(); + $users = Request::processRequest('UsersManager.getUsers'); $view->otherUsersCount = count($users) - 1; $view->themeEnabled = \Piwik\Plugin\Manager::getInstance()->getThemeEnabled()->getPluginName(); diff --git a/plugins/CorePluginsAdmin/Marketplace.php b/plugins/CorePluginsAdmin/Marketplace.php index c4835856b02305eb2f88778eedd8753a9748d172..b46d1932e44355abc968a47c45f450c487924d89 100644 --- a/plugins/CorePluginsAdmin/Marketplace.php +++ b/plugins/CorePluginsAdmin/Marketplace.php @@ -114,14 +114,14 @@ class Marketplace $pluginsHavingUpdate = array(); } - foreach ($pluginsHavingUpdate as &$updatePlugin) { + foreach ($pluginsHavingUpdate as $key => $updatePlugin) { foreach ($loadedPlugins as $loadedPlugin) { if (!empty($updatePlugin['name']) && $loadedPlugin->getPluginName() == $updatePlugin['name'] ) { $updatePlugin['currentVersion'] = $loadedPlugin->getVersion(); $updatePlugin['isActivated'] = $pluginManager->isPluginActivated($updatePlugin['name']); - $updatePlugin = $this->addMissingRequirements($updatePlugin); + $pluginsHavingUpdate[$key] = $this->addMissingRequirements($updatePlugin); break; } } @@ -129,9 +129,7 @@ class Marketplace // remove plugins that have updates but for some reason are not loaded foreach ($pluginsHavingUpdate as $key => $updatePlugin) { - if (empty($updatePlugin['currentVersion']) - || empty($updatePlugin['isActivated']) - ) { + if (empty($updatePlugin['currentVersion'])) { unset($pluginsHavingUpdate[$key]); } } diff --git a/plugins/CorePluginsAdmin/lang/cs.json b/plugins/CorePluginsAdmin/lang/cs.json index fa4527c3532d9429248a2e294e2a00578825c7ad..8ae77b996fc35dfe3b9780a92382afa88fe78d10 100644 --- a/plugins/CorePluginsAdmin/lang/cs.json +++ b/plugins/CorePluginsAdmin/lang/cs.json @@ -23,7 +23,7 @@ "Developer": "Vývojář", "DevelopersLearnHowToDevelopPlugins": "Vývojáři: nauÄte se, jak rozÅ¡ÃÅ™it Piwik vývojem %szásuvných modulů nebo témat vzhledu%s.", "DoMoreContactPiwikAdmins": "Pokud chcete nainstalovat nový zásuvný modul nebo Å¡ablonu,, kontaktujte vaÅ¡e administrátory Piwiku.", - "EmailToEnquireUpdatedVersion": "NapiÅ¡te e-mail %1$s a požádejte o novÄ›jšà verzi %2$s.", + "EmailToEnquireUpdatedVersion": "NapiÅ¡te email %1$s a požádejte o novÄ›jšà verzi %2$s.", "FeaturedPlugin": "DoporuÄovaný zásuvný modul", "ChangeLookByManageThemes": "Vzhled Piwiku můžete zmÄ›nit %sve správÄ› motivů%s.", "GetEarlyAccessForPaidPlugins": "Poznámka: MomentálnÄ› jsou vÅ¡echny zásuvné moduly v obchodÄ› zdarma. V budoucnu máme v plánu povolit placené zásuvné moduly. %sKontaktujte nás%s pro vÄasný pÅ™Ãstup.", diff --git a/plugins/CorePluginsAdmin/lang/id.json b/plugins/CorePluginsAdmin/lang/id.json index 100b8e195bbb4be5cf15d7c851d0e9fcbcc4c278..1e4ef37aaaef88c140656ee1c78012e435991fe0 100644 --- a/plugins/CorePluginsAdmin/lang/id.json +++ b/plugins/CorePluginsAdmin/lang/id.json @@ -12,6 +12,7 @@ "PluginHomepage": "Alamat Pengaya", "PluginKeywords": "Kata Kunci", "PluginsManagement": "Pengatur Pengaya", + "PluginVersionInfo": "%1$s dari %2$s", "Status": "Status", "Version": "Versi", "Websites": "Situs" diff --git a/plugins/CorePluginsAdmin/lang/ja.json b/plugins/CorePluginsAdmin/lang/ja.json index 2da547a233cd79cdcf6dcfb913da08b679bc8cdf..708b4a6560ca4852936d8807b13d283f7bf6cbc9 100644 --- a/plugins/CorePluginsAdmin/lang/ja.json +++ b/plugins/CorePluginsAdmin/lang/ja.json @@ -38,12 +38,18 @@ "LastCommitTime": "(最終更新 %s)", "LastUpdated": "最終更新日", "LicenseHomepage": "ライセンスã®ãƒ›ãƒ¼ãƒ ページ", + "LikeThisPlugin": "ã“ã®ãƒ—ラグインを気ã«å…¥ã‚Šã¾ã—ãŸã‹ï¼Ÿ", + "ConsiderDonating": "寄付を検討", + "CommunityContributedPlugin": "ã“ã®ãƒ—ラグインã¯ã€ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã®è²¢çŒ®ã«ã‚ˆã‚Šç„¡æ–™ã§å…¬é–‹ã•れã¦ã„ã¾ã™ã€‚", + "ConsiderDonatingCreatorOf": "%s ã®ä½œæˆè€…ã¸ã®å¯„付を検討", "PluginsExtendPiwik": "プラグイン㯠Piwik ã®æ©Ÿèƒ½æ€§ã‚’æ‹¡å¼µã—ã¾ã™ã€‚", "OncePluginIsInstalledYouMayActivateHere": "プラグインをインストールã™ã‚‹ã¨ã€ã“ã“ã§æœ‰åŠ¹åŒ–ã¨ç„¡åŠ¹åŒ–ã‚’è¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚", "Marketplace": "マーケットプレイス", "MarketplaceSellPluginSubject": "マーケットプレイス - プラグインã®è²©å£²", "MenuPlatform": "プラットフォーム", "MissingRequirementsNotice": "%1$s %3$s ãŒå¿…è¦ã§ã™ã€‚ %1$s %2$s を最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã‚¢ãƒƒãƒ—デートã—ã¦ãã ã•ã„。", + "MissingRequirementsPleaseInstallNotice": "%3$s ã§å¿…è¦ã¨ã•れる〠%1$s %2$s をインストールã—ã¦ãã ã•ã„。", + "NewVersion": "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³", "NoPluginsFound": "プラグインã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ", "NotAllowedToBrowseMarketplacePlugins": "Piwik プラットフォームã®ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã¾ãŸã¯æ‹¡å¼µã®ãŸã‚ã«ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«å¯èƒ½ãªãƒ—ラグインã®ãƒªã‚¹ãƒˆã‚’閲覧ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã‚‚ã—ã“れらã®ã„ã¥ã‚Œã‹ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ãªå ´åˆã¯ã€ç®¡ç†è€…ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。", "NotAllowedToBrowseMarketplaceThemes": "Piwik プラットフォームã®å¤–観をカスタマイズã™ã‚‹ã®ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«å¯èƒ½ãª Piwik テーマã®ãƒªã‚¹ãƒˆã‚’ã”確èªãã ã•ã„。ã“れらã®ã„ã¥ã‚Œã‹ã‚’インストールã—ãŸã„å ´åˆã¯ã€ç®¡ç†è€…ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。", diff --git a/plugins/CorePluginsAdmin/lang/ko.json b/plugins/CorePluginsAdmin/lang/ko.json index 6949605d48acc8a51ba5186335fdf782287e5a06..406ec44c78ce1de35b1162035c9e0f198cbff55d 100644 --- a/plugins/CorePluginsAdmin/lang/ko.json +++ b/plugins/CorePluginsAdmin/lang/ko.json @@ -1,19 +1,59 @@ { "CorePluginsAdmin": { + "ActionActivatePlugin": "í”ŒëŸ¬ê·¸ì¸ í™œì„±í™”", + "ActionActivateTheme": "테마 활성화", + "ActionInstall": "설치", + "ActionUninstall": "ì œê±°", "Activate": "활성화", "Activated": "활성화ë¨", "Active": "활성", + "Activity": "활ë™", + "AllowedUploadFormats": "zip í¬ë©§ì„ 통해 플러그ì¸ì´ë‚˜ 테마를 업로드 í• ìˆ˜ 있습니다.", "AuthorHomepage": "ìž‘ì„±ìž í™ˆíŽ˜ì´ì§€", + "Authors": "작성ìž", + "BackToExtendPiwik": "ë§ˆì¼“í”Œë ˆì´ìŠ¤ë¡œ ëŒì•„ê°€", + "BeCarefulUsingPlugins": "Piwik 팀으로부터 ê²€ì¦ë˜ì§€ ì•Šì€ í”ŒëŸ¬ê·¸ì¸ì€ 사용 시 주ì˜í•´ì£¼ì„¸ìš”. 해당 플러그ì¸ì„ 리뷰하지 않았습니다.", + "BeCarefulUsingThemes": "Piwik 팀으로부터 ê²€ì¦ë˜ì§€ ì•Šì€ í”ŒëŸ¬ê·¸ì¸ì€ 사용 시 주ì˜í•´ì£¼ì„¸ìš”. 해당 플러그ì¸ì„ 리뷰하지 않았습니다.", + "Changelog": "ë³€", "Deactivate": "비활성화", + "Developer": "개발ìž", + "DoMoreContactPiwikAdmins": "새로운 플러그ì¸ì´ë‚˜ 테마를 설치하기 위해서, Piwik 관리ìžì—게 ì—°ë½í•´ì£¼ì„¸ìš”.", + "GetEarlyAccessForPaidPlugins": "ì°¸ê³ ì‚¬í•: ëª¨ë“ í”ŒëŸ¬ê·¸ì¸ì€ 현재 무료로 ì‚¬ìš©í• ìˆ˜ 있습니다. 향후 ìœ ë£Œ ë§ˆì¼“í”Œë ˆì´ìŠ¤ë¥¼ ì œê³µí• ì˜ˆì •ìž…ë‹ˆë‹¤ (ìžì„¸í•œ 사í•ì€ %sì—°ë½ ì£¼ì‹œê¸¸%s ë°”ëžë‹ˆë‹¤.).", "Inactive": "비활성", + "InstallNewPlugins": "새로운 í”ŒëŸ¬ê·¸ì¸ ì„¤ì¹˜", + "InstallNewThemes": "새로운 테마 설치", + "LastUpdated": "최근 ì—…ë°ì´íЏ", "LicenseHomepage": "ë¼ì´ì„¼ìФ 홈페ì´ì§€", + "LikeThisPlugin": "í”ŒëŸ¬ê·¸ì¸ ì¢‹ì•„ìš”", + "ConsiderDonating": "기부 ê³ ë ¤í•˜ê¸°", "PluginsExtendPiwik": "í”ŒëŸ¬ê·¸ì¸ í™•ìž¥ê³¼ Piwikì˜ ê¸°ëŠ¥ì„± 확장페ì´ì§€ìž…니다.", "OncePluginIsInstalledYouMayActivateHere": "플러그ì¸ì´ 한번 설치ë˜ë©´ ì´ê³³ì—서 활성화하거나 ë¹„í™œì„±í™”í• ìˆ˜ 있습니다.", + "Marketplace": "ë§ˆì¼“í”Œë ˆì´ìФ", + "MenuPlatform": "플랫í¼", + "NewVersion": "새로운 ë²„ì „", + "NoPluginsFound": "플러그ì¸ì„ ì°¾ì„ ìˆ˜ 없습니다.", + "NoThemesFound": "테마를 ì°¾ì„ ìˆ˜ 없습니다.", + "NoZipFileSelected": "ZIP 파ì¼ì„ ì„ íƒí•´ì£¼ì„¸ìš”.", + "OriginThirdParty": "서드파티", "PluginHomepage": "í”ŒëŸ¬ê·¸ì¸ í™ˆíŽ˜ì´ì§€", "PluginKeywords": "검색어", "PluginsManagement": "í”ŒëŸ¬ê·¸ì¸ ê´€ë¦¬", + "PluginWebsite": "í”ŒëŸ¬ê·¸ì¸ ì›¹ì‚¬ì´íЏ", + "Screenshots": "스í¬ë¦°ìƒ·", + "SortByAlpha": "ì•ŒíŒŒë²„ì „", + "SortByNewest": "ìµœì‹ ", + "SortByPopular": "ì¸ê¸°ìˆœ", "Status": "ìƒíƒœ", + "StepDownloadingPluginFromMarketplace": "ë§ˆì¼“í”Œë ˆì´ìФì—서 í”ŒëŸ¬ê·¸ì¸ ë‹¤ìš´ë¡œë“œ 중", + "StepDownloadingThemeFromMarketplace": "ë§ˆì¼“í”Œë ˆì´ìФì—서 테마 다운로드 중", + "StepUnzippingPlugin": "í”ŒëŸ¬ê·¸ì¸ ì••ì¶• 푸는 중", + "StepUnzippingTheme": "테마 ì••ì¶• 푸는 중", + "Theme": "테마", + "Themes": "테마", + "ThemesManagement": "테마 관리", + "UploadZipFile": "ZIP íŒŒì¼ ì—…ë¡œë“œ", "Version": "ë²„ì „", + "ViewRepositoryChangelog": "ë³€ê²½ì‚¬í• ë³´ê¸°", "Websites": "웹사ì´íЏ" } } \ No newline at end of file diff --git a/plugins/CorePluginsAdmin/lang/pt-br.json b/plugins/CorePluginsAdmin/lang/pt-br.json index a068f02ccaff6e9bcaa2f5c007cf2a68608b48b2..479cc31bb8202daf32fd99e83cdb18c692a1c678 100644 --- a/plugins/CorePluginsAdmin/lang/pt-br.json +++ b/plugins/CorePluginsAdmin/lang/pt-br.json @@ -8,7 +8,7 @@ "Activated": "Ativado", "Active": "Ativo", "Activity": "Atividade", - "AllowedUploadFormats": "Você pode fazer upload de um plugin ou tema em formato zip através desta página.", + "AllowedUploadFormats": "Você pode carregar um plugin ou tema em formato zip através desta página.", "AuthorHomepage": "Página do autor", "Authors": "Autores", "BackToExtendPiwik": "Voltar ao Marketplace", @@ -89,8 +89,8 @@ "TeaserExtendPiwik": "Estenda Piwik com plugins e temas", "TeaserExtendPiwikByPlugin": "Estenda Piwik instalando um novo plugin", "TeaserExtendPiwikByTheme": "Aproveite um outro look & feel instalando um novo tema", - "TeaserExtendPiwikByUpload": "Estenda Piwik fazendo o upload de um arquivo ZIP", - "InstallingNewPluginViaMarketplaceOrUpload": "Você pode instalar automaticamente plugins do mercado ou %supload um plugin%s em formato .zip.", + "TeaserExtendPiwikByUpload": "Estenda o Piwik carregando um arquivo ZIP", + "InstallingNewPluginViaMarketplaceOrUpload": "Você pode instalar automaticamente plugins do mercado ou %scarregar um plugin%s em formato .zip.", "Theme": "Tema", "Themes": "Temas", "ThemesDescription": "Os temas podem alterar a aparência da interface do usuário do Piwik, e fornecer uma experiência completamente nova visual para desfrutar dos seus relatórios de análise.", @@ -98,7 +98,7 @@ "UninstallConfirm": "Você está prestes a desinstalar um plugin %s. O plugin será completamente removido da sua plataforma e isso não poderá ser desfeito. Tem certeza que deseja fazer isso?", "Updated": "Atualizado(a)", "UpdatingPlugin": "Atualizando %s", - "UploadZipFile": "Enviar arquivo ZIP", + "UploadZipFile": "Carregar arquivo ZIP", "Version": "Versão", "ViewRepositoryChangelog": "Ver as mudanças", "Websites": "Websites" diff --git a/plugins/CorePluginsAdmin/templates/macros.twig b/plugins/CorePluginsAdmin/templates/macros.twig index d7e7c459b0ddda44c6bacaccfa201b35982ea5c7..f0b66123e5fb6be6289cd75d495905764206774d 100644 --- a/plugins/CorePluginsAdmin/templates/macros.twig +++ b/plugins/CorePluginsAdmin/templates/macros.twig @@ -184,7 +184,7 @@ 'http://piwik.org', 'http://www.piwik.org', 'http://piwik.org/', 'http://www.piwik.org/' ] %} <span class="plugin-homepage"> - <a href="{{ plugin.info.homepage }}">({{ 'CorePluginsAdmin_PluginHomepage'|translate|replace({' ': ' '})|raw }})</a> + <a target="_blank" href="{{ plugin.info.homepage }}">({{ 'CorePluginsAdmin_PluginHomepage'|translate|replace({' ': ' '})|raw }})</a> </span> {% endif %} diff --git a/plugins/CorePluginsAdmin/tests/Integration/UpdateCommunicationTest.php b/plugins/CorePluginsAdmin/tests/Integration/UpdateCommunicationTest.php index dff84a7feeecd7970974df097d01df727505477f..bbfd7af0810e3cef1fb4d8698a9e5249ead6f96a 100644 --- a/plugins/CorePluginsAdmin/tests/Integration/UpdateCommunicationTest.php +++ b/plugins/CorePluginsAdmin/tests/Integration/UpdateCommunicationTest.php @@ -11,6 +11,7 @@ namespace Piwik\Plugins\CorePluginsAdmin\tests\Integration; use Piwik\Config; use Piwik\Option; use Piwik\Plugins\CorePluginsAdmin\UpdateCommunication; +use Piwik\Tests\Framework\Fixture; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; /** @@ -121,7 +122,8 @@ class UpdateCommunicationTest extends IntegrationTestCase public function test_sendNotificationIfUpdatesAvailable_ShouldSendCorrectText() { $subject = 'CoreUpdater_NotificationSubjectAvailablePluginUpdate'; - $message = 'ScheduledReports_EmailHello + $rootUrl = Fixture::getTestRootUrl(); + $message = "ScheduledReports_EmailHello CoreUpdater_ThereIsNewPluginVersionAvailableForUpdate @@ -130,9 +132,9 @@ CoreUpdater_ThereIsNewPluginVersionAvailableForUpdate * MyTest3 31.0.0 CoreUpdater_NotificationClickToUpdatePlugins -http://localhost/tests/PHPUnit/proxy/index.php?module=CorePluginsAdmin&action=plugins +{$rootUrl}index.php?module=CorePluginsAdmin&action=plugins -Installation_HappyAnalysing'; +Installation_HappyAnalysing"; $mock = $this->getCommunicationMockHavingManyUpdates(); diff --git a/plugins/CoreUpdater/Test/Integration/UpdateCommunicationTest.php b/plugins/CoreUpdater/Test/Integration/UpdateCommunicationTest.php index 156138d770f9e507237797634557d70a935e018a..d43e11ebf4531a9b7d0a34d01f5d82d13555fdec 100644 --- a/plugins/CoreUpdater/Test/Integration/UpdateCommunicationTest.php +++ b/plugins/CoreUpdater/Test/Integration/UpdateCommunicationTest.php @@ -11,6 +11,7 @@ namespace Piwik\Plugins\CoreUpdater\Test; use Piwik\Config; use Piwik\Option; use Piwik\Plugins\CoreUpdater\UpdateCommunication; +use Piwik\Tests\Framework\Fixture; use Piwik\UpdateCheck; use Piwik\Version; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; @@ -67,33 +68,35 @@ class UpdateCommunicationTest extends IntegrationTestCase public function test_sendNotifications_shouldSentCorrectEmail() { - $message = 'ScheduledReports_EmailHello + $rootUrl = Fixture::getTestRootUrl(); + $message = "ScheduledReports_EmailHello CoreUpdater_ThereIsNewVersionAvailableForUpdate CoreUpdater_YouCanUpgradeAutomaticallyOrDownloadPackage -http://localhost/tests/PHPUnit/proxy/index.php?module=CoreUpdater&action=newVersionAvailable +{$rootUrl}index.php?module=CoreUpdater&action=newVersionAvailable CoreUpdater_ViewVersionChangelog http://piwik.org/changelog/piwik-33-0-0/ CoreUpdater_FeedbackRequest -http://piwik.org/contact/'; +http://piwik.org/contact/"; $this->assertEmailForVersion('33.0.0', $message); } public function test_sendNotifications_shouldNotIncludeChangelogIfNotMajorVersionUpdate() { - $message = 'ScheduledReports_EmailHello + $rootUrl = Fixture::getTestRootUrl(); + $message = "ScheduledReports_EmailHello CoreUpdater_ThereIsNewVersionAvailableForUpdate CoreUpdater_YouCanUpgradeAutomaticallyOrDownloadPackage -http://localhost/tests/PHPUnit/proxy/index.php?module=CoreUpdater&action=newVersionAvailable +{$rootUrl}index.php?module=CoreUpdater&action=newVersionAvailable CoreUpdater_FeedbackRequest -http://piwik.org/contact/'; +http://piwik.org/contact/"; $this->assertEmailForVersion('33.0.0-b1', $message); } diff --git a/plugins/CoreUpdater/lang/cs.json b/plugins/CoreUpdater/lang/cs.json index 1aba35db9fc6ad99ecf26c2adbc2cad3f96aba4e..d77907655a66892d442ddfee47fb978585404cbf 100644 --- a/plugins/CoreUpdater/lang/cs.json +++ b/plugins/CoreUpdater/lang/cs.json @@ -19,7 +19,7 @@ "ExceptionArchiveIncompatible": "Nekompatibilnà archiv: %s", "ExceptionArchiveIncomplete": "Archiv je nekompletnÃ: nÄ›které soubory chybà (napÅ™.: %s).", "FeedbackRequest": "Zde můžete s týmem Piwiku sdÃlet nápady a návrhy:", - "HelpMessageContent": "Zkontrolujte %1$s Piwik FAQ %2$s , kde jsou vysvÄ›tleny nejÄastÄ›jšà chybi pÅ™i aktualizaci. %3$s Požádejte vaÅ¡eho systémového administrátora - může vám pomoct s chybou, která je nejÄastÄ›ji způsobena nastavenÃm serveru MySQL.", + "HelpMessageContent": "Zkontrolujte %1$s Piwik FAQ %2$s , kde jsou vysvÄ›tleny nejÄastÄ›jšà chybi pÅ™i aktualizaci. %3$s Požádejte svéo systémového administrátora - může vám pomoci s chybou, která je nejÄastÄ›ji způsobena nastavenÃm serveru MySQL.", "HelpMessageIntroductionWhenError": "NÞe je hlavnà chybová hláška. Pomůže vám zjistit pÅ™ÃÄinu, ale pokud budete potÅ™ebovat dalšà pomoc:", "HelpMessageIntroductionWhenWarning": "Aktualizace probÄ›hla v pořádku, ale byly zaznamenány problémy. ProsÃm pÅ™eÄtÄ›te si jejich popis výše. Pro dalšà pomoc:", "HighTrafficPiwikServerEnableMaintenance": "Pokud provozujete Piwik server s velkým provozem, doporuÄujeme %sna chvÃli zakázat sledovánà návÅ¡tÄ›vnÃků a pÅ™epnout uživatelské rozhranà do režimu údržby%s.", diff --git a/plugins/CoreUpdater/lang/fr.json b/plugins/CoreUpdater/lang/fr.json index 5b170cfe553a19728bea960362f0f0b0f7920239..4a4e84f9830b6eaed35936310a0068311874e2b6 100644 --- a/plugins/CoreUpdater/lang/fr.json +++ b/plugins/CoreUpdater/lang/fr.json @@ -22,7 +22,7 @@ "HelpMessageContent": "Allez voir la %1$s FAQ Piwik %2$s qui explique les erreurs courantes lors de la mise à jour. %3$s Demandez à votre administrateur système - il pourra être à même avec cette erreur qui est très probablement liée à la configuration de votre serveur MySQL.", "HelpMessageIntroductionWhenError": "Ci-dessus est le message d'erreur du noyau. Cela devrait expliquer la cause, mais si vous nécessitez davantage d'aide merci de :", "HelpMessageIntroductionWhenWarning": "La mise à jour a été complétée avec succès. Cependant, des problèmes sont survenus. Lisez la description ci-dessus pour plus de détails. Pour davantage d'aide :", - "HighTrafficPiwikServerEnableMaintenance": "Si vous gérez un serveur Piwik à haut traffic, nous recommandons de %sdésactiver momentanément le suivit des visiteurs et de mettre l'interface utilisateur de Piwik en mode de maintenance%s.", + "HighTrafficPiwikServerEnableMaintenance": "Si vous gérez un serveur Piwik à haut traffic, nous recommandons de %sdésactiver momentanément le suivi des visiteurs et de mettre l'interface utilisateur de Piwik en mode de maintenance%s.", "IncompatbilePluginsWillBeDisabledInfo": "Note : certains plugins ne sont pas compatbles avec Piwik %s. Ils seront désactivés lorsque vous mettrez à jour :", "InstallingTheLatestVersion": "Installation de la dernière version", "LatestBetaRelease": "Dernière version beta", diff --git a/plugins/CoreUpdater/lang/ja.json b/plugins/CoreUpdater/lang/ja.json index c7f307ea0cda6e5bd31cad739f04bf0cc17f4ac1..25e1fb5caf81cf2a31770f6f6bfd2ebdeb039e8b 100644 --- a/plugins/CoreUpdater/lang/ja.json +++ b/plugins/CoreUpdater/lang/ja.json @@ -25,6 +25,11 @@ "HighTrafficPiwikServerEnableMaintenance": "高トラフィック㮠Piwik サーãƒãƒ¼ã‚’管ç†ã™ã‚‹å ´åˆã€ %smomentarily disable visitor Tracking and put the Piwik User Interface in maintenance mode%s ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚", "IncompatbilePluginsWillBeDisabledInfo": "注 : 一部ã®ãƒ—ラグインã¯ã€Piwik %s ã«äº’æ›æ€§ãŒã‚りã¾ã›ã‚“。アップグレード時ã«ã€ã“れらã®ãƒ—ラグインã¯ç„¡åйã«ãªã‚Šã¾ã™ã€‚", "InstallingTheLatestVersion": "最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’インストールä¸", + "LatestBetaRelease": "最新ã®ãƒ™ãƒ¼ã‚¿ç‰ˆ リリース", + "LatestStableRelease": "最新ã®å®‰å®šç‰ˆãƒªãƒªãƒ¼ã‚¹", + "Latest2XStableRelease": "最新ã®å®‰å®šç‰ˆ 2.X", + "Latest2XBetaRelease": "最新ã®ãƒ™ãƒ¼ã‚¿ç‰ˆ 2.X", + "LtsSupportVersion": "長期サãƒãƒ¼ãƒˆç‰ˆ", "MajorUpdateWarning1": "ã“ã‚Œã¯æœ€æ–°ç‰ˆã¸ã®ã‚¢ãƒƒãƒ—デートã§ã™ï¼é€šå¸¸ã‚ˆã‚Šã‚‚時間ãŒã‹ã‹ã‚Šã¾ã™", "MajorUpdateWarning2": "以下ã®ã‚¢ãƒ‰ãƒã‚¤ã‚¹ã¯ã€ç‰¹ã«å¤§è¦æ¨¡ãªã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã®éš›ã€é‡è¦ã§ã™ã€‚", "NoteForLargePiwikInstances": "Piwik ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãŒå¤§ãã„å ´åˆã®é‡è¦æ³¨æ„", @@ -48,11 +53,15 @@ "UpdateHasBeenCancelledExplanation": "Piwik ワンクリックアップデートãŒã‚ャンセルã•れã¾ã—ãŸã€‚ ã‚ãªãŸãŒä¸Šè¨˜ã®ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’ä¿®æ£ã§ããªã„å ´åˆã¯ã€Piwik を手作æ¥ã§ã‚¢ãƒƒãƒ—デートã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚%1$s アップデートを始ã‚ã‚‹ã«ã¯ã€%2$sアップデートã®ãƒ‰ã‚ュメント%3$sã‚’å‚ç…§ã—ã¦ãã ã•ã„ï¼", "UpdateTitle": "アップデート", "UpdateSuccessTitle": "Piwik ã¯æ£å¸¸ã«ã‚¢ãƒƒãƒ—グレードã•れã¾ã—ãŸï¼", + "UpdateErrorTitle": "アップデートエラー", + "ThankYouUpdatePiwik": "Piwik を利用ã—ã€æœ€æ–°ã®çŠ¶æ…‹ã‚’ç¶æŒã—ã¦é ‚ãã‚りãŒã¨ã†ã”ã–ã„ã¾ã™ï¼", + "PostUpdateMessage": "Piwik ã¯ã€å¸¸ã«ç„¡æ–™ã§ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã—ã¦è‡ªç”±ã«ä½¿ç”¨ã§ãã¾ã™ãŒã€æˆé•·ã—ã€æ”¹å–„ã™ã‚‹ãŸã‚ã«ã¯çš†æ§˜ã®ã”支æ´ãŒå¿…è¦ã§ã™ã€‚", "PostUpdateSupport": "Piwik ã®ä½¿ã„æ–¹ã§åŠ©ã‘ãŒå¿…è¦ãªå ´åˆã¯ã€ãã®ã‚¯ãƒªã‚¨ã‚¤ã‚¿ãƒ¼ã‹ã‚‰ã‚µãƒãƒ¼ãƒˆã‚’å¾—ã‚‹ã“ã¨ãŒã§ãã¾ã™ï¼š", "EnterpriseSolutions": "エンタープライズソリューション", "CloudHosting": "クラウドホスティング", "Updating": "アップデート", "UpdateUsingHttpsFailed": "以下ã®ã‚¨ãƒ©ãƒ¼ã«ã‚ˆã‚Šã€ã‚»ã‚ュリティã§ä¿è·ã•れ㟠HTTPS 接続㧠Piwik ã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚", + "UpdateUsingHttpsFailedHelp": "Piwik ã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ãŒ ( ã‚»ã‚ュリティã§ä¿è·ã•れ㟠HTTPS 接続㧠) 失敗ã™ã‚‹æ§˜ã€…ãªç†ç”±ã¨ã—ã¦ã€ãŸã¨ãˆã°ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーや低速ãªãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯é€Ÿåº¦ã¾ãŸã¯é–“é•ã£ãŸã‚·ã‚¹ãƒ†ãƒ æ§‹æˆãªã©ãŒã‚りã¾ã™ã€‚ ãれã¯ã¾ãŸã€ã‚ãªãŸã®ã‚µãƒ¼ãƒãŒ MITM æ”»æ’ƒã®æ¨™çš„ã§ã‚りã€èª°ã‹ãŒ Piwik ã®æ‚ªè³ªãªãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ç½®ãæ›ãˆã¦æ›´æ–°ã—よã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。", "UpdateUsingHttpsFailedHelpWhatToDo": "MITM 攻撃を防ããŸã‚ã«ã€ã‚»ã‚ュリティã§ä¿è·ã•れ㟠HTTPS 接続を使用ã—ã¦ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã‚’å†è©¦è¡Œã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚", "UsingHttps": "(推奨) ã‚»ã‚ュリティã§ä¿è·ã•れ㟠HTTPS 接続を使用ã—ã¦ãã ã•ã„", "UsingHttp": "ã‚»ã‚ュリティä¿è·ã•れã¦ã„ãªã„ HTTP 接続ã®ä½¿ç”¨", diff --git a/plugins/CoreUpdater/lang/ko.json b/plugins/CoreUpdater/lang/ko.json index b54a774bb70cb0b51c7ffbe6088c82ee8d14b35b..1131e70c6d9afa9e876d7388d146e75baea40a0b 100644 --- a/plugins/CoreUpdater/lang/ko.json +++ b/plugins/CoreUpdater/lang/ko.json @@ -21,6 +21,11 @@ "HelpMessageIntroductionWhenError": "위와 ê°™ì€ ê²½ìš°ëŠ” 코어 ì—러 메세지입니다. ì›ì¸ì„ ì„¤ëª…í• ìˆ˜ 있으나 ë„ì›€ì´ í•„ìš”í•˜ë‹¤ë©´:", "HelpMessageIntroductionWhenWarning": "ì—…ë°ì´íŠ¸ëŠ” 성공ì 으로 완료ë˜ì—ˆìŠµë‹ˆë‹¤. 하지만 ì§„í–‰ì¤‘ì— ë¬¸ì œê°€ 있었습니다. ìžì„¸í•œ 사í•ì€ ìœ„ì˜ ì„¤ëª…ì„ ì½ì–´ì£¼ì„¸ìš”. ë” ë§Žì€ ë„움ì€:", "InstallingTheLatestVersion": "최근 ë²„ì „ 설치중", + "LatestBetaRelease": "최근 릴리즈 ëœ ë² íƒ€ ë²„ì „", + "LatestStableRelease": "최근 릴리즈 ëœ ì•ˆì • ë²„ì „", + "Latest2XStableRelease": "최근 ì•ˆì • 2.X ë²„ì „", + "Latest2XBetaRelease": "최근 ë² íƒ€ 2.X ë²„ì „", + "LtsSupportVersion": "Long Term Support ë²„ì „", "MajorUpdateWarning1": "중요한 ì—…ë°ì´íŠ¸ìž…ë‹ˆë‹¤! í‰ì†Œë³´ë‹¤ ë” ì˜¤ëž˜ ê±¸ë¦´ì§€ë„ ëª¨ë¦…ë‹ˆë‹¤.", "MajorUpdateWarning2": "다ìŒì€ 무거운 설치시 알아야하는 중요한 내용입니다.", "NoteForLargePiwikInstances": "ìš©ëŸ‰ì´ í° Piwik 설치시 주ì˜í•´ì•¼ í• ì ", diff --git a/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php b/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php index 1a41a07df3a1dec63b1ef1be9134964181364e3f..5acf9b50bedbbf7a48b39c9bd771e63fdc34b655 100644 --- a/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php +++ b/plugins/CoreVisualizations/Visualizations/HtmlTable/AllColumns.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable; use Piwik\DataTable; +use Piwik\Metrics; use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable; use Piwik\View; @@ -40,11 +41,13 @@ class AllColumns extends HtmlTable $this->dataTable->filter(function (DataTable $dataTable) use ($properties) { $columnsToDisplay = array('label', 'nb_visits'); - if (in_array('nb_uniq_visitors', $dataTable->getColumns())) { + $columns = $dataTable->getColumns(); + + if (in_array('nb_uniq_visitors', $columns)) { $columnsToDisplay[] = 'nb_uniq_visitors'; } - if (in_array('nb_users', $dataTable->getColumns())) { + if (in_array('nb_users', $columns)) { $columnsToDisplay[] = 'nb_users'; } diff --git a/plugins/CustomAlerts b/plugins/CustomAlerts index 6c05ca43d7c83dd795eb713b9feb624d8d6d2eb1..013821049089ae8d16f67e0a1b6c6525cb88a5ad 160000 --- a/plugins/CustomAlerts +++ b/plugins/CustomAlerts @@ -1 +1 @@ -Subproject commit 6c05ca43d7c83dd795eb713b9feb624d8d6d2eb1 +Subproject commit 013821049089ae8d16f67e0a1b6c6525cb88a5ad diff --git a/plugins/CustomDimensions b/plugins/CustomDimensions new file mode 160000 index 0000000000000000000000000000000000000000..5027b250120c8ecccb25d82e50fe993514122981 --- /dev/null +++ b/plugins/CustomDimensions @@ -0,0 +1 @@ +Subproject commit 5027b250120c8ecccb25d82e50fe993514122981 diff --git a/plugins/CustomVariables/API.php b/plugins/CustomVariables/API.php index fa3a99dbca344ff8501d26ee8f185f245d8bd760..69e6ee720c06be878898d269cfb3181527c8d602 100644 --- a/plugins/CustomVariables/API.php +++ b/plugins/CustomVariables/API.php @@ -8,10 +8,13 @@ */ namespace Piwik\Plugins\CustomVariables; +use Piwik\API\Request; use Piwik\Archive; +use Piwik\Container\StaticContainer; use Piwik\DataTable; use Piwik\Date; use Piwik\Metrics; +use Piwik\Piwik; use Piwik\Plugins\Actions\Actions\ActionSiteSearch; /** @@ -71,6 +74,7 @@ class API extends \Piwik\Plugin\API } } + if ($flat) { $dataTable->filterSubtables('Piwik\Plugins\CustomVariables\DataTable\Filter\CustomVariablesValuesFromNameId'); } else { @@ -109,9 +113,64 @@ class API extends \Piwik\Plugin\API // Hack Ecommerce product price tracking to display correctly $dataTable->renameColumn('price_viewed', 'price'); } + $dataTable->filter('Piwik\Plugins\CustomVariables\DataTable\Filter\CustomVariablesValuesFromNameId'); return $dataTable; } + + /** + * Get a list of all available custom variable slots (scope + index) and which names have been used so far in + * each slot since the beginning of the website. + * + * @param int $idSite + * @return array + */ + public function getUsagesOfSlots($idSite) + { + Piwik::checkUserHasAdminAccess($idSite); + + $numVars = CustomVariables::getNumUsableCustomVariables(); + + $usedCustomVariables = array( + 'visit' => array_fill(1, $numVars, array()), + 'page' => array_fill(1, $numVars, array()), + ); + + /** @var DataTable $customVarUsages */ + $today = StaticContainer::get('CustomVariables.today'); + $date = '2008-12-12,' . $today; + $customVarUsages = Request::processRequest('CustomVariables.getCustomVariables', + array('idSite' => $idSite, 'period' => 'range', 'date' => $date, + 'format' => 'original') + ); + + foreach ($customVarUsages->getRows() as $row) { + $slots = $row->getMetadata('slots'); + + if (!empty($slots)) { + foreach ($slots as $slot) { + $usedCustomVariables[$slot['scope']][$slot['index']][] = array( + 'name' => $row->getColumn('label'), + 'nb_visits' => $row->getColumn('nb_visits'), + 'nb_actions' => $row->getColumn('nb_actions'), + ); + } + } + } + + $grouped = array(); + foreach ($usedCustomVariables as $scope => $scopes) { + foreach ($scopes as $index => $cvars) { + $grouped[] = array( + 'scope' => $scope, + 'index' => $index, + 'usages' => $cvars + ); + } + } + + return $grouped; + } } diff --git a/plugins/CustomVariables/Archiver.php b/plugins/CustomVariables/Archiver.php index bc43cbc8ddfdf245ccc588d8f291cd0a9bb38474..39aa9e6bb735e25196c78d24dccb4c6ab03ae321 100644 --- a/plugins/CustomVariables/Archiver.php +++ b/plugins/CustomVariables/Archiver.php @@ -8,10 +8,10 @@ */ namespace Piwik\Plugins\CustomVariables; -use Piwik\Common; use Piwik\Config; use Piwik\DataAccess\LogAggregator; use Piwik\DataArray; +use Piwik\DataTable; use Piwik\Metrics; use Piwik\Tracker\GoalManager; use Piwik\Tracker; @@ -35,6 +35,9 @@ class Archiver extends \Piwik\Plugin\Archiver protected $maximumRowsInSubDataTable; protected $newEmptyRow; + private $metadata = array(); + private $metadataFlat = array(); + function __construct($processor) { parent::__construct($processor); @@ -50,7 +53,7 @@ class Archiver extends \Piwik\Plugin\Archiver public function aggregateMultipleReports() { - $columnsAggregationOperation = null; + $columnsAggregationOperation = array('slots' => 'uniquearraymerge'); $this->getProcessor()->aggregateDataTableRecords( self::CUSTOM_VARIABLE_RECORD_NAME, @@ -74,6 +77,16 @@ class Archiver extends \Piwik\Plugin\Archiver $this->removeVisitsMetricsFromActionsAggregate(); $this->dataArray->enrichMetricsWithConversions(); $table = $this->dataArray->asDataTable(); + + foreach ($table->getRows() as $row) { + $label = $row->getColumn('label'); + if (!empty($this->metadata[$label])) { + foreach ($this->metadata[$label] as $name => $value) { + $row->addMetadata($name, $value); + } + } + } + $blob = $table->getSerialized( $this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable, $columnToSort = Metrics::INDEX_NB_VISITS @@ -118,6 +131,8 @@ class Archiver extends \Piwik\Plugin\Archiver $key = $row[$keyField]; $value = $this->cleanCustomVarValue($row[$valueField]); + $this->addMetadata($keyField, $key, Model::SCOPE_VISIT); + $this->dataArray->sumMetricsVisits($key, $row); $this->dataArray->sumMetricsVisitsPivot($key, $value, $row); } @@ -137,6 +152,8 @@ class Archiver extends \Piwik\Plugin\Archiver $key = $row[$keyField]; $value = $this->cleanCustomVarValue($row[$valueField]); + $this->addMetadata($keyField, $key, Model::SCOPE_PAGE); + $alreadyAggregated = $this->aggregateEcommerceCategories($key, $value, $row); if (!$alreadyAggregated) { $this->aggregateActionByKeyAndValue($key, $value, $row); @@ -145,6 +162,22 @@ class Archiver extends \Piwik\Plugin\Archiver } } + private function addMetadata($keyField, $label, $scope) + { + $index = (int) str_replace('custom_var_k', '', $keyField); + + if (!array_key_exists($label, $this->metadata)) { + $this->metadata[$label] = array('slots' => array()); + } + + $uniqueId = $label . 'scope' . $scope . 'index' . $index; + + if (!isset($this->metadataFlat[$uniqueId])) { + $this->metadata[$label]['slots'][] = array('scope' => $scope, 'index' => $index); + $this->metadataFlat[$uniqueId] = true; + } + } + /** * @param string $key * @param string $value @@ -205,6 +238,7 @@ class Archiver extends \Piwik\Plugin\Archiver } while ($row = $query->fetch()) { $key = $row[$keyField]; + $value = $this->cleanCustomVarValue($row[$valueField]); $this->dataArray->sumMetricsGoals($key, $row); $this->dataArray->sumMetricsGoalsPivot($key, $value, $row); diff --git a/plugins/CustomVariables/Columns/Base.php b/plugins/CustomVariables/Columns/Base.php index 1818ca3145455f505621965828a195ce7c716722..4c6a4ea54218a8265671dabd76a841c59a074c14 100644 --- a/plugins/CustomVariables/Columns/Base.php +++ b/plugins/CustomVariables/Columns/Base.php @@ -16,7 +16,7 @@ use Piwik\Plugins\CustomVariables\CustomVariables; class Base extends VisitDimension { - protected function configureSegmentsFor($fieldPrefix, $segmentNameSuffix) + protected function configureSegmentsFor($segmentNameSuffix) { $numCustomVariables = CustomVariables::getNumUsableCustomVariables(); @@ -25,10 +25,7 @@ class Base extends VisitDimension $segment->setSegment('customVariable' . $segmentNameSuffix); $segment->setName($this->getName() . ' (' . Piwik::translate('CustomVariables_ScopeVisit') . ')'); $segment->setCategory('CustomVariables_CustomVariables'); - $segment->setSqlSegment($this->getSegmentColumns('log_visit.' . $fieldPrefix, $numCustomVariables)); - $segment->setSuggestedValuesCallback(function ($idSite, $ignore, DataTable $table) use ($segmentNameSuffix) { - return $table->getColumnsStartingWith('customVariable' . $segmentNameSuffix); - }); + $segment->setUnionOfSegments($this->getSegmentColumns('customVariable' . $segmentNameSuffix, $numCustomVariables)); $this->addSegment($segment); $segment = new Segment(); @@ -36,10 +33,7 @@ class Base extends VisitDimension $segment->setSegment('customVariablePage' . $segmentNameSuffix); $segment->setName($this->getName() . ' (' . Piwik::translate('CustomVariables_ScopePage') . ')'); $segment->setCategory('CustomVariables_CustomVariables'); - $segment->setSqlSegment($this->getSegmentColumns('log_link_visit_action.' . $fieldPrefix, $numCustomVariables)); - $segment->setSuggestedValuesCallback(function ($idSite, $ignore, DataTable $table) use ($segmentNameSuffix) { - return $table->getColumnsStartingWith('customVariablePage' . $segmentNameSuffix); - }); + $segment->setUnionOfSegments($this->getSegmentColumns('customVariablePage' . $segmentNameSuffix, $numCustomVariables)); $this->addSegment($segment); } diff --git a/plugins/CustomVariables/Columns/CustomVariableName.php b/plugins/CustomVariables/Columns/CustomVariableName.php index 85aa46436f6fe4410b411be4c4e11a0eed2644e2..b42f2e8ae7ceb2610fe6fbb904c990573899c356 100644 --- a/plugins/CustomVariables/Columns/CustomVariableName.php +++ b/plugins/CustomVariables/Columns/CustomVariableName.php @@ -14,7 +14,7 @@ class CustomVariableName extends Base { protected function configureSegments() { - $this->configureSegmentsFor('custom_var_k', 'Name'); + $this->configureSegmentsFor('Name'); } public function getName() diff --git a/plugins/CustomVariables/Columns/CustomVariableValue.php b/plugins/CustomVariables/Columns/CustomVariableValue.php index 03046758cf8b40db1656d1ac19f4e1b0e9024e2b..a565a8136c0434abcbcacb40cf68cb22a7df5a81 100644 --- a/plugins/CustomVariables/Columns/CustomVariableValue.php +++ b/plugins/CustomVariables/Columns/CustomVariableValue.php @@ -14,7 +14,7 @@ class CustomVariableValue extends Base { protected function configureSegments() { - $this->configureSegmentsFor('custom_var_v', 'Value'); + $this->configureSegmentsFor('Value'); } public function getName() diff --git a/plugins/CustomVariables/Controller.php b/plugins/CustomVariables/Controller.php index 59a4a949de473ded0bec8055307aee477a201d4c..e73e58b257a7f43c521798c5a465e15f5fba5615 100644 --- a/plugins/CustomVariables/Controller.php +++ b/plugins/CustomVariables/Controller.php @@ -8,7 +8,20 @@ */ namespace Piwik\Plugins\CustomVariables; +use Piwik\Common; +use Piwik\DataTable; +use Piwik\Piwik; + class Controller extends \Piwik\Plugin\Controller { + public function manage() + { + $idSite = Common::getRequestVar('idSite'); + + Piwik::checkUserHasAdminAccess($idSite); + + return $this->renderTemplate('manage', array()); + } + } diff --git a/plugins/CustomVariables/CustomVariables.php b/plugins/CustomVariables/CustomVariables.php index b8a57ad6a65fd3152d2ab9d76b8295f6fbad8e57..9059482c333117c6d3bbeb027bbb681c878a1adc 100644 --- a/plugins/CustomVariables/CustomVariables.php +++ b/plugins/CustomVariables/CustomVariables.php @@ -22,7 +22,10 @@ class CustomVariables extends \Piwik\Plugin { return array( 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata', - 'Live.getAllVisitorDetails' => 'extendVisitorDetails' + 'Live.getAllVisitorDetails' => 'extendVisitorDetails', + 'AssetManager.getJavaScriptFiles' => 'getJsFiles', + 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys', + 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles', ); } @@ -144,4 +147,35 @@ class CustomVariables extends \Piwik\Plugin } } + public function getClientSideTranslationKeys(&$translationKeys) + { + $translationKeys[] = 'CustomVariables_CustomVariables'; + $translationKeys[] = 'CustomVariables_ManageDescription'; + $translationKeys[] = 'CustomVariables_ScopeX'; + $translationKeys[] = 'CustomVariables_Index'; + $translationKeys[] = 'CustomVariables_Usages'; + $translationKeys[] = 'CustomVariables_Unused'; + $translationKeys[] = 'CustomVariables_CreateNewSlot'; + $translationKeys[] = 'CustomVariables_UsageDetails'; + $translationKeys[] = 'CustomVariables_CurrentAvailableCustomVariables'; + $translationKeys[] = 'CustomVariables_ToCreateCustomVarExecute'; + $translationKeys[] = 'CustomVariables_CreatingCustomVariableTakesTime'; + $translationKeys[] = 'CustomVariables_SlotsReportIsGeneratedOverTime'; + $translationKeys[] = 'General_Loading'; + $translationKeys[] = 'General_TrackingScopeVisit'; + $translationKeys[] = 'General_TrackingScopePage'; + } + + public function getStylesheetFiles(&$stylesheets) + { + $stylesheets[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.less"; + } + + public function getJsFiles(&$jsFiles) + { + $jsFiles[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.model.js"; + $jsFiles[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.controller.js"; + $jsFiles[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.js"; + } + } diff --git a/plugins/CustomVariables/Menu.php b/plugins/CustomVariables/Menu.php new file mode 100644 index 0000000000000000000000000000000000000000..b97aa1bb015177c7d7d5831466b6ee028069965a --- /dev/null +++ b/plugins/CustomVariables/Menu.php @@ -0,0 +1,33 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\CustomVariables; + +use Piwik\Common; +use Piwik\Menu\MenuUser; +use Piwik\Piwik; +use Piwik\Plugins\UsersManager\UserPreferences; + +/** + * This class allows you to add, remove or rename menu items. + * To configure a menu (such as Admin Menu, Reporting Menu, User Menu...) simply call the corresponding methods as + * described in the API-Reference http://developer.piwik.org/api-reference/Piwik/Menu/MenuAbstract + */ +class Menu extends \Piwik\Plugin\Menu +{ + public function configureUserMenu(MenuUser $menu) + { + $userPreferences = new UserPreferences(); + $default = $userPreferences->getDefaultWebsiteId(); + $idSite = Common::getRequestVar('idSite', $default, 'int'); + + if (Piwik::isUserHasAdminAccess($idSite)) { + $menu->addManageItem('Custom Variables', $this->urlForAction('manage'), $orderId = 15); + } + } +} diff --git a/plugins/CustomVariables/Model.php b/plugins/CustomVariables/Model.php index 9d98a352fa2683069bcf49378aecc56769d986db..235809e1da3bf0999b3af1f0daaa2334075898cd 100644 --- a/plugins/CustomVariables/Model.php +++ b/plugins/CustomVariables/Model.php @@ -15,12 +15,14 @@ use Piwik\Log; class Model { - const SCOPE_PAGE = 'log_link_visit_action'; - const SCOPE_VISIT = 'log_visit'; - const SCOPE_CONVERSION = 'log_conversion'; const DEFAULT_CUSTOM_VAR_COUNT = 5; + const SCOPE_PAGE = 'page'; + const SCOPE_VISIT = 'visit'; + const SCOPE_CONVERSION = 'conversion'; + private $scope = null; + private $table = null; public function __construct($scope) { @@ -29,21 +31,27 @@ class Model } $this->scope = $scope; + $this->table = Common::prefixTable($this->getTableNameFromScope($scope)); } - public function getScopeName() + private function getTableNameFromScope($scope) { // actually we should have a class for each scope but don't want to overengineer it for now - switch ($this->scope) { + switch ($scope) { case self::SCOPE_PAGE: - return 'Page'; + return 'log_link_visit_action'; case self::SCOPE_VISIT: - return 'Visit'; + return 'log_visit'; case self::SCOPE_CONVERSION: - return 'Conversion'; + return 'log_conversion'; } } + public function getScopeName() + { + return ucfirst($this->scope); + } + /** * @see getHighestCustomVarIndex() * @return int @@ -96,8 +104,7 @@ class Model private function getCustomVarColumnNames() { - $dbTable = $this->getDbTableName(); - $columns = Db::getColumnNamesFromTable($dbTable); + $columns = Db::getColumnNamesFromTable($this->table); $customVarColumns = array_filter($columns, function ($column) { return false !== strpos($column, 'custom_var_'); @@ -108,14 +115,13 @@ class Model public function removeCustomVariable() { - $dbTable = $this->getDbTableName(); - $index = $this->getHighestCustomVarIndex(); + $index = $this->getHighestCustomVarIndex(); if ($index < 1) { return null; } - Db::exec(sprintf('ALTER TABLE %s ', $dbTable) + Db::exec(sprintf('ALTER TABLE %s ', $this->table) . sprintf('DROP COLUMN custom_var_k%d,', $index) . sprintf('DROP COLUMN custom_var_v%d;', $index)); @@ -124,22 +130,16 @@ class Model public function addCustomVariable() { - $dbTable = $this->getDbTableName(); - $index = $this->getHighestCustomVarIndex() + 1; - $maxLen = CustomVariables::getMaxLengthCustomVariables(); + $index = $this->getHighestCustomVarIndex() + 1; + $maxLen = CustomVariables::getMaxLengthCustomVariables(); - Db::exec(sprintf('ALTER TABLE %s ', $dbTable) + Db::exec(sprintf('ALTER TABLE %s ', $this->table) . sprintf('ADD COLUMN custom_var_k%d VARCHAR(%d) DEFAULT NULL,', $index, $maxLen) . sprintf('ADD COLUMN custom_var_v%d VARCHAR(%d) DEFAULT NULL;', $index, $maxLen)); return $index; } - private function getDbTableName() - { - return Common::prefixTable($this->scope); - } - public static function getCustomVariableIndexFromFieldName($fieldName) { $onlyNumber = str_replace(array('custom_var_k', 'custom_var_v'), '', $fieldName); diff --git a/plugins/CustomVariables/Tracker/CustomVariablesRequestProcessor.php b/plugins/CustomVariables/Tracker/CustomVariablesRequestProcessor.php index 44e6d593504ba183293a9e167fe61351b828fc96..2b068ba03eaad8e562a6f5220296c73398404d56 100644 --- a/plugins/CustomVariables/Tracker/CustomVariablesRequestProcessor.php +++ b/plugins/CustomVariables/Tracker/CustomVariablesRequestProcessor.php @@ -9,6 +9,8 @@ namespace Piwik\Plugins\CustomVariables\Tracker; use Piwik\Common; +use Piwik\Plugins\CustomVariables\Model; +use Piwik\Tracker\Action; use Piwik\Tracker\Request; use Piwik\Tracker\RequestProcessor; use Piwik\Tracker\Visit\VisitProperties; @@ -36,7 +38,7 @@ class CustomVariablesRequestProcessor extends RequestProcessor public function processRequestParams(VisitProperties $visitProperties, Request $request) { // TODO: re-add optimization where if custom variables exist in request, don't bother selecting them in Visitor - $visitorCustomVariables = $request->getCustomVariables($scope = 'visit'); + $visitorCustomVariables = $request->getCustomVariables($scope = Model::SCOPE_VISIT); if (!empty($visitorCustomVariables)) { Common::printDebug("Visit level Custom Variables: "); Common::printDebug($visitorCustomVariables); @@ -62,4 +64,25 @@ class CustomVariablesRequestProcessor extends RequestProcessor $valuesToUpdate = array_merge($valuesToUpdate, $visitCustomVariables); } } + + public function afterRequestProcessed(VisitProperties $visitProperties, Request $request) + { + $action = $request->getMetadata('Actions', 'action'); + + if (empty($action) || !($action instanceof Action)) { + return; + } + + $customVariables = $action->getCustomVariables(); + + if (!empty($customVariables)) { + Common::printDebug("Page level Custom Variables: "); + Common::printDebug($customVariables); + + foreach ($customVariables as $field => $value) { + $action->setCustomField($field, $value); + } + } + + } } diff --git a/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.controller.js b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.controller.js new file mode 100644 index 0000000000000000000000000000000000000000..f8098eb114b7322a39a301f8c867bb4ae744ea9d --- /dev/null +++ b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.controller.js @@ -0,0 +1,22 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +(function () { + angular.module('piwikApp').controller('ManageCustomVarsController', ManageCustomVarsController); + + ManageCustomVarsController.$inject = ['manageCustomVarsModel', 'piwik', '$filter']; + + function ManageCustomVarsController(manageCustomVarsModel, piwik, $filter) { + manageCustomVarsModel.fetchUsages(); + + this.model = manageCustomVarsModel; + this.siteName = piwik.siteName; + this.scopes = [ + {value: 'visit', name: _pk_translate('General_TrackingScopeVisit')}, + {value: 'page', name: _pk_translate('General_TrackingScopePage')} + ]; + } +})(); \ No newline at end of file diff --git a/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.html b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.html new file mode 100644 index 0000000000000000000000000000000000000000..6ab9ea6ba679b98f839ab2ab86dec6877103259b --- /dev/null +++ b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.html @@ -0,0 +1,54 @@ +<div class="manageCustomVars"> + <h2 piwik-enriched-headline help-url="http://piwik.org/docs/custom-variables/">{{ 'CustomVariables_CustomVariables'|translate }}</h2> + + <p> + <span ng-bind-html="'CustomVariables_ManageDescription'|translate:manageCustomVars.siteName"></span> + </p> + + <div class="alert alert-info" ng-show="!manageCustomVars.model.isLoading && manageCustomVars.model.hasCustomVariablesInGeneral && !manageCustomVars.model.hasAtLeastOneUsage"> + {{ 'CustomVariables_SlotsReportIsGeneratedOverTime'|translate }} + </div> + + <div ng-repeat="scope in manageCustomVars.scopes"> + <h2 class="secondary">{{ 'CustomVariables_ScopeX'|translate:(scope.name) }}</h2> + <table class="dataTable entityTable"> + <thead> + <tr> + <th>{{'CustomVariables_Index'|translate }}</th> + <th>{{'CustomVariables_Usages'|translate }}</th> + </tr> + </thead> + <tbody> + <tr> + <td colspan="3" ng-show="manageCustomVars.model.isLoading">{{ 'General_Loading'|translate }}</td> + </tr> + <tr ng-repeat="customVariables in manageCustomVars.model.customVariables|filter:{scope: scope.value}"> + <td class="index">{{ customVariables.index }}</td> + <td> + <span ng-show="(customVariables.usages|length) === 0" + class="unused">{{'CustomVariables_Unused'|translate }}</span> + <span ng-show="customVariables.usages|length" ng-repeat="cvar in customVariables.usages|orderBy:'-nb_actions'"> + <span title="{{ 'CustomVariables_UsageDetails'|translate:(cvar.nb_visits ? cvar.nb_visits : 0):(cvar.nb_actions ? cvar.nb_actions : 0) }}">{{ cvar.name }}</span><span ng-show="!$last">, </span> + </span> + </td> + </tr> + </tbody> + </table> + </div> + + <h2 class="secondary" ng-show="!manageCustomVars.model.isLoading">{{ 'CustomVariables_CreateNewSlot'|translate }}</h2> + + <p ng-show="!manageCustomVars.model.isLoading"> + {{ 'CustomVariables_CreatingCustomVariableTakesTime'|translate }} + <br /><br /> + <span ng-bind-html="'CustomVariables_CurrentAvailableCustomVariables'|translate:('<strong>'+manageCustomVars.model.numSlotsAvailable+'</strong>')"></span> + <br /> + <br /> + {{ 'CustomVariables_ToCreateCustomVarExecute'|translate }} + <br /> + <br /> + <code>./console customvariables:set-max-custom-variables {{ manageCustomVars.model.numSlotsAvailable + 1 }}</code> + </p> + + +</div> \ No newline at end of file diff --git a/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.js b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.js new file mode 100644 index 0000000000000000000000000000000000000000..1623d50b273d2d0b5d77cbcd90d22dfaf97c06d2 --- /dev/null +++ b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.js @@ -0,0 +1,26 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +/** + * Usage: + * <div piwik-manage-custom-vars> + */ +(function () { + angular.module('piwikApp').directive('piwikManageCustomVars', piwikManageCustomVars); + + piwikManageCustomVars.$inject = ['piwik']; + + function piwikManageCustomVars(piwik){ + return { + restrict: 'A', + scope: {}, + templateUrl: 'plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.html?cb=' + piwik.cacheBuster, + controller: 'ManageCustomVarsController', + controllerAs: 'manageCustomVars' + }; + } +})(); \ No newline at end of file diff --git a/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.less b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.less new file mode 100644 index 0000000000000000000000000000000000000000..b666abebcaf8ab63e2f65cc4ba651344dafb0c03 --- /dev/null +++ b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.less @@ -0,0 +1,18 @@ +.manageCustomVars { + .unused { + color: @color-silver; + } + + table, p { + width: 900px; + } + + .alert-info { + margin-top: 15px; + } + + .scope, .index { + width: 90px; + max-width: 90px; + } +} \ No newline at end of file diff --git a/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.model.js b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.model.js new file mode 100644 index 0000000000000000000000000000000000000000..ceb6442a8f3c63e5bcb76aa618d4fbde020a0c27 --- /dev/null +++ b/plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.model.js @@ -0,0 +1,59 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +(function () { + angular.module('piwikApp').factory('manageCustomVarsModel', manageCustomVarsModel); + + manageCustomVarsModel.$inject = ['piwikApi']; + + function manageCustomVarsModel(piwikApi) { + + var model = { + customVariables : [], + extractions : [], + isLoading: false, + fetchUsages: fetchUsages, + hasCustomVariablesInGeneral: false, + hasAtLeastOneUsage: false, + numSlotsAvailable: 5, + }; + + return model; + + function fetchCustomVariables() { + return piwikApi.fetch({method: 'CustomVariables.getCustomVariables', period: 'year', date: 'today', filter_limit: 1}) + .then(function (customVariables) { + model.hasCustomVariablesInGeneral = (customVariables && customVariables.length > 0); + }); + } + + function fetchUsages() { + + model.isLoading = true; + + fetchCustomVariables().then(function () { + return piwikApi.fetch({method: 'CustomVariables.getUsagesOfSlots'}); + + }).then(function (customVariables) { + model.customVariables = customVariables; + + angular.forEach(customVariables, function (customVar) { + if (customVar.index > model.numSlotsAvailable) { + model.numSlotsAvailable = customVar.index; + } + + if (customVar.usages && customVar.usages.length > 0) { + model.hasAtLeastOneUsage = true; + } + }); + + })['finally'](function () { // .finally() is not IE8 compatible see https://github.com/angular/angular.js/commit/f078762d48d0d5d9796dcdf2cb0241198677582c + model.isLoading = false; + }); + } + + } +})(); \ No newline at end of file diff --git a/plugins/CustomVariables/config/config.php b/plugins/CustomVariables/config/config.php index 82a0058e024e0a2c65d4847f2e22f013ed599480..cba8dd0f59740801964af9f07096b6bf7736afdc 100644 --- a/plugins/CustomVariables/config/config.php +++ b/plugins/CustomVariables/config/config.php @@ -1,9 +1,6 @@ <?php return array( - - 'tracker.request.processors' => DI\add(array( - DI\get('Piwik\Plugins\CustomVariables\Tracker\CustomVariablesRequestProcessor'), - )), - + // in tests we do not use 'today' to make tests results deterministic + 'CustomVariables.today' => 'today', ); diff --git a/plugins/CustomVariables/config/test.php b/plugins/CustomVariables/config/test.php new file mode 100644 index 0000000000000000000000000000000000000000..d1ef28244a153a07b7878571afc3a562fedc7b38 --- /dev/null +++ b/plugins/CustomVariables/config/test.php @@ -0,0 +1,4 @@ +<?php +return array( + 'CustomVariables.today' => '2015-01-01' +); \ No newline at end of file diff --git a/plugins/CustomVariables/lang/cs.json b/plugins/CustomVariables/lang/cs.json index 5a75dd2cd15d7f26ef22220bb436de8ff6a4b433..98a5db6ea637834df2218982a9d84274b165f77a 100644 --- a/plugins/CustomVariables/lang/cs.json +++ b/plugins/CustomVariables/lang/cs.json @@ -6,6 +6,17 @@ "CustomVariablesReportDocumentation": "Toto hlášenà obsahuje informace o vaÅ¡ich vlastnÃch promÄ›nných. KliknÄ›te na promÄ›nnou pro zobrazenà distribuce hodnot. %s Pro vÃce informacà si pÅ™eÄtÄ›te %sdokumentaci o vlastnÃch promÄ›nných na piwik.org%s", "PluginDescription": "Vlastnà promÄ›nné jsou páry (jméno, hodnota), které můžete nastavit návÅ¡tÄ›vnÃkovi, nebo libovolné akci, pomocà javascriptového API. Piwik potom ohlásÃ, kolik návÅ¡tÄ›v, stránek, konverzà bylo pro každé z tÄ›chto jmen a hodnot. ProhlédnÄ›te si detailnÄ› tyto promÄ›nné pro každého uživatele a akci v záznamu návÅ¡tÄ›vnÃků.<br \/>Vyžadováno, pokud chcete použÃt <a href=\"http:\/\/piwik.org\/docs\/ecommerce-analytics\/\">analýzu E-obchodu<\/a>!", "ScopePage": "rozsah stránky", - "ScopeVisit": "rozsah návÅ¡tÄ›vy" + "ScopeVisit": "rozsah návÅ¡tÄ›vy", + "ManageDescription": "Tento pÅ™ehled zobrazuje vÅ¡echny sloty vlastnÃch promÄ›nných a jejich využità pro stránku '%s'. Jména v každém ze slotů jsou seÅ™azena dle jejich celkového využitÃ.", + "ScopeX": "Rozsah %s", + "Index": "Index", + "Usages": "VyužitÃ", + "Unused": "Nevyužito", + "CreateNewSlot": "Navýšit poÄet dostupných slotů vlastnÃch promÄ›nných", + "UsageDetails": "%s návÅ¡tÄ›v a %s akcà od vytvoÅ™enà této webové stránky.", + "CreatingCustomVariableTakesTime": "VytvoÅ™enà nové vlastnà promÄ›nné hodnoty může trvat déle v závislosti na velikosti vašà databáze. Proto je toto možné provést pouze pomocà pÅ™Ãkazu spuÅ¡tÄ›nému v pÅ™Ãkazové řádce.", + "CurrentAvailableCustomVariables": "AktuálnÄ› můžete použÃt až %s vlastnÃch promÄ›nných na stránku.", + "ToCreateCustomVarExecute": "Pro vytvoÅ™enà nového slotu pro vlastnà promÄ›nnou spusÅ¥te následujÃcà pÅ™Ãkaz ve své instalaci Piwik:", + "SlotsReportIsGeneratedOverTime": "Data pro tento report budou dostupná pozdÄ›ji. Než budou data vidÄ›t, může to den nebo dva trvat a poté nÄ›kolik týdnů než bude report vypovÃdajÃcÃ." } } \ No newline at end of file diff --git a/plugins/CustomVariables/lang/de.json b/plugins/CustomVariables/lang/de.json index 0dd793331aec2f5a4d65bfe8cec2432455d38358..c60483ec21f99c3ae934b04aa97e11bdf7e566a6 100644 --- a/plugins/CustomVariables/lang/de.json +++ b/plugins/CustomVariables/lang/de.json @@ -6,6 +6,17 @@ "CustomVariablesReportDocumentation": "Dieser Bericht enthält Informationen über Ihre benutzerdefinierten Variablen. Klicken Sie auf einen Variablennamen, um die Verteilung der Werte zu sehen. %s Für mehr Informationen über benutzerdefinierte Variablen, lesen Sie die %sDokumentation auf piwik.org%s", "PluginDescription": "Benutzerdefinierte Variablen sind (Namen-, Wert-) Paare, welche Sie mit Hilfe der Javascript API auf Besucher oder deren Aktionen festlegen können. Piwik wird Sie dann über die Menge an Besuchen, Seiten, Konversionen für jede der benutzerdefinierten Variablen und Werte informieren. Die detaillierten benutzerdefinierten Variablen für jeden Benutzer und Aktionen im Besucher-Log einsehbar.<br \/>Benötigt um das Feature <a href=\"http:\/\/piwik.org\/docs\/ecommerce-analytics\/\">Ecommerce Analyse<\/a>nutzen zu können.", "ScopePage": "Anwendungsbereich Seite", - "ScopeVisit": "Anwendungsbereich Besuch" + "ScopeVisit": "Anwendungsbereich Besuch", + "ManageDescription": "Diese Übersicht zeigt alle benutzerdefinierten Variablen und deren Gebrauch für Webseite %s. Die Namen auf jeder Position sind danach sortiert, wie oft sie insgesamt benützt wurden.", + "ScopeX": "Anwendungsbereich %s", + "Index": "Index", + "Usages": "Verwendungen", + "Unused": "Unbenutzt", + "CreateNewSlot": "Die Anzahl verfügbarer benutzerdefinierter Variablen erhöhen", + "UsageDetails": "%s Besuche und %s Aktionen seit der Erstellung dieser Webseite.", + "CreatingCustomVariableTakesTime": "Neue benutzerdefinierte Variablen zu erstellen kann viel Zeit beanspruchen, abhängig von der Grösse Ihrer Datenbank. Deshalb ist dieser Vorgang nur über Kommandozeilen verfügbar.", + "CurrentAvailableCustomVariables": "Aktuell können Sie bis zu %s benutzerdefinierte Variablen pro Seite einsetzen.", + "ToCreateCustomVarExecute": "Um eine neue benutzerdefinierte Variable zu erstellen, führen Sie in Ihrer Piwik Installation folgende Befehle aus:", + "SlotsReportIsGeneratedOverTime": "Daten für diesen Bericht werden periodisch veröffentlicht. Es mag ein oder zwei Tage dauern, bis Daten sichtbar sind und einige Wochen bis der Bericht vollständig aussagekräftig ist." } } \ No newline at end of file diff --git a/plugins/CustomVariables/lang/el.json b/plugins/CustomVariables/lang/el.json index baf9456547ff0618913abc033ac805390971c266..25b790a4f9d69a30a8161ed74cc100eb3e42f7cc 100644 --- a/plugins/CustomVariables/lang/el.json +++ b/plugins/CustomVariables/lang/el.json @@ -6,6 +6,17 @@ "CustomVariablesReportDocumentation": "Αυτή η αναφοÏά πεÏιÎχει πληÏοφοÏίες για τις Î ÏοσαÏμοσμÎνες ΜεταβλητÎÏ‚. Πατήστε σε Îνα όνομα μεταβλητής για να δείτε την κατανομή των τιμών. %s Για πεÏισσότεÏες πληÏοφοÏίες για τις Î ÏοσαÏμοσμÎνες ΜεταβλητÎÏ‚ γενικά, διαβάστε την %sτεκμηÏίωση Î ÏοσαÏμοσμÎνων Μεταβλητών στο piwik.org%s.", "PluginDescription": "Οι Î ÏοσαÏμοσμÎνες ΜεταβλητÎÏ‚ (όνομα, τιμή) είναι ζεÏγη που δίνετε με χÏήση του Javascript API σε επισκÎπτες ή οποιαδήποτε ενÎÏγειά τους. Το Piwik τότε θα αναφÎÏει τις επισκÎψεις, σελίδες, μετατÏοπÎÏ‚ για κάθε μία από τις Ï€ÏοσαÏμοσμÎνες αυτÎÏ‚ μεταβλητÎÏ‚. Δείτε τις λεπτομεÏείς Î ÏοσαÏμοσμÎνες ΜεταβλητÎÏ‚ για κάθε χÏήστη και ενÎÏγεια στο ΗμεÏολόγιο Επισκεπτών.<br \/>Απαιτείται για τη χÏήση του χαÏακτηÏÎ¹ÏƒÏ„Î¹ÎºÎ¿Ï <a href=\"http:\/\/piwik.org\/docs\/ecommerce-analytics\/\">Αναλυτικά Ηλ. ΕμποÏίου<\/a>!", "ScopePage": "σελίδα σκοποÏ", - "ScopeVisit": "επίσκεψη σκοποÏ" + "ScopeVisit": "επίσκεψη σκοποÏ", + "ManageDescription": "Η σÏνοψη αυτή δείχνει όλες τις σχισμÎÏ‚ Ï€ÏοσαÏμοσμÎνων μεταβλητών και τις χÏήσεις τους για τον ιστοτόπο '%s'. Τα ονόματα σε κάθε σχισμή ταξινομοÏνται με βάση το πόσο συχνά χÏησιμοποιοÏνται στο σÏνολο.", + "ScopeX": "ΕμβÎλεια %s", + "Index": "ΕυÏετήÏιο", + "Usages": "ΧÏήσεις", + "Unused": "Δεν χÏησιμοποιοÏνται", + "CreateNewSlot": "Αυξήστε τον αÏιθμό των σχισμών Î ÏοσαÏμοσμÎνων Μεταβλητών", + "UsageDetails": "%s επισκÎψεις και %s ενÎÏγειες από την δημιουÏγία του ιστοτόπου.", + "CreatingCustomVariableTakesTime": "Η δημιουÏγία σχισμής Ï€ÏοσαÏμοσμÎνης μεταβλητής μποÏεί να διαÏκÎσει αÏκετή ÏŽÏα ανάλογα με το μÎγεθος της βάσης. Οπότε, αυτό είναι Ï€ÏÎπει να γίνεται από εντολή που χÏειάζεται να εκτελεστεί από την γÏαμμή εντολών.", + "CurrentAvailableCustomVariables": "Αυτή τη στιγμή μποÏείτε να χÏησιμοποιήσετε %s Î ÏοσαÏμοσμÎνες ΜεταβλητÎÏ‚ ανά ιστοτόπο.", + "ToCreateCustomVarExecute": "Για να δημιουÏγήσετε μια σχισμή Ï€ÏοσαÏμοσμÎνης μεταβλητής Ï€ÏÎπει να εκτελÎσετε την παÏακάτω εντολή για την εγκατάσταση του PIwik σας:", + "SlotsReportIsGeneratedOverTime": "Τα δεδομÎνα για αυτή την αναφοÏά θα συμπληÏώνονται με το Ï€ÎÏασμα του χÏόνου. ΜποÏεί να χÏειαστοÏν μία ή δÏο μÎÏες για να δείτε δεδομÎνα και μεÏικÎÏ‚ εβδομάδες μÎχÏι η αναφοÏά να είναι ακÏιβής." } } \ No newline at end of file diff --git a/plugins/CustomVariables/lang/en.json b/plugins/CustomVariables/lang/en.json index 7d99f97bf27c1b6204c4b500750f47fedad54ad3..45052df4d9e1c5e8e20686bbb731dd6c2ad90846 100644 --- a/plugins/CustomVariables/lang/en.json +++ b/plugins/CustomVariables/lang/en.json @@ -6,6 +6,17 @@ "CustomVariablesReportDocumentation": "This report contains information about your Custom Variables. Click on a variable name to see the distribution of the values. %s For more information about Custom Variables in general, read the %sCustom Variables documentation on piwik.org%s", "PluginDescription": "Custom Variables are (name, value) pairs that you can assign using the Javascript API to visitors or any of their action. Piwik will then report how many visits, pages, conversions for each of these custom names and values. View the detailed Custom Variables for each user and action in the Visitor Log.<br />Required to use <a href=\"http://piwik.org/docs/ecommerce-analytics/\">Ecommerce Analytics</a> feature!", "ScopePage": "scope page", - "ScopeVisit": "scope visit" + "ScopeVisit": "scope visit", + "ManageDescription": "This overview shows all custom variable slots and their usages for website '%s'. The names within each slot are ordered by how often they were used in total.", + "ScopeX": "Scope %s", + "Index": "Index", + "Usages": "Usages", + "Unused": "Unused", + "CreateNewSlot": "Increase the number of available Custom Variables slots", + "UsageDetails": "%s visits and %s actions since creation of this website.", + "CreatingCustomVariableTakesTime": "Creating a new custom variable slot can take a long time depending on the size of your database. Therefore it is only possible to do this via a command which needs to be executed on the command line.", + "CurrentAvailableCustomVariables": "Currently you can use up to %s Custom Variables per site.", + "ToCreateCustomVarExecute": "To create a new custom variable slot execute the following command within your Piwik installation: ", + "SlotsReportIsGeneratedOverTime": "Data for this report will be populated over time. It may take a day or two to see any data and a few weeks until the report is fully accurate." } } \ No newline at end of file diff --git a/plugins/CustomVariables/lang/it.json b/plugins/CustomVariables/lang/it.json index 3162fc90272245d940a963aeec1ae77b4b13b3cf..ec7b07a778fd4d66cb5c2cbd463eff9a33bff73c 100644 --- a/plugins/CustomVariables/lang/it.json +++ b/plugins/CustomVariables/lang/it.json @@ -6,6 +6,17 @@ "CustomVariablesReportDocumentation": "Questo report contiene le informazioni sulle variabili personalizzate. Clicca su un nome di variabile per visualizzarne la distribuzione dei valori. %s Per ulteriori informazioni sulle variabili personalizzate in generale, leggere la %sDocumentazione Variabili Personalizzatesu piwik.org %s", "PluginDescription": "Le variabili personalizzate sono coppie (nome, valore) che puoi assegnare ai visitatori o a una qualunque loro azione tramite API Javascript. Poi Piwik riporterà le visite, le pagine e le conversioni per questi nomi e valori. Guarda nel dettaglio le Variabili Personalizzate per ciascun utente nel Log Visitatori.<br>Necessario per utilizzare la funzione <a href=\"http:\/\/piwik.org\/docs\/ecommerce-analytics\/\">Statistiche Ecommerce<\/a>", "ScopePage": "ambito pagina", - "ScopeVisit": "ambito visita" + "ScopeVisit": "ambito visita", + "ManageDescription": "Questa panoramica mostra tutti gli slot di variabili personali e il loro utilizzo nel sito '%s'. I nomi in ciascuno slot vengono ordinati a seconda di quanto sono stati utilizzati in totale.", + "ScopeX": "Ambito %s", + "Index": "Indice", + "Usages": "Usi", + "Unused": "Inutilizzate", + "CreateNewSlot": "Aumenta il numero degli slot di variabili personali disponibili", + "UsageDetails": "%s visite e %s azioni dalla creazione di questo sito web.", + "CreatingCustomVariableTakesTime": "La creazione di un nuovo slot di variabili personali può richiedere un tempo lungo che dipende dalla dimensione del tuo database. Pertanto è possibile fare ciò solo tramite un comando che deve essere eseguito da riga di comando.", + "CurrentAvailableCustomVariables": "Attualmente puoi utilizzare fino a %s variabili personali per sito.", + "ToCreateCustomVarExecute": "Per creare un nuovo slot di variabili personali esegui il comando seguente nella tua installazione di Piwik.", + "SlotsReportIsGeneratedOverTime": "I dati per questo report saranno popolati nel tempo. Ciò può richiedere un giorno o due per vedere dei dati, e qualche settimana perché il report sia totalmente accurato." } } \ No newline at end of file diff --git a/plugins/CustomVariables/lang/pt-br.json b/plugins/CustomVariables/lang/pt-br.json index 172cf7eabb0d22240bbcb7496e473a61bc7e0eea..9f46739d4ada4c84eaf9d9aa9df5873432f56488 100644 --- a/plugins/CustomVariables/lang/pt-br.json +++ b/plugins/CustomVariables/lang/pt-br.json @@ -6,6 +6,17 @@ "CustomVariablesReportDocumentation": "Este relatório contém informações sobre as suas variáveis ​​personalizadas. Clique em um nome de variável para ver a distribuição dos valores. %s para mais informações sobre variáveis ​​personalizadas em geral, leia a documentação %sCustom Variáveis ​​em piwik.org%s", "PluginDescription": "Variáveis Personalizadas são pares (nome, valor) que você pode atribuir utilizando a API Javascript para visitantes ou qualquer ações deles. Então, Piwik reporta o número de visitas, páginas e conversões para cada um desses nomes e valores personalizados. Veja as Variáveis Personalizadas detalhadas para cada usuário e ação no Registro de Visitantes.<br \/> É necessário utilizar a função <a href=\"http:\/\/piwik.org\/docs\/ecommerce-analytics\/\">Ecommerce Analytics<\/a>!", "ScopePage": "página escopo", - "ScopeVisit": "visita escopo" + "ScopeVisit": "visita escopo", + "ManageDescription": "Esta visão geral mostra todos os compartimentos personalizados de variáveis ​ e seus usos para o website '%s'. Os nomes dentro de cada compartimento são ordenados por quantas vezes foram utilizados no total.", + "ScopeX": "Escopo %s", + "Index": "Ãndice", + "Usages": "Utilizações", + "Unused": "Não utilizado", + "CreateNewSlot": "Aumentar o número de compartimentos de Variáveis ​​Personalizadas disponÃveis", + "UsageDetails": "%s visitas e %s ações desde a criação deste website.", + "CreatingCustomVariableTakesTime": "Criar um novo compartimento de variável personalizada pode levar um longo tempo, dependendo do tamanho do seu banco de dados. Por isso, só é possÃvel fazer isso através de um comando que deve ser executado na linha de comando.", + "CurrentAvailableCustomVariables": "Atualmente você pode usar até %s Variáveis Personalizadas por site.", + "ToCreateCustomVarExecute": "Para criar um novo compartimento de variável personalizada execute o seguinte comando dentro da sua instalação Piwik:", + "SlotsReportIsGeneratedOverTime": "Os dados para este relatório serão preenchidos ao longo do tempo. Pode demorar um dia ou dois para ver todos os dados e algumas semanas até que o relatório seja totalmente preciso." } } \ No newline at end of file diff --git a/plugins/CustomVariables/lang/sk.json b/plugins/CustomVariables/lang/sk.json index f936be8fdd7001b19f017390c32bee405fec16e0..84445a23389462e0c0c72925e18802b0d67a5ac1 100644 --- a/plugins/CustomVariables/lang/sk.json +++ b/plugins/CustomVariables/lang/sk.json @@ -1,7 +1,10 @@ { "CustomVariables": { - "ColumnCustomVariableName": "Názov vlastnej premmennej", + "ColumnCustomVariableName": "Názov vlastnej premennej", "ColumnCustomVariableValue": "Hodnota vlastnej premennej", - "CustomVariables": "Vlastné premenné" + "CustomVariables": "Vlastné premenné", + "ScopeX": "Rozsah %s", + "Index": "Index", + "Unused": "Nepoužité" } } \ No newline at end of file diff --git a/plugins/CustomVariables/templates/manage.twig b/plugins/CustomVariables/templates/manage.twig new file mode 100644 index 0000000000000000000000000000000000000000..dc170ff2c97d30f203a9a1d1d398ba99a84c9a7d --- /dev/null +++ b/plugins/CustomVariables/templates/manage.twig @@ -0,0 +1,11 @@ +{% extends 'user.twig' %} + +{% block topcontrols %} + <div class="top_bar_sites_selector piwikTopControl"> + <div piwik-siteselector show-selected-site="true" class="sites_autocomplete"></div> + </div> +{% endblock %} + +{% block content %} + <div piwik-manage-custom-vars> +{% endblock %} \ No newline at end of file diff --git a/plugins/CustomVariables/tests/Integration/ModelTest.php b/plugins/CustomVariables/tests/Integration/ModelTest.php index 128e5b09ef4cec35f5a0fe75de9a4c9fd080f0b8..905a5f6a1da51510ac5cac9054f12bfeeb228e16 100644 --- a/plugins/CustomVariables/tests/Integration/ModelTest.php +++ b/plugins/CustomVariables/tests/Integration/ModelTest.php @@ -19,7 +19,7 @@ use Piwik\Tests\Framework\TestCase\IntegrationTestCase; */ class ModelTest extends IntegrationTestCase { - private static $cvarScopes = array('log_link_visit_action', 'log_visit', 'log_conversion'); + private static $cvarScopes = array('page', 'visit', 'conversion'); public function setUp() { diff --git a/plugins/CustomVariables/tests/System/expected/test_CustomVariablesSystemTest__CustomVariables.getCustomVariables_day.xml b/plugins/CustomVariables/tests/System/expected/test_CustomVariablesSystemTest__CustomVariables.getCustomVariables_day.xml index e504b8e8c7030ff4b297fd872e02c14e613a9ea9..766be4e97d9ced055897b37fc7465e0704bb2e63 100644 --- a/plugins/CustomVariables/tests/System/expected/test_CustomVariablesSystemTest__CustomVariables.getCustomVariables_day.xml +++ b/plugins/CustomVariables/tests/System/expected/test_CustomVariablesSystemTest__CustomVariables.getCustomVariables_day.xml @@ -17,6 +17,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_1</segment> <subtable> <row> @@ -56,6 +62,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_2</segment> <subtable> <row> @@ -95,6 +107,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_3</segment> <subtable> <row> @@ -134,6 +152,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_4</segment> <subtable> <row> @@ -173,6 +197,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_5</segment> <subtable> <row> @@ -212,6 +242,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>6</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_6</segment> <subtable> <row> @@ -251,6 +287,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>7</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_7</segment> <subtable> <row> @@ -290,6 +332,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>8</index> + </row> + </slots> <segment>customVariableName==Name_VISIT_8</segment> <subtable> <row> @@ -312,100 +360,148 @@ </row> </subtable> </row> - <row> - <label>Name_PAGE_1</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_1</segment> - <subtable> - <row> - <label>Val_PAGE1</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> - <row> - <label>Name_PAGE_2</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_2</segment> - <subtable> - <row> - <label>Val_PAGE2</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> - <row> - <label>Name_PAGE_3</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_3</segment> - <subtable> - <row> - <label>Val_PAGE3</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> - <row> - <label>Name_PAGE_4</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_4</segment> - <subtable> - <row> - <label>Val_PAGE4</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> - <row> - <label>Name_PAGE_5</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_5</segment> - <subtable> - <row> - <label>Val_PAGE5</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> - <row> - <label>Name_PAGE_6</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_6</segment> - <subtable> - <row> - <label>Val_PAGE6</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> - <row> - <label>Name_PAGE_7</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_7</segment> - <subtable> - <row> - <label>Val_PAGE7</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> - <row> - <label>Name_PAGE_8</label> - <nb_actions>1</nb_actions> - <segment>customVariableName==Name_PAGE_8</segment> - <subtable> - <row> - <label>Val_PAGE8</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> -</result> + <row> + <label>Name_PAGE_1</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_1</segment> + <subtable> + <row> + <label>Val_PAGE1</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> + <row> + <label>Name_PAGE_2</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_2</segment> + <subtable> + <row> + <label>Val_PAGE2</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> + <row> + <label>Name_PAGE_3</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>3</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_3</segment> + <subtable> + <row> + <label>Val_PAGE3</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> + <row> + <label>Name_PAGE_4</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_4</segment> + <subtable> + <row> + <label>Val_PAGE4</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> + <row> + <label>Name_PAGE_5</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_5</segment> + <subtable> + <row> + <label>Val_PAGE5</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> + <row> + <label>Name_PAGE_6</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>6</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_6</segment> + <subtable> + <row> + <label>Val_PAGE6</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> + <row> + <label>Name_PAGE_7</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>7</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_7</segment> + <subtable> + <row> + <label>Val_PAGE7</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> + <row> + <label>Name_PAGE_8</label> + <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>8</index> + </row> + </slots> + <segment>customVariableName==Name_PAGE_8</segment> + <subtable> + <row> + <label>Val_PAGE8</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> +</result> \ No newline at end of file diff --git a/plugins/CustomVariables/tests/UI/.gitignore b/plugins/CustomVariables/tests/UI/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f39be478e7a412cafbcc27f53a9875baaa92b664 --- /dev/null +++ b/plugins/CustomVariables/tests/UI/.gitignore @@ -0,0 +1,2 @@ +/processed-ui-screenshots +/screenshot-diffs \ No newline at end of file diff --git a/plugins/CustomVariables/tests/UI/CustomVariables_spec.js b/plugins/CustomVariables/tests/UI/CustomVariables_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..1e247fca56ec5664eaf7781dddbec0015013a1ae --- /dev/null +++ b/plugins/CustomVariables/tests/UI/CustomVariables_spec.js @@ -0,0 +1,25 @@ +/*! + * Piwik - free/libre analytics platform + * + * Screenshot integration tests. + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +describe("CustomVariables", function () { + this.timeout(0); + + this.fixture = "Piwik\\Plugins\\CustomVariables\\tests\\Fixtures\\VisitWithManyCustomVariables"; + + it('should show an overview of all used custom variables', function (done) { + expect.screenshot('manage').to.be.captureSelector('.pageWrap', function (page) { + page.load("?idSite=1&period=day&date=2010-01-03&module=CustomVariables&action=manage"); + }, done); + }); + + it('should be visible in the menu', function (done) { + expect.screenshot('link_in_menu').to.be.captureSelector('li:contains(Manage)', function (page) { + }, done); + }); +}); \ No newline at end of file diff --git a/plugins/CustomVariables/tests/UI/expected-ui-screenshots/CustomVariables_link_in_menu.png b/plugins/CustomVariables/tests/UI/expected-ui-screenshots/CustomVariables_link_in_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..39480bbf29159ce7837d0b24cdb64ada9e0f70d7 Binary files /dev/null and b/plugins/CustomVariables/tests/UI/expected-ui-screenshots/CustomVariables_link_in_menu.png differ diff --git a/plugins/CustomVariables/tests/UI/expected-ui-screenshots/CustomVariables_manage.png b/plugins/CustomVariables/tests/UI/expected-ui-screenshots/CustomVariables_manage.png new file mode 100644 index 0000000000000000000000000000000000000000..c03b7e379504e7703ca6ba08ff1dcb19094e6a45 Binary files /dev/null and b/plugins/CustomVariables/tests/UI/expected-ui-screenshots/CustomVariables_manage.png differ diff --git a/plugins/DBStats/lang/cs.json b/plugins/DBStats/lang/cs.json index bd3a1b434d2bdeb685bfea9a9321e8d89a8cd3b5..57074b7cdd97b846d1feb5a636522cf19dad427a 100644 --- a/plugins/DBStats/lang/cs.json +++ b/plugins/DBStats/lang/cs.json @@ -6,7 +6,7 @@ "EstimatedSize": "Odhadovaná velikost", "IndexSize": "Velikost indexu", "LearnMore": "Abyste lépe zjistili, jak Piwik zpracovává data a jak jej nastavit pro weby se stÅ™ednÃm a velkým provozem, podÃvejte se do dokumentace %s.", - "MainDescription": "Piwik ukládá vÅ¡echny vaÅ¡e data webové analýzy v MySQL databázi. Nynà tabulky Piwiku využÃvajà %s.", + "MainDescription": "Piwik ukládá vÅ¡echna vaÅ¡e data webové analýzy v MySQL databázi. Nynà tabulky Piwiku využÃvajà %s.", "MetricDataByYear": "Tabulky měřenà za rok", "MetricTables": "Tabulky měřenÃ", "OtherTables": "Ostatnà tabulky", diff --git a/plugins/DBStats/lang/ko.json b/plugins/DBStats/lang/ko.json index f56a86418f05da6a1642e7006036e32c95177d2f..84900837227aeea0b94ac43bb5489c3cdad508fb 100644 --- a/plugins/DBStats/lang/ko.json +++ b/plugins/DBStats/lang/ko.json @@ -10,6 +10,7 @@ "MetricDataByYear": "연별 통계 표", "MetricTables": "통계표", "OtherTables": "기타 표", + "PluginDescription": "ìžì„¸í•œ MySQL ë°ì´í„°ë² ì´ìФ 사용 ë³´ê³ ì„œë¥¼ ì œê³µí•©ë‹ˆë‹¤. 진단 ìƒí™©ì—서 ìŠˆí¼ ìœ ì €ë§Œì´ ì‚¬ìš©í• ìˆ˜ 있습니다.", "ReportDataByYear": "연별 ë³´ê³ í‘œ", "ReportTables": "ë³´ê³ í‘œ", "RowCount": "í–‰ 수", diff --git a/plugins/Dashboard/lang/cs.json b/plugins/Dashboard/lang/cs.json index 8db9ceb7cfecb3679d83b7e806cea04f617f5557..1a952809f1c810b4e13da1396bc5b331783b6949 100644 --- a/plugins/Dashboard/lang/cs.json +++ b/plugins/Dashboard/lang/cs.json @@ -13,7 +13,7 @@ "DefaultDashboard": "Výchozà nástÄ›nka - použÃváte výchozà rozvrženà nástÄ›nky", "DeleteWidgetConfirm": "Opravdu chcete odstranit tento widget z nástÄ›nky?", "EmptyDashboard": "Prázdná nástÄ›nka - vyberte si své oblÃbené widgety", - "LoadingWidget": "NaÄÃtám widget, prosÃm Äekejte...", + "LoadingWidget": "NaÄÃtánà widgetu, chvÃli strpenÃ...", "ManageDashboard": "Správa nástÄ›nky", "Maximise": "Maximalizovat", "Minimise": "Minimalizovat", @@ -21,6 +21,7 @@ "PluginDescription": "VaÅ¡e nástÄ›nka analýzy webu. PÅ™izpůsobte si vaÅ¡i nástÄ›nku pÅ™idánÃm nových widgetů, jejich pÅ™esunutÃm nebo zmÄ›nou rozvrženà sloupců. Každý uživatel může pÅ™izpůsobit svou vlastnà nástÄ›nku.", "RemoveDashboard": "Odstranit nástÄ›nku", "RemoveDashboardConfirm": "Opravdu chcete odstranit nástÄ›nku: %s?", + "RemoveDefaultDashboardNotPossible": "Výchozà nástÄ›nka nemůže být odstranÄ›na", "RenameDashboard": "PÅ™ejmenovat nástÄ›nku", "ResetDashboard": "Obnovit nástÄ›nku", "ResetDashboardConfirm": "Opravdu chcete obnovit nastavenà nástÄ›nky do továrnÃho stavu?", diff --git a/plugins/Dashboard/lang/de.json b/plugins/Dashboard/lang/de.json index 6b6a1a6db94f8744a387857913358dccb3e37a54..35cc204fec00c89a6d8798e53e2fb95143ad6fd3 100644 --- a/plugins/Dashboard/lang/de.json +++ b/plugins/Dashboard/lang/de.json @@ -21,6 +21,7 @@ "PluginDescription": "Ihr Web Analyse Dashboard. Personalisieren Sie Ihr Dashboard, in dem Sie neue Widgets hinzufügen, per Drag und Drop herumschieben, und das Dashboard Spaltenlayout ändern. Jeder Benutzer kann sein eigenes personalisiertes Dashboard verwalten.", "RemoveDashboard": "Dashboard entfernen", "RemoveDashboardConfirm": "Sind Sie sicher, dass Sie das Dashboard \"%s\" löschen möchten?", + "RemoveDefaultDashboardNotPossible": "Das Standard-Dashboard kann nicht entfernt werden.", "RenameDashboard": "Dashboard umbenennen", "ResetDashboard": "Dashboard zurücksetzen", "ResetDashboardConfirm": "Wollen Sie wirklich das Dashboardlayout auf die Standardeinstellungen zurücksetzen?", diff --git a/plugins/Dashboard/lang/el.json b/plugins/Dashboard/lang/el.json index 0f03e52550d612dab6744eaec214da2697205975..965d5329d1df757cfc590d560b21e647deb08614 100644 --- a/plugins/Dashboard/lang/el.json +++ b/plugins/Dashboard/lang/el.json @@ -21,6 +21,7 @@ "PluginDescription": "Ο κεντÏικός πίνακας Αναλυτικών ΙστοÏ. Î ÏοσαÏμόστε τον πίνακα με την Ï€Ïοσθήκη νÎων γÏαφικών συστατικών, σÏÏτε και αφήστε τα όπου θÎλετε και αλλάξτε την διάταξη στήλης του πίνακα. Κάθε χÏήστης μποÏεί να διαχειÏίζεται τον δικό του πίνακα.", "RemoveDashboard": "ΑπομάκÏυνση κεντÏÎ¹ÎºÎ¿Ï Ï€Î¯Î½Î±ÎºÎ±", "RemoveDashboardConfirm": "ΘÎλετε, σίγουÏα, να απομακÏÏνετε τον ΚεντÏικό Πίνακα «%s»;", + "RemoveDefaultDashboardNotPossible": "Ο Ï€ÏοκαθοÏισμÎνος πίνακας εÏγαλείων δεν είναι δυνατό να αφαιÏεθεί", "RenameDashboard": "Μετονομασία κεντÏÎ¹ÎºÎ¿Ï Ï€Î¯Î½Î±ÎºÎ±", "ResetDashboard": "ΕπαναφοÏά κεντÏÎ¹ÎºÎ¿Ï Ï€Î¯Î½Î±ÎºÎ±", "ResetDashboardConfirm": "ΘÎλετε σίγουÏα να επαναφÎÏετε τον κεντÏικό σας πίνακα στις Ï€ÏοεπιλεγμÎνες ΜικÏοεφαÏμογÎÏ‚;", diff --git a/plugins/Dashboard/lang/fr.json b/plugins/Dashboard/lang/fr.json index 933c82bf36db9622f5f64fe569e96d9cc06b3c6c..1dc3fdb4a153809c981d8150d25440bf20eac402 100644 --- a/plugins/Dashboard/lang/fr.json +++ b/plugins/Dashboard/lang/fr.json @@ -21,6 +21,7 @@ "PluginDescription": "Votre tableau de bord, personnalisez le en ajoutant des widgets, en les déplaçant et en modifiant la disposition des colonnes. Chaque utilisateur possède son propre tableau de bord.", "RemoveDashboard": "Supprimer le tableau de bord", "RemoveDashboardConfirm": "Êtes vous sûr(e) de vouloir supprimer le tableau de bord \"%s\" ?", + "RemoveDefaultDashboardNotPossible": "Le tableau de bord par défaut ne peut pas être supprimé", "RenameDashboard": "Renommer le tableau de bord", "ResetDashboard": "Restaurer le tableau de bord", "ResetDashboardConfirm": "Voulez-vous vraiment restaurer votre tableau de bord avec les widgets par défaut ?", diff --git a/plugins/Dashboard/lang/it.json b/plugins/Dashboard/lang/it.json index b97e35430d5ef0e485aa5bbabdf2212c70597dcb..8105f3f90f386ed24af74f255cdc2fba6651247e 100644 --- a/plugins/Dashboard/lang/it.json +++ b/plugins/Dashboard/lang/it.json @@ -21,6 +21,7 @@ "PluginDescription": "La tua Dashboard delle Statistiche Web. Personalizzala aggiungendo nuovi widgets, trascinandoli e spostandoli e cambiando l'aspetto delle colonne. Ciascun utente può gestire una propria dashboard.", "RemoveDashboard": "Rimuovi la dashboard", "RemoveDashboardConfirm": "Sei sicuro di voler rimuovere la dashboard \"%s\"?", + "RemoveDefaultDashboardNotPossible": "La dashboard predefinita non può essere eliminata", "RenameDashboard": "Rinomina dashboard", "ResetDashboard": "Reimposta la dashboard", "ResetDashboardConfirm": "Sei sicuro di voler ripristinare il layout della dashboard alla selezione di widget predefinita?", diff --git a/plugins/Dashboard/lang/ja.json b/plugins/Dashboard/lang/ja.json index 10c0b763d9d3cfd229374d9c13fae5792cda75fd..f673fd143f008aad557362d5d53004d09fa35259 100644 --- a/plugins/Dashboard/lang/ja.json +++ b/plugins/Dashboard/lang/ja.json @@ -21,6 +21,7 @@ "PluginDescription": "ユーザー㮠Web Analytics ã®ãƒ€ãƒƒã‚·ãƒ¥ ボード。新ã—ã„ã‚¦ã‚£ã‚¸ã‚§ãƒƒãƒˆã‚’è¿½åŠ ã™ã‚‹ã“ã¨ã«ã‚ˆã£ã¦ã€ãƒ€ãƒƒã‚·ãƒ¥ ボードをカスタマイズã€ãƒ‰ãƒ©ãƒƒã‚° アンドドãƒãƒƒãƒ—ã—ã§ãƒ€ãƒƒã‚·ãƒ¥ ボードã®ã‚«ãƒ©ãƒ ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’変更ã—ã¾ã™ã€‚å„ユーザーã¯ã€ç‹¬è‡ªã®ã‚«ã‚¹ã‚¿ãƒ ダッシュ ボードを管ç†ã§ãã¾ã™ã€‚", "RemoveDashboard": "ダッシュボードã®å‰Šé™¤", "RemoveDashboardConfirm": "本当ã«ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ \"%s\" を削除ã—ã¾ã™ã‹ï¼Ÿ", + "RemoveDefaultDashboardNotPossible": "既定ã®ãƒ€ãƒƒã‚·ãƒ¥ ボードを削除ã§ãã¾ã›ã‚“。", "RenameDashboard": "ダッシュボードã®å称変更", "ResetDashboard": "ダッシュボードã®ãƒªã‚»ãƒƒãƒˆ", "ResetDashboardConfirm": "ダッシュボードã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’リセットã—ã¦ãƒ‡ãƒ•ォルトã®ã‚¦ã‚£ã‚¸ã‚§ãƒƒãƒˆã«æˆ»ã—ã¾ã™ã‹ï¼Ÿ", diff --git a/plugins/Dashboard/lang/ko.json b/plugins/Dashboard/lang/ko.json index 535fe103191ffb332b16a95ac013864cd8341777..6c4dd23b1ce3070c188a465552e576356cf4930c 100644 --- a/plugins/Dashboard/lang/ko.json +++ b/plugins/Dashboard/lang/ko.json @@ -21,6 +21,7 @@ "PluginDescription": "ë‹¹ì‹ ì˜ ì‚¬ì´íŠ¸ë¥¼ ë¶„ì„한 대시보드입니다. 드래그 앤 드ë¡ìœ¼ë¡œ 새로운 ìœ„ì ¯ì„ ì¶”ê°€í•˜ê±°ë‚˜ 대시보드 ë ˆì´ì•„ì›ƒì„ ë°”ê¾¸ëŠ” ê¸°ëŠ¥ì„ í†µí•´ ë‹¹ì‹ ë§Œì˜ ëŒ€ì‹œë³´ë“œë¥¼ 꾸며보세요. ëª¨ë“ ì‚¬ìš©ìžë“¤ì€ ìžì‹ ë§Œì˜ ëŒ€ì‹œë³´ë“œë¥¼ 가질 수 있습니다.", "RemoveDashboard": "대시보드 ì‚ì œ", "RemoveDashboardConfirm": "ì •ë§ ëŒ€ì‹œë³´ë“œ \"%s\"를 ì‚ì œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", + "RemoveDefaultDashboardNotPossible": "기본 대시보드는 ì‚ì œí• ìˆ˜ 없습니다.", "RenameDashboard": "대시보드 ì´ë¦„ 변경", "ResetDashboard": "대시보드 ìž¬ì„¤ì •", "ResetDashboardConfirm": "ëŒ€ì‹œë³´ë“œì˜ ë ˆì´ì•„ì›ƒì„ ìž¬ì„¤ì •í•˜ì—¬ 기본 ìœ„ì ¯ìœ¼ë¡œ ë³µì›í•˜ì‹œê² 습니까?", diff --git a/plugins/Dashboard/lang/pt-br.json b/plugins/Dashboard/lang/pt-br.json index 1ec93d487cbd5780214b2022023dde670cc1559d..e913ffd254735adea01cd88d2f227a08c22bc65b 100644 --- a/plugins/Dashboard/lang/pt-br.json +++ b/plugins/Dashboard/lang/pt-br.json @@ -21,6 +21,7 @@ "PluginDescription": "Seu Painel de Análise da Rede. Personalize seu painel adicionando novos widgets, arrastando para suas posições, e mudando o leiaute das colunas do painel. Cada usuário pode gerenciar seus próprios painéis personalizados.", "RemoveDashboard": "Remover painel", "RemoveDashboardConfirm": "Tem certeza de que deseja remover o painel \"%s\"?", + "RemoveDefaultDashboardNotPossible": "O painel padrão não pode ser removido", "RenameDashboard": "Renomear painel", "ResetDashboard": "Resetar o painel", "ResetDashboardConfirm": "Tem certeza de que deseja redefinir o layout do painel para a seleção Widgets padrão?", diff --git a/plugins/Dashboard/lang/sk.json b/plugins/Dashboard/lang/sk.json index ddd7c84c40054442ac6153172b35389b6b921aee..9382122befd98e5541e79605a0b32997b07e451c 100644 --- a/plugins/Dashboard/lang/sk.json +++ b/plugins/Dashboard/lang/sk.json @@ -21,6 +21,7 @@ "PluginDescription": "VaÅ¡a nástenka webovej analýzy. Prispôsobte si svoj panel pridanÃm nových miniaplikáciÃ, popresúvajte ich, a zmeňte rozvrhnutie stĺpcov panela. Každý použÃvateľ môže spravovaÅ¥ svoju vlastnú nástenku.", "RemoveDashboard": "OdstrániÅ¥ nástenku", "RemoveDashboardConfirm": "Naozaj chcete odstrániÅ¥ panel \"%s\"?", + "RemoveDefaultDashboardNotPossible": "Å tandardnú nástenku nie je možné odstrániÅ¥.", "RenameDashboard": "PremenovaÅ¥ nástenku", "ResetDashboard": "ResetovaÅ¥ nástenku", "ResetDashboardConfirm": "Naozaj chcete resetovaÅ¥ rozvrhnutie vaÅ¡ej nástenky na výber prednastavených miniaplikáciÃ?", diff --git a/plugins/Dashboard/lang/tr.json b/plugins/Dashboard/lang/tr.json index f8ef1520828e27465f6b8806c2e5593ac492b63b..645b2c2f13ec25c2d4ad3ef0d333cbcd621a0008 100644 --- a/plugins/Dashboard/lang/tr.json +++ b/plugins/Dashboard/lang/tr.json @@ -19,6 +19,7 @@ "NotUndo": "Bu eylemi geri alamazsınız.", "RemoveDashboard": "Paneli kaldır", "RemoveDashboardConfirm": "\"%s\" panelini kaldırmak istediÄŸinize emin misiniz?", + "RemoveDefaultDashboardNotPossible": "Varsayılan pano silinemez", "RenameDashboard": "Panel yeniden adlandır", "ResetDashboard": "Paneli sıfırla", "ResetDashboardConfirm": "Kontrol paneli ÅŸablonunuzu varsayılan widget seçimlerine sıfırlamak istediÄŸinizden emin misiniz?", diff --git a/plugins/DevicePlugins/lang/cs.json b/plugins/DevicePlugins/lang/cs.json index 759e2e487ce85b39634638e4ffe1dc24714944c8..3854a6916a3522cc8ba75b84495d93b32a2cf057 100644 --- a/plugins/DevicePlugins/lang/cs.json +++ b/plugins/DevicePlugins/lang/cs.json @@ -3,7 +3,7 @@ "BrowserWithNoPluginsEnabled": "%1$s bez povolených zásuvných modulů", "BrowserWithPluginsEnabled": "%1$s s povolenými zásuvnými moduly %2$s", "PluginDescription": "Hlásà podporované zásuvné moduly v prohlÞeÄÃch návÅ¡tÄ›vnÃků.", - "PluginDetectionDoesNotWorkInIE": "Poznámka: Detekce zásuvných modulů nepracuje v prohlÞeÄi Interet Explorer. Toto hlášenà je založeno na ostatnÃch prohlÞeÄÃch", + "PluginDetectionDoesNotWorkInIE": "Poznámka: Detekce zásuvných modulů nepracuje v prohlÞeÄi Interet Explorer. Toto hlášenà je založeno pouze na jiných prohlÞeÄÃch", "WidgetPlugins": "Seznam zásuvných modulů", "WidgetPluginsDocumentation": "Toto hlášenà zobrazuje zásuvné moduly, které mÄ›li vaÅ¡i návÅ¡tÄ›vnÃci povoleny. Tato informace může být důležitá pÅ™i rozhodovánà o tom, jakým způsobem prezentovat obsah." } diff --git a/plugins/DevicesDetection/lang/ja.json b/plugins/DevicesDetection/lang/ja.json index 071d79b71368d76937a4f58fb339e14a7ee7cd33..b53d32e6228ad1bd2bac418fa0e9d6606f1790f3 100644 --- a/plugins/DevicesDetection/lang/ja.json +++ b/plugins/DevicesDetection/lang/ja.json @@ -32,8 +32,10 @@ "PluginDescription": "ブランド ( メーカー ) ã€ãƒ¢ãƒ‡ãƒ« ( デãƒã‚¤ã‚¹ ãƒãƒ¼ã‚¸ãƒ§ãƒ³ ) ã€ãƒ‡ãƒã‚¤ã‚¹ã®ç¨®é¡ž ( テレビã€ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã€ã‚¹ãƒžãƒ¼ãƒˆ フォンã€ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ— ) ãªã©ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ デãƒã‚¤ã‚¹ã«é–¢ã™ã‚‹æ‹¡å¼µæƒ…å ±ã‚’æä¾›ã—ã¾ã™ã€‚", "SmartDisplay": "スマートディスプレイ", "Smartphone": "スマートフォン", + "PortableMediaPlayer": "ãƒãƒ¼ã‚¿ãƒ–ルメディアプレーヤー", "Devices": "デãƒã‚¤ã‚¹", "Tablet": "タブレット", + "Phablet": "ファブレット", "TV": "TV", "UserAgent": "ユーザーエージェント", "WidgetBrowsers": "ブラウザ", diff --git a/plugins/DevicesDetection/lang/ko.json b/plugins/DevicesDetection/lang/ko.json index 865556c18b7f7f46b52d7bb5819cfd0e6ffd4227..55711fbbe65e42a9cbf42a6e1031363b8b866893 100644 --- a/plugins/DevicesDetection/lang/ko.json +++ b/plugins/DevicesDetection/lang/ko.json @@ -1,15 +1,43 @@ { "DevicesDetection": { - "BrowserEngine": "브ë¼ìš°ì €", + "BrowserEngine": "브ë¼ìš°ì € 엔진", "BrowserEngineDocumentation": "ì´ ì°¨íŠ¸ëŠ” 방문ìžì˜ 브ë¼ìš°ì €ë¥¼ ì œí’ˆêµ°ë³„ë¡œ 표시합니다. %s 웹개발ìžì—게 가장 중요한 ì •ë³´ëŠ” 사용ìžì˜ ë Œë”ë§ ì—”ì§„ 종류입니다. ì—”ì§„ì˜ ì´ë¦„ê³¼ 괄호 ì•ˆì— ì¼ë°˜ì ì¸ í•´ë‹¹ 브ë¼ìš°ì € ì´ë¦„ì„ í‘œì‹œí•˜ê³ ìžˆìŠµë‹ˆë‹¤.", + "BrowserEngines": "브ë¼ìš°ì € 엔진들", "BrowserFamily": "브ë¼ìš°ì € 타입", - "Browsers": "브ë¼ìš°ì €", + "Browsers": "브ë¼ìš°ì €ë“¤", "BrowserVersion": "브ë¼ìš°ì € ë²„ì „", + "BrowserVersions": "브ë¼ìš°ì € ë²„ì „ë“¤", + "Camera": "ì¹´ë©”ë¼", + "CarBrowser": "ìžë™ì°¨ 브ë¼ìš°ì €", + "Software": "소프트웨어", "ColumnBrowser": "브ë¼ìš°ì €", - "ColumnOperatingSystem": "ìš´ì˜ì²´ì œ", + "ColumnOperatingSystem": "ìš´ì˜ ì²´ì œ", + "ColumnOperatingSystemVersion": "ìš´ì˜ ì²´ì œ ë²„ì „", + "Console": "콘솔", + "dataTableLabelBrands": "브랜드", + "dataTableLabelModels": "모ë¸", + "dataTableLabelSystemVersion": "ìš´ì˜ ì²´ì œ ë²„ì „", "dataTableLabelTypes": "ìœ í˜•", + "Device": "기기장치", + "DeviceBrand": "기기장치 브랜드", + "DeviceDetection": "기기장치 íƒì§€", + "DeviceModel": "기기장치 모ë¸", + "DevicesDetection": "ë°©ë¬¸ìž ê¸°ê¸°ìž¥ì¹˜ë“¤", + "DeviceType": "기기장치 타입", + "FeaturePhone": "피처 í°", + "OperatingSystemFamilies": "ìš´ì˜ ì²´ì œ ì œí’ˆêµ°ë“¤", "OperatingSystemFamily": "ìš´ì˜ ì²´ì œ ì œí’ˆêµ°", "OperatingSystems": "ìš´ì˜ì²´ì œ", + "OperatingSystemVersions": "ìš´ì˜ ì²´ì œ ë²„ì „ë“¤", + "PluginDescription": "ìœ ì €ì˜ ê¸°ê¸°ìž¥ì¹˜ì— ê´€í•˜ì—¬ 좀 ë” ìžì„¸í•œ ì •ë³´ë¥¼ ì œê³µí•©ë‹ˆë‹¤. ì´ëŠ” 브랜드(ìƒì‚°ìž), 모ë¸(기기장치 ë²„ì „), 타입(í…”ë ˆë¹„ì „, 콘솔, 스마트í°, ë°ìФí¬íƒ‘ 컴퓨터 등) 외 여러 ì •ë³´ë¥¼ í¬í•¨í•©ë‹ˆë‹¤.", + "SmartDisplay": "스마트 ë””ìŠ¤í”Œë ˆì´", + "Smartphone": "스마트í°", + "PortableMediaPlayer": "휴대용 미디어 í”Œë ˆì´ì–´", + "Devices": "기기장치들", + "Tablet": "태블릿", + "Phablet": "패블릿", + "TV": "í…”ë ˆë¹„ì „", + "UserAgent": "ì‚¬ìš©ìž ì—ì´ì „트", "WidgetBrowsers": "ë°©ë¬¸ìž ë¸Œë¼ìš°ì €", "WidgetBrowsersDocumentation": "사용ìžê°€ ì–´ë–¤ 브ë¼ìš°ì €ë¥¼ ì‚¬ìš©í•˜ëŠ”ì§€ì— ëŒ€í•œ ë³´ê³ ì„œìž…ë‹ˆë‹¤. ê° ë¸Œë¼ìš°ì €ì˜ ë²„ì „ì€ ë³„ë„로 기재ë˜ì–´ 있습니다." } diff --git a/plugins/DevicesDetection/lang/tr.json b/plugins/DevicesDetection/lang/tr.json index 15b3d61a9f56fa8ee7aa213405a3ba98516164d6..affb773e9020f806001b1dc0629bf55fb689b5c1 100644 --- a/plugins/DevicesDetection/lang/tr.json +++ b/plugins/DevicesDetection/lang/tr.json @@ -7,8 +7,10 @@ "BrowserVersions": "Tarayıcı versiyonları", "Camera": "Kamera", "CarBrowser": "Araba tarayıcısı", + "Software": "Yazılım", "ColumnBrowser": "Tarayıcı", "ColumnOperatingSystem": "İşletim sistemi", + "ColumnOperatingSystemVersion": "İşletim Sistemi Versiyonu", "Console": "Konsol", "dataTableLabelBrands": "Marka", "dataTableLabelModels": "Model", @@ -21,6 +23,7 @@ "DevicesDetection": "Ziyaretçi Cihazları", "DeviceType": "Cihaz tipi", "OperatingSystemFamilies": "İşletim Sistemi aileleri", + "OperatingSystemFamily": "İşletim Sistemi Ailesi", "OperatingSystems": "İşletim sistemleri", "OperatingSystemVersions": "İşletim Sistemi versiyonları", "SmartDisplay": "Akıllı görüntüleme", diff --git a/plugins/Ecommerce/config/config.php b/plugins/Ecommerce/config/config.php deleted file mode 100644 index 3431748e415b04f0415c692d4c417932994cb493..0000000000000000000000000000000000000000 --- a/plugins/Ecommerce/config/config.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php - -return array( - - 'tracker.request.processors' => DI\add(array( - DI\get('Piwik\Plugins\Ecommerce\Tracker\EcommerceRequestProcessor'), - )), - -); diff --git a/plugins/Ecommerce/lang/ja.json b/plugins/Ecommerce/lang/ja.json index 62ccf9fe7dafc8c502557839b9e47c06db866ae3..822234b79565747e6faf40dfa118749d7e714370 100644 --- a/plugins/Ecommerce/lang/ja.json +++ b/plugins/Ecommerce/lang/ja.json @@ -1,5 +1,8 @@ { "Ecommerce": { - "Sales": "売り上ã’" + "PluginDescription": "E コマースã§ã¯ã€ã„ã¤ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒã‚«ãƒ¼ãƒˆã«è£½å“ã‚’è¿½åŠ ã—ã€ã„㤠E コマース販売ã«çµã³ã¤ã„ãŸã‹ã€ã‚’追跡ã§ãã¾ã™ã€‚製å“ã€è£½å“ã®ã‚«ãƒ†ã‚´ãƒªãƒ“ューã€ãŠã‚ˆã³æ”¾æ£„ã•れãŸã‚«ãƒ¼ãƒˆã‚‚追跡ã§ãã¾ã™ã€‚", + "Sales": "売り上ã’", + "SalesBy": "%s 別売り上ã’高", + "SalesAdjective": "売り上㒠%s" } } \ No newline at end of file diff --git a/plugins/Events/Actions/ActionEvent.php b/plugins/Events/Actions/ActionEvent.php index 9921c8d39bd6a2628f8744abf2787558139764c0..5106ec6092c49c26f6a338229b1170f385d51eb9 100644 --- a/plugins/Events/Actions/ActionEvent.php +++ b/plugins/Events/Actions/ActionEvent.php @@ -60,9 +60,17 @@ class ActionEvent extends Action protected function getActionsToLookup() { - return array( - 'idaction_url' => $this->getUrlAndType() - ); + $actionUrl = false; + + $url = $this->getActionUrl(); + + if (!empty($url)) { + // normalize urls by stripping protocol and www + $url = Tracker\PageUrl::normalizeUrl($url); + $actionUrl = array($url['url'], $this->getActionType(), $url['prefixId']); + } + + return array('idaction_url' => $actionUrl); } // Do not track this Event URL as Entry/Exit Page URL (leave the existing entry/exit) diff --git a/plugins/Events/lang/ja.json b/plugins/Events/lang/ja.json index 4304953ddf9591342b379935ff41591280ea8c5b..10051096aadbb9711401ce0e6bb75290fac46f10 100644 --- a/plugins/Events/lang/ja.json +++ b/plugins/Events/lang/ja.json @@ -1,5 +1,6 @@ { "Events": { + "PluginDescription": "イベントを追跡ã—ã€ãƒ“ジターアクティビティã®ãƒ¬ãƒãƒ¼ãƒˆã‚’å–å¾—ã—ã¾ã™ã€‚", "AvgEventValue": "イベントã®å¹³å‡å€¤: %s", "AvgValue": "å¹³å‡å€¤", "AvgValueDocumentation": "ã“ã®ã‚¤ãƒ™ãƒ³ãƒˆã®ã™ã¹ã¦ã®å€¤ã®å¹³å‡å€¤", @@ -14,6 +15,7 @@ "EventsWithValue": "値をæŒã¤ã‚¤ãƒ™ãƒ³ãƒˆ", "EventsWithValueDocumentation": "イベントã®å€¤ãŒè¨å®šã•れãŸã‚¤ãƒ™ãƒ³ãƒˆæ•°", "EventValue": "イベントã®å€¤", + "EventValueTooltip": "ç·ã‚¤ãƒ™ãƒ³ãƒˆå€¤ã¯ %s ä»¶ã®ã‚¤ãƒ™ãƒ³ãƒˆå€¤ã®åˆè¨ˆã§ã™ã€‚ %s 最å°å€¤ã¯ %s ã€æœ€å¤§å€¤ã¯ %s ã§ã™ 。", "MaxValue": "最大値", "MaxValueDocumentation": "ã“ã®ã‚¤ãƒ™ãƒ³ãƒˆã®æœ€å¤§å€¤", "MinValue": "最å°å€¤", diff --git a/plugins/Events/lang/sk.json b/plugins/Events/lang/sk.json index 396cf2c31972b4b0593baa99ac761d575a621663..a45b722eb4b27b2865e77a6af2835ebd9e8bd2d6 100644 --- a/plugins/Events/lang/sk.json +++ b/plugins/Events/lang/sk.json @@ -1,5 +1,14 @@ { "Events": { - "AvgValue": "Priemerná hodnota" + "PluginDescription": "Sledovanie Udalostà a zÃskanie reportu ohľadom aktivity vaÅ¡ich návÅ¡tevnÃkov.", + "AvgValue": "Priemerná hodnota", + "Events": "Udalosti", + "EventsWithValue": "Udalosti s hodnotou", + "EventsWithValueDocumentation": "PoÄet udalostÃ, kde bola nastavená hodnota Udalosti", + "EventValueTooltip": "Hodnota Udalostà celom je suma %s hodnôt udalostà %s medzi minimom %s a maximom %s.", + "TopEvents": "Top Udalosti", + "TotalEvents": "Udalosti celkom", + "TotalEventsDocumentation": "Celkový poÄet udalostÃ", + "ViewEvents": "ZobraziÅ¥ udalosti" } } \ No newline at end of file diff --git a/plugins/ExamplePlugin/tests/travis/addons.apt.packages.yml b/plugins/ExamplePlugin/tests/travis/addons.apt.packages.yml new file mode 100644 index 0000000000000000000000000000000000000000..db3733500a49938a4a3fd6fde753ae63825b5d42 --- /dev/null +++ b/plugins/ExamplePlugin/tests/travis/addons.apt.packages.yml @@ -0,0 +1,3 @@ +- custom apt package +- another custom apt package + diff --git a/plugins/ExamplePlugin/tests/travis/addons.apt.sources.yml b/plugins/ExamplePlugin/tests/travis/addons.apt.sources.yml new file mode 100644 index 0000000000000000000000000000000000000000..3504520e3c85097a36fd379ec12edb79815134fe --- /dev/null +++ b/plugins/ExamplePlugin/tests/travis/addons.apt.sources.yml @@ -0,0 +1 @@ +- custom apt source \ No newline at end of file diff --git a/plugins/Feedback/lang/cs.json b/plugins/Feedback/lang/cs.json index 42d124d0a4c7b4055b5153c8756965665348b6d4..935e9913b4af72d8b06bcbcd2e6ea1691a5d3719 100644 --- a/plugins/Feedback/lang/cs.json +++ b/plugins/Feedback/lang/cs.json @@ -5,11 +5,11 @@ "IWantTo": "Chci:", "LearnWaysToParticipate": "NauÄit způsoby jak %s spolupracovat %s", "ManuallySendEmailTo": "ProsÃm poÅ¡lete ruÄnÄ› zprávu", - "PluginDescription": "PoÅ¡lete tým Piwiku vaÅ¡i odezvu. PodÄ›lte se o své návrhy a nápady a pomozte nám, aby se Piwi stal nejlepšà analytickou platformou vůbec.", + "PluginDescription": "PoÅ¡lete tým Piwiku vaÅ¡i odezvu. PodÄ›lte se o své návrhy a nápady a pomozte nám, aby se Piwik stal nejlepšà analytickou platformou vůbec.", "PrivacyClaim": "Piwik respektuje vaÅ¡e %1$ssoukromÃ%2$s a dává vám plnou kontrolu nad vaÅ¡imi daty.", "RateFeatureLeaveMessageDislike": "Je nám lÃto, že se vám to nelÃbÃ. ŘeknÄ›te nám, jak se můžeme zlepÅ¡it.", "RateFeatureLeaveMessageLike": "Jsme rádi, že se vám to lÃbÃ. ŘeknÄ›te nám, co se vám lÃbà nejvÃc, nebo jestli máte nÄ›jaký návrh na novou funkci.", - "RateFeatureSendFeedbackInformation": "Piwik platforma nám (týmu Piwiku) poÅ¡le e-mail s vašà e-mailovou adresou, abychom vás v pÅ™ÃpadÄ› otázek mohli kontaktovat.", + "RateFeatureSendFeedbackInformation": "Piwik platforma nám (týmu Piwiku) poÅ¡le zprávu s vašà emailovou adresou, abychom vás v pÅ™ÃpadÄ› otázek mohli kontaktovat.", "RateFeatureThankYouTitle": "DÄ›kujeme za ohodnocenà %s.", "RateFeatureTitle": "LÃbà se vám vlastnost %s? OhodnoÅ¥te ji a zanechte komentář", "SendFeedback": "Odeslat odezvu", @@ -22,8 +22,8 @@ "PiwikProIntro": "Piwik Pro poskytuje konzultace s experty pro ty, kteřà hostujà Piwik na vlastnà infrastruktuÅ™e.", "PiwikProOfferIntro": "NaÅ¡e nabÃdka obsahuje", "PiwikProReviewPiwikSetup": "Kontrolu vaÅ¡eho nastavenà Piwik", - "PiwikProOptimizationMaintenance": "Služby optimalizace & údržby Piwiku", - "PiwikProPhoneEmailSupport": "Telefonická a e-mailová podpora", + "PiwikProOptimizationMaintenance": "Služby optimalizace a údržby Piwiku", + "PiwikProPhoneEmailSupport": "Telefonická a emailová podpora", "PiwikProTraining": "Uživatelská, technická a vývojářská Å¡kolenÃ", "PiwikProPremiumFeatures": "Prémiové funkce", "PiwikProCustomDevelopment": "Služby vlastnÃho vývoje", diff --git a/plugins/Feedback/lang/fr.json b/plugins/Feedback/lang/fr.json index 9bfff5b40f0b3526b6a6c1970d0e4dae629da51c..b992c5cfbc901565dca228c4565e9ac26f0c5ee1 100644 --- a/plugins/Feedback/lang/fr.json +++ b/plugins/Feedback/lang/fr.json @@ -1,7 +1,7 @@ { "Feedback": { "DoYouHaveBugReportOrFeatureRequest": "Avez-vous un bug à rapporter ou une fonctionnalité à demander ?", - "HowToCreateTicket": "Veuillez consulter les recommandations sur la rédaction d'un bon %1$srapport de bug%2$s ou %3$sdemande de fonctionnalité%4$s. Puis s'enregistrer ou se connecter sur %5$snotre système de suivit des incidents%6$s et créer un %7$snouvel incident%8$s.", + "HowToCreateTicket": "Veuillez consulter les recommandations sur la rédaction d'un bon %1$srapport de bug%2$s ou %3$sdemande de fonctionnalité%4$s. Puis s'enregistrer ou se connecter sur %5$snotre système de suivi des incidents%6$s et créer un %7$snouvel incident%8$s.", "IWantTo": "Je veux:", "LearnWaysToParticipate": "Renseignez vous sur les manières dont vous pouvez %s participer%s", "ManuallySendEmailTo": "Merci d'envoyer manuellement votre message à ", diff --git a/plugins/Feedback/lang/ja.json b/plugins/Feedback/lang/ja.json index c66634eb4348ea9184537f075a416bd13783c28e..1819573a93a68ad3b951159a3602e1424b4079b1 100644 --- a/plugins/Feedback/lang/ja.json +++ b/plugins/Feedback/lang/ja.json @@ -17,12 +17,14 @@ "TopLinkTooltip": "ã‚ãªãŸã®æ„見をãŠçŸ¥ã‚‰ã›ãã ã•ã„。ã¾ãŸã¯ã€ãƒ—ãƒãƒ•ェッショナルサãƒãƒ¼ãƒˆã‚’リクエストã—ã¦ãã ã•ã„。", "ViewAnswersToFAQ": "%s Frequently Asked Questions %s ã¸ã®å›žç”ã‚’ã”覧ãã ã•ã„。", "ViewUserGuides": "Piwik ã®è¨å®šæ–¹æ³•ã¨ã€åŠ¹æžœçš„ãªãƒ‡ãƒ¼ã‚¿åˆ†æžæ–¹æ³•ã¯ã€%1$s user guides %2$s ã‚’ã”確èªãã ã•ã„。", + "CommunityHelp": "コミュニティヘルプ", "ProfessionalHelp": "プãƒãƒ•ェッショナルヘルプ", "PiwikProIntro": "Piwik PRO ã¯ã€å°‚門家ã®ã‚µãƒãƒ¼ãƒˆã¨ Piwik 独自ã®ã‚¤ãƒ³ãƒ•ラストラクãƒãƒ£ä¸Šã§ãƒ›ã‚¹ãƒˆã™ã‚‹ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã¸ã®ã‚³ãƒ³ã‚µãƒ«ãƒ†ã‚£ãƒ³ã‚°ã‚’æä¾›ã—ã¾ã™ã€‚", "PiwikProOfferIntro": "当社オファーã«ã¯ä»¥ä¸‹ãŒå«ã¾ã‚Œã¾ã™", "PiwikProReviewPiwikSetup": "Piwik セットアップã®ãƒ¬ãƒ“ュー", "PiwikProOptimizationMaintenance": "Piwikiã®æœ€é©åŒ–ã¨ä¿å®ˆã®ã‚µãƒ¼ãƒ“ス", "PiwikProPhoneEmailSupport": "電話ã¨Eメールã®ã‚µãƒãƒ¼ãƒˆ", + "PiwikProTraining": "ユーザーåŠã³æŠ€è¡“開発者ã®ãƒˆãƒ¬ãƒ¼ãƒ‹ãƒ³ã‚°", "PiwikProPremiumFeatures": "プレミア機能", "PiwikProCustomDevelopment": "カスタム開発サービス", "PiwikProAnalystConsulting": "アナリストã®ã‚³ãƒ³ã‚µãƒ«ãƒ†ã‚£ãƒ³ã‚°ã‚µãƒ¼ãƒ“ス", diff --git a/plugins/Feedback/lang/ko.json b/plugins/Feedback/lang/ko.json index ed80f5b83b2607257e808d49ef5f55db0b8b06a3..64a1086e7805dac522a5f389c2dbf1f816d50290 100644 --- a/plugins/Feedback/lang/ko.json +++ b/plugins/Feedback/lang/ko.json @@ -1,12 +1,34 @@ { "Feedback": { "DoYouHaveBugReportOrFeatureRequest": "발견한 버그나 ê¸°ëŠ¥ì— ëŒ€í•œ ì˜ê²¬ì„ ë³´ê³ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", + "HowToCreateTicket": "ì¢‹ì€ %1$s버그 리í¬íЏ%2$s í˜¹ì€ %3$s기능 ê°œì„ %4$sì„ ìž‘ì„±í•˜ëŠ” ì¶”ì²œë²•ì— ëŒ€í•´ ì½ì–´ì£¼ì„¸ìš”. ê·¸ 후 %5$sìš°ë¦¬ì˜ ì´ìŠˆ 트래커%6$sì— ê°€ìž… ë° ë¡œê·¸ì¸ í•˜ì…”ì„œ %7$s새로운 ì´ìŠˆ%8$s를 만들어주세요.", "IWantTo": "ë‚´ê°€ ì›í•˜ëŠ” 것ì€:", "LearnWaysToParticipate": "ë‹¹ì‹ ì´ %s참여%sí• ìˆ˜ìžˆëŠ” ëª¨ë“ ë°©ë²•", "ManuallySendEmailTo": "ë‹¹ì‹ ì˜ ë©”ì‹œì§€ë¥¼ ë‹¤ìŒ ì£¼ì†Œë¡œ ì§ì ‘ 보내주세요:", + "PluginDescription": "Piwik 팀ì—게 피드백 보내기. ë‹¹ì‹ ì˜ ì•„ì´ë””어와 ì œì•ˆì€ ë” ë‚˜ì€ ì„¸ìƒì—서 가장 우수한 ë¶„ì„ í”Œëž«í¼ì´ ë Piwik를 ë§Œë“œëŠ”ë° í° ë„ì›€ì´ ë©ë‹ˆë‹¤.", + "PrivacyClaim": "Piwik는 ë‹¹ì‹ ì˜ %1$s프ë¼ì´ë²„시%2$s를 존중하며 ë™ì‹œì— ë‹¹ì‹ ì˜ ë°ì´í„°ê°€ ë‹¹ì‹ ì˜ í†µì œ í•˜ì— ìžˆë„ë¡ ë…¸ë ¥í•©ë‹ˆë‹¤.", + "RateFeatureLeaveMessageDislike": "안 ì¢‹ì•„í•˜ì‹ ë‹¤ê³ ìš”! 죄송합니다! 우리가 ì´ë¥¼ ê°œì„ í• ìˆ˜ 있ë„ë¡ ë„ì›€ì„ ì£¼ì„¸ìš”!", + "RateFeatureLeaveMessageLike": "ì¢‹ì•„ìš”ì— ê°ì‚¬ 드립니다! ì–´ë–¤ ì ì„ ì¢‹ê²Œ ìƒê°í•˜ì‹œëŠ”ì§€ í˜¹ì€ ì–´ë–¤ 기능ì ê°œì„ ìš”êµ¬ê°€ 있는지 ì•Œê³ ì‹¶ìŠµë‹ˆë‹¤.", + "RateFeatureSendFeedbackInformation": "ë‹¹ì‹ ì˜ Piwik 플랫í¼ì€ 우리들(Piwik 팀)ì—게 (ë‹¹ì‹ ì˜ ì´ë©”ì¼ ì£¼ì†Œë¥¼ í¬í•¨í•œ) ë©”ì¼ì„ 보낼 것입니다. ë”°ë¼ì„œ ë‹¹ì‹ ì˜ ì§ˆë¬¸ì— ë”°ë¼ ìš°ë¦¬ê°€ ì—°ë½ì„ ì·¨í• ìˆ˜ 있습니다.", + "RateFeatureThankYouTitle": "'%s' ë“±ê¸‰ì— ê°ì‚¬ 드립니다.", + "RateFeatureTitle": "'%s'ì˜ ê¸°ëŠ¥ì´ ì–´ë–¤ê°€ìš”? í‰ê°€ ë° ì½”ë©˜íŠ¸ 해주세요.", "SendFeedback": "ì˜ê²¬ 보내기", "ThankYou": "우리가 Piwikì„ í–¥ìƒì‹œí‚¤ëŠ” ë° ë„ì›€ì„ ì£¼ì…”ì„œ ê°ì‚¬í•©ë‹ˆë‹¤!", - "TopLinkTooltip": "ë‹¹ì‹ ì´ ìƒê°í•˜ëŠ” ê¸°ìˆ ì§€ì› ìš”ì²ì„ ì•Œë ¤ì£¼ì„¸ìš”.", + "TopLinkTooltip": "ë‹¹ì‹ ì´ í•„ìš”ë¡œ 하는 ê¸°ìˆ ì§€ì› ìš”ì²ì„ ì•Œë ¤ì£¼ì„¸ìš”.", + "ViewAnswersToFAQ": "%sìžì£¼ 하는 질문%sì—서 답변 보기", + "ViewUserGuides": "%1$sì‚¬ìš©ìž ê°€ì´ë“œ%2$sì—서 효율ì 으로 ë‹¹ì‹ ì˜ ë°ì´í„°ë¥¼ ë¶„ì„하는 방법과 Piwik를 구성하는 ë²•ì— ëŒ€í•´ì„œ 알 수 있습니다.", + "CommunityHelp": "커뮤니티ì—ì„œì˜ ë„움", + "ProfessionalHelp": "ì „ë¬¸ê°€ì˜ ë„움", + "PiwikProIntro": "Piwik PRO는 ì „ë¬¸ê°€ë“¤ì´ êµ¬ì¶•í•œ ì¸í”„ë¼ì—서 ê·¸ë“¤ì˜ ì§€ì›ê³¼ ì»¨ì„¤íŒ…ì„ ë°›ì„ ìˆ˜ 있는 서비스입니다.", + "PiwikProOfferIntro": "ì œê³µë˜ëŠ” 것들", + "PiwikProReviewPiwikSetup": "Piwik ì…‹ì—…", + "PiwikProOptimizationMaintenance": "Piwik 최ì í™” ë° ê´€ë¦¬ 보수", + "PiwikProPhoneEmailSupport": "ì „í™” ë° ì´ë©”ì¼", + "PiwikProTraining": "사용ìž, ê¸°ìˆ ìž ë° ê°œë°œìž", + "PiwikProPremiumFeatures": "프리미엄", + "PiwikProCustomDevelopment": "맞춤 개발", + "PiwikProAnalystConsulting": "ì „ë¬¸ê°€ 컨설팅", + "ContactUs": "ì—°ë½ì£¼ì„¸ìš”", "VisitTheForums": "%sí¬ëŸ¼%s으로 ì´ë™" } } \ No newline at end of file diff --git a/plugins/Goals/API.php b/plugins/Goals/API.php index 351e70078219b66ba57aa04e36fd51453d7e8e4f..89af85f9c0f50f6871b264374949642c5629616d 100644 --- a/plugins/Goals/API.php +++ b/plugins/Goals/API.php @@ -366,7 +366,6 @@ class API extends \Piwik\Plugin\API 'date' => $date, 'idGoal' => $idGoal, 'columns' => $columns, - 'serialize' => '0', 'format_metrics' => 'bc' )); diff --git a/plugins/Goals/Pages.php b/plugins/Goals/Pages.php index 9ab7a96d6617f7bc13cb9759cdb2827b9a166872..571a5f75cd74cbe62730af00bb90939cface237d 100644 --- a/plugins/Goals/Pages.php +++ b/plugins/Goals/Pages.php @@ -292,8 +292,14 @@ class Pages $report['viewDataTable'] = 'tableGoals'; } + if (!empty($report['parameters'])) { + $params = array_merge($customParams, $report['parameters']); + } else { + $params = $customParams; + } + $widget = $this->createWidgetForReport($report['module'], $report['action']); - $widget->setParameters($customParams); + $widget->setParameters($params); $widget->setCategoryId($categoryText); $widget->setSubcategoryId($categoryText); $widget->setOrder($order); diff --git a/plugins/Goals/Reports/Base.php b/plugins/Goals/Reports/Base.php index 3f9cb9c98ae4031d8320eb131657a085a779f29f..f9e36d6787234b18c22878e67a7b1bbb53c81dd1 100644 --- a/plugins/Goals/Reports/Base.php +++ b/plugins/Goals/Reports/Base.php @@ -33,7 +33,7 @@ abstract class Base extends \Piwik\Plugin\Report $this->parameters = array('idGoal' => $goal['idgoal']); $this->order = $this->orderGoal + $goal['idgoal'] * 3; - $availableReports[] = $this->buildReportMetadata($availableReports, $infos); + $availableReports[] = $this->buildReportMetadata(); } $this->init(); diff --git a/plugins/Goals/config/config.php b/plugins/Goals/config/config.php deleted file mode 100644 index 119946796589fad1f180d2a811524da1677bbc1e..0000000000000000000000000000000000000000 --- a/plugins/Goals/config/config.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php - -return array( - - 'tracker.request.processors' => DI\add(array( - DI\get('Piwik\Plugins\Goals\Tracker\GoalsRequestProcessor'), - )), - -); diff --git a/plugins/Goals/lang/cs.json b/plugins/Goals/lang/cs.json index 7bc7cbc8bbb8d5bd5c6747de37fd7b28b1eacc81..e229f04e1446ee2402b69cb66de9fe76aa7bffc0 100644 --- a/plugins/Goals/lang/cs.json +++ b/plugins/Goals/lang/cs.json @@ -9,15 +9,15 @@ "BestCountries": "ZemÄ› s nejvyššÃm poÄtem konverzà jsou:", "BestKeywords": "KlÃÄová slova s nejvyššÃm poÄtem konverzà jsou:", "BestReferrers": "OdkazujÃcà stránky s nejvyššÃm poÄtem konverzà jsou:", - "CaseSensitive": "shoda s velikostà pÃsmen", + "CaseSensitive": "rozliÅ¡ovat velikost pÃsmen", "CancelAndReturnToGoals": "ZruÅ¡it a %svrátit se na seznam cÃlů%s", "CategoryTextGeneral_Visitors": "UmÃstÄ›nà uživatele", "CategoryTextReferrers_Referrers": "Referrery", "CategoryTextVisitsSummary_VisitsSummary": "Uživatelský atribut", "CategoryTextGeneral_Visit": "ZapojenÃ", "ChooseGoal": "Vyberte cÃl", - "ClickOutlink": "Kliknout na odkaz na externà web", - "SendEvent": "Poslat událost", + "ClickOutlink": "Kliknou na odkaz na externà web", + "SendEvent": "OdeÅ¡lou událost", "ColumnAverageOrderRevenueDocumentation": "PrůmÄ›rná hodnota objednávky (AOV) je celkový pÅ™Ãjem ze vÅ¡ech objednávek dÄ›lený jejich poÄtem.", "ColumnAveragePriceDocumentation": "PrůmÄ›rný pÅ™Ãjem z tohoto %s.", "ColumnAverageQuantityDocumentation": "PrůmÄ›rný poÄet tohoto %s prodaný v elektronických objednávkách.", @@ -45,7 +45,7 @@ "DefaultRevenueHelp": "Na pÅ™Ãklad kontaktnà formulář odeslaný návÅ¡tÄ›vnÃkem má průmÄ›rnou cenu $10. Piwik vám pomůže dobÅ™e pochopit chovánà skupin uživatelů", "DeleteGoalConfirm": "Jste si jisti, že chcete vymazat tento cÃl %s?", "DocumentationRevenueGeneratedByProductSales": "Tržby produktu. NepoÄÃtajà se danÄ›, poplatky za doruÄenà a slevy.", - "Download": "Stáhnout soubor", + "Download": "Stáhnou soubor", "Ecommerce": "Obchody", "EcommerceAndGoalsMenu": "Obchody a CÃle", "EcommerceLog": "Logy", @@ -58,17 +58,17 @@ "GoalConversion": "CÃl konverze", "GoalConversions": "Konverze cÃle", "GoalConversionsBy": "Konverze cÃle %s podle typu návÅ¡tÄ›vy", - "GoalIsTriggered": "CÃle je zaznamenáván", - "GoalIsTriggeredWhen": "CÃl je zaznamenáván, když", + "GoalIsTriggered": "CÃl je zaznamenán", + "GoalIsTriggeredWhen": "CÃl je zaznamenán, pokud", "GoalName": "Jméno cÃle", "Goals": "CÃle", "ManageGoals": "Spravovat cÃle", "GoalsOverview": "PÅ™ehled cÃlů", - "GoalsOverviewDocumentation": "Toto je pÅ™ehled vaÅ¡ich konverzà cÃlů. VNe vchozÃm stavu graf zobrazuje souÄet vÅ¡ech konverzÃ. %s Pod grafem jsou zobrazena hlášenà pro každý cÃl. Můžete je zvÄ›tÅ¡it kliknutÃm, pokud chcete.", + "GoalsOverviewDocumentation": "Toto je pÅ™ehled vaÅ¡ich konverzà cÃlů. Ve výchozÃm stavu graf zobrazuje souÄet vÅ¡ech konverzÃ. %s Pod grafem jsou zobrazena hlášenà pro každý cÃl. Můžete je zvÄ›tÅ¡it kliknutÃm, pokud chcete.", "GoalX": "CÃl: %s", "HelpOneConversionPerVisit": "Pokud byla stránka odpovÃdajÃcà cÃli pÅ™i návÅ¡tÄ›vÄ› obnovena nebo zobrazena vÃcekrát, bude cÃl zapoÄÃtán pouze jednou a to pÅ™i prvnÃm zobrazenÃ.", "IsExactly": "je pÅ™esnÄ› %s", - "LearnMoreAboutGoalTrackingDocumentation": "VÃce o sledovánà cÃlu se dozvÃte v %suživatelské dokumentaci%s.", + "LearnMoreAboutGoalTrackingDocumentation": "VÃce o sledovánà cÃlů se dozvÃte v %suživatelské dokumentaci%s.", "LeftInCart": "%s Zbylo v koÅ¡Ãku", "ManageGoalsOrCreateANewGoal": "%sSpravovat cÃle%s nebo ho vytvoÅ™te.", "Manually": "ruÄnÄ›", @@ -86,7 +86,7 @@ "PluginDescription": "VytvoÅ™te cÃle a sledujte detailnà hlášenà o jejich konverzÃch: vývoj v Äase, pÅ™Ãjem za návÅ¡tÄ›vu, konverze prro referrer, pro klÃÄové slovo a vÃce.", "ProductCategory": "Kategorie produktu", "ProductName": "Název produktu", - "Products": "Produktů", + "Products": "Produkty", "ProductSKU": "SKU produktu", "ReturningVisitorsConversionRateIs": "PomÄ›r konverze navracejÃcÃch se uživatelů je %s", "SingleGoalOverviewDocumentation": "Toto je pÅ™ehled konverzà jednoho cÃle. %s Linky lze zvÄ›tÅ¡it kliknutÃm na nÄ›.", @@ -96,12 +96,12 @@ "ViewAndEditGoals": "Zobrazit a editovat cÃle", "GoalsBy": "CÃle podle %s", "GoalsAdjective": "CÃle %s", - "VisitPageTitle": "NavÅ¡tÃvit stránku s daným titulkem", + "VisitPageTitle": "NavÅ¡tÃvà stránku s daným titulkem", "VisitsUntilConv": "NávÅ¡tÄ›v ke konverzi", - "VisitUrl": "NavÅ¡tÃvÃt zadanou URL (stránku, nebo skupiny stránek)", - "WhenVisitors": "když návÅ¡tÄ›vnÃci", + "VisitUrl": "NavÅ¡tÃvà zadanou URL (stránku nebo skupiny stránek)", + "WhenVisitors": "pokud návÅ¡tÄ›vnÃci", "WhereThe": "když", - "WhereVisitedPageManuallyCallsJavascriptTrackerLearnMore": "kde návÅ¡tÃvená stránka obsahuhe volánà metody JavaScriptu piwikTracker.trackGoal() (%svÃce%s)", - "YouCanEnableEcommerceReports": "Pro tyto stránky můžete %s povolit na stránce %s." + "WhereVisitedPageManuallyCallsJavascriptTrackerLearnMore": "kde navÅ¡tÃvená stránka obsahuhe volánà metody JavaScriptu 'trackGoal' (%svÃce%s)", + "YouCanEnableEcommerceReports": "Pro tyto stránky můžete povolit %s na stránce %s." } } \ No newline at end of file diff --git a/plugins/Goals/lang/fr.json b/plugins/Goals/lang/fr.json index c8945cf794723522e1504c5dad06b5028d1d0475..8518515c2efab677b97ccce87d3476fff53d8e03 100644 --- a/plugins/Goals/lang/fr.json +++ b/plugins/Goals/lang/fr.json @@ -76,7 +76,7 @@ "MatchesExpression": "correspond à l'expression %s", "NewGoalIntro": "Le suivi de la conversion des objectifs et une des manières les plus efficaces de mesurer et améliorer vos objectifs d'affaires.", "NewVisitorsConversionRateIs": "Le taux de conversion des nouveaux visiteurs est %s", - "NoGoalsNeedAccess": "Uniquement un Administrateur ou un utilisateur avec un accès Super Utilisateur peut gérer les Objectifs d'un site web donné. Veuillez demander à votre administrateur Piwik de mettre en place un Objectif pour votre site web. <br \/>Le suivit d'Objectifs est une bonne manière de mieux comprendre et de maximiser les performances de votre site web!", + "NoGoalsNeedAccess": "Uniquement un Administrateur ou un utilisateur avec un accès Super Utilisateur peut gérer les Objectifs d'un site web donné. Veuillez demander à votre administrateur Piwik de mettre en place un Objectif pour votre site web. <br \/>Le suivi d'objectifs est une bonne manière de mieux comprendre et de maximiser les performances de votre site web!", "NeedAccess": "Uniquement un administrateur ou un utilisateur avec le rôle super utilisateur peut gérer les objectifs pour un site web.", "Optional": "(optionnel)", "OverallConversionRate": "%s taux de conversion global (visites avec un objectif rempli)", diff --git a/plugins/Goals/lang/ja.json b/plugins/Goals/lang/ja.json index 9699895d820120dd81e9d1734dd6647842b175f4..bbb26f8859031302b20444f019028ee06c04c5cd 100644 --- a/plugins/Goals/lang/ja.json +++ b/plugins/Goals/lang/ja.json @@ -11,6 +11,10 @@ "BestReferrers": "ベストコンãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®å‚照元ウェブサイト", "CaseSensitive": "大文å—å°æ–‡å—を区別ã™ã‚‹ä¸€è‡´", "CancelAndReturnToGoals": "ã‚ャンセルã—ã¦ç›®æ¨™ %s ã®ãƒªã‚¹ãƒˆ %s ã«æˆ»ã‚‹", + "CategoryTextGeneral_Visitors": "ユーザーã®ä½ç½®æƒ…å ±", + "CategoryTextReferrers_Referrers": "リファラー", + "CategoryTextVisitsSummary_VisitsSummary": "ユーザー属性", + "CategoryTextGeneral_Visit": "エンゲージメント", "ChooseGoal": "Choose Goal", "ClickOutlink": "外部ウェブサイトã¸ã®ãƒªãƒ³ã‚¯ã‚’クリック", "SendEvent": "イベントをé€ä¿¡", @@ -35,6 +39,7 @@ "ConversionsOverview": "コンãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®æ¦‚観", "ConversionsOverviewBy": "ビジットã®ç¨®é¡žã«ã‚ˆã‚‹ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³æ¦‚観", "DaysToConv": "日数別ã®ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³", + "Details": "目標ã®è©³ç´°", "DefaultGoalConvertedOncePerVisit": "(デフォルト)ç›®æ¨™é”æˆã¯è¨ªå•ã®éƒ½åº¦1回ã ã‘カウント", "DefaultRevenue": "目標ã®ãƒ‡ãƒ•ォルトåŽç›Š", "DefaultRevenueHelp": "例ãˆã°ã€ãƒ“ジターã«ã‚ˆã£ã¦é€ä¿¡ã•れãŸã‚³ãƒ³ã‚¿ã‚¯ãƒˆãƒ•ォームãŒã€å¹³å‡ã—㦠$10 ã®ä¾¡å€¤ã‚’æŒã¤ã‹ã‚‚ã—れã¾ã›ã‚“。 Piwik ã¯ã€ãƒ“ジターセグメントãŒã©ã‚Œãらã„ã†ã¾ã実行ã—ã¦ã„ã‚‹ã‹ã‚’ç†è§£ã™ã‚‹ã®ã‚’助ã‘ã¾ã™ã€‚", @@ -71,6 +76,8 @@ "MatchesExpression": "æ£è¦è¡¨ç¾ %s ã«ä¸€è‡´ã™ã‚‹", "NewGoalIntro": "目標コンãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒˆãƒ©ãƒƒã‚ングã¯ã€ã‚ãªãŸã®ãƒ“ジãƒã‚¹ç›®æ¨™ã®æ¸¬å®šã‚„改善ã®ãŸã‚ã«ã€æœ€ã‚‚åŠ¹çŽ‡çš„ãªæ–¹æ³•ã®ä¸€ã¤ã§ã™ã€‚", "NewVisitorsConversionRateIs": "æ–°è¦ãƒ“ジターã®ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³çŽ‡ã¯ %s ã§ã™", + "NoGoalsNeedAccess": "管ç†è€…ã¾ãŸã¯ã‚¹ãƒ¼ãƒ‘ー ユーザーã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ãƒ¼ã ã‘ãŒã€ã‚¦ã‚§ãƒ–サイトã®ç›®æ¨™ã‚’管ç†ã§ãã¾ã™ã€‚ウェブサイトã®ç›®æ¨™ã‚’è¨å®šã™ã‚‹å ´åˆã¯ Piwik ã®ç®¡ç†è€…ã«ä¾é ¼ã—ã¦ãã ã•ã„。<br> 目標を追跡ã™ã‚‹ã“ã¨ã¯ã€ã‚¦ã‚§ãƒ–サイトã®ç†è§£ã«å½¹ç«‹ã¡ã€ãƒ‘フォーマンスを最大é™ã«é«˜ã‚ã‚‹ãŸã‚ã®ç´ 晴らã—ã„æ–¹æ³•ã§ã™ï¼", + "NeedAccess": "管ç†è€…ã¾ãŸã¯ã‚¹ãƒ¼ãƒ‘ー ユーザーã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ãƒ¼ã ã‘ãŒã€ã‚¦ã‚§ãƒ–サイトã®ç›®æ¨™ã‚’管ç†ã§ãã¾ã™ã€‚", "Optional": "(オプション)", "OverallConversionRate": "%s ç·ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³çŽ‡ï¼ˆç›®æ¨™é”æˆãƒ“ジット)", "OverallRevenue": "%s ç·åŽç›Š", @@ -87,6 +94,8 @@ "UpdateGoal": "目標を更新", "URL": "URL", "ViewAndEditGoals": "目標ã®è¡¨ç¤ºã¨ç·¨é›†", + "GoalsBy": "%s ã®ç›®æ¨™", + "GoalsAdjective": "目標 %s", "VisitPageTitle": "入力ã•れãŸã‚¿ã‚¤ãƒˆãƒ«ã®ãƒšãƒ¼ã‚¸ã‚’訪å•", "VisitsUntilConv": "ビジット数別ã®ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³", "VisitUrl": "特定㮠URL を訪å•(ページã¾ãŸã¯ãƒšãƒ¼ã‚¸ã‚°ãƒ«ãƒ¼ãƒ—)", diff --git a/plugins/Goals/lang/ko.json b/plugins/Goals/lang/ko.json index 705ff073c9ff1980db4d5a4ee3ac4634754877c2..8dc370de94ecb655b2bfd9b1847a37b686eebab2 100644 --- a/plugins/Goals/lang/ko.json +++ b/plugins/Goals/lang/ko.json @@ -10,7 +10,14 @@ "BestKeywords": "ìƒìœ„ ì „í™˜ 검색어:", "BestReferrers": "ìµœê³ ì „í™˜ 참조 웹사ì´íЏ:", "CaseSensitive": "ëŒ€ì†Œë¬¸ìž êµ¬ë¶„í•¨", + "CancelAndReturnToGoals": "ì·¨ì†Œí•˜ê³ %s목표 리스트로 ëŒì•„가기%s", + "CategoryTextGeneral_Visitors": "ì‚¬ìš©ìž ìœ„ì¹˜", + "CategoryTextReferrers_Referrers": "리í¼ëŸ¬", + "CategoryTextVisitsSummary_VisitsSummary": "ì‚¬ìš©ìž ì†ì„±", + "CategoryTextGeneral_Visit": "약ì†", + "ChooseGoal": "목표 ì„ íƒ", "ClickOutlink": "외부 웹사ì´íŠ¸ì— ëŒ€í•œ ë§í¬ í´ë¦", + "SendEvent": "ì´ë²¤íЏ 보내기", "ColumnAverageOrderRevenueDocumentation": "í‰ê· 주문액 (AOV)ì€ ëª¨ë“ ì „ìžìƒ 거래 ì£¼ë¬¸ì˜ ì´ìˆ˜ìµì„ 주문수로 나눈 것입니다.", "ColumnAveragePriceDocumentation": "ì´ %sì˜ í‰ê· 수ìµ.", "ColumnAverageQuantityDocumentation": "ì „ìžìƒê±°ëž˜ 주문ì—서 íŒë§¤ëœ %sì˜ í‰ê· 수량입니다.", @@ -32,6 +39,7 @@ "ConversionsOverview": "ì „í™˜ 개요", "ConversionsOverviewBy": "방문 ìœ í˜•ë³„ ì „í™˜ 개요", "DaysToConv": "ì¼ë³„ ì „í™˜", + "Details": "목표 ìƒì„¸", "DefaultGoalConvertedOncePerVisit": "(기본) 목표 ë‹¬ì„±ì€ ë°©ë¬¸í• ë•Œ 마다 한번만 계산", "DefaultRevenue": "ëª©í‘œì˜ ê¸°ë³¸ 수ìµì€", "DefaultRevenueHelp": "예를 들어 방문ìžê°€ ì „ì†¡ëœ ì—°ë½ì²˜ ì–‘ì‹ì´ í‰ê· ì 으로 10ì›ì˜ 가치가 있ì„ì§€ë„ ëª¨ë¦…ë‹ˆë‹¤. Piwikì€ ë°©ë¬¸ìž ì„¸ê·¸ë¨¼íŠ¸ê°€ 얼마나 잘 ìˆ˜í–‰í•˜ê³ ìžˆëŠ”ì§€ë¥¼ ì´í•´í•˜ëŠ” ê²ƒì„ ë•ê³ ìžˆìŠµë‹ˆë‹¤.", @@ -54,30 +62,40 @@ "GoalIsTriggeredWhen": "목표 트리거 시ì ", "GoalName": "목표 ì´ë¦„", "Goals": "목표", + "ManageGoals": "목표 관리", "GoalsOverview": "목표 개요", "GoalsOverviewDocumentation": "ì´ê²ƒì€ 목표 ì „í™˜ 개요입니다. ë¨¼ì € 그래프는 ëª¨ë“ ì´ ì „í™˜ì„ ë³´ì—¬ì¤ë‹ˆë‹¤. %s 그래프 ì•„ëž˜ì— ê°ê°ì˜ ëª©í‘œì— ëŒ€í•œ ì „í™˜ ë³´ê³ ì„œë¥¼ ë³¼ 수 있습니다. ìŠ¤íŒŒí¬ ë¼ì¸ì€ í´ë¦í•˜ì—¬ 확대 í• ìˆ˜ 있습니다.", "GoalX": "목표 %s", "HelpOneConversionPerVisit": "만약 ëª©í‘œì— ì¼ì¹˜í•˜ëŠ” 페ì´ì§€ê°€ ì—…ë°ì´íЏë˜ê±°ë‚˜ 한번 ì´ìƒ 방문해ë„, 첫 번째 방문시ì—ë§Œ 목표가 달성ë©ë‹ˆë‹¤.", "IsExactly": "%s와 ì¼ì¹˜", + "LearnMoreAboutGoalTrackingDocumentation": "ì‚¬ìš©ìž ë¬¸ì„œ ë‚´ %sPiwik 목표 ì¶”ì %s 문서를 통해서 좀 ë” ì•Œ 수 있습니다.", "LeftInCart": "ì¹´íŠ¸ì— ë‚¨ê²¨ì§„ %s", + "ManageGoalsOrCreateANewGoal": "%s목표 관리%s í˜¹ì€ ìƒˆë¡œìš´ 목표를 만드세요!", "Manually": "수ë™ìœ¼ë¡œ", "ManuallyTriggeredUsingJavascriptFunction": "JavaScript APIì˜ trackGoal()ì„ ì‚¬ìš©í•˜ì—¬ ìˆ˜ë™ íŠ¸ë¦¬ê±°", "MatchesExpression": "ì •ê·œì‹ %sì— ì¼ì¹˜", + "NewGoalIntro": "목표 ì „í™˜ ì¶”ì ì€ ë‹¹ì‹ ì˜ ë¹„ì§€ë‹ˆìŠ¤ 목ì ì„ ì¸¡ì •í•˜ê³ í–¥ìƒì‹œí‚¤ëŠ” 매우 효과ì ì¸ ë°©ë²•ìž…ë‹ˆë‹¤.", "NewVisitorsConversionRateIs": "ì‹ ê·œ 방문ìžì˜ ì „í™˜ìœ¨ì€ %s", + "NoGoalsNeedAccess": "주어진 웹사ì´íŠ¸ëŠ” ì˜¤ì§ ê´€ë¦¬ìžë‚˜ ìŠˆí¼ ìœ ì € ê¶Œí•œì„ ê°€ì§„ 사용ìžë§Œì´ 목표를 ê´€ë¦¬í• ìˆ˜ 있습니다. Piwikì˜ ê´€ë¦¬ìžì—게 ë‹¹ì‹ ì˜ ì›¹ì‚¬ì´íЏ 목표 ì„¤ì •ì„ ìš”ì²í•˜ì„¸ìš”. <br>목표 ì¶”ì ì€ ì›¹ì‚¬ì´íЏ ì„±ëŠ¥ì„ ì´í•´í•˜ê³ í–¥ìƒì‹œí‚¤ëŠ”ë° í° ë„ì›€ì´ ë©ë‹ˆë‹¤.", + "NeedAccess": "주어진 웹사ì´íŠ¸ëŠ” ì˜¤ì§ ê´€ë¦¬ìžë‚˜ ìŠˆí¼ ìœ ì € ê¶Œí•œì„ ê°€ì§„ 사용ìžë§Œì´ 목표를 ê´€ë¦¬í• ìˆ˜ 있습니다.", "Optional": "(ì„ íƒí•목)", "OverallConversionRate": "%s ì´ ì „í™˜ìœ¨ (목표 달성 방문)", "OverallRevenue": "%s ì´ ìˆ˜ìµ", "PageTitle": "페ì´ì§€ ì œëª©", "Pattern": "패턴", + "PluginDescription": "목표를 ë§Œë“¤ê³ ëª©í‘œ ì „í™˜ë“¤ - ì‹œê°„ì— ë”°ë¥¸ 변화, 방문 당 수ìµ, 리í¼ëŸ¬ì™€ 키워드 당 ì „í™˜ë“¤ - ì— ëŒ€í•œ ìƒì„¸ ë³´ê³ ì„œ 보기", "ProductCategory": "ì œí’ˆ ì¹´í…Œê³ ë¦¬", "ProductName": "ì œí’ˆ ì´ë¦„", "Products": "ì œí’ˆ", "ProductSKU": "ì œí’ˆ 번호", "ReturningVisitorsConversionRateIs": "재방분 ì „í™˜ìœ¨ì€ %s", "SingleGoalOverviewDocumentation": "ì´ê²ƒì€ í•˜ë‚˜ì˜ ëª©í‘œ ì „í™˜ 개요입니다. %s 그래프 ì•„ëž˜ì˜ ìŠ¤íŒŒí¬ë¼ì¸ì€ í´ë¦í•˜ì—¬ í™•ëŒ€í• ìˆ˜ 있습니다.", + "ThereIsNoGoalToManage": "웹사ì´íЏ %sì—는 ê´€ë¦¬í• ëª©í‘œê°€ 없습니다.", "UpdateGoal": "목표 ê°±ì‹ ", "URL": "URL", "ViewAndEditGoals": "목표 보기 ë° íŽ¸ì§‘", + "GoalsBy": "%sê°€ ë§Œë“ ëª©í‘œ", + "GoalsAdjective": "%s 목표들", "VisitPageTitle": "ìž…ë ¥ëœ ì œëª©ì˜ íŽ˜ì´ì§€ 방문", "VisitsUntilConv": "방문수별 ì „í™˜", "VisitUrl": "íŠ¹ì • URL 방문 (페ì´ì§€ ë˜ëŠ” 페ì´ì§€ 그룹)", diff --git a/plugins/Heartbeat/config/config.php b/plugins/Heartbeat/config/config.php deleted file mode 100644 index 6f7a1417abdb9fb9b2e6331632e6f75de165ebe6..0000000000000000000000000000000000000000 --- a/plugins/Heartbeat/config/config.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php - -return array( - - 'tracker.request.processors' => DI\add(array( - DI\get('Piwik\Plugins\Heartbeat\Tracker\PingRequestProcessor'), - )), - -); diff --git a/plugins/ImageGraph/API.php b/plugins/ImageGraph/API.php index 4e7b466b21f6d3e46bd84b40409f2518700954d3..ffdd223d46025fb3f7e3689c931a9c954ff34a16 100644 --- a/plugins/ImageGraph/API.php +++ b/plugins/ImageGraph/API.php @@ -122,7 +122,8 @@ class API extends \Piwik\Plugin\API $gridColor = API::DEFAULT_GRID_COLOR, $idSubtable = false, $legendAppendMetric = true, - $segment = false + $segment = false, + $idDimension = false ) { Piwik::checkUserHasViewAccess($idSite); @@ -151,6 +152,9 @@ class API extends \Piwik\Plugin\API if (!empty($idGoal)) { $apiParameters = array('idGoal' => $idGoal); } + if (!empty($idDimension)) { + $apiParameters = array('idDimension' => $idDimension); + } // Fetch the metadata for given api-action $parameters = array( 'idSite' => $idSite, @@ -305,6 +309,7 @@ class API extends \Piwik\Plugin\API 'column' => $plottedMetric, 'language' => $languageLoaded, 'idGoal' => $idGoal, + 'idDimension' => $idDimension, 'legendAppendMetric' => $legendAppendMetric, 'labelUseAbsoluteUrl' => false ); @@ -361,6 +366,7 @@ class API extends \Piwik\Plugin\API 'segment' => $segment, 'apiParameters' => false, 'idGoal' => $idGoal, + 'idDimension' => $idDimension, 'language' => $languageLoaded, 'showTimer' => true, 'hideMetricsDoc' => false, @@ -506,7 +512,10 @@ class API extends \Piwik\Plugin\API if ($idGoal != '') { $idGoal = '_' . $idGoal; } - $fileName = self::$DEFAULT_PARAMETERS[$graphType][self::FILENAME_KEY] . '_' . $apiModule . '_' . $apiAction . $idGoal . ' ' . str_replace(',', '-', $date) . ' ' . $idSite . '.png'; + if ($idDimension != '') { + $idDimension = '__' . $idDimension; + } + $fileName = self::$DEFAULT_PARAMETERS[$graphType][self::FILENAME_KEY] . '_' . $apiModule . '_' . $apiAction . $idGoal . $idDimension . ' ' . str_replace(',', '-', $date) . ' ' . $idSite . '.png'; $fileName = str_replace(array(' ', '/'), '_', $fileName); if (!Filesystem::isValidFilename($fileName)) { diff --git a/plugins/Insights/Visualizations/Insight.php b/plugins/Insights/Visualizations/Insight.php index 7fe304e5bef6a7c22cc16036127745656abd504c..91d2c90b63da00284253309b8b2370d855796909 100644 --- a/plugins/Insights/Visualizations/Insight.php +++ b/plugins/Insights/Visualizations/Insight.php @@ -40,6 +40,10 @@ class Insight extends Visualization $report = $this->requestConfig->apiMethodToRequestDataTable; $report = str_replace('.', '_', $report); + if (!empty($this->requestConfig->request_parameters_to_modify['reportUniqueId'])) { + $report = $this->requestConfig->request_parameters_to_modify['reportUniqueId']; + } + $this->requestConfig->apiMethodToRequestDataTable = 'Insights.getInsights'; $this->requestConfig->request_parameters_to_modify = array( diff --git a/plugins/Insights/lang/cs.json b/plugins/Insights/lang/cs.json index f3897366924a0b312785479ffbf472f586466661..7abc7c7112f529004ca31e1f6eee3c4e83b7f738 100644 --- a/plugins/Insights/lang/cs.json +++ b/plugins/Insights/lang/cs.json @@ -8,7 +8,7 @@ "DayComparedToPreviousWeek": "Stejný den v minulém týdnu", "DayComparedToPreviousYear": "Stejný den v pÅ™edchozÃm roce", "Filter": "Filtr", - "FilterIncreaserAndDecreaser": "ZvyÅ¡ovaÄ & snižovaÄ", + "FilterIncreaserAndDecreaser": "ZvyÅ¡ovaÄ a snižovaÄ", "FilterOnlyDecreaser": "Pouze snižovaÄ", "FilterOnlyDisappeared": "Pouze ztracenÃ", "FilterOnlyIncreaser": "Pouze zvyÅ¡ovaÄ", diff --git a/plugins/Insights/lang/ja.json b/plugins/Insights/lang/ja.json index 9695c7fa547d12b50cacc23fd87f55aa50b2510d..db9cce115bec67d875dfc6297a9cefd0c72f0a65 100644 --- a/plugins/Insights/lang/ja.json +++ b/plugins/Insights/lang/ja.json @@ -1,5 +1,6 @@ { "Insights": { + "PluginDescription": "トラフィックã«ã¤ã„ã¦ã®ã‚¤ãƒ³ã‚µã‚¤ãƒˆã‚’æä¾›ã—ã¦ã„ã¾ã™ã€‚インサイトã¯ã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã‚¦ã‚£ã‚¸ã‚§ãƒƒãƒˆã ã‘ã§ãªãã€ãƒ‡ãƒ¼ã‚¿ã®ä¸ã§æœ€ã‚‚é‡è¦ãªãƒˆãƒ¬ãƒ³ãƒ‰ã‚’見るãŸã‚ã®ãƒ¬ãƒãƒ¼ãƒˆã§æ–°ã—ã„アイコンã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã™ã€‚", "ControlComparedToDescription": "比較ã™ã‚‹å®Ÿç¸¾å€¤ã¯", "ControlFilterByDescription": "ã™ã¹ã¦ã€å¤‰å‹•ã®ã¿ã€æ–°è¦ã®ã¿ã€å‰Šé™¤ã®ã¿ã‚’表示", "DatePeriodCombinationNotSupported": "ã“ã®æ—¥ä»˜ã¨æœŸé–“ã®çµ„ã¿åˆã‚ã›ã«å¯¾ã™ã‚‹ã‚¤ãƒ³ã‚µã‚¤ãƒˆã¯ä½œæˆã§ãã¾ã›ã‚“。", diff --git a/plugins/Installation/lang/cs.json b/plugins/Installation/lang/cs.json index b6ffa6dba8357e71ce2a6ca1eeb45bdcdc106354..8e32ed6f4a2ecaf70642a5dfe7cc5b42bcc21c6f 100644 --- a/plugins/Installation/lang/cs.json +++ b/plugins/Installation/lang/cs.json @@ -4,7 +4,7 @@ "ConfigurationHelp": "Váš konfiguraÄnà soubor Piwiku je Å¡patnÄ› nastavený. Můžete buÄ odstranit soubor config\/config.ini a znovu zaÄÃt instalaci, nebo opravit nastavenà databáze.", "ConfirmDeleteExistingTables": "Jste si jistÃ, že chcete vymazat tabulky: %s z vašà databáze? UPOZORNÄšNÃ: DATA Z TÄšCHTO TABULEK NEPÅ®JDOU OBNOVIT!", "Congratulations": "Gratulujeme", - "CongratulationsHelp": "<p>Gratulujeme! VaÅ¡e instalace Piwiku je komplentnÃ.<\/p><p>UjistÄ›te se, že máte JavaScriptový kód vložen do vaÅ¡ich stránek a Äekejte na prvnà návÅ¡tÄ›vnÃky!<\/p>", + "CongratulationsHelp": "<p>Gratulujeme! VaÅ¡e instalace Piwiku je kompletnÃ.<\/p><p>UjistÄ›te se, že máte JavaScriptový kód vložen do svých stránek a Äekejte na prvnà návÅ¡tÄ›vnÃky!<\/p>", "DatabaseAbilities": "Schopnosti databáze", "DatabaseCreation": "VytvoÅ™enà databáze", "DatabaseErrorConnect": "Nastala chyba pÅ™i pÅ™ipojovánà k databázovému serveru", @@ -15,7 +15,7 @@ "DatabaseSetupLogin": "uživatelské jméno", "DatabaseSetupServer": "server s databázÃ", "DatabaseSetupTablePrefix": "prefix tabulek", - "Email": "E-mail", + "Email": "Email", "Extension": "pÅ™Ãpona", "Filesystem": "Souborový systém", "GetInvolved": "Pokud se vám lÃbÃ, co vidÃte, %1$szapojte se%2$s.", @@ -28,12 +28,12 @@ "InvalidStateError": "Chyba: Piwik je již nainstalován. %1$s JÃt zpÄ›t %2$s do piwiku%3$s.", "JsTagArchivingHelp1": "Pro stÅ™ednà a velké stránky jsou urÄité optimalizace, které umožňujà Piwiku běžet rychleji, jako tÅ™eba %1$snastavenà automatického archivovánÃ%2$s.", "JSTracking_EndNote": "Poznámka: Po dokonÄenà procesu instalace můžete vytvoÅ™it vlastnà sledovacà kód na stránce %1$ssledovacà kód%2$s.", - "JSTracking_Intro": "Pokud chcete sledovat Pokud chcete Piwikem sledovat váš provoz na webu, musÃte zajistit, že do každé stránky bude pÅ™idán extra kód.", + "JSTracking_Intro": "Pokud chcete Piwikem sledovat provoz na vaÅ¡em webu, musÃte zajistit, že do každé stránky bude pÅ™idán extra kód.", "LargePiwikInstances": "NápovÄ›da pro velké instalace Piwiku", "Legend": "Legenda", "LoadDataInfileRecommended": "Pokud váš Piwik server zaznamenává provoz na stránkách s vysokým provozem t. j. 100000 stránek za mÄ›sÃc, doporuÄujeme se pokusit o Å™eÅ¡enà tohoto problému.", "LoadDataInfileUnavailableHelp": "Použità %1$s velmi zrychlà archivaÄnà proces Piwiku. Pro zpÅ™ÃstupnÄ›nà zkuste aktualizovat PHP a Mysql a ujistÄ›te se, že má databázový uživatel privilegium %2$s.", - "NfsFilesystemWarning": "Váš server použÃvá soborový systém NFS.", + "NfsFilesystemWarning": "Váš server použÃvá souborový systém NFS.", "NfsFilesystemWarningSuffixAdmin": "To znamená, že Piwik bude pÅ™i použità sessions založených na souborech velmi pomalý.", "NfsFilesystemWarningSuffixInstall": "Sessions založené na souborech jsou na NFS velmi pomalé. Proto Piwik použije databázové sessions. Pokud bude k nástÄ›nkám pÅ™istupovat souÄasnÄ› hodnÄ› uživatelů, možná budete muset zvýšit maximálnà poÄet klientských databázových spojenà v konfiguraci databázového serveru.", "NoConfigFound": "KonfiguraÄnà soubor Piwiku nebyl nalezen a snažÃte se vstoupit na stránku Piwiku.<br \/><b> » Můžete <a href='index.php'>teÄ nainstalovat<\/a><\/b><br \/><small>Pokud jste Piwik již instalovali a máte v DB nÄ›jaké tabulky, nemÄ›jte obavy. Můžete je použÃt a zachovat jejich data.!<\/small>", @@ -48,7 +48,7 @@ "Requirements": "Požadavky Piwiku", "RestartWebServer": "Po uloženà zmÄ›n restartujte Vás web server.", "ReusingTables": "Použità existujÃcÃch tabulek", - "PiwikOrgNewsletter": "odesÃlat e-maily s důležitými událostmi v komunitÄ› Piwiku", + "PiwikOrgNewsletter": "odesÃlat emaily s důležitými událostmi v komunitÄ› Piwiku", "PiwikProNewsletter": "ZasÃlejte mi informace o službách a nabÃdkách %sPiwik pro%s", "SeeBelowForMoreInfo": "Pro vÃce informacà se podÃvejte nÞe.", "SetupWebsite": "Nastavit Web", @@ -57,7 +57,7 @@ "SetupWebsiteSetupSuccess": "Web %s byl úspěšnÄ› vytvoÅ™en", "SetupWebSiteURL": "URL webových stránek", "SiteSetup": "ProsÃm vytvoÅ™te prvnà stránky, které budou sledovány a analyzovány Piwikem:", - "SiteSetupFootnote": "Poznámka: Jakmile bude instalace Piwiku dokonÄena, budete moct pÅ™idat dalšà stránky ke sledovánÃ.", + "SiteSetupFootnote": "Poznámka: Jakmile bude instalace Piwiku dokonÄena, budete moci pÅ™idat dalšà stránky ke sledovánÃ.", "SuperUser": "Super uživatel", "SuperUserLogin": "PÅ™ihlaÅ¡ovacà jméno super uživatele", "SuperUserSetupError": "PÅ™i pÅ™idávánà super uživatele doÅ¡lo k chybÄ›", @@ -85,7 +85,7 @@ "SystemCheckMbstring": "mbstring", "SystemCheckMbstringHelp": "RozÅ¡ÃÅ™enà mbstring je nutné ke zpracovánà vÃcebajtových znaků v uživatelském rozhranà a odpovÄ›dÃch API. Také zajistÄ›te, aby byla v souboru php.ini hodnota mbstring.func_overload nastavena na 0.", "SystemCheckMemoryLimit": "Limit pamÄ›ti", - "SystemCheckMemoryLimitHelp": "Na webech s vysokým provozem, může archivace vyžadovat vÃce pamÄ›ti něž je nynà povoleno.<br \/>Pokud je potÅ™eba podÃvejte se na direktivu memory_limit ve vaÅ¡em souboru php.ini.", + "SystemCheckMemoryLimitHelp": "Na webech s vysokým provozem, může archivace vyžadovat vÃce pamÄ›ti něž je nynà povoleno.<br \/>Pokud je potÅ™eba, podÃvejte se na direktivu memory_limit ve vaÅ¡em souboru php.ini.", "SystemCheckOpenURL": "OtevÅ™Ãt URL", "SystemCheckOpenURLHelp": "PÅ™edplatné novinek, informace o aktualizaci a aktualizace jednÃm kliknutÃm vyžadujà rozÅ¡ÃÅ™enà \"curl\", allow_url_fopen=On, nebo povolené fsockopen().", "SystemCheckOtherExtensions": "Ostatnà rozÅ¡ÃÅ™enÃ", @@ -93,20 +93,20 @@ "SystemCheckPageSpeedDisabled": "PageSpeed zakázán", "SystemCheckPageSpeedWarn": "DoporuÄujeme modul PageSpeed zakázat v konfiguraci webového serveru: %s Bylo hlášeno, že způsobuje problémy s Piwikem.", "SystemCheckPackHelp": "Funkce pack() je nutná ke sledovánà návÅ¡tÄ›vnosti v Piwiku.", - "SystemCheckParseIniFileHelp": "Tato vestavÄ›ná funkce byla na vaÅ¡em hostiteli zakázaná. Piwik se pokusà tuto funkci emulovat, ale můžete zaznamenat dalšà bezpeÄnostnà omezenÃ. Výkonnost trackeru bude také omezena.", + "SystemCheckParseIniFileHelp": "Tato vestavÄ›ná funkce byla na vaÅ¡em hostiteli zakázána. Piwik se pokusà tuto funkci emulovat, ale můžete zaznamenat dalšà bezpeÄnostnà omezenÃ. Výkonnost trackeru bude také omezena.", "SystemCheckPdoAndMysqliHelp": "Na GNU\/Linux systému můžete zkompilovat PHP s následujÃcÃmi volbami: %1$s PÅ™idejte následujÃcà řádky do php.ini: %2$s", "SystemCheckPhp": "Verze PHP", "SystemCheckPhpPdoAndMysqli": "VÃce informacà na: %1$sPHP PDO%2$s and %3$sMYSQLI%4$s.", "SystemCheckSplHelp": "MusÃte pÅ™ekompilovat PHP s povolenou standardnà PHP knihovou (ve výchozÃm stavu povolena).", "SystemCheckSettings": "Požadovaná konfigurace PHP (php.ini)", - "SystemCheckSummaryNoProblems": "Hurááá! Nejsou zde žádné problémy s nastavenÃm Piwiku. Gratulujeme", + "SystemCheckSummaryNoProblems": "Hurááá! Nejsou zde žádné problémy s nastavenÃm Piwiku. Gratulujeme!", "SystemCheckSummaryThereWereErrors": "Ajaj! Piwik zjistil %1$skritické problémy%2$s s nastavenÃm instalace Piwiku. %3$sTyto problémy musà být okamžitÄ› vyÅ™eÅ¡eny.%4$s", - "SystemCheckSummaryThereWereWarnings": "JVyskytly se problémy s vaÅ¡Ãm systémem. Piwik poběžÃ, ale možná se nevyhnete menÅ¡Ãm problémům.", - "SystemCheckTimeLimitHelp": "na webech s vysokým pÅ™enosem, může archivace vyžadovat vÃce Äasu, než je nynà povoleno.<br \/>Pokud je potÅ™eba podÃvejte se na direktivu max_execution_time ve vaÅ¡em souboru php.ini", + "SystemCheckSummaryThereWereWarnings": "Vyskytly se problémy s vaÅ¡Ãm systémem. Piwik poběžÃ, ale možná se nevyhnete menÅ¡Ãm problémům.", + "SystemCheckTimeLimitHelp": "na webech s vysokým pÅ™enosem, může archivace vyžadovat vÃce Äasu, než je nynà povoleno. Pokud je potÅ™eba, podÃvejte se na direktivu max_execution_time ve svém souboru php.ini", "SystemCheckTracker": "Stav sledovánÃ", - "SystemCheckTrackerHelp": "Get požadavek na piwik.php selhal. Zkuste vylouÄit tuto URL z HTTP autentizace a zakažte mod_security (možná budete muset požádat vaÅ¡eho poskytovatele hostingu). VÃce informacà naleznete v záznamu chyb web serveru.", + "SystemCheckTrackerHelp": "Get požadavek na piwik.php selhal. Zkuste vylouÄit tuto URL z HTTP autentizace a zakažte mod_security (možná budete muset požádat svého poskytovatele hostingu). VÃce informacà naleznete v záznamu chyb web serveru.", "SystemCheckWarnDomHelp": "MÄ›li byste povolit \"dom\" rozÅ¡ÃÅ™enà t. j. nainstalovat balÃÄek \"php-dom\" nebo \"php-xml\".", - "SystemCheckWarning": "Piwik bude pracovat normálnÄ›, ale nÄ›které funkce budou chybÄ›t", + "SystemCheckWarning": "Piwik bude pracovat normálnÄ›, ale nÄ›které funkce mohou chybÄ›t", "SystemCheckWarnJsonHelp": "Pro lepšà výkon byste mÄ›li povolit rozÅ¡ÃÅ™enà \"json\" t. j. nainstalovat balÃÄek \"php-json\".", "SystemCheckWarnLibXmlHelp": "Protože je vyžadováno dalÅ¡Ãmi php rozÅ¡ÃÅ™enÃmi, mÄ›li byste povolit rozÅ¡ÃÅ™enà \"libxml\" t. j. nainstalovat balÃÄek \"php-libxml\".", "SystemCheckWarnSimpleXMLHelp": "MÄ›li byste povolit rozÅ¡ÃÅ™enà \"SimpleXML\" t. j. nainstalovat balÃÄek \"php-simplexml\" nebo \"php-xml\".", @@ -116,9 +116,9 @@ "SystemCheckZlibHelp": "MusÃte nakonfigurovat a pÅ™ekompilovat PHP s podporou pro \"zlib\", --with-zlib", "SystemCheckCronArchiveProcess": "ArchivaÄnà cron", "SystemCheckCronArchiveProcessCLI": "Správa procesů pomocà CLI", - "SystemCheckPhpSetting": "Abyste zabránili vážným problémům, ve vaÅ¡em souboru php.ini musÃte nastavit %s", + "SystemCheckPhpSetting": "Abyste zabránili vážným problémům, ve svém souboru php.ini musÃte nastavit %s", "SystemCheckUpdateHttps": "Aktualizace pÅ™es HTTPS", - "SystemCheckUpdateHttpsNotSupported": "Piwik nemůže použÃt HTTPS pro aktualizaci, bude použit nezabezpeÄený protokol HTTP. Ověřte že je podporováno CURL nebo allow_url_fopen a že je nainstalované rozÅ¡ÃÅ™enà openssl PHP: http:\/\/piwik.org\/faq\/troubleshooting\/faq_177\/.", + "SystemCheckUpdateHttpsNotSupported": "Piwik nemůže použÃt HTTPS pro aktualizaci, bude použit nezabezpeÄený protokol HTTP. Ověřte, že je podporováno CURL nebo allow_url_fopen a že je nainstalované rozÅ¡ÃÅ™enà openssl PHP: http:\/\/piwik.org\/faq\/troubleshooting\/faq_177\/.", "NotSupported": "nepodporováno", "Tables": "Vytvářenà tabulek", "TablesCreatedSuccess": "Tabulky vytvoÅ™eny úspěšnÄ›!", @@ -132,9 +132,9 @@ "Timezone": "ÄŒasové pásmo webových stránek", "WeHopeYouWillEnjoyPiwik": "Doufáme, že si užijete použÃvánà Piwiku tak, jako si my užÃváme jeho vývoj.", "Welcome": "VÃtejte!", - "WelcomeHelp": "<p>Piwik je open source program pro analýzu webu, pomocà kterého můžete jednoduÅ¡e zÃskat informace, které chcete od vaÅ¡Ãch návÅ¡tÄ›vnÃků.<\/p><p>Tento proces je rozdÄ›len to %s jednoduchých kroků a zabere pÅ™ibližne 5 minut.<\/p>", + "WelcomeHelp": "<p>Piwik je volnÄ› dostupný open source program pro analýzu webu, pomocà kterého můžete jednoduÅ¡e zÃskávat informace o návÅ¡tÄ›vnÃcÃch svého webu.<\/p><p>Tento proces je rozdÄ›len do %s jednoduchých kroků a zabere pÅ™ibližne 5 minut.<\/p>", "WelcomeToCommunity": "VÃtejte v komunitÄ› Piwiku!", "CannotConnectToDb": "Nelze se pÅ™ipojit k databázi", - "CannotConnectToDbResolvingExplanation": "To může být doÄasný problém, zkuste %1$sobnovit stránku%2$s. Pokud problém pÅ™etrvá, kontaktujte vaÅ¡eho administrátora Piwiku." + "CannotConnectToDbResolvingExplanation": "To může být doÄasný problém, zkuste %1$sobnovit stránku%2$s. Pokud problém pÅ™etrvá, kontaktujte svého administrátora Piwiku." } } \ No newline at end of file diff --git a/plugins/Installation/lang/fr.json b/plugins/Installation/lang/fr.json index 1fea6290ca2920298dc49b33adf79c767263d20a..d20170b82aceac4bcf25bbee73b71781f72cb6a0 100644 --- a/plugins/Installation/lang/fr.json +++ b/plugins/Installation/lang/fr.json @@ -115,7 +115,7 @@ "SystemCheckZlibHelp": "Vous devez reconfigurer et recompiler PHP avec le support zlib, --with-zlib.", "SystemCheckCronArchiveProcess": "Tâche Cron d'archivage", "SystemCheckCronArchiveProcessCLI": "Gestion des processus via la ligne de commande", - "SystemCheckPhpSetting": "Pour éviter certaines erreurs critique, vous devez définier les entrées suivantes dans votre fichier php.ini : %s", + "SystemCheckPhpSetting": "Pour éviter certaines erreurs critique, vous devez définir les entrées suivantes dans votre fichier php.ini : %s", "SystemCheckUpdateHttps": "Mettre à jour via HTTPS", "SystemCheckUpdateHttpsNotSupported": "Piwik ne peut pas utiliser du HTTPS pour se mettre à jour, il va rétrograder vers une mise à jour utilisant du HTTP non sécurisé. Vérifiez que CURL ou allow_url_fopen est supporté et que l'extesion PHP openssl est installée: http:\/\/piwik.org\/faq\/troubleshooting\/faq_177\/", "NotSupported": "non supporté", diff --git a/plugins/Installation/lang/ja.json b/plugins/Installation/lang/ja.json index d6d57a86005709e0279b59662d9bd51e683f2c81..a2bfe0e5b4c0f340b513af9e01d9d55139e6fed1 100644 --- a/plugins/Installation/lang/ja.json +++ b/plugins/Installation/lang/ja.json @@ -15,6 +15,7 @@ "DatabaseSetupLogin": "ãƒã‚°ã‚¤ãƒ³å", "DatabaseSetupServer": "データベースサーãƒãƒ¼", "DatabaseSetupTablePrefix": "テーブルプレフィックス", + "Email": "メール", "Extension": "エクステンション", "Filesystem": "ファイルシステム", "GetInvolved": "ã‚‚ã— Piwik ã‚’æ°—ã«ã£ã¦é ‚ã‘ãŸã‚‰ã€æ˜¯éž %1$sget involved%2$s 。", @@ -24,6 +25,7 @@ "InstallationStatus": "インストール状æ³", "InsufficientPrivilegesHelp": "phpMyAdminã®ã‚ˆã†ãªãƒ„ールを使用ã™ã‚‹ã‹ã€æ£ã—ã„SQLクエリを実行ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ã“ã‚Œã‚‰ã®æ¨©é™ã‚’è¿½åŠ ã§ãã¾ã™ã€‚やり方ãŒã‚ã‹ã‚‰ãªã„å ´åˆã¯ã€ã‚·ã‚¹ãƒ†ãƒ 管ç†è€…ã«ä¾é ¼ã—ã¦ã€æ¨©é™ã‚’付与ã—ã¦ã‚‚らã£ã¦ãã ã•ã„。", "InsufficientPrivilegesMain": "データベースãŒå˜åœ¨ã—ãªã„ ( ãŠã‚ˆã³ä½œæˆã§ããªã„ ) ã€ã¾ãŸã¯å…·ä½“çš„ãªãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒååˆ†ãªæ¨©é™ã‚’æŒã£ã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚データベースユーザーã¯ã€æ¬¡ã®æ¨©é™ã‚’有ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚: %s", + "InvalidStateError": "エラー: Piwik ãŒæ—¢ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ã€‚Piwik %3$s 㸠%1$s 戻る %2$s 。", "JsTagArchivingHelp1": "ä¸ï½žé«˜ãƒˆãƒ©ãƒ•ィックã®ã‚¦ã‚§ãƒ–サイトã®ãŸã‚ã«ã€Piwik をより早ã(例ãˆã° %1$ssetting up auto-archiving%2$s ã®ã‚ˆã†ã«) 実行ã™ã‚‹ãŸã‚ã®æœ€é©åŒ–ã®æ‰‹æ®µãŒã‚りã¾ã™ã€‚", "JSTracking_EndNote": "注:インストールã®å‡¦ç†å¾Œã€%1$sTracking Code%2$s ã®ç®¡ç†ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã§ã€ãƒˆãƒ©ãƒƒã‚ングコードã®ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã‚’行ã†ã“ã¨ãŒã§ãã¾ã™ã€‚", "JSTracking_Intro": "Piwik ã§ã‚¦ã‚§ãƒ–トラフィックã®è¿½è·¡ã‚’ã™ã‚‹ã«ã¯ã€ä¸€éƒ¨ã®ç‰¹åˆ¥ãªã‚³ãƒ¼ãƒ‰ãŒå„ web ページã«è¿½åŠ ã•れã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’確èªã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚", @@ -36,20 +38,28 @@ "NfsFilesystemWarningSuffixInstall": "NFS 上ã§ãƒ•ァイルベースã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’利用ã™ã‚‹ã¨æ¥µç«¯ã«é…ã„ã®ã§ã€Piwik ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’使用ã—ã¾ã™ã€‚åŒæ™‚ã«å¤šãã®ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒã„ã‚‹å ´åˆã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚µãƒ¼ãƒãƒ¼ã¸ã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆæŽ¥ç¶šã®æœ€å¤§æ•°ã‚’増やã™å¿…è¦ãŒã‚りã¾ã™ã€‚", "NoConfigFound": "Piwik ã®è¨å®šãƒ•ァイルを見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸãŒã€ã‚ãªãŸã¯ Piwik ページã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚<br \/><b>  »<a href='index.php'>ãŸã ã¡ã« Piwik をインストール<\/a>ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚<\/b><br \/><small>以å‰ã« Piwik をインストールã—ãŸã“ã¨ãŒã‚りã€DB ã«å¤šå°‘ã®ãƒ‡ãƒ¼ã‚¿ãŒã‚ã‚‹å ´åˆã§ã‚‚心é…ã—ãªã„ã§ãã ã•ã„。 æ—¢å˜ã®ãƒ‡ãƒ¼ã‚¿ã‚’ä¿æŒã—ãŸã¾ã¾ã€åŒã˜ãƒ†ãƒ¼ãƒ–ルをå†åˆ©ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ï¼<\/small>", "Optional": "オプション", + "Password": "パスワード", "PasswordDoNotMatch": "パスワードãŒä¸€è‡´ã—ã¾ã›ã‚“ã§ã—ãŸ", + "PasswordRepeat": "パスワード (å†å…¥åŠ›)", "PercentDone": "%s %% 完了", "PleaseFixTheFollowingErrors": "次ã®ã‚¨ãƒ©ãƒ¼ã‚’ä¿®æ£ã—ã¦ãã ã•ã„", + "DefaultSettings": "Piwik ã®ãƒ‡ãƒ•ォルトã®è¨å®š", + "DefaultSettingsHelp": "Piwik ã®è¨å®šã¯ãƒ‡ãƒ•ォルトã§ã™ã€‚後ã§ç®¡ç†ç”»é¢ã‹ã‚‰ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚", "Requirements": "Piwik ã®å‹•作環境", "RestartWebServer": "ã“ã®å¤‰æ›´ã‚’行ã£ãŸå¾Œã€ã‚¦ã‚§ãƒ–サーãƒãƒ¼ã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„。", "ReusingTables": "表ã®å†åˆ©ç”¨", "PiwikOrgNewsletter": "ç§ã« Piwik ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã®æœ€æ–°æƒ…å ±ã‚’ãƒ¡ãƒ¼ãƒ«ã§é€ã‚‹", + "PiwikProNewsletter": "%s Piwik PRO %s ã®ã‚µãƒ¼ãƒ“ã‚¹ã‚„æœ€æ–°æƒ…å ±ã‚’é€ã£ã¦ãã ã•ã„", "SeeBelowForMoreInfo": "詳細ã¯ã€ä»¥ä¸‹ã‚’ã”確èªãã ã•ã„。", "SetupWebsite": "ウェブサイトã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—", "SetupWebsiteError": "ã‚¦ã‚§ãƒ–ã‚µã‚¤ãƒˆã‚’è¿½åŠ ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ", + "SetupWebSiteName": "ウェブサイトã®åå‰", "SetupWebsiteSetupSuccess": "ウェブサイト %s ã¯æ£å¸¸ã«ä½œæˆã•れã¾ã—ãŸï¼", + "SetupWebSiteURL": "ウェブサイト㮠URL", "SiteSetup": "Piwik ã§è¿½è·¡ãƒ»åˆ†æžã—ãŸã„åˆã‚ã®ã‚¦ã‚§ãƒ–サイトをè¨å®šã—ã¦ãã ã•ã„。", "SiteSetupFootnote": "注: Piwik ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå®Œäº†ã™ã‚‹ã¨ã€ã•らã«è¿½è·¡å¯¾è±¡ã®ã‚¦ã‚§ãƒ–ã‚µã‚¤ãƒˆã‚’è¿½åŠ ã™ã‚‹ã“ã¨ãŒã§ãるよã†ã«ãªã‚Šã¾ã™!", "SuperUser": "スーパーユーザー", + "SuperUserLogin": "スーパーユーザーã®ãƒã‚°ã‚¤ãƒ³", "SuperUserSetupError": "スーパーユーザーã®è¿½åŠ æ™‚ã«ã€ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚", "SuperUserSetupSuccess": "スーパーユーザーã®ä½œæˆã«æˆåŠŸã—ã¾ã—ãŸï¼", "SystemCheck": "システムã®ç¢ºèª", @@ -63,6 +73,7 @@ "SystemCheckExtensions": "ãã®ä»–ã®å¿…é ˆã‚¨ã‚¯ã‚¹ãƒ†ãƒ³ã‚·ãƒ§ãƒ³", "SystemCheckFileIntegrity": "ãƒ•ã‚¡ã‚¤ãƒ«ã®æ•´åˆæ€§", "SystemCheckFunctions": "å¿…é ˆé–¢æ•°", + "SystemCheckFunctionHelp": "ã‚ãªãŸã¯ã€ã“ã®ãƒ“ルトイン関数を有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚", "SystemCheckGDFreeType": "GD > 2.x + Freetype (graphics)", "SystemCheckGDHelp": "スパークライン(å°ã•ãªã‚°ãƒ©ãƒ•)ã¯å‹•作ã—ã¾ã›ã‚“。", "SystemCheckGlobHelp": "ã“ã®çµ„ã¿è¾¼ã¿é–¢æ•°ã¯ãƒ›ã‚¹ãƒˆã§ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™ã€‚ Piwik ã¯ã“ã®é–¢æ•°ã®ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ãƒˆã‚’試ã¿ã¾ã™ãŒã€ã•らãªã‚‹ã‚»ã‚ュリティ制é™ã«éé‡ã™ã‚‹å ´åˆãŒã‚りã¾ã™ã€‚ ã¾ãŸã€æ©Ÿèƒ½æ€§ã«ã‚‚影響を与ãˆã‚‹å ´åˆãŒã‚りã¾ã™ã€‚", @@ -93,6 +104,7 @@ "SystemCheckSummaryThereWereWarnings": "システムã«ã„ãã¤ã‹ã®å•題ãŒã‚りã¾ã™ã€‚Piwik ã¯å®Ÿè¡Œã§ãã¾ã™ãŒã€ã„ãã¤ã‹å°ã•ãªå•題ãŒã¿ã‚‰ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚", "SystemCheckTimeLimitHelp": "アクセス数ã®å¤šã„ウェブサイトã§ã¯ã€ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–処ç†ã®å®Ÿè¡Œã«ã€ç¾åœ¨è¨±å¯ã•れã¦ã„る以上ã«å¤šãã®æ™‚é–“ã‚’å¿…è¦ã¨ã™ã‚‹å ´åˆãŒã‚りã¾ã™ã€‚<br \/>å¿…è¦ã§ã‚れã°ã€php.ini ファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒ†ã‚£ãƒ– max_execution_time ã‚’å‚ç…§ã—ã¦ãã ã•ã„。", "SystemCheckTracker": "トラッカー状æ³", + "SystemCheckTrackerHelp": "失敗ã—㟠piwik.php ã¸ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’å–å¾—ã—ã¾ã™ã€‚HTTP èªè¨¼ã‹ã‚‰ã®ã“ã® URL ã®ãƒ›ãƒ¯ã‚¤ãƒˆ リスト化を試ã¿ã¦ã€mod_security を無効ã«ã—ã¾ã™(ウェブホストã«ä¾é ¼ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™)。エラーã®è©³ç´°ã«ã¤ã„ã¦ã¯ã€web サーãƒãƒ¼ã®ã‚¨ãƒ©ãƒ¼ ãƒã‚° ファイルを確èªã—ã¾ã™ã€‚", "SystemCheckWarnDomHelp": "\"dom\" エクステンションを有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ï¼ˆä¾‹ãˆã° \"php-dom\" 㨠\"php-xml\" パッケージã®ã©ã¡ã‚‰ã‹ã€ã‚ã‚‹ã„ã¯ä¸¡æ–¹ã‚’インストールã™ã‚‹ï¼‰ã€‚", "SystemCheckWarning": "Piwik ã¯æ£å¸¸ã«å‹•作ã—ã¾ã™ãŒã€ã„ãã¤ã‹ã®æ©Ÿèƒ½ã¯å‹•作ã—ãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。", "SystemCheckWarnJsonHelp": "より良ã„パフォーマンスã®ãŸã‚ã«ã€\"json\" エクステンションを有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ï¼ˆä¾‹ãˆã° \"php-json\" パッケージをインストールã™ã‚‹ï¼‰ã€‚", @@ -117,6 +129,7 @@ "TablesUpdatedSuccess": "データベース㮠%1$s ã‹ã‚‰ %2$s ã¸ã®ã‚¢ãƒƒãƒ—ãƒ‡ãƒ¼ãƒˆãŒæˆåŠŸã—ã¾ã—ãŸã€‚", "TablesWarningHelp": "æ—¢å˜ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ†ãƒ¼ãƒ–ルをå†åˆ©ç”¨ã™ã‚‹ã‹ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å†…ã®å…¨ãƒ‡ãƒ¼ã‚¿ã‚’消去ã—ã¦ã‚¯ãƒªãƒ¼ãƒ³ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã‹ã‚’é¸æŠžã—ã¦ãã ã•ã„。", "TablesWithSameNamesFound": "%1$sæ—¢å˜ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å†…ã®ã„ãã¤ã‹ã®ãƒ†ãƒ¼ãƒ–ル%2$sãŒã€Piwik ãŒä½œæˆã—よã†ã¨ã—ã¦ã„るテーブルã¨åŒã˜åå‰ã‚’æŒã£ã¦ã„ã¾ã™", + "Timezone": "ウェブサイトã®ã‚¿ã‚¤ãƒ ゾーン", "WeHopeYouWillEnjoyPiwik": "ç§é”㌠Piwik ã®é–‹ç™ºã‚’楽ã—ã‚“ã§ã„るよã†ã«ã€Piwik ã®ã”åˆ©ç”¨ã‚’ãŠæ¥½ã—ã¿é ‚ã‘る事を願ã£ã¦ã„ã¾ã™ã€‚", "Welcome": "よã†ã“ãï¼", "WelcomeHelp": "<p>Piwik ã¯ã€ãƒ“ジターã‹ã‚‰ã‚ãªãŸãŒå¿…è¦ã¨ã™ã‚‹æƒ…å ±ã‚’åŽé›†ã™ã‚‹ã“ã¨ã‚’容易ã«ã™ã‚‹ã€ã‚ªãƒ¼ãƒ—ンソースã®ã‚¦ã‚§ãƒ–è§£æžã‚½ãƒ•トウェアã§ã™ã€‚<\/p><p>ã“ã®å‡¦ç†ã¯ %s ã®ç°¡å˜ãªã‚¹ãƒ†ãƒƒãƒ—ã«åˆ†ã‹ã‚Œã¦ã„ã¦ã€5分程度ã§å®Œäº†ã—ã¾ã™ã€‚<\/p>", diff --git a/plugins/Installation/lang/ko.json b/plugins/Installation/lang/ko.json index ff083470d6e2875b0a767c9ab19e73ce85f92754..3fa7374b09e81bb16a0a7ecca5b958a8041cf0f1 100644 --- a/plugins/Installation/lang/ko.json +++ b/plugins/Installation/lang/ko.json @@ -1,5 +1,6 @@ { "Installation": { + "CollaborativeProject": "Piwik는 ì „ì„¸ê³„ 사람들과 함께 만들어 나가는 í˜‘ë™ í”„ë¡œì 트입니다.", "ConfigurationHelp": "Piwik ì„¤ì • 파ì¼ì´ 잘못 ì„¤ì •ë˜ì–´ìžˆëŠ” 것 같습니다. config\/config.ini.php를 ì œê±°í•˜ê³ ì„¤ì¹˜ë¥¼ 다시 시작하거나 ë°ì´í„°ë² ì´ìŠ¤ì˜ ì—°ê²° ì„¤ì •ì„ ìˆ˜ì •í•˜ì„¸ìš”.", "ConfirmDeleteExistingTables": "í…Œì´ë¸” %s ì„(를) ë°ì´í„°ë² ì´ìŠ¤ë¡œë¶€í„° ì‚ì œí•˜ê¸°ë¥¼ ì›í•©ë‹ˆê¹Œ? ê²½ê³ : ì´ í…Œì´ë¸”ì˜ ë°ì´í„°ëŠ” 복구ë˜ì§€ 않습니다!", "Congratulations": "축하합니다", @@ -14,12 +15,20 @@ "DatabaseSetupLogin": "로그ì¸", "DatabaseSetupServer": "ë°ì´í„°ë² ì´ìФ 서버", "DatabaseSetupTablePrefix": "í…Œì´ë¸” ì ‘ë‘사", + "Email": "ì´ë©”ì¼", "Extension": "확장", "Filesystem": "파ì¼ì‹œìŠ¤í…œ", + "GetInvolved": "만약 ì´ë¥¼ 좋아한다면, ì–¸ì œë¼ë„ %1$sì°¸ì—¬í• ìˆ˜ 있습니다%2$s.", "GoBackAndDefinePrefix": "ëŒì•„가서 Piwik í…Œì´ë¸”ì„ ìœ„í•´ Prefix를 ì •ì˜í•©ë‹ˆë‹¤", + "HappyAnalysing": "ì¦ê±°ìš´ ë¶„ì„!", "Installation": "설치", "InstallationStatus": "설치 ìƒíƒœ", "InsufficientPrivilegesHelp": "phpMyAdmin ê°™ì€ ë„구를 사용하거나 올바른 SQL 쿼리를 실행하여 ì´ëŸ¬í•œ ê¶Œí•œì„ ì¶”ê°€ í• ìˆ˜ 있습니다. ë°©ë²•ì„ ìž˜ 모를 경우 시스템 관리ìžì—게 문ì˜í•˜ì—¬ ê¶Œí•œì„ ë¶€ì—¬ 받으세요.", + "InsufficientPrivilegesMain": "ë°ì´í„°ë² ì´ìŠ¤ê°€ 존재하지 않거나 (í˜¹ì€ ìƒì„±ë˜ì§€ 않았거나), ì§€ì •ëœ ì‚¬ìš©ìžê°€ 충분한 ê¶Œí•œì„ ê°€ì§€ê³ ìžˆì§€ 않습니다. ë°ì´í„°ë² ì´ìФ 사용ìžëŠ” 반드시 ì•„ëž˜ì˜ ê¶Œí•œì„ ê°€ì§€ê³ ìžˆì–´ì•¼ 합니다: %s", + "InvalidStateError": "ì—러: Piwikê°€ ì´ë¯¸ 설치ë˜ì–´ 있습니다. %1$s ë’¤ëŒì•„ 가기 %2$s ì„¤ì¹˜ëœ Piwik로...%3$s.", + "JsTagArchivingHelp1": "ì¤‘ê°„ì˜ í˜¹ì€ ë†’ì€ íŠ¸ëž˜í”½ì„ ê°€ì§„ 웹사ì´íŠ¸ë¥¼ 위해 Piwik를 ë¹ ë¥´ê²Œ ë™ìž‘시키는 여러 최ì í™” 기법(예: %1$sìžë™-ì•„ì¹´ì´ë¸Œ 작업 ì„¤ì •%2$s)ì´ ì œê³µë˜ê³ 있습니다.", + "JSTracking_EndNote": "ì°¸ê³ : ì¸ìŠ¤í†¨ ê³¼ì •ì´ ë난 후 %1$s트래킹 코드%2$s ê´€ë¦¬ìž í™”ë©´ì—서 맞춤 트래킹 코드를 ìƒì„±í• 수 있습니다.", + "JSTracking_Intro": "웹사ì´íЏ ë‚´ íŠ¸ëž˜í”½ì„ ì¶”ì 하기 위해서 ë‹¹ì‹ ì˜ ê° ì›¹íŽ˜ì´ì§€ì— 코드를 추가해야 합니다.", "LargePiwikInstances": "ë†’ì€ íŠ¸ëž˜í”½ 환경ì—서 Piwik를 사용하기 위한 íŒ", "Legend": "범례", "LoadDataInfileRecommended": "íŠ¸ëž˜í”½ì´ ë†’ì€ ì›¹ì‚¬ì´íŠ¸ë¥¼ Piwik 서버ì—서 ì¶”ì í•˜ë ¤ëŠ” 경우 (예: 한달 100,000 페ì´ì§€ë·° ì´ìƒ), ì´ ë¬¸ì œë¥¼ í•´ê²°í•˜ê³ ì‚¬ìš©í• ê²ƒì„ ê¶Œìž¥í•©ë‹ˆë‹¤.", @@ -29,22 +38,34 @@ "NfsFilesystemWarningSuffixInstall": "NFSì˜ íŒŒì¼ ê¸°ë°˜ ì„¸ì…˜ì„ ì‚¬ìš©í•˜ë©´ 매우 ëŠë¦½ë‹ˆë‹¤, 그래서 Piwik ë°ì´í„°ë² ì´ìФ ì„¸ì…˜ì„ ì‚¬ìš©í•©ë‹ˆë‹¤. 대시보드 사용ìžê°€ ë§Žì€ ê²½ìš°ëŠ”, ë°ì´í„°ë² ì´ìФ ì„œë²„ì— í´ë¼ì´ì–¸íЏ ì—°ê²°ì˜ ìµœëŒ€ 수를 ì¦ê°€í•´ì•¼ í• ì§€ë„ ëª¨ë¦…ë‹ˆë‹¤.", "NoConfigFound": "Piwik ì„¤ì • 파ì¼ì„ ì°¾ì„ ìˆ˜ 없으며 ë‹¹ì‹ ì€ Piwik 페ì´ì§€ë¡œ ì ‘ê·¼ì„ ê³„ì† ì‹œë„í•˜ê³ ìžˆìŠµë‹ˆë‹¤.<br \/><b>  » <a href='index.php'>지금 Piwikì„ ì„¤ì¹˜í•˜ì„¸ìš”.<\/a><\/b><br \/><small>만약 Piwikì„ ì´ì „ì— ì„¤ì¹˜í•œ ì ì´ ìžˆê³ DBì— í…Œì´ë¸”ì´ ì¢€ 있다면 ê±±ì •í•˜ì§€ë§ˆì„¸ìš”, ê°™ì€ í…Œì´ë¸”ì„ ìž¬ì‚¬ìš©í• ìˆ˜ ìžˆê³ í˜„ìž¬ ë°ì´í„°ë¥¼ ë³´ì¡´í• ìˆ˜ 있습니다!<\/small>", "Optional": "옵션", + "Password": "비밀번호", "PasswordDoNotMatch": "비밀번호가 ë§žì§€ 않습니다", + "PasswordRepeat": "비밀번호 (반복 ìž…ë ¥)", "PercentDone": "%s %% 완료", "PleaseFixTheFollowingErrors": "ë‹¤ìŒ ì˜¤ë¥˜ë¥¼ ìˆ˜ì •í•˜ì„¸ìš”", + "DefaultSettings": "기본 Piwik ì„¤ì •", + "DefaultSettingsHelp": "Piwik 기본 ì„¤ì •ì— ë”°ë¦…ë‹ˆë‹¤. ì´ë¥¼ 지금 í˜¹ì€ í›„ì— ê´€ë¦¬ìž í™”ë©´ì—서 ë³€ê²½í• ìˆ˜ 있습니다.", "Requirements": "Piwik 요구 사í•", "RestartWebServer": "변경한 후 웹서버를 다시 시작하세요.", + "ReusingTables": "í…Œì´ë¸”", + "PiwikOrgNewsletter": "주요 Piwik ì»¤ë®¤ë‹ˆí‹°ì˜ ì—…ë°ì´íЏ ì´ë©”ì¼ êµ¬ë…", + "PiwikProNewsletter": "%sPiwik PRO%s 서비스 ë° ì‹ ì²ê³¼ ê´€ë ¨í•œ ì •ë³´ 받기", "SeeBelowForMoreInfo": "ìžì„¸í•œ ë‚´ìš©ì€ ì•„ëž˜ë¥¼ 참조하세요.", "SetupWebsite": "웹사ì´íЏ ì„¤ì •", "SetupWebsiteError": "웹사ì´íЏ ì¶”ê°€ì¤‘ì— ì—러가 있었습니다", + "SetupWebSiteName": "웹사ì´íЏ", "SetupWebsiteSetupSuccess": "웹사ì´íЏ %sê°€ 성공ì 으로 작성ë˜ì—ˆìŠµë‹ˆë‹¤!", - "SiteSetup": "Piwik으로 ì¶”ì ë° ë¶„ì„í•˜ë ¤ëŠ” 첫 번째 웹사ì´íŠ¸ë¥¼ ì„¤ì •í•˜í•˜ì„¸ìš”:", + "SetupWebSiteURL": "웹사ì´íЏ URL", + "SiteSetup": "Piwik으로 ì¶”ì ë° ë¶„ì„í•˜ë ¤ëŠ” 첫 번째 웹사ì´íŠ¸ë¥¼ ì„¤ì •í•˜ì„¸ìš”:", "SiteSetupFootnote": "ì°¸ê³ : Piwik 설치가 완료ë˜ë©´, ë” ë§Žì€ ì›¹ì‚¬ì´íŠ¸ë¥¼ ì¶”ì í• ìˆ˜ 있습니다!", - "SuperUser": "ìˆ˜í¼ ìœ ì €", - "SuperUserSetupSuccess": "ìˆ˜í¼ ìœ ì €ê°€ 만들어졌습니다!", + "SuperUser": "ìŠˆí¼ ìœ ì €", + "SuperUserLogin": "ìŠˆí¼ ìœ ì € 로그ì¸", + "SuperUserSetupError": "ìŠˆí¼ ìœ ì €ë¥¼ ì¶”ê°€í•¨ì— ìžˆì–´ ë¬¸ì œê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤.", + "SuperUserSetupSuccess": "ìŠˆí¼ ìœ ì €ê°€ 만들어졌습니다!", "SystemCheck": "시스템 ì²´í¬", "SystemCheckAutoUpdateHelp": "주ì˜: Piwikì˜ ì›í´ë¦ ì—…ë°ì´íŠ¸ëŠ” Piwik í´ë”와 파ì¼ì— 쓰기 ê¶Œí•œì´ í•„ìš”í•©ë‹ˆë‹¤.", "SystemCheckCreateFunctionHelp": "Piwikì€ ì½œë°±ì— ìµëª… 함수를 사용합니다.", + "SystemCheckDatabaseExtensions": "MySQL 확장", "SystemCheckDatabaseHelp": "Piwikì€ mysqli 확장하거나 PDO와 pdo_mysql í™•ìž¥ì˜ ë‘˜ 중 하나가 필요합니다.", "SystemCheckDebugBacktraceHelp": "View::factory는 ëª¨ë“ˆì„ í˜¸ì¶œí•˜ì—¬ 뷰를 만들 수 없습니다.", "SystemCheckError": "ì—러 ë°œìƒ - ì§„í–‰ ì „ì— ìˆ˜ì •ì´ í•„ìš”í•¨", @@ -52,30 +73,38 @@ "SystemCheckExtensions": "필수 확장", "SystemCheckFileIntegrity": "íŒŒì¼ ë¬´ê²°ì„±", "SystemCheckFunctions": "필수 기능", + "SystemCheckFunctionHelp": "ë¹ŒíŠ¸ì¸ í•¨ìˆ˜ë“¤ì„ í™œì„±í™”í•´ì•¼ 합니다.", + "SystemCheckGDFreeType": "GD > 2.x + Freetype (그래픽)", "SystemCheckGDHelp": "스파í¬ë¼ì¸(소규모 그래프)ì€ ìž‘ë™í•˜ì§€ 않습니다.", "SystemCheckGlobHelp": "ì´ ë‚´ìž¥ 함수는 호스트ì—서 비활성화ë˜ì–´ 있습니다. Piwikì´ í•¨ìˆ˜ì˜ ì—ë®¬ë ˆì´ì…˜ì„ 시ë„하지만, 새로운 보안 ì œí•œìœ¼ë¡œ ë°œìƒí•˜ëŠ” 경우가 있습니다. ë˜í•œ ê¸°ëŠ¥ì— ì˜í–¥ì„ ë¯¸ì¹ ìˆ˜ 있습니다.", "SystemCheckGzcompressHelp": "zlib 확장과 gzcompress() 함수를 활성화해야합니다.", "SystemCheckGzuncompressHelp": "zlib 확장과 gzuncompress() 함수를 활성화해야합니다.", "SystemCheckIconvHelp": "\"iconv\"ì˜ ì§€ì›ì„ í™œì„±í™”í•˜ê³ , PHP 재구축 ì„¤ì •ì„ í•´ì•¼í•©ë‹ˆë‹¤ --with-iconv.", + "SystemCheckJsonHelp": "Piwikê°€ JSON ë°ì´í„°ë¥¼ ì½ê³ 쓰기 위해서 php5-json í™•ìž¥ì´ í•„ìš”í•©ë‹ˆë‹¤.", "SystemCheckMailHelp": "mail() ì—†ì´ í”¼ë“œë°±ê³¼ 잊어버린 비밀번호 메세지는 보내지지 않습니다.", "SystemCheckMbstring": "mbstring", + "SystemCheckMbstringHelp": "mbstring í™•ìž¥ì€ ì‚¬ìš©ìž ì¸í„°íŽ˜ì´ìŠ¤ì™€ API ì‘답 ë‚´ 멀티바ì´íЏ 문ìžì—´ì„ ë‹¤ë£¨ëŠ”ë° í•„ìš”í•©ë‹ˆë‹¤. ë˜í•œ, php.ini ë‚´ mbstring.func_overloadì´ 0으로 ë˜ì–´ 있는지 확ì¸í•˜ì„¸ìš”.", "SystemCheckMemoryLimit": "메모리 ì œí•œ", "SystemCheckMemoryLimitHelp": "ë†’ì€ íŠ¸ëž˜í”½ì˜ ì›¹ì‚¬ì´íЏì—서는 ì••ì¶• ì§„í–‰ì¤‘ì— í˜„ìž¬ í—ˆìš©ëœ ê²ƒë³´ë‹¤ ë” ë†’ì€ ë©”ëª¨ë¦¬ë¥¼ 필요로 í• ìˆ˜ 있습니다. 만약 필요하다면 php.ini 파ì¼ì—서 memory_limitì„ ë³€ê²½í•˜ì„¸ìš”.", "SystemCheckOpenURL": "URL 열기", "SystemCheckOpenURLHelp": "뉴스 ë ˆí„° 구ë…, ì—…ë°ì´íЏ 알림, ì› í´ë¦ ì—…ë°ì´íŠ¸ëŠ” \"curl\"확장, allow_url_fopen = On ë˜ëŠ” fsockopen()ì´ ìœ íš¨í•´ì•¼í•©ë‹ˆë‹¤.", "SystemCheckOtherExtensions": "기타 확장", "SystemCheckOtherFunctions": "기타 함수", + "SystemCheckPageSpeedDisabled": "PageSpeed 비활성화", + "SystemCheckPageSpeedWarn": "우리는 웹서버 %s ë‚´ PageSpeed ëª¨ë“ˆì„ ë¹„í™œì„±í™” 하는 ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤. 그간 Piwikì— ì—¬ëŸ¬ ë¬¸ì œë“¤ì´ PageSpeed와 연관있었습니다.", "SystemCheckPackHelp": "pack() 함수는 Piwikì—서 방문ìžë¥¼ ì¶”ì 하는 ë° í•„ìš”í•©ë‹ˆë‹¤.", "SystemCheckParseIniFileHelp": "ì´ ë‚´ìž¥ 함수는 호스트ì—서 비활성화ë˜ì–´ 있습니다. Piwikì´ í•¨ìˆ˜ì˜ ì—ë®¬ë ˆì´ì…˜ì„ 시ë„하지만, 새로운 보안 ì œí•œìœ¼ë¡œ ë°œìƒí•˜ëŠ” 경우가 있습니다. ë˜í•œ 트래커 성능ì—ë„ ì˜í–¥ì„ 미칩니다.", "SystemCheckPdoAndMysqliHelp": "Linux 서버는 ë‹¤ìŒ ì˜µì…˜ìœ¼ë¡œ PHP를 컴파ì¼í•©ë‹ˆë‹¤: %1$sphp.iniì— ë‹¤ìŒ ì¤„ì„ ì¶”ê°€í•©ë‹ˆë‹¤: %2$s", "SystemCheckPhp": "PHP ë²„ì „", "SystemCheckPhpPdoAndMysqli": "ìžì„¸í•œ 문서: %1$sPHP PDO%2$s and %3$sMYSQLI%4$s.", "SystemCheckSplHelp": "ìŠ¤íƒ ë‹¤ë“œ PHP ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ í™œì„±í™”ëœ ìƒíƒœë¡œ PHP를 ì„¤ì •í•˜ê³ ë¦¬ë¹Œë”©í•´ì•¼ 합니다. (기본).", + "SystemCheckSettings": "요구ë˜ëŠ” PHP ì„¤ì • (php.ini)", "SystemCheckSummaryNoProblems": "만세! Piwik ì„¤ì •ì— ì•„ë¬´ëŸ° ë¬¸ì œê°€ 없습니다. 스스로ì—게 ì¹ì°¬í•˜ì„¸ìš”.", "SystemCheckSummaryThereWereErrors": "í—! Piwik ì„¤ì •ì—서 ì¼ë¶€ %1$s심ê°í•œ 오류%2$s를 ê°ì§€í–ˆìŠµë‹ˆë‹¤. %3$sì´ ë¬¸ì œëŠ” 즉시 해결해야합니다.%4$s", "SystemCheckSummaryThereWereWarnings": "ì‹œìŠ¤í…œì— ëª‡ëª‡ ë¬¸ì œê°€ 있습니다. Piwikê°€ 설치ë˜ì—ˆì§€ë§Œ 몇가지 사소한 ë¬¸ì œê°€ ë°œìƒí• 수 있습니다.", "SystemCheckTimeLimitHelp": "ë†’ì€ íŠ¸ëž˜í”½ì˜ ì›¹ì‚¬ì´íЏì—서는 ì••ì¶• ì§„í–‰ì¤‘ì— í˜„ìž¬ í—ˆìš©ëœ ê²ƒë³´ë‹¤ ë” ë§Žì€ ì‹œê°„ì„ í•„ìš”ë¡œ í• ìˆ˜ 있습니다. 만약 필요하다면 php.ini 파ì¼ì—서 max_execution_timeì„ ë³€ê²½í•˜ì„¸ìš”..", "SystemCheckTracker": "ì¶”ì 기 ìƒíƒœ", + "SystemCheckTrackerHelp": "piwik.phpì—서 GET 리퀘스트가 실패하였습니다. 현재 URLì„ HTTP Authenticationì˜ í™”ì´íЏ ë¦¬ìŠ¤íŠ¸ì— ì¶”ê°€í•´ì£¼ì‹œê³ mod_security를 꺼주시길 ë°”ëžë‹ˆë‹¤(ì´ëŠ” ë‹¹ì‹ ì˜ ì›¹íŽ˜ì´ì§€ 관리ìžì—게 ì—°ë½í•´ì•¼ í• ê²ƒìž…ë‹ˆë‹¤). ì´ë²ˆ ì—러와 ê´€ë ¨í•˜ì—¬ 웹 ì„œë²„ì˜ ì—러 로그 파ì¼ì„ 확ì¸í•˜ì‹¤ ê²ƒì„ ê¶Œìž¥í•©ë‹ˆë‹¤.", "SystemCheckWarnDomHelp": "\"dom\"í™•ìž¥ì„ í™œì„±í™”í•´ì•¼í•©ë‹ˆë‹¤ (예: \"php-dom\"ê³¼ \"php-xml\"패키지 중 하나 ë˜ëŠ” ëª¨ë‘ ì„¤ì¹˜).", "SystemCheckWarning": "Piwik ì€ ì •ìƒì 으로 ìž‘ë™í•˜ì§€ë§Œ ëª‡ëª‡ì˜ ê¸°ëŠ¥ì´ ìž‘ë™í•˜ì§€ ì•Šì„ ìˆ˜ 있습니다.", "SystemCheckWarnJsonHelp": "ë” ë‚˜ì€ ì„±ëŠ¥ì„ ìœ„í•´ \"json\"í™•ìž¥ì„ í™œì„±í™”í•´ì•¼í•©ë‹ˆë‹¤ (예: \"php-json\"패키지를 설치).", @@ -85,15 +114,27 @@ "SystemCheckWriteDirs": "쓰기 ì ‘ê·¼ 가능 ë””ë ‰í† ë¦¬", "SystemCheckWriteDirsHelp": "리눅스 시스템ì—서 ì´ ì—러를 ê³ ì¹˜ê¸° 위해서, ë‹¤ìŒ ëª…ë ¹ì–´ë¥¼ ìž…ë ¥í•´ë³´ì„¸ìš”.", "SystemCheckZlibHelp": "zlib ì§€ì› í™œì„±í™”ëœ ìƒíƒœë¡œ PHP를 ì„¤ì •í•˜ê³ ë¦¬ë¹Œë¹™í•´ì•¼ 합니다.", + "SystemCheckCronArchiveProcess": "ì•„ì¹´ì´ë¸Œ cron", + "SystemCheckCronArchiveProcessCLI": "CLI를 통해서 프로세스 관리", + "SystemCheckPhpSetting": "치명ì ì¸ ë¬¸ì œë¥¼ 막기 위해, 다ìŒì˜ ê²ƒì„ php.ini 파ì¼ì— ì„¤ì •í•˜ì…”ì•¼ 합니다: %s", + "SystemCheckUpdateHttps": "HTTPS를 통한 ì—…ë°ì´íЏ", + "SystemCheckUpdateHttpsNotSupported": "Piwik는 ì—…ë°ì´íЏ 시 HTTPS를 ì‚¬ìš©í• ìˆ˜ 없으며, ì•ˆì „í•˜ì§€ ì•Šì€ HTTP ì—…ë°ì´íŠ¸ë¡œ ì „í™˜ë 것입니다. CURL í˜¹ì€ allow_url_fopenì„ í™•ì¸í•˜ì‹œê³ , ë˜í•œ openssl PHP í™•ìž¥ì´ ì„¤ì¹˜ë˜ì–´ 있는지 확ì¸í•˜ì„¸ìš”.: http:\/\/piwik.org\/faq\/troubleshooting\/faq_177\/", + "NotSupported": "ì§€ì›ë˜ì§€ 않ìŒ", "Tables": "í…Œì´ë¸” ìƒì„±", "TablesCreatedSuccess": "í…Œì´ë¸” ìƒì„±ì„ 성공ì 으로 마쳤습니다!", "TablesDelete": "ê°ì§€ëœ í…Œì´ë¸” ì‚ì œ", "TablesDeletedSuccess": "존재하는 Piwik í…Œì´ë¸”ì„ ì„±ê³µì 으로 ì‚ì œí–ˆìŠµë‹ˆë‹¤", "TablesFound": "ë°ì´í„°ë² ì´ìФì—서 다ìŒì˜ í…Œì´ë¸”ì„ ì°¾ì•˜ìŠµë‹ˆë‹¤", "TablesReuse": "존재하는 í…Œì´ë¸”ì„ ìž¬ì‚¬ìš©", + "TablesUpdatedSuccess": "ë°ì´í„°ë² ì´ìŠ¤ê°€ %1$sì—서 %2$s로 성공ì 으로 ì—…ë°ì´íЏ ë˜ì—ˆìŠµë‹ˆë‹¤.", "TablesWarningHelp": "존재하는 ë°ì´í„°ë² ì´ìФ í…Œì´ë¸”ì„ ìž¬ì‚¬ìš©í•˜ê±°ë‚˜ ëª¨ë“ ì¡´ìž¬í•˜ëŠ” ë°ì´í„°ë¥¼ ì‚ì œí•˜ê³ í´ë¦° 설치를 í• ì§€ ì„ íƒí•˜ì„¸ìš”.", "TablesWithSameNamesFound": "ëª‡ëª‡ì˜ í…Œì´ë¸”: %1$s \/ ë°ì´í„°ë² ì´ìФ: %2$s ê°€ Piwikì´ ìƒì„±í•˜ë ¤ê³ 하는 í…Œì´ë¸” ì´ë¦„ê³¼ 같습니다.", + "Timezone": "웹사ì´íЏ 시간대", + "WeHopeYouWillEnjoyPiwik": "ë‹¹ì‹ ì´ Piwik를 ì‚¬ìš©í•¨ì— ìžˆì–´ ì¦ê¸°ëŠ” ë§Œí¼ ìš°ë¦¬ëŠ” ì´ë¥¼ ë§Œë“¦ì— ì¦ê±°ì›€ì„ ëŠë‚€ë‹¤.", "Welcome": "환ì˜í•©ë‹ˆë‹¤!", - "WelcomeHelp": "<p>Piwik ì€ ì˜¤í”ˆ 소스 웹 ë¶„ì„ ì†Œí”„íŠ¸ì›¨ì–´ë¡œì¨ ì‰½ê³ ì›í•˜ëŠ” ì •ë³´ë¥¼ ë‹¹ì‹ ì˜ ë°©ë¬¸ìžë“¤ë¡œë¶€í„° ì–»ì„ ìˆ˜ 있게 í•´ì¤ë‹ˆë‹¤.<\/p><p>ì´ ê³¼ì •ì€ %s ì˜ ì‰¬ìš´ 단계로 나뉘어 ìžˆê³ 5ë¶„ ì •ë„ë§Œ 소요ë©ë‹ˆë‹¤.<\/p>" + "WelcomeHelp": "<p>Piwik ì€ ì˜¤í”ˆ 소스 웹 ë¶„ì„ ì†Œí”„íŠ¸ì›¨ì–´ë¡œì¨ ì‰½ê³ ì›í•˜ëŠ” ì •ë³´ë¥¼ ë‹¹ì‹ ì˜ ë°©ë¬¸ìžë“¤ë¡œë¶€í„° ì–»ì„ ìˆ˜ 있게 í•´ì¤ë‹ˆë‹¤.<\/p><p>ì´ ê³¼ì •ì€ %s ì˜ ì‰¬ìš´ 단계로 나뉘어 ìžˆê³ 5ë¶„ ì •ë„ë§Œ 소요ë©ë‹ˆë‹¤.<\/p>", + "WelcomeToCommunity": "Piwik ì»¤ë®¤ë‹ˆí‹°ì— ì˜¤ì‹ ê±¸ 환ì˜í•©ë‹ˆë‹¤!", + "CannotConnectToDb": "ë°ì´í„°ë² ì´ìŠ¤ì— ì—°ê²°í• ìˆ˜ 없습니다.", + "CannotConnectToDbResolvingExplanation": "ì´ê²ƒì€ ì¼ì‹œì ì¸ ë¬¸ì œì¼ ê²ƒìž…ë‹ˆë‹¤. %1$s페ì´ì§€ ìƒˆë¡œê³ ì¹¨%2$sì„ í•´ë³´ì„¸ìš”. 만약 ë¬¸ì œê°€ ì§€ì†ì 으로 ë°œìƒí•œë‹¤ë©´ Piwik 관리ìžì—게 ì—°ë½í•˜ì„¸ìš”." } } \ No newline at end of file diff --git a/plugins/Installation/lang/nb.json b/plugins/Installation/lang/nb.json index 136a352d207c30079b164a91e9d0a1db736aed94..fcc75d8190b2f190b092019f2a81ba0969b33f50 100644 --- a/plugins/Installation/lang/nb.json +++ b/plugins/Installation/lang/nb.json @@ -1,5 +1,7 @@ { "Installation": { + "CollaborativeProject": "Piwik er et samarbeidsprosjekt, bygget med kjærlighet av folk fra hele verden.", + "ConfigurationHelp": "Det ser ut til at det er en feil i din konfigurasjonsfil for Piwik. Du kan enten slette config\/config.ini.php og fortsette installasjonen, eller endre tilkoblingsinnstillingene til databasen.", "ConfirmDeleteExistingTables": "Er du sikker pÃ¥ at du vil slette tabellene %s fra databasen din? ADVARSEL: DATA FRA DISSE TABELLENE KAN IKKE GJENOPPRETTES!", "Congratulations": "Gratulerer", "CongratulationsHelp": "<p>Gratulerer! Din Piwik installasjon er fullført.<\/p><p>Sørg for at JavaScript-koden er lagt inn pÃ¥ dine sider, og vent pÃ¥ dine første besøkende!<\/p>", @@ -8,36 +10,52 @@ "DatabaseErrorConnect": "Klarte ikke koble til databasetjeneren", "DatabaseServerVersion": "Databasetjener-versjon", "DatabaseSetup": "Databaseinnstillinger", - "DatabaseSetupAdapter": "adapter", - "DatabaseSetupDatabaseName": "databasenavn", - "DatabaseSetupLogin": "brukernavn", - "DatabaseSetupServer": "databasetjener", - "DatabaseSetupTablePrefix": "tabellprefiks", + "DatabaseSetupAdapter": "Adapter", + "DatabaseSetupDatabaseName": "Databasenavn", + "DatabaseSetupLogin": "Brukernavn", + "DatabaseSetupServer": "Databasetjener", + "DatabaseSetupTablePrefix": "Tabellprefiks", "Email": "E-post", "Extension": "utvidelse", "Filesystem": "Filsystem", + "GetInvolved": "Hvis du liker det du ser, kan du %1$sinvolvere deg%2$s.", "GoBackAndDefinePrefix": "GÃ¥ tilbake og definer et prefiks for Piwik-tabellene", + "HappyAnalysing": "God analyse!", "Installation": "Installasjon", "InstallationStatus": "Installasjonsstatus", + "InsufficientPrivilegesHelp": "Du kan legge til disse privilegiene ved Ã¥ bruke et verktøy som phpMyAdmin, eller Ã¥ kjøre de rette SQL-spørringene. Hvis du ikke vet hvordan du gjør disse tingene, vennligst spør din sysadmin om Ã¥ hjelpe deg.", + "InsufficientPrivilegesMain": "Enten finnes ikke databasen (og kunne ikke opprettes), eller sÃ¥ har brukeren ikke tilstrekkelige rettigheter. Databasebrukeren mÃ¥ ha de følgende rettighetene: %s", "InvalidStateError": "Feil: Piwik er allerede installert. %1$s GÃ¥ tilbake %2$s til Piwik%3$s.", + "JsTagArchivingHelp1": "For nettsteder med medium til høy trafikk er det noen optimaliseringer som bør gjøres for Ã¥ hjelpe Piwik Ã¥ kjøre raskere (slik som Ã¥ %1$ssette opp auto-arkivering%2$s).", + "JSTracking_EndNote": "Merk: etter installasjonsprosessen kan du generere tilpassede sporingskoder i adminseksjonen %1$sSporingskode%2$s.", + "JSTracking_Intro": "For Ã¥ spore nettrafikk med Piwik mÃ¥ du legge til litt ekstra kode pÃ¥ alle sider pÃ¥ ditt nettsted.", "LargePiwikInstances": "Hjelp for store Piwik-instanser", "Legend": "Forklaring", - "NfsFilesystemWarning": "Din tjeneren bruker et NFS filsystem.", + "LoadDataInfileRecommended": "Hvis din Piwik-server sporer nettsider med mye trafikk (for eksempel >100 000 sider per mÃ¥ned), anbefaler vi deg Ã¥ prøve Ã¥ fikse dette problemet.", + "LoadDataInfileUnavailableHelp": "Ã… bruke %1$s vil gjøre arkiveringsprosessen til Piwik mye raskere. For Ã¥ gjøre det tilgjengelig, prøv Ã¥ oppdatere PHP og MySQL og forsikre deg om at databasebrukeren har rettigheten %2$s.", + "NfsFilesystemWarning": "Din tjeneren bruker et NFS-filsystem.", "NfsFilesystemWarningSuffixAdmin": "Dette betyr Piwik vil være svært treg nÃ¥r du bruker filbaserte økter.", - "NoConfigFound": "Klarte ikke finne konfigurasjonsfilen for Piwik, og du prøver Ã¥ fÃ¥ tilgang til en Piwik-side. <br \/><b>  »Du kan <a href='index.php'>installere Piwik nÃ¥<\/a><\/b><br \/><small>Hvis du prøvde Ã¥ installere Piwik tidligere og har noen tabeller i databasen, kan du ta det med ro. Du kan bruke de gamle tabellene og beholde dine eksisterende data!<\/small>", + "NfsFilesystemWarningSuffixInstall": "Ã… bruke filbaserte sesjoner pÃ¥ NFS er ekstremt tregt, sÃ¥ Piwik vil bruke databasesesjoner. Hvis det er mange som ser pÃ¥ kontrollpanelene samtidig, kan det tenkes at du mÃ¥ øke maks antall klienttilkoblinger som er tillatt pÃ¥ databaseserveren.", + "NoConfigFound": "Klarte ikke finne konfigurasjonsfilen for Piwik, og du prøver Ã¥ fÃ¥ tilgang til en Piwik-side. <br \/><b>  » Du kan <a href='index.php'>installere Piwik nÃ¥<\/a><\/b><br \/><small>Hvis du prøvde Ã¥ installere Piwik tidligere og har noen tabeller i databasen, kan du ta det med ro. Du kan bruke de gamle tabellene og beholde dine eksisterende data!<\/small>", "Optional": "Valgfritt", "Password": "Passord", "PasswordDoNotMatch": "passordene stemmer ikke overens", "PasswordRepeat": "Passord (gjenta)", "PercentDone": "%s %% ferdig", "PleaseFixTheFollowingErrors": "Fiks følgende feil", + "DefaultSettings": "Standard Piwik-innstillinger", + "DefaultSettingsHelp": "Piwik kommer med standardinnstillinger. Du kan tilpasse dem nÃ¥ eller gjøre det senere i administrasjonsskjermen.", "Requirements": "Krav for Ã¥ kjøre Piwik", + "RestartWebServer": "Etter Ã¥ ha gjort denne endringen mÃ¥ du restarte webserveren.", "ReusingTables": "Gjenbruker tabellene", + "PiwikOrgNewsletter": "Send meg e-poster med viktige oppdateringer om Piwik", "PiwikProNewsletter": "send meg informasjon om %sPiwik PRO%s tjenester og tilbud", "SeeBelowForMoreInfo": "Se nedenfor for mer informasjon.", "SetupWebsite": "Legg til et nettsted", "SetupWebsiteError": "Det skjedde en feil da nettstedet ble lagt til.", + "SetupWebSiteName": "Nettstedsnavn", "SetupWebsiteSetupSuccess": "Nettstedet %s ble opprettet.", + "SetupWebSiteURL": "Nettsteds-URL", "SuperUser": "Superbruker", "SuperUserSetupSuccess": "Superbruker ble opprettet!", "SystemCheck": "Systemsjekk", diff --git a/plugins/Installation/lang/tr.json b/plugins/Installation/lang/tr.json index 33f074fa7d4c940ef2dc22bfe8319885ddfbcf7a..2b51d7634d394b211ae240a5589afc6cf87defa5 100644 --- a/plugins/Installation/lang/tr.json +++ b/plugins/Installation/lang/tr.json @@ -2,27 +2,38 @@ "Installation": { "Congratulations": "Tebrikler", "CongratulationsHelp": "<p>Tebrikler! Piwik BaÅŸarıyla kuruldu.<\/p><p>JavaScript kodunu sayfalarınıza yerleÅŸtirdiÄŸinizden emin olun ve ilk ziyaretçilerinizi beklemeye baÅŸlayın!<\/p>", - "DatabaseCreation": "Veritabaı oluÅŸturma", + "DatabaseCreation": "Veritabanı oluÅŸturma", + "DatabaseErrorConnect": "Veritabanına baÄŸlanırken hata oluÅŸtu", "DatabaseServerVersion": "Veritabanı sunucu versiyonu", "DatabaseSetup": "Veritabanı Yüklemesi", "DatabaseSetupDatabaseName": "Veritabanı adı", "DatabaseSetupLogin": "GiriÅŸ", "DatabaseSetupServer": "Veritabanı Sunucusu", "DatabaseSetupTablePrefix": "Tablo öneki", + "Email": "E-posta", "Extension": "eklenti", "Filesystem": "Dosya sistemi", "Installation": "Yükleme", "InstallationStatus": "Yükleme durumu", + "InvalidStateError": "Hata: Piwik zaten kurulmuÅŸ. %1$s Geri dön %2$s Piwik%3$s.", "LargePiwikInstances": "Büyük Piwik örnekleri için yardım", "Legend": "Gösterge", "NfsFilesystemWarning": "Sunucunuz NFS dosya sistemini kullanıyor.", "Optional": "Opsiyonel", + "Password": "Åžifre", "PasswordDoNotMatch": "Girilen ÅŸifreler aynı deÄŸil.", + "PasswordRepeat": "Åžifre (Tekrardan)", "PercentDone": "%s %% tamamlandı", + "PleaseFixTheFollowingErrors": "OluÅŸan hataları düzeltin lütfen.", + "DefaultSettings": "Varsayılan Piwik ayarları", + "DefaultSettingsHelp": "Piwik varsayılan ayarlarla gelecektir. Åžimdi özelleÅŸtirebilirsiniz yada daha sonra yönetici ekranından da yapabilirsiniz.", "Requirements": "Piwik gereklilikleri", + "RestartWebServer": "Bu deÄŸiÅŸiklikten sonra, web sunucunuzu yeniden baÅŸlatın.", "SetupWebsite": "Web sitesi ekle", "SetupWebsiteError": "Web site eklenirken bir sorun oluÅŸtu.", + "SetupWebSiteName": "Web site adı", "SetupWebsiteSetupSuccess": "Web site %s baÅŸarıyla eklendi.", + "SetupWebSiteURL": "Web site adresi", "SystemCheck": "Sistem kontrolü", "SystemCheckDatabaseHelp": "Piwik mysqli eklentisi ya da PDO ve pdo_mysql eklentilerine ihtiyaç duyar.", "SystemCheckError": "Bir hata oluÅŸtu. Devam edebilmek için hatayı gidermelisiniz.", @@ -32,11 +43,20 @@ "SystemCheckMbstring": "mbstring", "SystemCheckMemoryLimit": "Hafıza limiti", "SystemCheckOtherExtensions": "DiÄŸer eklentiler", + "SystemCheckOtherFunctions": "DiÄŸer fonksiyonlar", + "SystemCheckPageSpeedDisabled": "Sayfa Hızı devre dışı", "SystemCheckPhp": "PHP versiyonu", + "SystemCheckPhpPdoAndMysqli": "Daha fazla bilgi için: %1$sPHP PDO%2$s ve %3$sMYSQLI%4$s.", + "SystemCheckSettings": "Gerekli PHP yapılandırmaları (php.ini)", + "SystemCheckSummaryNoProblems": "Vayy! Piwik kurulumunda hiçbir sorun bulunamadı. Sırtınızı sıvazlayabiliriz.", "SystemCheckWarning": "Piwik normal olarak çalışacaktır ancak bazı özellikler eksik olacak.", + "NotSupported": "desteklenmiyor", "Tables": "Tablolar oluÅŸturuluyor", - "TablesCreatedSuccess": "Tablolar baÅŸarılı bir ÅŸekilde yaratıldı!", + "TablesCreatedSuccess": "Tablolar baÅŸarılı bir ÅŸekilde oluÅŸturuldu!", + "Timezone": "Web site zaman dilimi", "Welcome": "HoÅŸgeldiniz!", - "CannotConnectToDb": "Veritabanına baÄŸlanamadı" + "WelcomeToCommunity": "Piwik topluluÄŸuna hoÅŸgeldiniz!", + "CannotConnectToDb": "Veritabanına baÄŸlanamadı", + "CannotConnectToDbResolvingExplanation": "Bu geçici bir sorun olabilir, %1$ssayfayı yenilemeyi deneyin%2$s. EÄŸer sorun devam ederse Piwik yöneticinize baÅŸvurun." } } \ No newline at end of file diff --git a/plugins/Intl/Commands/GenerateIntl.php b/plugins/Intl/Commands/GenerateIntl.php index 45637452a8d33096a4fcf66d219d6f8cf4489006..d9710f5977f5940e6d075de232d7ea2b50ad0512 100644 --- a/plugins/Intl/Commands/GenerateIntl.php +++ b/plugins/Intl/Commands/GenerateIntl.php @@ -262,7 +262,9 @@ class GenerateIntl extends ConsoleCommand $translations['Intl']['Time_AM'] = $calendarData['dayPeriods']['format']['wide']['am']; $translations['Intl']['Time_PM'] = $calendarData['dayPeriods']['format']['wide']['pm']; - $translations['Intl']['Format_Time'] = $calendarData['timeFormats']['medium']; + $translations['Intl']['Format_Time'] = '{time}'; + $translations['Intl']['Format_Time_12'] = $calendarData['dateTimeFormats']['availableFormats']['hms']; + $translations['Intl']['Format_Time_24'] = $calendarData['dateTimeFormats']['availableFormats']['Hms']; $translations['Intl']['Format_Date_Long'] = $calendarData['dateFormats']['full']; $translations['Intl']['Format_Date_Day_Month'] = $calendarData['dateTimeFormats']['availableFormats']['MMMEd']; $translations['Intl']['Format_Date_Short'] = $calendarData['dateFormats']['medium']; @@ -273,8 +275,8 @@ class GenerateIntl extends ConsoleCommand } $translations['Intl']['Format_Year'] = $calendarData['dateTimeFormats']['availableFormats']['y']; - $translations['Intl']['Format_DateTime_Long'] = $calendarData['dateFormats']['full'] . ' ' . $calendarData['timeFormats']['medium']; - $translations['Intl']['Format_DateTime_Short'] = $calendarData['dateFormats']['medium'] . ' ' . $calendarData['timeFormats']['medium']; + $translations['Intl']['Format_DateTime_Long'] = $calendarData['dateFormats']['full'] . ' {time}'; + $translations['Intl']['Format_DateTime_Short'] = $calendarData['dateFormats']['medium'] . ' {time}'; $translations['Intl']['Format_Interval_Long_D'] = $this->transformDateFormat($calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['d'], array('MMMM' => 'MMM', 'LLLL' => 'LLL', 'MMM' => 'MMMM', 'LLL' => 'LLLL')); $translations['Intl']['Format_Interval_Long_M'] = $this->transformDateFormat($calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['M'], array('MMMM' => 'MMM', 'LLLL' => 'LLL', 'MMM' => 'MMMM', 'LLL' => 'LLLL')); diff --git a/plugins/Intl/DateTimeFormatProvider.php b/plugins/Intl/DateTimeFormatProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..19fcd7acca9a21dbf32bc9cb532850654b8e165f --- /dev/null +++ b/plugins/Intl/DateTimeFormatProvider.php @@ -0,0 +1,133 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\Intl; + +use Piwik\Plugins\LanguagesManager\LanguagesManager; +use Piwik\Translation\Translator; + +/** + * Provides date and time formats. + */ +class DateTimeFormatProvider extends \Piwik\Intl\Data\Provider\DateTimeFormatProvider +{ + protected $use12HourClock; + + /** + * @var Translator + */ + protected $translator; + + public function __construct(Translator $translator) + { + $this->translator = $translator; + } + + /** + * Returns the format pattern for the given format type + * + * @param int $format one of the format constants + * + * @return string + */ + public function getFormatPattern($format) + { + + switch ($format) { + case self::DATETIME_FORMAT_LONG: + $pattern = $this->translator->translate('Intl_Format_DateTime_Long'); + break; + + case self::DATETIME_FORMAT_SHORT: + $pattern = $this->translator->translate('Intl_Format_DateTime_Short'); + break; + + case self::DATE_FORMAT_LONG: + $pattern = $this->translator->translate('Intl_Format_Date_Long'); + break; + + case self::DATE_FORMAT_DAY_MONTH: + $pattern = $this->translator->translate('Intl_Format_Date_Day_Month'); + break; + + case self::DATE_FORMAT_SHORT: + $pattern = $this->translator->translate('Intl_Format_Date_Short'); + break; + + case self::DATE_FORMAT_MONTH_SHORT: + $pattern = $this->translator->translate('Intl_Format_Month_Short'); + break; + + case self::DATE_FORMAT_MONTH_LONG: + $pattern = $this->translator->translate('Intl_Format_Month_Long'); + break; + + case self::DATE_FORMAT_YEAR: + $pattern = $this->translator->translate('Intl_Format_Year'); + break; + + case self::TIME_FORMAT: + $pattern = $this->translator->translate('Intl_Format_Time'); + break; + + default: + $pattern = $format; + } + + if (strpos($pattern, '{time}') !== false) { + $pattern = str_replace('{time}', $this->getTimeFormat(), $pattern); + } + + return $pattern; + } + + /** + * Returns interval format pattern for the given format type + * + * @param bool $short whether to return short or long format pattern + * @param string $maxDifference maximal difference in interval dates (Y, M or D) + * + * @return string + */ + public function getRangeFormatPattern($short=false, $maxDifference='Y') + { + return $this->translator->translate( + sprintf( + 'Intl_Format_Interval_%s_%s', + $short ? 'Short' : 'Long', + $maxDifference + )); + } + + protected function getTimeFormat() + { + if (is_null($this->use12HourClock)) { + $this->use12HourClock = LanguagesManager::uses12HourClockForCurrentUser(); + } + + $timeFormat = 'Intl_Format_Time_24'; + + if ($this->use12HourClock) { + $timeFormat = 'Intl_Format_Time_12'; + } + + $template = $this->translator->translate($timeFormat); + + return $template; + } + + /** + * For testing purpose only: Overwrites time format + * + * @param bool $use12HourClock + */ + public function forceTimeFormat($use12HourClock = false) + { + $this->use12HourClock = $use12HourClock; + } +} \ No newline at end of file diff --git a/plugins/Intl/config/config.php b/plugins/Intl/config/config.php new file mode 100644 index 0000000000000000000000000000000000000000..11e540614e777c9dbedd0c5892e3000b49f83295 --- /dev/null +++ b/plugins/Intl/config/config.php @@ -0,0 +1,5 @@ +<?php + +return array( + 'Piwik\Intl\Data\Provider\DateTimeFormatProvider' => DI\object('Piwik\Plugins\Intl\DateTimeFormatProvider') +); \ No newline at end of file diff --git a/plugins/Intl/lang/am.json b/plugins/Intl/lang/am.json index 49992598502e773df97aa110aeb9bb6d4c0410cd..e6fc689e526c8309cdc7530e7a3f56321099d8f1 100644 --- a/plugins/Intl/lang/am.json +++ b/plugins/Intl/lang/am.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "ቅዳሜ", "Day_Short_StandAlone_7": "እሑድ", "EnglishLanguageName": "Amharic", - "Format_DateTime_Long": "EEEE á£d MMMM y h:mm:ss a", - "Format_DateTime_Short": "d MMM y h:mm:ss a", + "Format_DateTime_Long": "EEEE á£d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "EᣠMMM d", "Format_Date_Long": "EEEE á£d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "MMM dᣠy – MMM dᣠy", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ሰዓቶች", "Language_aa": "አá‹áˆáŠ›", diff --git a/plugins/Intl/lang/ar.json b/plugins/Intl/lang/ar.json index 481c4e62ce3364a608f3958ccb9806b4d3ac1304..be7becbd50ecc187ac6f0cb27f17c7cf7cfa4d87 100644 --- a/plugins/Intl/lang/ar.json +++ b/plugins/Intl/lang/ar.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "السبت", "Day_Short_StandAlone_7": "Ø§Ù„Ø£ØØ¯", "EnglishLanguageName": "Arabic", - "Format_DateTime_Long": "EEEEØŒ d MMMMØŒ y h:mm:ss a", - "Format_DateTime_Short": "ddâ€\/MMâ€\/y h:mm:ss a", + "Format_DateTime_Long": "EEEEØŒ d MMMMØŒ y {time}", + "Format_DateTime_Short": "ddâ€\/MMâ€\/y {time}", "Format_Date_Day_Month": "EØŒ d MMM", "Format_Date_Long": "EEEEØŒ d MMMMØŒ y", "Format_Date_Short": "ddâ€\/MMâ€\/y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMMØŒ y – d MMMØŒ y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ساعات", "Language_aa": "Ø§Ù„Ø£ÙØ§Ø±ÙŠØ©", diff --git a/plugins/Intl/lang/be.json b/plugins/Intl/lang/be.json index 88bb7c14cbe074fb86e6f48e4c2b14b00483f957..c5b8f8c82671daa8de5338cd0ac96c4fab52bcb3 100644 --- a/plugins/Intl/lang/be.json +++ b/plugins/Intl/lang/be.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Сб", "Day_Short_StandAlone_7": "Ðд", "EnglishLanguageName": "Belarusian", - "Format_DateTime_Long": "EEEE, d MMMM y HH.mm.ss", - "Format_DateTime_Short": "d.M.y HH.mm.ss", + "Format_DateTime_Long": "EEEE, d MMMM y {time}", + "Format_DateTime_Short": "d.M.y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM y", "Format_Date_Short": "d.M.y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "LLLL y", "Format_Month_Short": "LLL y", - "Format_Time": "HH.mm.ss", + "Format_Time": "{time}", + "Format_Time_12": "hh.mm.ss a", + "Format_Time_24": "HH.mm.ss", "Format_Year": "y", "Hours": "гадзіны", "Language_ab": "ÐбхазÑкаÑ", diff --git a/plugins/Intl/lang/bg.json b/plugins/Intl/lang/bg.json index 02880b589d95bd8ebea83270c825d1b4da377418..511e99fffd036be83585fa9dcf4207a74bc2ac9c 100644 --- a/plugins/Intl/lang/bg.json +++ b/plugins/Intl/lang/bg.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Сб", "Day_Short_StandAlone_7": "Ðд", "EnglishLanguageName": "Bulgarian", - "Format_DateTime_Long": "EEEE, d MMMM y 'г'. H:mm:ss", - "Format_DateTime_Short": "d.MM.y 'г'. H:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM y 'г'. {time}", + "Format_DateTime_Short": "d.MM.y 'г'. {time}", "Format_Date_Day_Month": "E, d.MM", "Format_Date_Long": "EEEE, d MMMM y 'г'.", "Format_Date_Short": "d.MM.y 'г'.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d.MM.y 'г'. – d.MM.y 'г'.", "Format_Month_Long": "MMMM y 'г'.", "Format_Month_Short": "MM.y 'г'.", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "H:mm:ss", "Format_Year": "y 'г'.", "Hours": "чаÑове", "Language_aa": "Ðфар", diff --git a/plugins/Intl/lang/bn.json b/plugins/Intl/lang/bn.json index 2bac13f1beec03b28276d92e56b5a65e6cbbde2c..92676e3ab46ffc2468316914abf6179e8f96fac1 100644 --- a/plugins/Intl/lang/bn.json +++ b/plugins/Intl/lang/bn.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "শনি", "Day_Short_StandAlone_7": "রবি", "EnglishLanguageName": "Bengali", - "Format_DateTime_Long": "EEEE, d MMMM, y h:mm:ss a", - "Format_DateTime_Short": "d MMM, y h:mm:ss a", + "Format_DateTime_Long": "EEEE, d MMMM, y {time}", + "Format_DateTime_Short": "d MMM, y {time}", "Format_Date_Day_Month": "E d MMM", "Format_Date_Long": "EEEE, d MMMM, y", "Format_Date_Short": "d MMM, y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM, y – d MMM, y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ঘনà§à¦Ÿà¦¾", "Language_aa": "আফার", diff --git a/plugins/Intl/lang/bs.json b/plugins/Intl/lang/bs.json index 89e795036398058eb942a719dfe1c5e1e28f9690..abd090f32cc9de8b6dfc060963f0d5e32d3d6bef 100644 --- a/plugins/Intl/lang/bs.json +++ b/plugins/Intl/lang/bs.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sub", "Day_Short_StandAlone_7": "Ned", "EnglishLanguageName": "Bosnian", - "Format_DateTime_Long": "EEEE, dd. MMMM y. HH:mm:ss", - "Format_DateTime_Short": "dd. MMM. y. HH:mm:ss", + "Format_DateTime_Long": "EEEE, dd. MMMM y. {time}", + "Format_DateTime_Short": "dd. MMM. y. {time}", "Format_Date_Day_Month": "E, dd. MMM", "Format_Date_Long": "EEEE, dd. MMMM y.", "Format_Date_Short": "dd. MMM. y.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "dd. MMM y. – dd. MMM y.", "Format_Month_Long": "LLLL y.", "Format_Month_Short": "MMM y.", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "hh:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y.", "Hours": "sati", "Language_aa": "Afarski", diff --git a/plugins/Intl/lang/ca.json b/plugins/Intl/lang/ca.json index d2b8a9a26e43b165825f9ae3c26ef7d4b693b056..7a0b18b3243e3166fc83283b7aeb2f3b30984d8d 100644 --- a/plugins/Intl/lang/ca.json +++ b/plugins/Intl/lang/ca.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Ds.", "Day_Short_StandAlone_7": "Dg.", "EnglishLanguageName": "Catalan", - "Format_DateTime_Long": "EEEE, d MMMM 'de' y H:mm:ss", - "Format_DateTime_Short": "d MMM y H:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM 'de' y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM 'de' y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "LLLL 'de' y", "Format_Month_Short": "LLL 'de' y", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "hores", "Language_aa": "Àfar", diff --git a/plugins/Intl/lang/cs.json b/plugins/Intl/lang/cs.json index 813e0506eea7d0f8e4e09aad58666d318223729c..5d13f324a12c52e812d7f90f017f7aef5adaba81 100644 --- a/plugins/Intl/lang/cs.json +++ b/plugins/Intl/lang/cs.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "So", "Day_Short_StandAlone_7": "Ne", "EnglishLanguageName": "Czech", - "Format_DateTime_Long": "EEEE d. MMMM y H:mm:ss", - "Format_DateTime_Short": "d. M. y H:mm:ss", + "Format_DateTime_Long": "EEEE d. MMMM y {time}", + "Format_DateTime_Short": "d. M. y {time}", "Format_Date_Day_Month": "E d. M.", "Format_Date_Long": "EEEE d. MMMM y", "Format_Date_Short": "d. M. y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. M. y – d. M. y", "Format_Month_Long": "LLLL y", "Format_Month_Short": "LLLL y", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "H:mm:ss", "Format_Year": "y", "Hours": "hodiny", "Language_aa": "AfarÅ¡tina", diff --git a/plugins/Intl/lang/cy.json b/plugins/Intl/lang/cy.json index 69a71a6022a283c530b0522920489535a77e68f6..eea1cb48d6fed1330bf6d8f3c1ba772233fe9f5a 100644 --- a/plugins/Intl/lang/cy.json +++ b/plugins/Intl/lang/cy.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sad", "Day_Short_StandAlone_7": "Sul", "EnglishLanguageName": "Welsh", - "Format_DateTime_Long": "EEEE, d MMMM y HH:mm:ss", - "Format_DateTime_Short": "d MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM, y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "oriau", "Language_aa": "Affareg", diff --git a/plugins/Intl/lang/da.json b/plugins/Intl/lang/da.json index 3710ea0c0b04552c1b3243c5c64f22183a861b9b..960a7be38573ac723e5a6a301391619d9190fd1a 100644 --- a/plugins/Intl/lang/da.json +++ b/plugins/Intl/lang/da.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Lør", "Day_Short_StandAlone_7": "Søn", "EnglishLanguageName": "Danish", - "Format_DateTime_Long": "EEEE 'den' d. MMMM y HH.mm.ss", - "Format_DateTime_Short": "d. MMM y HH.mm.ss", + "Format_DateTime_Long": "EEEE 'den' d. MMMM y {time}", + "Format_DateTime_Short": "d. MMM y {time}", "Format_Date_Day_Month": "E d. MMM", "Format_Date_Long": "EEEE 'den' d. MMMM y", "Format_Date_Short": "d. MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. MMM y – d. MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH.mm.ss", + "Format_Time": "{time}", + "Format_Time_12": "h.mm.ss a", + "Format_Time_24": "HH.mm.ss", "Format_Year": "y", "Hours": "timer", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/de.json b/plugins/Intl/lang/de.json index 813e67dde74a5c806848b3ceb318842593467456..d6a6e7e70be074792938094228155cfad84f2db5 100644 --- a/plugins/Intl/lang/de.json +++ b/plugins/Intl/lang/de.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sa", "Day_Short_StandAlone_7": "So", "EnglishLanguageName": "German", - "Format_DateTime_Long": "EEEE, d. MMMM y HH:mm:ss", - "Format_DateTime_Short": "dd.MM.y HH:mm:ss", + "Format_DateTime_Long": "EEEE, d. MMMM y {time}", + "Format_DateTime_Short": "dd.MM.y {time}", "Format_Date_Day_Month": "E, d. MMM", "Format_Date_Long": "EEEE, d. MMMM y", "Format_Date_Short": "dd.MM.y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. MMM y – d. MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "Stunden", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/el.json b/plugins/Intl/lang/el.json index 2af13ce2f3679a1c2e1b513da0b06edc5d590b5b..49c3bf989721ca21c6fa7dd765829b5f6a016fed 100644 --- a/plugins/Intl/lang/el.json +++ b/plugins/Intl/lang/el.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Σάβ", "Day_Short_StandAlone_7": "ΚυÏ", "EnglishLanguageName": "Greek", - "Format_DateTime_Long": "EEEE, d MMMM y h:mm:ss a", - "Format_DateTime_Short": "d MMM y h:mm:ss a", + "Format_DateTime_Long": "EEEE, d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "dd MMM y – dd MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ÏŽÏες", "Language_aa": "ΑφάÏ", diff --git a/plugins/Intl/lang/en.json b/plugins/Intl/lang/en.json index a52b7b2cf6f3ad0e6a5b329982e1aeb3552e4278..db73bc9a0817b1616b24ecb2a030f501f22d48b3 100644 --- a/plugins/Intl/lang/en.json +++ b/plugins/Intl/lang/en.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sat", "Day_Short_StandAlone_7": "Sun", "EnglishLanguageName": "English", - "Format_DateTime_Long": "EEEE, MMMM d, y h:mm:ss a", - "Format_DateTime_Short": "MMM d, y h:mm:ss a", + "Format_DateTime_Long": "EEEE, MMMM d, y {time}", + "Format_DateTime_Short": "MMM d, y {time}", "Format_Date_Day_Month": "E, MMM d", "Format_Date_Long": "EEEE, MMMM d, y", "Format_Date_Short": "MMM d, y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "MMM d, y – MMM d, y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "hours", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/es.json b/plugins/Intl/lang/es.json index 10590cb9265ee04211ce615317f9906c31e63cb5..4a08bbae01d3d01e4f9fa2ecc7958bc8d7b8dec7 100644 --- a/plugins/Intl/lang/es.json +++ b/plugins/Intl/lang/es.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sáb.", "Day_Short_StandAlone_7": "Dom.", "EnglishLanguageName": "Spanish", - "Format_DateTime_Long": "EEEE, d 'de' MMMM 'de' y H:mm:ss", - "Format_DateTime_Short": "d MMM y H:mm:ss", + "Format_DateTime_Long": "EEEE, d 'de' MMMM 'de' y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d 'de' MMMM 'de' y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM 'de' y", "Format_Month_Short": "MMM y", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "H:mm:ss", "Format_Year": "y", "Hours": "horas", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/et.json b/plugins/Intl/lang/et.json index db9277a739613cc470776cd97017c88f770e84b7..bb9cdd7b163cab683e9de9895da2f4be9b8338ae 100644 --- a/plugins/Intl/lang/et.json +++ b/plugins/Intl/lang/et.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "L", "Day_Short_StandAlone_7": "P", "EnglishLanguageName": "Estonian", - "Format_DateTime_Long": "EEEE, d. MMMM y H:mm.ss", - "Format_DateTime_Short": "d. MMM y H:mm.ss", + "Format_DateTime_Long": "EEEE, d. MMMM y {time}", + "Format_DateTime_Short": "d. MMM y {time}", "Format_Date_Day_Month": "E, d. MMM", "Format_Date_Long": "EEEE, d. MMMM y", "Format_Date_Short": "d. MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. MMM y – d. MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "H:mm.ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm.ss a", + "Format_Time_24": "H:mm.ss", "Format_Year": "y", "Hours": "tunnid", "Language_aa": "Afari", diff --git a/plugins/Intl/lang/eu.json b/plugins/Intl/lang/eu.json index a102605b6dd91bd9b78ba65ddb4f81804e14c375..ec30c090f13a179c1b9ec980835b283fb9adf836 100644 --- a/plugins/Intl/lang/eu.json +++ b/plugins/Intl/lang/eu.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Lr.", "Day_Short_StandAlone_7": "Ig.", "EnglishLanguageName": "Basque", - "Format_DateTime_Long": "y('e')'ko' MMMM d, EEEE HH:mm:ss", - "Format_DateTime_Short": "y MMM d HH:mm:ss", + "Format_DateTime_Long": "y('e')'ko' MMMM d, EEEE {time}", + "Format_DateTime_Short": "y MMM d {time}", "Format_Date_Day_Month": "MMM d, E", "Format_Date_Long": "y('e')'ko' MMMM d, EEEE", "Format_Date_Short": "y MMM d", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "y('e')'ko' MMM d – y('e')'ko' MMM d", "Format_Month_Long": "y('e')'ko' MMMM", "Format_Month_Short": "y MMM", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ordu", "Language_ab": "Abkhazera", diff --git a/plugins/Intl/lang/fa.json b/plugins/Intl/lang/fa.json index 26110dfa0d0565ad3315bc499ee7b04e32d8c5b4..992ec00575cd1fc9640201962acfafc846a5bb2a 100644 --- a/plugins/Intl/lang/fa.json +++ b/plugins/Intl/lang/fa.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "شنبه", "Day_Short_StandAlone_7": "یکشنبه", "EnglishLanguageName": "Persian", - "Format_DateTime_Long": "EEEE d MMMM y H:mm:ss", - "Format_DateTime_Short": "d MMM y H:mm:ss", + "Format_DateTime_Long": "EEEE d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E d LLL", "Format_Date_Long": "EEEE d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y تا d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "H:mm:ss", "Format_Year": "y", "Hours": "ساعت", "Language_aa": "Ø¢ÙØ§Ø±ÛŒ", diff --git a/plugins/Intl/lang/fi.json b/plugins/Intl/lang/fi.json index eb8f50332016311d944c11ac1c8b61203be407cd..ce88fa7bd55790c8fb2e4b1b7d574e9e5d15c77c 100644 --- a/plugins/Intl/lang/fi.json +++ b/plugins/Intl/lang/fi.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "La", "Day_Short_StandAlone_7": "Su", "EnglishLanguageName": "Finnish", - "Format_DateTime_Long": "cccc d. MMMM y H.mm.ss", - "Format_DateTime_Short": "d.M.y H.mm.ss", + "Format_DateTime_Long": "cccc d. MMMM y {time}", + "Format_DateTime_Short": "d.M.y {time}", "Format_Date_Day_Month": "ccc d. MMM", "Format_Date_Long": "cccc d. MMMM y", "Format_Date_Short": "d.M.y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. MMMM y – d. MMMM y", "Format_Month_Long": "LLLL y", "Format_Month_Short": "LLL y", - "Format_Time": "H.mm.ss", + "Format_Time": "{time}", + "Format_Time_12": "h.mm.ss a", + "Format_Time_24": "H.mm.ss", "Format_Year": "y", "Hours": "tunnit", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/fr.json b/plugins/Intl/lang/fr.json index 57438a91f047d28a4730c990574a53bc9381d30b..3b66a6e02e21a806259ffb3278f915d44a89c9ea 100644 --- a/plugins/Intl/lang/fr.json +++ b/plugins/Intl/lang/fr.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sam.", "Day_Short_StandAlone_7": "Dim.", "EnglishLanguageName": "French", - "Format_DateTime_Long": "EEEE d MMMM y HH:mm:ss", - "Format_DateTime_Short": "d MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E d MMM", "Format_Date_Long": "EEEE d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "heures", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/gl.json b/plugins/Intl/lang/gl.json index 15c88b8530853d1f2ff749ec602d89b8f1b64a2f..91d274e8987441bf1496c6e01aede46c4930d044 100644 --- a/plugins/Intl/lang/gl.json +++ b/plugins/Intl/lang/gl.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sáb", "Day_Short_StandAlone_7": "Dom", "EnglishLanguageName": "Galician", - "Format_DateTime_Long": "EEEE dd MMMM y HH:mm:ss", - "Format_DateTime_Short": "d MMM, y HH:mm:ss", + "Format_DateTime_Long": "EEEE dd MMMM y {time}", + "Format_DateTime_Short": "d MMM, y {time}", "Format_Date_Day_Month": "E d MMM", "Format_Date_Long": "EEEE dd MMMM y", "Format_Date_Short": "d MMM, y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM, y – d MMM, y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "horas", "Language_ab": "Abkhazo", diff --git a/plugins/Intl/lang/he.json b/plugins/Intl/lang/he.json index 50c63fc1d4f8b89e7176839b86693e393f01f6bd..78f07a3bc15e56940cffb8b950d7301a878cd0dc 100644 --- a/plugins/Intl/lang/he.json +++ b/plugins/Intl/lang/he.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "שבת", "Day_Short_StandAlone_7": "×™×•× ×׳", "EnglishLanguageName": "Hebrew", - "Format_DateTime_Long": "EEEE, d בMMMM y H:mm:ss", - "Format_DateTime_Short": "d בMMM y H:mm:ss", + "Format_DateTime_Long": "EEEE, d בMMMM y {time}", + "Format_DateTime_Short": "d בMMM y {time}", "Format_Date_Day_Month": "E, d בMMM", "Format_Date_Long": "EEEE, d בMMMM y", "Format_Date_Short": "d בMMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "H:mm:ss", "Format_Year": "y", "Hours": "שעות", "Language_aa": "×פ×רית", diff --git a/plugins/Intl/lang/hi.json b/plugins/Intl/lang/hi.json index 73c68868e8e5fe2284625951b3fee961c7335bbb..d9284fd761418110beff8a6c1928db083d597def 100644 --- a/plugins/Intl/lang/hi.json +++ b/plugins/Intl/lang/hi.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "शनि", "Day_Short_StandAlone_7": "रवि", "EnglishLanguageName": "Hindi", - "Format_DateTime_Long": "EEEE, d MMMM y h:mm:ss a", - "Format_DateTime_Short": "dd\/MM\/y h:mm:ss a", + "Format_DateTime_Long": "EEEE, d MMMM y {time}", + "Format_DateTime_Short": "dd\/MM\/y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM y", "Format_Date_Short": "dd\/MM\/y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "घंटे", "Language_aa": "अफ़ार", diff --git a/plugins/Intl/lang/hr.json b/plugins/Intl/lang/hr.json index 48bcdd8a09596daee8065d6154f9cdbe3ddc148f..39f7d403d9a84342e822b0321b187a46b0b5aa5c 100644 --- a/plugins/Intl/lang/hr.json +++ b/plugins/Intl/lang/hr.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sub", "Day_Short_StandAlone_7": "Ned", "EnglishLanguageName": "Croatian", - "Format_DateTime_Long": "EEEE, d. MMMM y. HH:mm:ss", - "Format_DateTime_Short": "d. MMM y. HH:mm:ss", + "Format_DateTime_Long": "EEEE, d. MMMM y. {time}", + "Format_DateTime_Short": "d. MMM y. {time}", "Format_Date_Day_Month": "E, d. MMM", "Format_Date_Long": "EEEE, d. MMMM y.", "Format_Date_Short": "d. MMM y.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "dd. MMM y. – dd. MMM y.", "Format_Month_Long": "LLLL y.", "Format_Month_Short": "LLL y.", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "hh:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y.", "Hours": "sati", "Language_aa": "Afarski", diff --git a/plugins/Intl/lang/hu.json b/plugins/Intl/lang/hu.json index 4df06ba7067eb8e35bf4ac631e26528a093ab72a..e730da6862077786075913e673c95dda4e090896 100644 --- a/plugins/Intl/lang/hu.json +++ b/plugins/Intl/lang/hu.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Szo", "Day_Short_StandAlone_7": "V", "EnglishLanguageName": "Hungarian", - "Format_DateTime_Long": "y. MMMM d., EEEE H:mm:ss", - "Format_DateTime_Short": "y. MMM d. H:mm:ss", + "Format_DateTime_Long": "y. MMMM d., EEEE {time}", + "Format_DateTime_Short": "y. MMM d. {time}", "Format_Date_Day_Month": "MMM d., E", "Format_Date_Long": "y. MMMM d., EEEE", "Format_Date_Short": "y. MMM d.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "y. MMM d. – y. MMM d.", "Format_Month_Long": "y. MMMM", "Format_Month_Short": "y. MMM", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "a h:mm:ss", + "Format_Time_24": "H:mm:ss", "Format_Year": "y.", "Hours": "óra", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/id.json b/plugins/Intl/lang/id.json index ef6ae7fafaca59b1ae2e5e4be0d3414b546153cf..2ed5145d34599a7f16ec6ead3b19f2fed6c0c257 100644 --- a/plugins/Intl/lang/id.json +++ b/plugins/Intl/lang/id.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sab", "Day_Short_StandAlone_7": "Min", "EnglishLanguageName": "Indonesian", - "Format_DateTime_Long": "EEEE, dd MMMM y HH.mm.ss", - "Format_DateTime_Short": "d MMM y HH.mm.ss", + "Format_DateTime_Long": "EEEE, dd MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, dd MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH.mm.ss", + "Format_Time": "{time}", + "Format_Time_12": "h.mm.ss a", + "Format_Time_24": "HH.mm.ss", "Format_Year": "y", "Hours": "jam", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/is.json b/plugins/Intl/lang/is.json index 1160564dd82535111cf7336467535dded7c4b111..b27b8783aad5da6817d14db74eee90e59e2bbda6 100644 --- a/plugins/Intl/lang/is.json +++ b/plugins/Intl/lang/is.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Lau.", "Day_Short_StandAlone_7": "Sun.", "EnglishLanguageName": "Icelandic", - "Format_DateTime_Long": "EEEE, d. MMMM y HH:mm:ss", - "Format_DateTime_Short": "d. MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE, d. MMMM y {time}", + "Format_DateTime_Short": "d. MMM y {time}", "Format_Date_Day_Month": "E, d. MMM", "Format_Date_Long": "EEEE, d. MMMM y", "Format_Date_Short": "d. MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. MMM y – d. MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "klukkustundir", "Language_ab": "AbkasÃska", diff --git a/plugins/Intl/lang/it.json b/plugins/Intl/lang/it.json index 5f8882536985f45ebfd329bdf45dbc3dc86d97d3..a8fdaac9037a546a9665769e0c64c28de6d9a084 100644 --- a/plugins/Intl/lang/it.json +++ b/plugins/Intl/lang/it.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sab", "Day_Short_StandAlone_7": "Dom", "EnglishLanguageName": "Italian", - "Format_DateTime_Long": "EEEE d MMMM y HH:mm:ss", - "Format_DateTime_Short": "dd MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE d MMMM y {time}", + "Format_DateTime_Short": "dd MMM y {time}", "Format_Date_Day_Month": "E d MMM", "Format_Date_Long": "EEEE d MMMM y", "Format_Date_Short": "dd MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "dd MMM y – dd MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ore", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/ja.json b/plugins/Intl/lang/ja.json index b1434f36d6ec6482be59e7f7488464aa0f5920f7..e63c4094d6ebbc36771dcfea4829b6633b0826a6 100644 --- a/plugins/Intl/lang/ja.json +++ b/plugins/Intl/lang/ja.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "土", "Day_Short_StandAlone_7": "æ—¥", "EnglishLanguageName": "Japanese", - "Format_DateTime_Long": "yå¹´M月dæ—¥EEEE H:mm:ss", - "Format_DateTime_Short": "y\/MM\/dd H:mm:ss", + "Format_DateTime_Long": "yå¹´M月dæ—¥EEEE {time}", + "Format_DateTime_Short": "y\/MM\/dd {time}", "Format_Date_Day_Month": "M月dæ—¥(E)", "Format_Date_Long": "yå¹´M月dæ—¥EEEE", "Format_Date_Short": "y\/MM\/dd", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "yå¹´M月d日~yå¹´M月dæ—¥", "Format_Month_Long": "yå¹´M月", "Format_Month_Short": "yå¹´M月", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "aK:mm:ss", + "Format_Time_24": "H:mm:ss", "Format_Year": "yå¹´", "Hours": "時間", "Language_aa": "アファル語", diff --git a/plugins/Intl/lang/ka.json b/plugins/Intl/lang/ka.json index 819f7ba2a0903a2ed1f30aeda29cc7fcf60d7cb6..91af2874216c7d60113717be2314c6484ee506ce 100644 --- a/plugins/Intl/lang/ka.json +++ b/plugins/Intl/lang/ka.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "შáƒáƒ‘", "Day_Short_StandAlone_7": "კვი", "EnglishLanguageName": "Georgian", - "Format_DateTime_Long": "EEEE, dd MMMM, y HH:mm:ss", - "Format_DateTime_Short": "d MMM. y HH:mm:ss", + "Format_DateTime_Long": "EEEE, dd MMMM, y {time}", + "Format_DateTime_Short": "d MMM. y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, dd MMMM, y", "Format_Date_Short": "d MMM. y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "dd MMM. y – d MMM. y", "Format_Month_Long": "MMMM, y", "Format_Month_Short": "MMM. y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "სáƒáƒáƒ—ი", "Language_aa": "áƒáƒ¤áƒáƒ ი", diff --git a/plugins/Intl/lang/ko.json b/plugins/Intl/lang/ko.json index 70b13cb503d3f0814168cff8b172f2934388847f..229b1e6144e30e0cbf8ad5040539f8e11b40158c 100644 --- a/plugins/Intl/lang/ko.json +++ b/plugins/Intl/lang/ko.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "í† ", "Day_Short_StandAlone_7": "ì¼", "EnglishLanguageName": "Korean", - "Format_DateTime_Long": "yë…„ Mì›” dì¼ EEEE a h:mm:ss", - "Format_DateTime_Short": "y. M. d. a h:mm:ss", + "Format_DateTime_Long": "yë…„ Mì›” dì¼ EEEE {time}", + "Format_DateTime_Short": "y. M. d. {time}", "Format_Date_Day_Month": "MMM dì¼ (E)", "Format_Date_Long": "yë…„ Mì›” dì¼ EEEE", "Format_Date_Short": "y. M. d.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "yë…„ Mì›” dì¼ ~ yë…„ Mì›” dì¼", "Format_Month_Long": "yë…„ MMMM", "Format_Month_Short": "yë…„ MMM", - "Format_Time": "a h:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "a h:mm:ss", + "Format_Time_24": "H시 më¶„ sì´ˆ", "Format_Year": "yë…„", "Hours": "시간", "Language_aa": "아파르어", diff --git a/plugins/Intl/lang/lt.json b/plugins/Intl/lang/lt.json index 7dc87c76a14896cca2a12937e42286f3c7ca3178..2fefcf67dcbb5d0256f19621d9bed7e698e896b7 100644 --- a/plugins/Intl/lang/lt.json +++ b/plugins/Intl/lang/lt.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Å t", "Day_Short_StandAlone_7": "Sk", "EnglishLanguageName": "Lithuanian", - "Format_DateTime_Long": "y 'm'. MMMM d 'd'., EEEE HH:mm:ss", - "Format_DateTime_Short": "y-MM-dd HH:mm:ss", + "Format_DateTime_Long": "y 'm'. MMMM d 'd'., EEEE {time}", + "Format_DateTime_Short": "y-MM-dd {time}", "Format_Date_Day_Month": "MM-dd, E", "Format_Date_Long": "y 'm'. MMMM d 'd'., EEEE", "Format_Date_Short": "y-MM-dd", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "y MMM d – y MMM d", "Format_Month_Long": "y 'm'. LLLL", "Format_Month_Short": "y-MM", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "hh:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "valandos", "Language_aa": "Afarų", diff --git a/plugins/Intl/lang/lv.json b/plugins/Intl/lang/lv.json index 2a91a4b6fb7fa59a5d1acfa1586991c586fea698..583d3e51a0e512b5e27e103ecf80d4c2397a24cf 100644 --- a/plugins/Intl/lang/lv.json +++ b/plugins/Intl/lang/lv.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Se", "Day_Short_StandAlone_7": "Sv", "EnglishLanguageName": "Latvian", - "Format_DateTime_Long": "EEEE, y. 'gada' d. MMMM HH:mm:ss", - "Format_DateTime_Short": "y. 'gada' d. MMM HH:mm:ss", + "Format_DateTime_Long": "EEEE, y. 'gada' d. MMMM {time}", + "Format_DateTime_Short": "y. 'gada' d. MMM {time}", "Format_Date_Day_Month": "E, d. MMM", "Format_Date_Long": "EEEE, y. 'gada' d. MMMM", "Format_Date_Short": "y. 'gada' d. MMM", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "y. 'gada' d. MMM – y. 'gada' d. MMM", "Format_Month_Long": "y. 'g'. MMMM", "Format_Month_Short": "y. 'g'. MMM", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y. 'g'.", "Hours": "stundas", "Language_aa": "AfÄru", diff --git a/plugins/Intl/lang/nb.json b/plugins/Intl/lang/nb.json index 84d427bd0b4cfb4075621b1ed75b6304d95b201a..812c4618295135c853a4286460f30f6a044f1b8d 100644 --- a/plugins/Intl/lang/nb.json +++ b/plugins/Intl/lang/nb.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Lør.", "Day_Short_StandAlone_7": "Søn.", "EnglishLanguageName": "Norwegian BokmÃ¥l", - "Format_DateTime_Long": "EEEE d. MMMM y HH.mm.ss", - "Format_DateTime_Short": "d. MMM y HH.mm.ss", + "Format_DateTime_Long": "EEEE d. MMMM y {time}", + "Format_DateTime_Short": "d. MMM y {time}", "Format_Date_Day_Month": "E d. MMM", "Format_Date_Long": "EEEE d. MMMM y", "Format_Date_Short": "d. MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. MMM y–d. MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH.mm.ss", + "Format_Time": "{time}", + "Format_Time_12": "h.mm.ss a", + "Format_Time_24": "HH.mm.ss", "Format_Year": "y", "Hours": "timer", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/nl.json b/plugins/Intl/lang/nl.json index 8c9cfa595392ff2f106ffa37a58ef2b33cbd1deb..66398aa589f6df521c490c454f69eac1a6698943 100644 --- a/plugins/Intl/lang/nl.json +++ b/plugins/Intl/lang/nl.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Za", "Day_Short_StandAlone_7": "Zo", "EnglishLanguageName": "Dutch", - "Format_DateTime_Long": "EEEE d MMMM y HH:mm:ss", - "Format_DateTime_Short": "d MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E d MMM", "Format_Date_Long": "EEEE d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "uur", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/nn.json b/plugins/Intl/lang/nn.json index 6f913f08ead4cd6a48989e76fdec6c850f28f57c..cbbc0bfdda709d3e4826cea1911b89e2d7e709c3 100644 --- a/plugins/Intl/lang/nn.json +++ b/plugins/Intl/lang/nn.json @@ -296,8 +296,8 @@ "Day_Short_StandAlone_6": "La.", "Day_Short_StandAlone_7": "Sø.", "EnglishLanguageName": "Norwegian Nynorsk", - "Format_DateTime_Long": "EEEE d. MMMM y HH:mm:ss", - "Format_DateTime_Short": "d. MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE d. MMMM y {time}", + "Format_DateTime_Short": "d. MMM y {time}", "Format_Date_Day_Month": "E d. MMM", "Format_Date_Long": "EEEE d. MMMM y", "Format_Date_Short": "d. MMM y", @@ -309,7 +309,9 @@ "Format_Interval_Short_Y": "d. MMM y–d. MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "hr", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/pl.json b/plugins/Intl/lang/pl.json index 7183cd5cbcc994107fd7fe4865cc829d4d51707d..f190ed6d4df4021f17e6110b643d024afa0927d6 100644 --- a/plugins/Intl/lang/pl.json +++ b/plugins/Intl/lang/pl.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sob.", "Day_Short_StandAlone_7": "Niedz.", "EnglishLanguageName": "Polish", - "Format_DateTime_Long": "EEEE, d MMMM y HH:mm:ss", - "Format_DateTime_Short": "dd.MM.y HH:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM y {time}", + "Format_DateTime_Short": "dd.MM.y {time}", "Format_Date_Day_Month": "E, d.MM", "Format_Date_Long": "EEEE, d MMMM y", "Format_Date_Short": "dd.MM.y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "dd.MM.y–dd.MM.y", "Format_Month_Long": "LLLL y", "Format_Month_Short": "MM.y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "godziny", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/pt-br.json b/plugins/Intl/lang/pt-br.json index 4e934e942dea2888ba10afbed5f608a1ba6ae1c4..9f2a028bb4710aec33c17a5de0222e65507d325c 100644 --- a/plugins/Intl/lang/pt-br.json +++ b/plugins/Intl/lang/pt-br.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sáb", "Day_Short_StandAlone_7": "Dom", "EnglishLanguageName": "Brazilian Portuguese", - "Format_DateTime_Long": "EEEE, d 'de' MMMM 'de' y HH:mm:ss", - "Format_DateTime_Short": "d 'de' MMM 'de' y HH:mm:ss", + "Format_DateTime_Long": "EEEE, d 'de' MMMM 'de' y {time}", + "Format_DateTime_Short": "d 'de' MMM 'de' y {time}", "Format_Date_Day_Month": "E, d 'de' MMM", "Format_Date_Long": "EEEE, d 'de' MMMM 'de' y", "Format_Date_Short": "d 'de' MMM 'de' y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d 'de' MMM 'de' y – d 'de' MMM 'de' y", "Format_Month_Long": "MMMM 'de' y", "Format_Month_Short": "MMM 'de' y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "horas", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/pt.json b/plugins/Intl/lang/pt.json index bacafa576db44460eab38d80dde2575ec7530873..60270770dfbfb1c8411afd871843311b6155e335 100644 --- a/plugins/Intl/lang/pt.json +++ b/plugins/Intl/lang/pt.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sábado", "Day_Short_StandAlone_7": "Domingo", "EnglishLanguageName": "Portuguese", - "Format_DateTime_Long": "EEEE, d 'de' MMMM 'de' y HH:mm:ss", - "Format_DateTime_Short": "dd\/MM\/y HH:mm:ss", + "Format_DateTime_Long": "EEEE, d 'de' MMMM 'de' y {time}", + "Format_DateTime_Short": "dd\/MM\/y {time}", "Format_Date_Day_Month": "E, d\/MM", "Format_Date_Long": "EEEE, d 'de' MMMM 'de' y", "Format_Date_Short": "dd\/MM\/y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d 'de' MMM 'de' y – d 'de' MMM 'de' y", "Format_Month_Long": "MMMM 'de' y", "Format_Month_Short": "MM\/y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "horas", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/ro.json b/plugins/Intl/lang/ro.json index 2e8973de3017c8ed8b9c2477d1d01e9f4032db7c..8f5b576ffb285da70bc333c8b75f9ab7cd6db690 100644 --- a/plugins/Intl/lang/ro.json +++ b/plugins/Intl/lang/ro.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sâm.", "Day_Short_StandAlone_7": "Dum.", "EnglishLanguageName": "Romanian", - "Format_DateTime_Long": "EEEE, d MMMM y HH:mm:ss", - "Format_DateTime_Short": "d MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ore", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/ru.json b/plugins/Intl/lang/ru.json index b26d8829715701463e1ed4282bc85ffb2ab74ac1..593daf525d4b30086be7c48923d575e03b17e6dc 100644 --- a/plugins/Intl/lang/ru.json +++ b/plugins/Intl/lang/ru.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Сб", "Day_Short_StandAlone_7": "Ð’Ñ", "EnglishLanguageName": "Russian", - "Format_DateTime_Long": "EEEE, d MMMM y 'г'. H:mm:ss", - "Format_DateTime_Short": "d MMM y 'г'. H:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM y 'г'. {time}", + "Format_DateTime_Short": "d MMM y 'г'. {time}", "Format_Date_Day_Month": "ccc, d MMM", "Format_Date_Long": "EEEE, d MMMM y 'г'.", "Format_Date_Short": "d MMM y 'г'.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y 'г'.", "Format_Month_Long": "LLLL y 'г'.", "Format_Month_Short": "LLL y 'г'.", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "H:mm:ss", "Format_Year": "y", "Hours": "чаÑÑ‹", "Language_aa": "Ðфар", diff --git a/plugins/Intl/lang/sk.json b/plugins/Intl/lang/sk.json index d926c8f1bd6874b7c2f297504ff04a28a2d7f68b..db39d8d374b366943d7d542c9628faf4e71ff865 100644 --- a/plugins/Intl/lang/sk.json +++ b/plugins/Intl/lang/sk.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "So", "Day_Short_StandAlone_7": "Ne", "EnglishLanguageName": "Slovak", - "Format_DateTime_Long": "EEEE, d. MMMM y H:mm:ss", - "Format_DateTime_Short": "d. M. y H:mm:ss", + "Format_DateTime_Long": "EEEE, d. MMMM y {time}", + "Format_DateTime_Short": "d. M. y {time}", "Format_Date_Day_Month": "E d. M.", "Format_Date_Long": "EEEE, d. MMMM y", "Format_Date_Short": "d. M. y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. M. y – d. M. y", "Format_Month_Long": "LLLL y", "Format_Month_Short": "M\/y", - "Format_Time": "H:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "H:mm:ss", "Format_Year": "y", "Hours": "hodiny", "Language_aa": "AfarÄina", diff --git a/plugins/Intl/lang/sl.json b/plugins/Intl/lang/sl.json index 054f53ca8b1c4302a05f40621c596a30aff08eda..2610cb1fa19a21f1df82db033d953982d76ab7ec 100644 --- a/plugins/Intl/lang/sl.json +++ b/plugins/Intl/lang/sl.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sob", "Day_Short_StandAlone_7": "Ned", "EnglishLanguageName": "Slovenian", - "Format_DateTime_Long": "EEEE, dd. MMMM y HH:mm:ss", - "Format_DateTime_Short": "d. MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE, dd. MMMM y {time}", + "Format_DateTime_Short": "d. MMM y {time}", "Format_Date_Day_Month": "E, d. MMM", "Format_Date_Long": "EEEE, dd. MMMM y", "Format_Date_Short": "d. MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d. MMM y–d. MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ur", "Language_aa": "AfarÅ¡Äina", diff --git a/plugins/Intl/lang/sq.json b/plugins/Intl/lang/sq.json index ee9aa0eae3a14bc4b9213192faeb193563eabc65..1c9acf73d32fc2dfdffc38f53e834db1b24ca5ae 100644 --- a/plugins/Intl/lang/sq.json +++ b/plugins/Intl/lang/sq.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sht", "Day_Short_StandAlone_7": "Die", "EnglishLanguageName": "Albanian", - "Format_DateTime_Long": "EEEE, d MMMM y h:mm:ss a", - "Format_DateTime_Short": "d MMM y h:mm:ss a", + "Format_DateTime_Long": "EEEE, d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "orë", "Language_ab": "Abkazisht", diff --git a/plugins/Intl/lang/sr.json b/plugins/Intl/lang/sr.json index 003e91483c3337e4cbdcba7feea1787d03a06062..3e59d08f33ab0b47fdda3cda6c26b55672188be5 100644 --- a/plugins/Intl/lang/sr.json +++ b/plugins/Intl/lang/sr.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Суб", "Day_Short_StandAlone_7": "Ðед", "EnglishLanguageName": "Serbian", - "Format_DateTime_Long": "EEEE, dd. MMMM y. HH.mm.ss", - "Format_DateTime_Short": "dd.MM.y. HH.mm.ss", + "Format_DateTime_Long": "EEEE, dd. MMMM y. {time}", + "Format_DateTime_Short": "dd.MM.y. {time}", "Format_Date_Day_Month": "E d. MMM", "Format_Date_Long": "EEEE, dd. MMMM y.", "Format_Date_Short": "dd.MM.y.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "dd. MMM y. – dd. MMM y.", "Format_Month_Long": "MMMM y.", "Format_Month_Short": "MMM y.", - "Format_Time": "HH.mm.ss", + "Format_Time": "{time}", + "Format_Time_12": "hh.mm.ss a", + "Format_Time_24": "HH.mm.ss", "Format_Year": "y.", "Hours": "Ñати", "Language_aa": "ÐфарÑки", diff --git a/plugins/Intl/lang/sv.json b/plugins/Intl/lang/sv.json index c829d8841880b1608f28514530ffe331176b22b4..6652fd399bcdfbd37011e3d1a17715b2b97ad81a 100644 --- a/plugins/Intl/lang/sv.json +++ b/plugins/Intl/lang/sv.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Lör", "Day_Short_StandAlone_7": "Sön", "EnglishLanguageName": "Swedish", - "Format_DateTime_Long": "EEEE d MMMM y HH:mm:ss", - "Format_DateTime_Short": "d MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEE d MMMM y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E d MMM", "Format_Date_Long": "EEEE d MMMM y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y–d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "timmar", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/ta.json b/plugins/Intl/lang/ta.json index 43708c2ba90f5fc7b23adf26cec4d1628d73950a..a24fad18e147302333633fe24916e26e196d81b7 100644 --- a/plugins/Intl/lang/ta.json +++ b/plugins/Intl/lang/ta.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "சனி", "Day_Short_StandAlone_7": "ஞாயி.", "EnglishLanguageName": "Tamil", - "Format_DateTime_Long": "EEEE, d MMMM, y a h:mm:ss", - "Format_DateTime_Short": "d MMM, y a h:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM, y {time}", + "Format_DateTime_Short": "d MMM, y {time}", "Format_Date_Day_Month": "MMM d, E", "Format_Date_Long": "EEEE, d MMMM, y", "Format_Date_Short": "d MMM, y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM, y – d MMM, y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "a h:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "a h:mm:ss", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "மணிநேரஙà¯à®•ளà¯", "Language_aa": "அஃபாரà¯", diff --git a/plugins/Intl/lang/te.json b/plugins/Intl/lang/te.json index 7c9679b3a13fe4bbd4dd5540a5f2e40e7e3d1b52..9122d011da1aef7f521c72557df2681aec54245a 100644 --- a/plugins/Intl/lang/te.json +++ b/plugins/Intl/lang/te.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "శని", "Day_Short_StandAlone_7": "ఆది", "EnglishLanguageName": "Telugu", - "Format_DateTime_Long": "d, MMMM y, EEEE h:mm:ss a", - "Format_DateTime_Short": "d MMM, y h:mm:ss a", + "Format_DateTime_Long": "d, MMMM y, EEEE {time}", + "Format_DateTime_Short": "d MMM, y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "d, MMMM y, EEEE", "Format_Date_Short": "d MMM, y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM, y – d MMM, y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "à°—à°‚à°Ÿà°²à±", "Language_aa": "అఫారà±", diff --git a/plugins/Intl/lang/th.json b/plugins/Intl/lang/th.json index afe4e21c493ed32e5ae4a30d9abf30a60d7be519..52034808c228976d838bc217bb57c70dff8f4dce 100644 --- a/plugins/Intl/lang/th.json +++ b/plugins/Intl/lang/th.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "ส.", "Day_Short_StandAlone_7": "à¸à¸².", "EnglishLanguageName": "Thai", - "Format_DateTime_Long": "EEEEที่ d MMMM G y HH:mm:ss", - "Format_DateTime_Short": "d MMM y HH:mm:ss", + "Format_DateTime_Long": "EEEEที่ d MMMM G y {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "E d MMM", "Format_Date_Long": "EEEEที่ d MMMM G y", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM G y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "ชั่วโมง", "Language_aa": "à¸à¸°à¸Ÿà¸²à¸£à¹Œ", diff --git a/plugins/Intl/lang/tl.json b/plugins/Intl/lang/tl.json index caebf74edfd81e9900382177c8e4531ad6ea09f8..793664da58fde64543eea130c6f067e5fbcddf42 100644 --- a/plugins/Intl/lang/tl.json +++ b/plugins/Intl/lang/tl.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Sab", "Day_Short_StandAlone_7": "Lin", "EnglishLanguageName": "Tagalog", - "Format_DateTime_Long": "EEEE, MMMM d, y h:mm:ss a", - "Format_DateTime_Short": "MMM d, y h:mm:ss a", + "Format_DateTime_Long": "EEEE, MMMM d, y {time}", + "Format_DateTime_Short": "MMM d, y {time}", "Format_Date_Day_Month": "E, MMM d", "Format_Date_Long": "EEEE, MMMM d, y", "Format_Date_Short": "MMM d, y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "MMM d, y – MMM d, y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "h:mm:ss a", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "mga oras", "Language_ab": "Abkhazian", diff --git a/plugins/Intl/lang/tr.json b/plugins/Intl/lang/tr.json index 0d2b4082e6cf17af335d8c5573af43042dabd6c7..3ceb15c281ef7598d58a8e2312ac69785996fdb2 100644 --- a/plugins/Intl/lang/tr.json +++ b/plugins/Intl/lang/tr.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Cmt", "Day_Short_StandAlone_7": "Paz", "EnglishLanguageName": "Turkish", - "Format_DateTime_Long": "d MMMM y EEEE HH:mm:ss", - "Format_DateTime_Short": "d MMM y HH:mm:ss", + "Format_DateTime_Long": "d MMMM y EEEE {time}", + "Format_DateTime_Short": "d MMM y {time}", "Format_Date_Day_Month": "d MMMM E", "Format_Date_Long": "d MMMM y EEEE", "Format_Date_Short": "d MMM y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "MMMM y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "a h:mm:ss", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "saat", "Language_aa": "Afar", diff --git a/plugins/Intl/lang/uk.json b/plugins/Intl/lang/uk.json index 69ec802cbb394b9b14da0ff8f17e7f75a7499155..44d6c12e92df0f8d736e272dfbd0cabdaec48c2c 100644 --- a/plugins/Intl/lang/uk.json +++ b/plugins/Intl/lang/uk.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Сб", "Day_Short_StandAlone_7": "Ðд", "EnglishLanguageName": "Ukrainian", - "Format_DateTime_Long": "EEEE, d MMMM y 'Ñ€'. HH:mm:ss", - "Format_DateTime_Short": "d MMM y 'Ñ€'. HH:mm:ss", + "Format_DateTime_Long": "EEEE, d MMMM y 'Ñ€'. {time}", + "Format_DateTime_Short": "d MMM y 'Ñ€'. {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, d MMMM y 'Ñ€'.", "Format_Date_Short": "d MMM y 'Ñ€'.", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "d MMM y – d MMM y", "Format_Month_Long": "LLLL y", "Format_Month_Short": "LLL y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "години", "Language_aa": "ÐфарÑька", diff --git a/plugins/Intl/lang/vi.json b/plugins/Intl/lang/vi.json index e89f2f527b26c65c0fa47485af171b78e2f1d420..9da64b533ada56933be19295c2eccfe1e3fadb21 100644 --- a/plugins/Intl/lang/vi.json +++ b/plugins/Intl/lang/vi.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "Th 7", "Day_Short_StandAlone_7": "CN", "EnglishLanguageName": "Vietnamese", - "Format_DateTime_Long": "EEEE, 'ngà y' dd MMMM 'năm' y HH:mm:ss", - "Format_DateTime_Short": "d MMM, y HH:mm:ss", + "Format_DateTime_Long": "EEEE, 'ngà y' dd MMMM 'năm' y {time}", + "Format_DateTime_Short": "d MMM, y {time}", "Format_Date_Day_Month": "E, d MMM", "Format_Date_Long": "EEEE, 'ngà y' dd MMMM 'năm' y", "Format_Date_Short": "d MMM, y", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "'Ngà y' dd 'tháng' M 'năm' y - 'Ngà y' dd 'tháng' M 'năm' y", "Format_Month_Long": "MMMM 'năm' y", "Format_Month_Short": "MMM y", - "Format_Time": "HH:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "h:mm:ss a", + "Format_Time_24": "HH:mm:ss", "Format_Year": "y", "Hours": "giá»", "Language_aa": "Tiếng Afar", diff --git a/plugins/Intl/lang/zh-cn.json b/plugins/Intl/lang/zh-cn.json index 5b48c6c6d84ef1c681edf1158b5ca11e2cc2044a..5cd4c2c680354e5fe32180b602ecfe9a8affb7ae 100644 --- a/plugins/Intl/lang/zh-cn.json +++ b/plugins/Intl/lang/zh-cn.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "周å…", "Day_Short_StandAlone_7": "周日", "EnglishLanguageName": "Simplified Chinese", - "Format_DateTime_Long": "yå¹´M月dæ—¥EEEE ah:mm:ss", - "Format_DateTime_Short": "yå¹´M月dæ—¥ ah:mm:ss", + "Format_DateTime_Long": "yå¹´M月dæ—¥EEEE {time}", + "Format_DateTime_Short": "yå¹´M月dæ—¥ {time}", "Format_Date_Day_Month": "M月dæ—¥E", "Format_Date_Long": "yå¹´M月dæ—¥EEEE", "Format_Date_Short": "yå¹´M月dæ—¥", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "yå¹´M月d日至yå¹´M月dæ—¥", "Format_Month_Long": "yå¹´M月", "Format_Month_Short": "yå¹´M月", - "Format_Time": "ah:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "ah:mm:ss", + "Format_Time_24": "HH:mm:ss", "Format_Year": "yå¹´", "Hours": "å°æ—¶", "Language_aa": "阿法文", diff --git a/plugins/Intl/lang/zh-tw.json b/plugins/Intl/lang/zh-tw.json index 5fac85b0ec8cbe8d9a1a89b52a63fcf723f56a6b..1bc630d29ac404f9363ce3dc4eed3bbb73aefbbd 100644 --- a/plugins/Intl/lang/zh-tw.json +++ b/plugins/Intl/lang/zh-tw.json @@ -300,8 +300,8 @@ "Day_Short_StandAlone_6": "週å…", "Day_Short_StandAlone_7": "週日", "EnglishLanguageName": "Traditional Chinese", - "Format_DateTime_Long": "yå¹´M月dæ—¥ EEEE ah:mm:ss", - "Format_DateTime_Short": "yå¹´M月dæ—¥ ah:mm:ss", + "Format_DateTime_Long": "yå¹´M月dæ—¥ EEEE {time}", + "Format_DateTime_Short": "yå¹´M月dæ—¥ {time}", "Format_Date_Day_Month": "M月dæ—¥ E", "Format_Date_Long": "yå¹´M月dæ—¥ EEEE", "Format_Date_Short": "yå¹´M月dæ—¥", @@ -313,7 +313,9 @@ "Format_Interval_Short_Y": "yå¹´M月d日至yå¹´M月dæ—¥", "Format_Month_Long": "yå¹´M月", "Format_Month_Short": "yå¹´M月", - "Format_Time": "ah:mm:ss", + "Format_Time": "{time}", + "Format_Time_12": "ah:mm:ss", + "Format_Time_24": "HH:mm:ss", "Format_Year": "yå¹´", "Hours": "å°æ™‚", "Language_aa": "阿法文", diff --git a/plugins/LanguagesManager/API.php b/plugins/LanguagesManager/API.php index dc252abbda4458d95dccb72e7458d21a38082a80..9d75f62c2f8987355efb39b03789f22614d2d9a0 100644 --- a/plugins/LanguagesManager/API.php +++ b/plugins/LanguagesManager/API.php @@ -275,6 +275,45 @@ class API extends \Piwik\Plugin\API return true; } + /** + * Returns whether the user uses 12 hour clock + * + * @param string $login + * @return string + */ + public function uses12HourClockForUser($login) + { + if ($login == 'anonymous') { + return false; + } + + Piwik::checkUserHasSuperUserAccessOrIsTheUser($login); + + $lang = $this->getModel()->uses12HourClock($login); + + return $lang; + } + + /** + * Returns whether the user uses 12 hour clock + * + * @param string $login + * @param bool $use12HourClock + * @return string + */ + public function set12HourClockForUser($login, $use12HourClock) + { + if ($login == 'anonymous') { + return false; + } + + Piwik::checkUserHasSuperUserAccessOrIsTheUser($login); + + $lang = $this->getModel()->set12HourClock($login, $use12HourClock); + + return $lang; + } + private function loadAvailableLanguages() { if (!is_null($this->availableLanguageNames)) { diff --git a/plugins/LanguagesManager/LanguagesManager.php b/plugins/LanguagesManager/LanguagesManager.php index 012de9cd50980606b1d96c95b3dd312ac10be909..2a468d550a23bf06d8d7ae0a33585b368691d6c4 100644 --- a/plugins/LanguagesManager/LanguagesManager.php +++ b/plugins/LanguagesManager/LanguagesManager.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\LanguagesManager; use Exception; +use Piwik\API\Request; use Piwik\Common; use Piwik\Config; use Piwik\Container\StaticContainer; @@ -137,6 +138,19 @@ class LanguagesManager extends \Piwik\Plugin Model::uninstall(); } + /** + * @return boolean + */ + public static function uses12HourClockForCurrentUser() + { + try { + $currentUser = Piwik::getCurrentUserLogin(); + return Request::processRequest('LanguagesManager.uses12HourClockForUser', array('login' => $currentUser)); + } catch (Exception $e) { + return false; + } + } + /** * @return string Two letters language code, eg. "fr" */ diff --git a/plugins/LanguagesManager/Model.php b/plugins/LanguagesManager/Model.php index e40452c1344897f199aa2e716def0cba7b912ef9..fad84238cd81a9dae31d6c02f43b536194233b1b 100644 --- a/plugins/LanguagesManager/Model.php +++ b/plugins/LanguagesManager/Model.php @@ -57,10 +57,41 @@ class Model return true; } + /** + * Returns whether the given user has choosen to use 12 hour clock + * + * @param $userLogin + * @return bool + * @throws \Exception + */ + public function uses12HourClock($userLogin) + { + return (bool) Db::fetchOne('SELECT use_12_hour_clock FROM ' . $this->table . + ' WHERE login = ? ', array($userLogin)); + } + + /** + * Sets whether the given user wants to use 12 hout clock + * + * @param string $login + * @param string $use12HourClock + * @return bool + */ + public function set12HourClock($login, $use12HourClock) + { + $query = 'INSERT INTO ' . $this->table . + ' (login, use_12_hour_clock) VALUES (?,?) ON DUPLICATE KEY UPDATE use_12_hour_clock=?'; + $bind = array($login, $use12HourClock, $use12HourClock); + Db::query($query, $bind); + + return true; + } + public static function install() { $userLanguage = "login VARCHAR( 100 ) NOT NULL , language VARCHAR( 10 ) NOT NULL , + use_12_hour_clock TINYINT(1) NOT NULL DEFAULT 0 , PRIMARY KEY ( login )"; DbHelper::createTable(self::$rawPrefix, $userLanguage); } diff --git a/plugins/LanguagesManager/Test/Integration/ModelTest.php b/plugins/LanguagesManager/Test/Integration/ModelTest.php new file mode 100644 index 0000000000000000000000000000000000000000..023b43f2939e893d2b1cdfbe23612024ba95e94c --- /dev/null +++ b/plugins/LanguagesManager/Test/Integration/ModelTest.php @@ -0,0 +1,136 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\LanguagesManager\tests\Integration; + +use Piwik\Common; +use Piwik\Db; +use Piwik\Plugins\LanguagesManager\Model; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; + +/** + * @group LanguagesManager + * @group ModelTest + * @group Plugins + */ +class ModelTest extends IntegrationTestCase +{ + + /** + * @var Model + */ + protected $model; + + public function setUp() + { + $this->model = new Model(); + parent::setUp(); + } + + public function test_install_ShouldNotFailAndActuallyCreateTheDatabases() + { + $this->assertContainTables(array('user_language')); + + $columns = Db::fetchAll('show columns from ' . Common::prefixTable('user_language')); + $this->assertCount(3, $columns); + } + + public function test_uninstall_ShouldNotFailAndRemovesAllAlertTables() + { + Model::uninstall(); + + $this->assertNotContainTables(array('user_language')); + + Model::install(); + } + + public function test_handlesUserLanguageEntriesCorrectly() + { + $this->model->setLanguageForUser('admin', 'de'); + + $this->assertTableEntryCount(1); + + $this->assertEquals('de', $this->model->getLanguageForUser('admin')); + + $this->model->deleteUserLanguage('admin'); + + $this->assertTableEntryCount(0); + } + + public function test_handlesUserTimeFormatEntriesCorrectly() + { + $this->model->set12HourClock('admin', false); + + $this->assertTableEntryCount(1); + + $this->assertEquals(false, $this->model->uses12HourClock('admin')); + + $this->model->deleteUserLanguage('admin'); + + $this->assertTableEntryCount(0); + } + + public function test_handlesUserLanguageAndTimeFormatEntriesCorrectly() + { + $this->model->setLanguageForUser('admin', 'de'); + + $this->assertTableEntryCount(1); + + $this->model->set12HourClock('admin', false); + $this->model->set12HourClock('user', true); + + $this->assertTableEntryCount(2); + + $this->assertEquals('de', $this->model->getLanguageForUser('admin')); + $this->assertEquals('', $this->model->getLanguageForUser('user')); + $this->assertEquals(false, $this->model->uses12HourClock('admin')); + $this->assertEquals(true, $this->model->uses12HourClock('user')); + + $this->model->deleteUserLanguage('admin'); + + $this->assertTableEntryCount(1); + } + + private function assertTableEntryCount($count) + { + $entryCount = Db::fetchOne('SELECT COUNT(*) FROM ' . Common::prefixTable('user_language')); + + $this->assertEquals($count, $entryCount); + + } + + private function assertContainTables($expectedTables) + { + $tableNames = $this->getCurrentAvailableTableNames(); + + foreach ($expectedTables as $expectedTable) { + $this->assertContains(Common::prefixTable($expectedTable), $tableNames); + } + } + + private function assertNotContainTables($expectedTables) + { + $tableNames = $this->getCurrentAvailableTableNames(); + + foreach ($expectedTables as $expectedTable) { + $this->assertNotContains(Common::prefixTable($expectedTable), $tableNames); + } + } + + private function getCurrentAvailableTableNames() + { + $tables = Db::fetchAll('show tables'); + + $tableNames = array(); + foreach ($tables as $table) { + $tableNames[] = array_shift($table); + } + + return $tableNames; + } +} diff --git a/plugins/LanguagesManager/Updates/2.15.1-b1.php b/plugins/LanguagesManager/Updates/2.15.1-b1.php new file mode 100644 index 0000000000000000000000000000000000000000..3465ad7b576d36f8762fd95f2dcaa61332ff1662 --- /dev/null +++ b/plugins/LanguagesManager/Updates/2.15.1-b1.php @@ -0,0 +1,32 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ + +namespace Piwik\Plugins\LanguagesManager; + +use Piwik\Common; +use Piwik\Updater; +use Piwik\Updates; + + +class Updates_2_15_1_b1 extends Updates +{ + public function getMigrationQueries(Updater $updater) + { + $updateSql = array( + 'ALTER TABLE `' . Common::prefixTable('user_language') + . '` ADD COLUMN `use_12_hour_clock` TINYINT(1) NOT NULL DEFAULT 0 AFTER `language`' => array(1060) + ); + return $updateSql; + } + + public function doUpdate(Updater $updater) + { + $updater->executeMigrationQueries(__FILE__, $this->getMigrationQueries($updater)); + } +} diff --git a/plugins/Live/Live.php b/plugins/Live/Live.php index 93e8d67881121261b4e800ef5ae4467cb90eab91..1a71aa7b83cb0a427bbef0acc85cca3576a6605d 100644 --- a/plugins/Live/Live.php +++ b/plugins/Live/Live.php @@ -54,5 +54,7 @@ class Live extends \Piwik\Plugin $translationKeys[] = "Live_RowActionTooltipDefault"; $translationKeys[] = "Live_RowActionTooltipWithDimension"; $translationKeys[] = "Live_SegmentedVisitorLogTitle"; + $translationKeys[] = "General_Segment"; + $translationKeys[] = "General_And"; } } \ No newline at end of file diff --git a/plugins/Live/Visitor.php b/plugins/Live/Visitor.php index 6d679a8a05ca6388bbd7d67bc6a0cfa903a5720f..fa7be4dd63d0ea08cb2f4ca1e2bf03ccecea5bb1 100644 --- a/plugins/Live/Visitor.php +++ b/plugins/Live/Visitor.php @@ -286,7 +286,7 @@ class Visitor implements VisitorInterface unset($actionDetails[$actionIdx]); continue; - } elseif ($actionDetail['type'] == Action::TYPE_EVENT_CATEGORY) { + } elseif ($actionDetail['type'] == Action::TYPE_EVENT) { // Handle Event if (strlen($actionDetail['pageTitle']) > 0) { $actionDetail['eventName'] = $actionDetail['pageTitle']; @@ -301,7 +301,7 @@ class Visitor implements VisitorInterface } // Event value / Generation time - if ($actionDetail['type'] == Action::TYPE_EVENT_CATEGORY) { + if ($actionDetail['type'] == Action::TYPE_EVENT) { if (strlen($actionDetail['custom_float']) > 0) { $actionDetail['eventValue'] = round($actionDetail['custom_float'], self::EVENT_VALUE_PRECISION); } @@ -310,7 +310,7 @@ class Visitor implements VisitorInterface } unset($actionDetail['custom_float']); - if ($actionDetail['type'] != Action::TYPE_EVENT_CATEGORY) { + if ($actionDetail['type'] != Action::TYPE_EVENT) { unset($actionDetail['eventCategory']); unset($actionDetail['eventAction']); } @@ -423,7 +423,7 @@ class Visitor implements VisitorInterface $details['type'] = 'search'; $details['icon'] = 'plugins/Morpheus/images/search_ico.png'; break; - case Action::TYPE_EVENT_CATEGORY: + case Action::TYPE_EVENT: $details['type'] = 'event'; $details['icon'] = 'plugins/Morpheus/images/event.png'; break; diff --git a/plugins/Live/javascripts/rowaction.js b/plugins/Live/javascripts/rowaction.js index 8baba18a2d570a1c856256e6ccce50ee52c3f6a6..5c54e961b5ea1a247dcdd21425fc1596fbd1dd59 100644 --- a/plugins/Live/javascripts/rowaction.js +++ b/plugins/Live/javascripts/rowaction.js @@ -150,6 +150,12 @@ var segmentName = getDimensionFromApiMethod(apiMethod); var segmentValue = findTitleOfRowHavingRawSegmentValue(apiMethod, segment); + if (!segmentName || (segment && segment.indexOf(';') > 0)) { + segmentName = _pk_translate('General_Segment'); + var segmentParts = segment.split(';'); + segmentValue = segmentParts.join(' ' + _pk_translate('General_And') + ' '); + } + segmentName = piwikHelper.escape(segmentName); segmentName = piwikHelper.htmlEntities(segmentName); segmentValue = piwikHelper.escape(segmentValue); diff --git a/plugins/Live/lang/cs.json b/plugins/Live/lang/cs.json index ec3ea624fdbfe2e68caf38cd198e3c926d34f6c6..caf56e0adc2115997a537ae243cc32fd5bf21ac5 100644 --- a/plugins/Live/lang/cs.json +++ b/plugins/Live/lang/cs.json @@ -4,7 +4,7 @@ "AveragePageGenerationTime": "Pro tohoto návÅ¡tÄ›vnÃka se každá stránka naÄetla v průmÄ›ru za %1$s.", "CalculatedOverNPageViews": "VypoÄÃtáno na základÄ› %1$s poslednÃch zobrazenà stránek tohoto návÅ¡tÄ›vnÃka.", "ClickToViewMoreAboutVisit": "KliknÄ›te pro zobrazenà vÃce informacà o této návÅ¡tÄ›vÄ›", - "ConvertedNGoals": "Zkonvertováno %s cÃlů", + "ConvertedNGoals": "PromÄ›nÄ›no %s cÃlů", "EcommerceSummaryConversions": "%1$s%2$s objednávek celkem za %3$s%4$s, zakoupeno %5$s položek.", "FirstVisit": "Prvnà návÅ¡tÄ›va", "GoalType": "Typ", diff --git a/plugins/Live/lang/fr.json b/plugins/Live/lang/fr.json index 0b099319fdd133656d157d8887caefa29af33fe9..ad9dd10a44cbc6f7a35041ede22247f694642c09 100644 --- a/plugins/Live/lang/fr.json +++ b/plugins/Live/lang/fr.json @@ -9,7 +9,7 @@ "FirstVisit": "Première visite", "GoalType": "Type", "HideMap": "Cacher la carte", - "KeywordRankedOnSearchResultForThisVisitor": "Le mot-clé %1$s a été a été noté %2$s dans la page de résultats de recherche %3$s pour ce visiteur", + "KeywordRankedOnSearchResultForThisVisitor": "Le mot-clé %1$s a été noté %2$s dans la page de résultats de recherche %3$s pour ce visiteur", "LastHours": "Dernières %s heures", "LastMinutes": "Dernières %s minutes", "LastVisit": "Dernière visite", diff --git a/plugins/Live/lang/ja.json b/plugins/Live/lang/ja.json index eee0e823c03ea51a3554b23f4c744bfd74f1084f..1bcc483702cfe8c3832ed7c367d586a84eff658d 100644 --- a/plugins/Live/lang/ja.json +++ b/plugins/Live/lang/ja.json @@ -35,6 +35,12 @@ "VisitorsInRealTime": "リアルタイムã®ãƒ“ジター", "VisitorsLastVisit": "ã“ã®ãƒ“ã‚¸ã‚¿ãƒ¼ã®æœ€æ–°ã®ãƒ“ジット㯠%s æ—¥å‰ã§ã™ã€‚", "VisitsFrom": "ã‹ã‚‰ %1$s%2$s ㌠%3$s を訪å•", - "VisitSummary": "ウェブサイト %3$s ã§ã€åˆè¨ˆ %1$s%2$s を消費ã—ã€%4$s 㯠%6$s 訪å•ã§ã€%5$s ページ閲覧ã—ã¾ã—ãŸã€‚%7$s" + "VisitSummary": "ウェブサイト %3$s ã§ã€åˆè¨ˆ %1$s%2$s を消費ã—ã€%4$s 㯠%6$s 訪å•ã§ã€%5$s ページ閲覧ã—ã¾ã—ãŸã€‚%7$s", + "RowActionTooltipDefault": "ã“ã®è¡Œã§åˆ†å‰²ã•れãŸãƒ“ジターãƒã‚°ã‚’表示", + "RowActionTooltipWithDimension": "ã“ã® %s ã§åˆ†å‰²ã•れãŸãƒ“ジターãƒã‚°ã‚’表示", + "RowActionTooltipTitle": "セグメントビジターãƒã‚°ã‚’表示", + "SegmentedVisitorLogTitle": "%s ㌠\" %s \" ã®ãƒ“ジットを示ã™ãƒ“ジターãƒã‚°", + "OnClickPause": "%s ãŒé–‹å§‹ã•れã¾ã—ãŸã€‚クリックã—ã¦ä¸€æ™‚åœæ¢ã—ã¾ã™ã€‚", + "OnClickStart": "%s ã¯åœæ¢ã—ã¦ã„ã¾ã™ã€‚クリックã—ã¦é–‹å§‹ã—ã¾ã™ã€‚" } } \ No newline at end of file diff --git a/plugins/Live/lang/ko.json b/plugins/Live/lang/ko.json index e6c78b24d098433f52e698565958ea9294abc4d0..e1de77a61ff4fad7437e1fec642007982578ec82 100644 --- a/plugins/Live/lang/ko.json +++ b/plugins/Live/lang/ko.json @@ -1,16 +1,34 @@ { "Live": { + "CalculatedOverNPageViews": "해당 방문ìžì˜ %1$s 번 페ì´ì§€ ë°©ë¬¸ì„ í†µí•´ 계산ë˜ì—ˆìŠµë‹ˆë‹¤.", + "ClickToViewMoreAboutVisit": "ì´ ë°©ë¬¸ì— ëŒ€í•´ ë” ìžì„¸í•œ ì •ë³´ë¥¼ 보기 위해서 í´ë¦í•˜ì„¸ìš”.", + "FirstVisit": "첫 방문", "GoalType": "ìœ í˜•", + "HideMap": "ì§€ë„ ìˆ¨ê¸°ê¸°", "KeywordRankedOnSearchResultForThisVisitor": "키워드 %1$s ì´ ë°©ë¬¸ìžì˜ %3$s 검색 ê²°ê³¼ 페ì´ì§€ì—서 %2$sì— ëží¬ë˜ì—ˆìŠµë‹ˆë‹¤.", "LastHours": "최근 %s시간", "LastMinutes": "최근 %së¶„", + "LastVisit": "최근 방문", "LinkVisitorLog": "ë°©ë¬¸ìž ê¸°ë¡ ìžì„¸ížˆ 보기", + "LoadMoreVisits": "ë” ë§Žì€ ë°©ë¬¸ë“¤ 불러오기", "MorePagesNotDisplayed": "ì´ ë°©ë¬¸ê°ì˜ 표시는 ë”ì´ìƒ 없습니다", + "NbVisitor": "1명 방문ìž", + "NbVisitors": "%s 방문ìžë“¤", + "NextVisitor": "ë‹¤ìŒ ë°©ë¬¸ìž", + "NoMoreVisits": "ì´ ë°©ë¬¸ìžê°€ 방문한 페ì´ì§€ëŠ” ë” ì´ìƒ 없습니다.", "PageRefreshed": "ì´ íŽ˜ì´ì§€ë¥¼ ë³¼ 수 ìžˆìŒ \/ ì—…ë°ì´íŠ¸ëœ íšŸìˆ˜", + "PreviousVisitor": "ì´ì „ 방문ìž", + "RealTimeVisitorCount": "실시간 ë°©ë¬¸ìž í•©ê³„", "Referrer_URL": "참조 URL", + "ShowMap": "ì§€ë„ ë³´ì´ê¸°", + "ViewVisitorProfile": "ë°©ë¬¸ìž í”„ë¡œí•„ 보기", + "VisitedPages": "방문한 페ì´ì§€ë“¤", "VisitorLog": "ë°©ë¬¸ìž ê¸°ë¡", "VisitorLogDocumentation": "ì´ í‘œëŠ” ì„ íƒí•œ ë‚ ì§œ 기간 ë‚´ì— ìµœì‹ ë°©ë¬¸ì— í‘œì‹œí•˜ê³ ìžˆìŠµë‹ˆë‹¤. 방문 ë‚ ì§œ 위로 마우스를 ì´ë™í•˜ê³ , ê·¸ 방문ìžì˜ 마지막 ë°©ë¬¸ì´ ë©°ì¹ ì „ì¸ì§€ ë³¼ 수 있습니다. %s ê¸°ê°„ë‚´ì— ì˜¤ëŠ˜ì´ í¬í•¨ë˜ì–´ 있으면, 방문ê°ì„ 실시간으로 ë³¼ 수 있습니다! %s ì—¬ê¸°ì— í‘œì‹œë˜ëŠ” ê²ƒì€ ë³´ê´€ì„위한 cron 작업 ì„¤ì • 빈ë„ì— ìƒê´€ì—†ëŠ” ë¼ì´ë¸Œ ë°ì´í„°ìž…니다.", + "VisitorProfile": "ë°©ë¬¸ìž í”„ë¡œí•„", "VisitorsInRealTime": "실시간 방문ìž", - "VisitorsLastVisit": "ì´ ë°©ë¬¸ê°ì˜ ìµœì‹ ë°©ë¬¸ì€ %sì¼ ìž…ë‹ˆë‹¤." + "VisitorsLastVisit": "ì´ ë°©ë¬¸ê°ì˜ ìµœì‹ ë°©ë¬¸ì€ %sì¼ ìž…ë‹ˆë‹¤.", + "OnClickPause": "%sì´\/ê°€ 시작ë˜ì—ˆìŠµë‹ˆë‹¤. 멈추기 위해서 í´ë¦í•´ì£¼ì„¸ìš”.", + "OnClickStart": "%sì´\/ê°€ 멈추었습니다. 시작하기 위해서 í´ë¦í•´ì£¼ì„¸ìš”." } } \ No newline at end of file diff --git a/plugins/LogViewer b/plugins/LogViewer index 25df816eed9b0d44ebcdb89f1dfc9dde8cb3de25..0ee846df5038e82a87abb98e35b4d7cd1718d228 160000 --- a/plugins/LogViewer +++ b/plugins/LogViewer @@ -1 +1 @@ -Subproject commit 25df816eed9b0d44ebcdb89f1dfc9dde8cb3de25 +Subproject commit 0ee846df5038e82a87abb98e35b4d7cd1718d228 diff --git a/plugins/Login/lang/cs.json b/plugins/Login/lang/cs.json index 311341374ea5532bac0e2c37e0bae870e9c45761..8dc2f4f2f0f4733b0772cc5472d4ac0da26a924c 100644 --- a/plugins/Login/lang/cs.json +++ b/plugins/Login/lang/cs.json @@ -1,15 +1,15 @@ { "Login": { - "ConfirmationLinkSent": "Do vašà e-mailové schránky byl odeslán potvrzovacà e-mail. Pro potvrzenà požadavku na zmÄ›nu hesla navÅ¡tivte odkaz v e-mailu uvedený.", - "ContactAdmin": "Možná pÅ™ÃÄina: Váš hosting zakázal funkci mail().. <br \/>ProsÃm kontaktujte vaÅ¡eho administrátora Piwiku.", + "ConfirmationLinkSent": "Do vašà schránky byl odeslán potvrzovacà email. Pro potvrzenà požadavku na zmÄ›nu hesla navÅ¡tivte odkaz uvedený v emailu.", + "ContactAdmin": "Možná pÅ™ÃÄina: Váš hosting zakázal funkci mail().. <br \/>ProsÃm kontaktujte svého administrátora Piwiku.", "ExceptionInvalidSuperUserAccessAuthenticationMethod": "Uživatel se Super uživatelským pÅ™Ãstupem nemůže být autentizován mechanismem %s.", "ExceptionPasswordMD5HashExpected": "Parametr hesla je oÄekáván jako MD5 hash hesla", "InvalidNonceOrHeadersOrReferrer": "ZabezpeÄenà formuláře selhalo. ProsÃm obnovte formulář a zkontrolujte, že máte povolené cookies. Pokud použÃváte proxy server, %smusÃte nakonfigurovat Piwik aby pÅ™ijÃmal proxy hlaviÄku%s, která pÅ™eposÃlá hlaviÄku hosta. Zkontrolujte také, že je správnÄ› posÃlána hlaviÄka referrer.", "InvalidOrExpiredToken": "KlÃÄ je neplatný, nebo vyprÅ¡el", - "InvalidUsernameEmail": "Neplatné uživatelské jméno a\/nebo e-mailová adresa", + "InvalidUsernameEmail": "Neplatné uživatelské jméno a\/nebo emailová adresa", "LogIn": "PÅ™ihlásit", - "LoginOrEmail": "Uživatelské jméno nebo E-mail", - "LoginPasswordNotCorrect": "Uživatelské jméno & heslo nejsou správné", + "LoginOrEmail": "Uživatelské jméno nebo Email", + "LoginPasswordNotCorrect": "Chybná kombinace uživatelského jména a hesla.", "LostYourPassword": "ZapomnÄ›li jste vaÅ¡e heslo?", "MailPasswordChangeBody": "Ahoj %1$s,\n\nZ %2$s byl zaslán požadavek o zmÄ›nu hesla. Pro potvrzenà nových pÅ™ihlaÅ¡ovacÃch údajů navÅ¡tivte následujÃcà odkaz:\n\n%3$s\n\nPoznámka: Tento token je platný 24 hodin.\n\nA dÃky za použÃvánà Piwiku!", "MailTopicPasswordChange": "PotvrÄte zmÄ›nu hesla", diff --git a/plugins/Login/lang/ko.json b/plugins/Login/lang/ko.json index bdc9d729372edef6a3d93e87f800ec7ce1a43b53..e924445eda88c7e9e71b052ea4ec77c5d945362b 100644 --- a/plugins/Login/lang/ko.json +++ b/plugins/Login/lang/ko.json @@ -2,6 +2,7 @@ "Login": { "ConfirmationLinkSent": "í™•ì¸ ë§í¬ê°€ ë‹¹ì‹ ì˜ ë°›ì€ íŽ¸ì§€í•¨ìœ¼ë¡œ ì „ì†¡ë˜ì—ˆìŠµë‹ˆë‹¤. ì´ë©”ì¼ì„ 확ì¸í•˜ê³ 비밀번호 변경요ì²ì„ 승ì¸í•˜ë ¤ë©´ ì´ ë§í¬ë¥¼ 방문하세요.", "ContactAdmin": "가능한 ì´ìœ : 호스트가 ë©”ì¼ ê¸°ëŠ¥ì„ ë¹„í™œì„±í™”í–ˆì„ ìˆ˜ 있습니다. <br \/>ë‹¹ì‹ ì˜ Piwik 관리ìžì—게 ì—°ë½í•´ë³´ì„¸ìš”.", + "ExceptionInvalidSuperUserAccessAuthenticationMethod": "ìŠˆí¼ ìœ ì € ì ‘ê·¼ì˜ '%s' 방법으로는 ì¸ì¦ë˜ì§€ 않습니다.", "ExceptionPasswordMD5HashExpected": "비밀번호 매개변수는 MD5해시 ê°’ì´ ì‚¬ìš©ë˜ê³ 있습니다.", "InvalidNonceOrHeadersOrReferrer": "ì–‘ì‹ ë³´ì•ˆ 실패, ì–‘ì‹ì„ ìƒˆë¡œê³ ì¹¨í•˜ì—¬ ì¿ í‚¤ê°€ 활성화ë˜ì–´ 있는지 확ì¸í•˜ì„¸ìš”. 프ë¡ì‹œ 서버를 사용하는 경우ë¼ë©´, 호스트 í—¤ë”ì— %sPiwik configureì—서 프ë¡ì‹œ í—¤ë”를 수ë½%sí•˜ê³ ì „ë‹¬í•´ì•¼í•©ë‹ˆë‹¤. ë˜í•œ 리í¼ëŸ¬ í—¤ë”ê°€ 올바르게 ì „ì†¡ë˜ëŠ”ì§€ 확ì¸í•©ë‹ˆë‹¤.", "InvalidOrExpiredToken": "í† í°ì´ 잘못ë˜ì—ˆê±°ë‚˜ 만료ë˜ì—ˆìŠµë‹ˆë‹¤.", @@ -15,7 +16,8 @@ "PasswordChanged": "비밀번호가 변경ë˜ì—ˆìŠµë‹ˆë‹¤.", "PasswordRepeat": "비빌번호 (ìž¬ìž…ë ¥)", "PasswordsDoNotMatch": "비밀번호가 ì¼ì¹˜í•˜ì§€ 않습니다.", - "RememberMe": "ì €ë¥¼ 기억해 주세요", + "PluginDescription": "ì•„ì´ë””와 비밀번호를 통해 ì‚¬ìš©ìž ì¸ì¦ë¿ë§Œ ì•„ë‹ˆë¼ ë¹„ë°€ë²ˆí˜¸ ìž¬ì„¤ì • 기능까지 ì œê³µí•©ë‹ˆë‹¤. 마켓ì—서 êµ¬í• ìˆ˜ 있는 LoginLdap와 ê°™ì€ ë˜ ë‹¤ë¥¸ ë¡œê·¸ì¸ í”ŒëŸ¬ê·¸ì¸ì„ 사용하여 ì¸ì¦ ë°©ë²•ì„ ë³€ê²½í• ìˆ˜ 있습니다.", + "RememberMe": "ê³„ì • 기억하기", "ResetPasswordInstructions": "ê³„ì •ì— ì‚¬ìš©í• ìƒˆë¡œìš´ 비밀번호를 ìž…ë ¥í•˜ì„¸ìš”." } } \ No newline at end of file diff --git a/plugins/Login/lang/sl.json b/plugins/Login/lang/sl.json index e14d69523b9a618776f1a18203421e7cc683d02b..7c83e0c2b42270668e61038e9debbb49ba013ec5 100644 --- a/plugins/Login/lang/sl.json +++ b/plugins/Login/lang/sl.json @@ -1,11 +1,17 @@ { "Login": { + "ConfirmationLinkSent": "Potrditveno sporoÄilo je bilo poslano na vaÅ¡ elektronski naslov. Poglejte elektronsko poÅ¡to in sledite povezavi v njem, da potrdite zahtevo za spremembo vaÅ¡ega gesla.", + "ContactAdmin": "Možen razlog: na strežniku je onemogoÄena mail() funkcija. <br \/>Prosimo, obrnite se na vaÅ¡ega Piwik administratorja.", + "ExceptionInvalidSuperUserAccessAuthenticationMethod": "Uporabnik z vlogo \"Super User\" se ne more prijaviti z uporabo mehanizma '%s'.", "InvalidOrExpiredToken": "Žeton je neveljaven ali pa je potekel.", "InvalidUsernameEmail": "NapaÄno uporabniÅ¡ko ime ali e-mail naslov.", "LogIn": "Vpis", "LoginOrEmail": "UporabniÅ¡ko ime ali E-mail", "LoginPasswordNotCorrect": "NapaÄna kombinacija uporabniÅ¡kega imena in gesla.", "LostYourPassword": "Ste pozabili geslo?", + "MailPasswordChangeBody": "Pozdravljen\/-a %1$s,\n\ns strani %2$s je bil prejet zahtevek za zamenjavo gesla. Za potrditev verodostojnosti te zahteve, prosimo sledite povezavi:\n\n%3$s\n\nOpozorilo: ta žeton bo potekel po 24-ih urah.\n\nHvala, ker uporabljate Piwik!", + "MailTopicPasswordChange": "Potrdite spremembo gesla", + "PasswordChanged": "VaÅ¡e geslo je bilo spremenjeno.", "PasswordRepeat": "Geslo (ponovno)", "PasswordsDoNotMatch": "Gesli se ne ujemata.", "RememberMe": "Zapomni si me" diff --git a/plugins/Login/lang/tr.json b/plugins/Login/lang/tr.json index d9c1c638ec07a78c063102f62b458503f03e8805..981d278bf013e0ae239ab6be80db56e4d7ed8d60 100644 --- a/plugins/Login/lang/tr.json +++ b/plugins/Login/lang/tr.json @@ -1,13 +1,18 @@ { "Login": { + "ConfirmationLinkSent": "Onaylama baÄŸlantısı gelen kutunuza gönderildi. Åžifre deÄŸiÅŸikliÄŸinı onaylamak için e-posta hesabınızı kontrol edin ve baÄŸlantıyı ziyaret edin.", + "ContactAdmin": "Olası nedeni: Sunucunuzda mail() fonksiyonunu devre dışı bırakmış olabilir. <br \/>Lütfen Piwik yöneticinizle iletiÅŸime geçiniz.", "InvalidOrExpiredToken": "Güvenlik kodu yanlış yada süresi dolmuÅŸ.", "InvalidUsernameEmail": "Geçersiz kullanıcı adı ve\/veya e-posta adresi", "LogIn": "Oturum aç", "LoginOrEmail": "GiriÅŸ veya E-posta", "LoginPasswordNotCorrect": "Kullanıcı adı & Åžifre yanlış", "LostYourPassword": "Åžifrenizi mi unuttunuz?", + "MailTopicPasswordChange": "Parola DeÄŸiÅŸikliÄŸini Onayla", + "PasswordChanged": "Parolanız deÄŸiÅŸtirildi.", "PasswordRepeat": "Åžifre (Tekrar)", "PasswordsDoNotMatch": "Åžifre eÅŸleÅŸmedi", - "RememberMe": "Beni Hatırla" + "RememberMe": "Beni Hatırla", + "ResetPasswordInstructions": "Hesabınız için yeni parolanızı giriniz." } } \ No newline at end of file diff --git a/plugins/Login/templates/login.twig b/plugins/Login/templates/login.twig index 4bcef0d7995ed754c77f284d21e324763c01214c..0140418af40eb19b92f2c32159ac341bd97c34ed 100644 --- a/plugins/Login/templates/login.twig +++ b/plugins/Login/templates/login.twig @@ -1,12 +1,12 @@ {% extends '@Morpheus/layout.twig' %} +{% block meta %} + <meta name="robots" content="index,follow"> +{% endblock %} + {% block head %} {{ parent() }} - {% block meta %} - <meta name="robots" content="index,follow"> - {% endblock %} - <script type="text/javascript" src="libs/bower_components/jquery-placeholder/jquery.placeholder.js"></script> <!--[if lt IE 9]> <script src="libs/bower_components/html5shiv/dist/html5shiv.min.js"></script> diff --git a/plugins/MobileAppMeasurable/lang/ja.json b/plugins/MobileAppMeasurable/lang/ja.json new file mode 100644 index 0000000000000000000000000000000000000000..deee803801a0a082e9b268687b269c187955f6df --- /dev/null +++ b/plugins/MobileAppMeasurable/lang/ja.json @@ -0,0 +1,7 @@ +{ + "MobileAppMeasurable": { + "MobileApp": "モãƒã‚¤ãƒ«ã‚¢ãƒ—リ", + "MobileApps": "モãƒã‚¤ãƒ«ã‚¢ãƒ—リ", + "MobileAppDescription": "IOSã€Android ã‚„ä»–ã®ãƒ¢ãƒã‚¤ãƒ« オペレーティング システムã®ãƒã‚¤ãƒ†ã‚£ãƒ– モãƒã‚¤ãƒ« アプリケーション。" + } +} \ No newline at end of file diff --git a/plugins/MobileAppMeasurable/lang/nb.json b/plugins/MobileAppMeasurable/lang/nb.json new file mode 100644 index 0000000000000000000000000000000000000000..49eee5557f48a98fe979bbfb1bc2b340e60e9a5d --- /dev/null +++ b/plugins/MobileAppMeasurable/lang/nb.json @@ -0,0 +1,7 @@ +{ + "MobileAppMeasurable": { + "MobileApp": "Mobil-app", + "MobileApps": "Mobil-apper", + "MobileAppDescription": "En spesialbygget mobil-app for iOS, Android eller hvilken som helst annen mobil plattform." + } +} \ No newline at end of file diff --git a/plugins/MobileMessaging/API.php b/plugins/MobileMessaging/API.php index aaf30e6a640136dbf7b931caacc0c64bdac9ba35..345c633b15fc6f1cda0ea78778026d043bc5a1c0 100644 --- a/plugins/MobileMessaging/API.php +++ b/plugins/MobileMessaging/API.php @@ -8,7 +8,6 @@ */ namespace Piwik\Plugins\MobileMessaging; -use Piwik\Common; use Piwik\Option; use Piwik\Piwik; use Piwik\Plugins\MobileMessaging\SMSProvider; @@ -26,15 +25,6 @@ class API extends \Piwik\Plugin\API const VERIFICATION_CODE_LENGTH = 5; const SMS_FROM = 'Piwik'; - /** - * @param string $provider - * @return SMSProvider - */ - private static function getSMSProviderInstance($provider) - { - return SMSProvider::factory($provider); - } - /** * determine if SMS API credential are available for the current user * @@ -83,7 +73,7 @@ class API extends \Piwik\Plugin\API { $this->checkCredentialManagementRights(); - $smsProviderInstance = self::getSMSProviderInstance($provider); + $smsProviderInstance = SMSProvider::factory($provider); $smsProviderInstance->verifyCredential($apiKey); $settings = $this->getCredentialManagerSettings(); @@ -160,7 +150,7 @@ class API extends \Piwik\Plugin\API Piwik::checkUserIsNotAnonymous(); $credential = $this->getSMSAPICredential(); - $SMSProvider = self::getSMSProviderInstance($credential[MobileMessaging::PROVIDER_OPTION]); + $SMSProvider = SMSProvider::factory($credential[MobileMessaging::PROVIDER_OPTION]); $SMSProvider->sendSMS( $credential[MobileMessaging::API_KEY_OPTION], $content, @@ -183,7 +173,7 @@ class API extends \Piwik\Plugin\API $this->checkCredentialManagementRights(); $credential = $this->getSMSAPICredential(); - $SMSProvider = self::getSMSProviderInstance($credential[MobileMessaging::PROVIDER_OPTION]); + $SMSProvider = SMSProvider::factory($credential[MobileMessaging::PROVIDER_OPTION]); return $SMSProvider->getCreditLeft( $credential[MobileMessaging::API_KEY_OPTION] ); diff --git a/plugins/MobileMessaging/Controller.php b/plugins/MobileMessaging/Controller.php index 2bb6f8d5f5f6ee0e431d661a3b54e966feb62ff3..7ba976c67e728fe8eee22bc22a9f0bb22921f27a 100644 --- a/plugins/MobileMessaging/Controller.php +++ b/plugins/MobileMessaging/Controller.php @@ -94,7 +94,12 @@ class Controller extends ControllerAdmin $view->creditLeft = $mobileMessagingAPI->getCreditLeft(); } - $view->smsProviders = SMSProvider::getAvailableSMSProviders(); + $providers = array(); + foreach (SMSProvider::findAvailableSmsProviders() as $provider) { + $providers[$provider->getId()] = $provider->getDescription(); + } + + $view->smsProviders = $providers; // construct the list of countries from the lang files $countries = array(); diff --git a/plugins/MobileMessaging/SMSProvider.php b/plugins/MobileMessaging/SMSProvider.php index 1711bfafed24ef49b51973526659619c81470651..14aec1bb247f32beec5bf1b6829b9e90ccd5125f 100644 --- a/plugins/MobileMessaging/SMSProvider.php +++ b/plugins/MobileMessaging/SMSProvider.php @@ -8,63 +8,120 @@ */ namespace Piwik\Plugins\MobileMessaging; -use Exception; -use Piwik\Development; +use Piwik\Container\StaticContainer; +use Piwik\Plugin; use Piwik\Piwik; -use Piwik\BaseFactory; /** - * The SMSProvider abstract class is used as a base class for SMS provider implementations. + * The SMSProvider abstract class is used as a base class for SMS provider implementations. To create your own custom + * SMSProvider extend this class and implement the methods to send text messages. The class needs to be placed in a + * `SMSProvider` directory of your plugin. * + * @api */ -abstract class SMSProvider extends BaseFactory +abstract class SMSProvider { const MAX_GSM_CHARS_IN_ONE_UNIQUE_SMS = 160; const MAX_GSM_CHARS_IN_ONE_CONCATENATED_SMS = 153; const MAX_UCS2_CHARS_IN_ONE_UNIQUE_SMS = 70; const MAX_UCS2_CHARS_IN_ONE_CONCATENATED_SMS = 67; - protected static $availableSMSProviders = array( - 'Clockwork' => 'You can use <a target="_blank" href="?module=Proxy&action=redirect&url=http://www.clockworksms.com/platforms/piwik/"><img src="plugins/MobileMessaging/images/Clockwork.png"/></a> to send SMS Reports from Piwik.<br/> - <ul> - <li> First, <a target="_blank" href="?module=Proxy&action=redirect&url=http://www.clockworksms.com/platforms/piwik/">get an API Key from Clockwork</a> (Signup is free!) - </li><li> Enter your Clockwork API Key on this page. </li> - </ul> - <br/><em>About Clockwork: </em><ul> - <li>Clockwork gives you fast, reliable high quality worldwide SMS delivery, over 450 networks in every corner of the globe. - </li><li>Cost per SMS message is around ~0.08USD (0.06EUR). - </li><li>Most countries and networks are supported but we suggest you check the latest position on their coverage map <a target="_blank" href="?module=Proxy&action=redirect&url=http://www.clockworksms.com/sms-coverage/">here</a>. - </li> - </ul> - ', - ); - - protected static function getClassNameFromClassId($id) + /** + * Get the ID of the SMS Provider. Eg 'Clockwork' or 'FreeMobile' + * @return string + */ + abstract public function getId(); + + /** + * Get a description about the SMS Provider. For example who the SMS Provider is, instructions how the API Key + * needs to be set, and more. You may return HTML here for better formatting. + * + * @return string + */ + abstract public function getDescription(); + + /** + * Verify the SMS API credential. + * + * @param string $apiKey API Key + * @return bool true if SMS API Key is valid, false otherwise + */ + abstract public function verifyCredential($apiKey); + + /** + * Get the amount of remaining credits. + * + * @param string $apiKey API Key + * @return string remaining credits + */ + abstract public function getCreditLeft($apiKey); + + /** + * Actually send the given text message. This method should only send the text message, it should not trigger + * any notifications etc. + * + * @param string $apiKey + * @param string $smsText + * @param string $phoneNumber + * @param string $from + * @return bool true + */ + abstract public function sendSMS($apiKey, $smsText, $phoneNumber, $from); + + /** + * Defines whether the SMS Provider is available. If a certain provider should be used only be a limited + * range of users you can restrict the provider here. For example there is a Development SMS Provider that is only + * available when the development is actually enabled. You could also create a SMS Provider that is only available + * to Super Users etc. Usually this method does not have to be implemented by a SMS Provider. + * + * @return bool + */ + public function isAvailable() { - return __NAMESPACE__ . '\\SMSProvider\\' . $id; + return true; } - protected static function getInvalidClassIdExceptionMessage($id) + /** + * @param string $provider The name of the string + * @return SMSProvider + * @throws \Exception + * @ignore + */ + public static function factory($provider) { - return Piwik::translate('MobileMessaging_Exception_UnknownProvider', - array($id, implode(', ', array_keys(self::getAvailableSMSProviders()))) - ); + $providers = self::findAvailableSmsProviders(); + + if (!array_key_exists($provider, $providers)) { + throw new \Exception(Piwik::translate('MobileMessaging_Exception_UnknownProvider', + array($provider, implode(', ', array_keys($providers))) + )); + } + + return $providers[$provider]; } /** * Returns all available SMS Providers - * - * @return array + * + * @return SMSProvider[] + * @ignore */ - public static function getAvailableSMSProviders() + public static function findAvailableSmsProviders() { - $smsProviders = self::$availableSMSProviders; + /** @var SMSProvider[] $smsProviders */ + $smsProviders = Plugin\Manager::getInstance()->findMultipleComponents('SMSProvider', 'Piwik\Plugins\MobileMessaging\SMSProvider'); + + $providers = array(); - if (Development::isEnabled()) { - $smsProviders['Development'] = 'Development SMS Provider<br />All sent SMS will be displayed as Notification'; + foreach ($smsProviders as $provider) { + /** @var SMSProvider $provider */ + $provider = StaticContainer::get($provider); + if ($provider->isAvailable()) { + $providers[$provider->getId()] = $provider; + } } - return $smsProviders; + return $providers; } /** @@ -72,6 +129,7 @@ abstract class SMSProvider extends BaseFactory * * @param string $string * @return bool true if $string contains UCS2 characters + * @ignore */ public static function containsUCS2Characters($string) { @@ -94,6 +152,7 @@ abstract class SMSProvider extends BaseFactory * @param int $maximumNumberOfConcatenatedSMS * @param string $appendedString * @return string original $string or truncated $string appended with $appendedString + * @ignore */ public static function truncate($string, $maximumNumberOfConcatenatedSMS, $appendedString = 'MobileMessaging_SMS_Content_Too_Long') { @@ -150,30 +209,4 @@ abstract class SMSProvider extends BaseFactory $maxCharsInOneConcatenatedSMS * $maximumNumberOfConcatenatedSMS; } - /** - * verify the SMS API credential - * - * @param string $apiKey API Key - * @return bool true if SMS API credential are valid, false otherwise - */ - abstract public function verifyCredential($apiKey); - - /** - * get remaining credits - * - * @param string $apiKey API Key - * @return string remaining credits - */ - abstract public function getCreditLeft($apiKey); - - /** - * send SMS - * - * @param string $apiKey - * @param string $smsText - * @param string $phoneNumber - * @param string $from - * @return bool true - */ - abstract public function sendSMS($apiKey, $smsText, $phoneNumber, $from); } diff --git a/plugins/MobileMessaging/SMSProvider/Clockwork.php b/plugins/MobileMessaging/SMSProvider/Clockwork.php index 2ae8e95da4145d540b9d92f5174220eea15cc598..50a7f0e50b4685c350dc987912f72fb430f121d0 100644 --- a/plugins/MobileMessaging/SMSProvider/Clockwork.php +++ b/plugins/MobileMessaging/SMSProvider/Clockwork.php @@ -15,8 +15,9 @@ use Piwik\Plugins\MobileMessaging\APIException; use Piwik\Plugins\MobileMessaging\SMSProvider; require_once PIWIK_INCLUDE_PATH . "/plugins/MobileMessaging/APIException.php"; + /** - * + * @ignore */ class Clockwork extends SMSProvider { @@ -31,6 +32,27 @@ class Clockwork extends SMSProvider const MAXIMUM_FROM_LENGTH = 11; const MAXIMUM_CONCATENATED_SMS = 3; + public function getId() + { + return 'Clockwork'; + } + + public function getDescription() + { + return 'You can use <a target="_blank" href="?module=Proxy&action=redirect&url=http://www.clockworksms.com/platforms/piwik/"><img src="plugins/MobileMessaging/images/Clockwork.png"/></a> to send SMS Reports from Piwik.<br/> + <ul> + <li> First, <a target="_blank" href="?module=Proxy&action=redirect&url=http://www.clockworksms.com/platforms/piwik/">get an API Key from Clockwork</a> (Signup is free!) + </li><li> Enter your Clockwork API Key on this page. </li> + </ul> + <br/><em>About Clockwork: </em><ul> + <li>Clockwork gives you fast, reliable high quality worldwide SMS delivery, over 450 networks in every corner of the globe. + </li><li>Cost per SMS message is around ~0.08USD (0.06EUR). + </li><li>Most countries and networks are supported but we suggest you check the latest position on their coverage map <a target="_blank" href="?module=Proxy&action=redirect&url=http://www.clockworksms.com/sms-coverage/">here</a>. + </li> + </ul> + '; + } + public function verifyCredential($apiKey) { $this->getCreditLeft($apiKey); diff --git a/plugins/MobileMessaging/SMSProvider/Development.php b/plugins/MobileMessaging/SMSProvider/Development.php index ef6cbe951d7b4d321b1372f0d7fc98c413982693..18cc57809abc5269cd9f25f52c76f35ad0c0cbd1 100644 --- a/plugins/MobileMessaging/SMSProvider/Development.php +++ b/plugins/MobileMessaging/SMSProvider/Development.php @@ -10,14 +10,31 @@ namespace Piwik\Plugins\MobileMessaging\SMSProvider; use Piwik\Notification; use Piwik\Plugins\MobileMessaging\SMSProvider; +use Piwik\Development as PiwikDevelopment; /** * Used for development only * + * @ignore */ class Development extends SMSProvider { + public function getId() + { + return 'Development'; + } + + public function getDescription() + { + return 'Development SMS Provider<br />All sent SMS will be displayed as Notification'; + } + + public function isAvailable() + { + return PiwikDevelopment::isEnabled(); + } + public function verifyCredential($apiKey) { return true; diff --git a/plugins/MobileMessaging/SMSProvider/StubbedProvider.php b/plugins/MobileMessaging/SMSProvider/StubbedProvider.php index b9527a3b8dd245324f1842d5f2e3617d3dab089e..8bda726a3e530a64d48f18ec1f243709b6dc8934 100644 --- a/plugins/MobileMessaging/SMSProvider/StubbedProvider.php +++ b/plugins/MobileMessaging/SMSProvider/StubbedProvider.php @@ -13,10 +13,26 @@ use Piwik\Plugins\MobileMessaging\SMSProvider; /** * Used for testing * + * @ignore */ class StubbedProvider extends SMSProvider { + public function getId() + { + return 'StubbedProvider'; + } + + public function getDescription() + { + return 'Only during testing available'; + } + + public function isAvailable() + { + return defined('PIWIK_TEST_MODE') && PIWIK_TEST_MODE; + } + public function verifyCredential($apiKey) { return true; diff --git a/plugins/MobileMessaging/lang/cs.json b/plugins/MobileMessaging/lang/cs.json index efe1d113af341133d77d5a7e35f81094b658d71e..6b4d0ad68b03454d8cdcf7ca697a65110435b1b4 100644 --- a/plugins/MobileMessaging/lang/cs.json +++ b/plugins/MobileMessaging/lang/cs.json @@ -6,24 +6,24 @@ "MobileReport_NoPhoneNumbers": "ProsÃm aktivujte aspoň jedno telefonnà ÄÃslo pÅ™ejitÃm na", "MultiSites_Must_Be_Activated": "Pro vytvářenà SMS zpráv se statistikami povolte v Piwiku plugin MultiSites.", "PhoneNumbers": "Telefonnà ÄÃsla", - "PluginDescription": "Vytvářejte a stahujte vlastnà SMS hlášenà a nechte si je zasÃlat do vaÅ¡eho telefonu dennÄ›, týdnnebo Ä› mÄ›sÃÄnÄ›.", + "PluginDescription": "Vytvářejte a stahujte vlastnà SMS hlášenà a nechte si je zasÃlat do svého telefonu dennÄ›, týdnÄ› nebo mÄ›sÃÄnÄ›.", "Settings_APIKey": "KlÃÄ k API", "Settings_CountryCode": "Kód zemÄ›", - "Settings_CredentialNotProvided": "Než budete moct vytvářet a spravovat telefonnà ÄÃsla, musÃte pÅ™ipojit Piwik k vaÅ¡emu SMS úÄtu výše.", - "Settings_CredentialNotProvidedByAdmin": "Než budete moct vytvářet a spravovat telefonnà ÄÃsla, požádejte vaÅ¡eho administrátora, aby pÅ™ipojil Piwik k SMS úÄtu.", + "Settings_CredentialNotProvided": "Než budete moci vytvářet a spravovat telefonnà ÄÃsla, musÃte pÅ™ipojit Piwik ke svému SMS úÄtu výše.", + "Settings_CredentialNotProvidedByAdmin": "Než budete moci vytvářet a spravovat telefonnà ÄÃsla, požádejte svého administrátora, aby pÅ™ipojil Piwik k SMS úÄtu.", "Settings_CredentialProvided": ";Váš %s SMS úÄet je nastaven správnÄ›.", "Settings_DeleteAccountConfirm": "Opravdu chcete odstranit tento SMS úÄet?", "Settings_InvalidActivationCode": "Zadaný kód nebyl platný, prosÃm zkuste to znovu.", "Settings_LetUsersManageAPICredential": "Povolit uživatelům správu vlastnÃch pověřenà API SMS úÄtů", "Settings_LetUsersManageAPICredential_No_Help": "VÅ¡ichni uživatelé mohou pÅ™ijÃmat hlášenà prostÅ™ednictvÃm SMS a budou použÃvat kredity vaÅ¡eho úÄtu.", - "Settings_LetUsersManageAPICredential_Yes_Help": "Každý uživatel bude moct nastavit svůj SMS API úÄet an nebude použÃvat váš kredit.", + "Settings_LetUsersManageAPICredential_Yes_Help": "Každý uživatel bude moci nastavit svůj SMS API úÄet a nebude použÃvat váš kredit.", "Settings_ManagePhoneNumbers": "Spravovat telefonnà ÄÃsla", "Settings_PhoneActivated": "Telefonnà ÄÃslo ověřeno! Nynà můžete pÅ™ijÃmat SMS se statistikami.", "Settings_PhoneNumber": "Telefonnà ÄÃslo", "Settings_PhoneNumbers_Add": "PÅ™idat nové telefonnà ÄÃslo", "Settings_PhoneNumbers_CountryCode_Help": "Pokud nevÃte telefonnà kód vašà zemÄ›, podÃvejte se zde", - "Settings_PhoneNumbers_Help": "Než budete moct pÅ™ijÃmat SMS se statistikami, telefonnà ÄÃslo musà být zadáno nÞe.", - "Settings_PhoneNumbers_HelpAdd": "Po stisknutà \"pÅ™idat\" bude na telefon odeslána SMS s kódem. Uživatel, který obdržà SMS by se mÄ›l pÅ™ihlásit do Piwiku, kliknout na nastavenÃ, pak na Mobilnà zprávy a zadat kód. Poté bude moct dostávat statistiky do svého telefonu.", + "Settings_PhoneNumbers_Help": "Než budete moci pÅ™ijÃmat SMS se statistikami, telefonnà ÄÃslo musà být zadáno nÞe.", + "Settings_PhoneNumbers_HelpAdd": "Po stisknutà \"pÅ™idat\" bude na telefon odeslána SMS s kódem. Uživatel, který obdržà SMS by se mÄ›l pÅ™ihlásit do Piwiku, kliknout na nastavenÃ, pak na Mobilnà zprávy a zadat kód. Poté bude moci dostávat statistiky do svého telefonu.", "Settings_PleaseSignUp": "Pokud chcetevytvářet SMS hlášenà a dostávat krátké zprávy o statistikách do svého telefonu, zaregistrujte se na SMS API a zadejte svoje informace nÞe.", "Settings_SMSAPIAccount": "Správa SMS API úÄtu", "Settings_SMSProvider": "SMS Provider", @@ -34,8 +34,8 @@ "Settings_VerificationCodeJustSent": "PrávÄ› jsme na zadané telefonnà ÄÃslo odeslali SMS s kódem. Zadejte ho výše a stisknÄ›te \"ověřit\".", "SettingsMenu": "Mobilnà zprávy", "SMS_Content_Too_Long": "[pÅ™ÃliÅ¡ dlouhé]", - "TopLinkTooltip": "Nechte si webové analýzi zasÃlat na e-mail nebo na váš mobilnà telefon.", - "TopMenu": "Email & SMS Reporty", + "TopLinkTooltip": "Nechte si webové analýzy zasÃlat na email nebo na svůj mobilnà telefon.", + "TopMenu": "Email a SMS reporty", "VerificationText": "Kód je %s. Pro ověřenà vaÅ¡eh otelefonnÃho ÄÃsla tento kód zkopÃrujte do formuláře pÅ™Ãstupného na Piwik > %s > %s." } } \ No newline at end of file diff --git a/plugins/MobileMessaging/lang/tr.json b/plugins/MobileMessaging/lang/tr.json new file mode 100644 index 0000000000000000000000000000000000000000..3a034272bae35a449612ed260a2ade0703b68908 --- /dev/null +++ b/plugins/MobileMessaging/lang/tr.json @@ -0,0 +1,22 @@ +{ + "MobileMessaging": { + "PhoneNumbers": "Telefon Numaraları", + "Settings_APIKey": "API Anahtarı", + "Settings_CountryCode": "Ülke Kodu", + "Settings_DeleteAccountConfirm": "Bu SMS hesabını silmek istediÄŸinizden emin misiniz?", + "Settings_InvalidActivationCode": "Girilen kod geçerli deÄŸil, lütfen tekrar deneyin.", + "Settings_ManagePhoneNumbers": "Telefon Numaralarını Yönet", + "Settings_PhoneActivated": "Telefon numarası doÄŸrulandı! Artık istatistikleri SMS ile alabilirsiniz.", + "Settings_PhoneNumber": "Telefon Numarası", + "Settings_PhoneNumbers_Add": "Yeni telefon numarası ekle", + "Settings_PhoneNumbers_CountryCode_Help": "Telefon ülke kodunu bilmiyorsanız, buradan ülkelere bakabilirsiniz.", + "Settings_SMSAPIAccount": "SMS API Hesabını Yönet", + "Settings_SMSProvider": "SMS SaÄŸlayıcı", + "Settings_ValidatePhoneNumber": "Onayla", + "Settings_VerificationCodeJustSent": "Biz az önce SMS ile numaranıza kod gönderdik: lütfen yukarıya kodu girin ve \"Onayla\" 'ya tıklayın.", + "SettingsMenu": "Mobil MesajlaÅŸma", + "SMS_Content_Too_Long": "[çok uzun]", + "TopLinkTooltip": "Web Analytics Raporlarını e-posta kutunuza veya cep telefonunuza teslim alın.", + "TopMenu": "E-posta ve SMS Raporları" + } +} \ No newline at end of file diff --git a/plugins/Monolog/tests/System/TrackerLoggingTest.php b/plugins/Monolog/tests/System/TrackerLoggingTest.php index 70c933d13ff08e91b0d137a95130439cf350d2aa..87162291165827780dcc9dc44ae13769d01f7a87 100644 --- a/plugins/Monolog/tests/System/TrackerLoggingTest.php +++ b/plugins/Monolog/tests/System/TrackerLoggingTest.php @@ -83,10 +83,8 @@ DEBUG: 'apiv' => '1',", $response); private function setTrackerConfig($trackerConfig) { $testingEnvironment = self::$fixture->getTestEnvironment(); - $configOverride = $testingEnvironment->configOverride; - $configOverride['Tracker'] = $trackerConfig; - $configOverride['log']['log_writers'] = array('screen'); - $testingEnvironment->configOverride = $configOverride; + $testingEnvironment->overrideConfig('Tracker', $trackerConfig); + $testingEnvironment->overrideConfig('log', 'log_writers', array('screen')); $testingEnvironment->save(); } diff --git a/plugins/MultiSites/API.php b/plugins/MultiSites/API.php index 60b9fab90af8859cf3c70734099b06ea1b96cd10..23ae8217381cbfc35f75f8c337385a5e20f697cf 100755 --- a/plugins/MultiSites/API.php +++ b/plugins/MultiSites/API.php @@ -147,7 +147,6 @@ class API extends \Piwik\Plugin\API 'limit' => SettingsPiwik::getWebsitesCountToDisplay(), 'showColumns' => '', 'hideColumns' => '', - 'serialize' => 0, 'format' => 'original')); if (!empty($sites)) { diff --git a/plugins/MultiSites/lang/ko.json b/plugins/MultiSites/lang/ko.json index c7bdb7ee7b917a92ef50e93175f3dca6c317a2c5..69e154b027f1981db627b9da8b060c01a9907175 100644 --- a/plugins/MultiSites/lang/ko.json +++ b/plugins/MultiSites/lang/ko.json @@ -1,6 +1,7 @@ { "MultiSites": { "Evolution": "변화 ì¶”ì´", - "TopLinkTooltip": "웹사ì´íŠ¸ì˜ ëª¨ë“ ì›¹ë¶„ì„ í†µê³„ë¥¼ 비êµí•©ë‹ˆë‹¤." + "TopLinkTooltip": "웹사ì´íŠ¸ì˜ ëª¨ë“ ì›¹ë¶„ì„ í†µê³„ë¥¼ 비êµí•©ë‹ˆë‹¤.", + "Pagination": "%s - %s ì˜ %s" } } \ No newline at end of file diff --git a/plugins/Overlay/Controller.php b/plugins/Overlay/Controller.php index 795d7b991d130e99cc1fcc262625bdc052a684fe..6327d34ddf9baeb1ef7d685a20ecd97a0348a4af 100644 --- a/plugins/Overlay/Controller.php +++ b/plugins/Overlay/Controller.php @@ -16,14 +16,26 @@ use Piwik\Metrics; use Piwik\Piwik; use Piwik\Plugin\Report; use Piwik\Plugins\Actions\ArchivingHelper; +use Piwik\Plugins\SegmentEditor\SegmentFormatter; use Piwik\Plugins\SitesManager\API as APISitesManager; use Piwik\ProxyHttp; +use Piwik\Segment; use Piwik\Tracker\Action; use Piwik\Tracker\PageUrl; use Piwik\View; class Controller extends \Piwik\Plugin\Controller { + /** + * @var SegmentFormatter + */ + private $segmentFormatter; + + public function __construct(SegmentFormatter $segmentFormatter) + { + $this->segmentFormatter = $segmentFormatter; + parent::__construct(); + } /** The index of the plugin */ public function index() @@ -38,6 +50,7 @@ class Controller extends \Piwik\Plugin\Controller $view = new View($template); $this->setGeneralVariablesView($view); + $view->segment = Request::getRawSegmentFromRequest(); $view->ssl = ProxyHttp::isHttps(); @@ -52,8 +65,9 @@ class Controller extends \Piwik\Plugin\Controller $period = Common::getRequestVar('period'); $date = Common::getRequestVar('date'); $currentUrl = Common::getRequestVar('currentUrl'); + $segment = Request::getRawSegmentFromRequest(); $currentUrl = Common::unsanitizeInputValue($currentUrl); - $segment = ''; + $segmentSidebar = ''; $normalizedCurrentUrl = PageUrl::excludeQueryParametersFromUrl($currentUrl, $idSite); $normalizedCurrentUrl = Common::unsanitizeInputValue($normalizedCurrentUrl); @@ -63,16 +77,21 @@ class Controller extends \Piwik\Plugin\Controller $path = ArchivingHelper::getActionExplodedNames($normalizedCurrentUrl, Action::TYPE_PAGE_URL); $path = array_map('urlencode', $path); $label = implode('>', $path); - $request = new Request( - 'method=Actions.getPageUrls' - . '&idSite=' . urlencode($idSite) - . '&date=' . urlencode($date) - . '&period=' . urlencode($period) - . '&label=' . urlencode($label) - . '&format=original' - . '&format_metrics=0' + + $params = array( + 'idSite' => $idSite, + 'date' => $date, + 'period' => $period, + 'label' => $label, + 'format' => 'original', + 'format_metrics' => 0, ); - $dataTable = $request->process(); + + if (!empty($segment)) { + $params['segment'] = $segment; + } + + $dataTable = Request::processRequest('Actions.getPageUrls', $params); $formatter = new Metrics\Formatter\Html(); @@ -84,7 +103,10 @@ class Controller extends \Piwik\Plugin\Controller $showMetrics = array('nb_hits', 'nb_visits', 'nb_users', 'nb_uniq_visitors', 'bounce_rate', 'exit_rate', 'avg_time_on_page'); - $segment = $row->getMetadata('segment'); + $segmentSidebar = $row->getMetadata('segment'); + if (!empty($segmentSidebar) && !empty($segment)) { + $segmentSidebar = $segment . ';' . $segmentSidebar; + } foreach ($showMetrics as $metric) { $value = $row->getColumn($metric); @@ -127,7 +149,8 @@ class Controller extends \Piwik\Plugin\Controller $view->idSite = $idSite; $view->period = $period; $view->date = $date; - $view->segment = $segment; + $view->segment = $segmentSidebar; + $view->segmentDescription = $this->segmentFormatter->getHumanReadable($segment, $idSite); $this->outputCORSHeaders(); return $view->render(); @@ -142,64 +165,20 @@ class Controller extends \Piwik\Plugin\Controller $idSite = Common::getRequestVar('idSite', 0, 'int'); Piwik::checkUserHasViewAccess($idSite); + $view = new View('@Overlay/startOverlaySession'); + $sitesManager = APISitesManager::getInstance(); $site = $sitesManager->getSiteFromId($idSite); $urls = $sitesManager->getSiteUrlsFromId($idSite); + $view->isHttps = ProxyHttp::isHttps(); + $view->knownUrls = json_encode($urls); + $view->mainUrl = $site['main_url']; + $this->outputCORSHeaders(); Common::sendHeader('Content-Type: text/html; charset=UTF-8'); - return ' - <html><head><title></title></head><body> - <script type="text/javascript"> - function handleProtocol(url) { - if (' . (ProxyHttp::isHttps() ? 'true' : 'false') . ') { - return url.replace(/http:\/\//i, "https://"); - } else { - return url.replace(/https:\/\//i, "http://"); - } - } - - function removeUrlPrefix(url) { - return url.replace(/http(s)?:\/\/(www\.)?/i, ""); - } - - if (window.location.hash) { - var match = false; - - var urlToRedirect = window.location.hash.substr(1); - var urlToRedirectWithoutPrefix = removeUrlPrefix(urlToRedirect); - - var knownUrls = ' . json_encode($urls) . '; - for (var i = 0; i < knownUrls.length; i++) { - var testUrl = removeUrlPrefix(knownUrls[i]); - if (urlToRedirectWithoutPrefix.substr(0, testUrl.length) == testUrl) { - match = true; - if (navigator.appName == "Microsoft Internet Explorer") { - // internet explorer loses the referrer if we use window.location.href=X - var referLink = document.createElement("a"); - referLink.href = handleProtocol(urlToRedirect); - document.body.appendChild(referLink); - referLink.click(); - } else { - window.location.href = handleProtocol(urlToRedirect); - } - break; - } - } - - if (!match) { - var idSite = window.location.href.match(/idSite=([0-9]+)/i)[1]; - window.location.href = "index.php?module=Overlay&action=showErrorWrongDomain" - + "&idSite=" + idSite - + "&url=" + encodeURIComponent(urlToRedirect); - } - } - else { - window.location.href = handleProtocol("' . $site['main_url'] . '"); - }; - </script> - </body></html> - '; + + return $view->render(); } /** diff --git a/plugins/Overlay/client/client.js b/plugins/Overlay/client/client.js index 75bd19f3b3842070d02c7df8edb6b88513e635a4..5fd99c466b804b4a247bc8a7e6aff64a1e777c40 100644 --- a/plugins/Overlay/client/client.js +++ b/plugins/Overlay/client/client.js @@ -10,7 +10,7 @@ var Piwik_Overlay_Client = (function () { var idSite; /** The current period and date */ - var period, date; + var period, date, segment; /** Reference to the status bar DOM element */ var statusBar; @@ -84,11 +84,12 @@ var Piwik_Overlay_Client = (function () { return { /** Initialize in-site analytics */ - initialize: function (pPiwikRoot, pIdSite, pPeriod, pDate) { + initialize: function (pPiwikRoot, pIdSite, pPeriod, pDate, pSegment) { piwikRoot = pPiwikRoot; idSite = pIdSite; period = pPeriod; date = pDate; + segment = pSegment; var load = this.loadScript; var loading = this.loadingNotification; @@ -146,6 +147,10 @@ var Piwik_Overlay_Client = (function () { var url = piwikRoot + 'index.php?module=API&method=Overlay.' + method + '&idSite=' + idSite + '&period=' + period + '&date=' + date + '&format=JSON&filter_limit=-1'; + if (segment) { + url += '&segment=' + segment; + } + if (additionalParams) { url += '&' + additionalParams; } diff --git a/plugins/Overlay/config/ui-test.php b/plugins/Overlay/config/ui-test.php new file mode 100644 index 0000000000000000000000000000000000000000..1bb5ae8b75ce2f7f9f877b7ede61cf36d72e9aed --- /dev/null +++ b/plugins/Overlay/config/ui-test.php @@ -0,0 +1,14 @@ +<?php + +return array( + + // Overlay needs the full URLs in order to find the links in the embedded page (otherwise the % + // tooltips don't show up) + 'tests.ui.url_normalizer_blacklist.api' => DI\add(array( + 'Overlay.getFollowingPages', + )), + 'tests.ui.url_normalizer_blacklist.controller' => DI\add(array( + 'Overlay.renderSidebar', + )), + +); \ No newline at end of file diff --git a/plugins/Overlay/javascripts/Overlay_Helper.js b/plugins/Overlay/javascripts/Overlay_Helper.js index e0681e7b454c4e48472936e3418f22bf3ec01b43..42ff388d81469b7b212f0cb4a9bb3132a0e2bd5e 100644 --- a/plugins/Overlay/javascripts/Overlay_Helper.js +++ b/plugins/Overlay/javascripts/Overlay_Helper.js @@ -20,11 +20,17 @@ var Overlay_Helper = { }, /** Get the url to launch overlay */ - getOverlayLink: function (idSite, period, date, link) { + getOverlayLink: function (idSite, period, date, segment, link) { var url = 'index.php?module=Overlay&period=' + encodeURIComponent(period) + '&date=' + encodeURIComponent(date) + '&idSite=' + encodeURIComponent(idSite); + + if (segment) { + url += '&segment=' + encodeURIComponent(segment); + } + if (link) { url += '#?l=' + Overlay_Helper.encodeFrameUrl(link); } + return url; } diff --git a/plugins/Overlay/javascripts/Piwik_Overlay.js b/plugins/Overlay/javascripts/Piwik_Overlay.js index 4c780808064bf8e67d5e0e7a3f30a0eb4035cc93..4bde0ee34364ba901596d1962cbc479ea027f2c4 100644 --- a/plugins/Overlay/javascripts/Piwik_Overlay.js +++ b/plugins/Overlay/javascripts/Piwik_Overlay.js @@ -10,7 +10,7 @@ var Piwik_Overlay = (function () { var $body, $iframe, $sidebar, $main, $location, $loading, $errorNotLoading; var $rowEvolutionLink, $transitionsLink, $fullScreenLink, $visitorLogLink; - var idSite, period, date; + var idSite, period, date, segment; var iframeSrcBase; var iframeDomain = ''; @@ -28,13 +28,19 @@ var Piwik_Overlay = (function () { iframeCurrentPage = currentUrl; iframeDomain = currentUrl.match(/http(s)?:\/\/(www\.)?([^\/]*)/i)[3]; - globalAjaxQueue.abort(); - var ajaxRequest = new ajaxHelper(); - ajaxRequest.addParams({ + var params = { module: 'Overlay', action: 'renderSidebar', currentUrl: currentUrl - }, 'get'); + }; + + if (segment) { + params.segment = segment; + } + + globalAjaxQueue.abort(); + var ajaxRequest = new ajaxHelper(); + ajaxRequest.addParams(params, 'get'); ajaxRequest.setCallback( function (response) { hideLoading(); @@ -111,6 +117,16 @@ var Piwik_Overlay = (function () { $fullScreenLink.show(); } + function getOverlaySegment(url) { + var location = broadcast.getParamValue('segment', url); + + // angular will encode the value again since it is added as the fragment path, not the fragment query parameter, + // so we have to decode it again after getParamValue + location = decodeURIComponent(location); + + return location; + } + function getOverlayLocationFromHash(urlHash) { var location = broadcast.getParamValue('l', urlHash); @@ -143,11 +159,12 @@ var Piwik_Overlay = (function () { return { /** This method is called when Overlay loads */ - init: function (iframeSrc, pIdSite, pPeriod, pDate) { + init: function (iframeSrc, pIdSite, pPeriod, pDate, pSegment) { iframeSrcBase = iframeSrc; idSite = pIdSite; period = pPeriod; date = pDate; + segment = pSegment; $body = $('body'); $iframe = $('#overlayIframe'); @@ -201,7 +218,7 @@ var Piwik_Overlay = (function () { if (parts.length == 2) { period = parts[0]; date = parts[1]; - window.location.href = Overlay_Helper.getOverlayLink(idSite, period, date, iframeCurrentPage); + window.location.href = Overlay_Helper.getOverlayLink(idSite, period, date, segment, iframeCurrentPage); } }); @@ -219,7 +236,11 @@ var Piwik_Overlay = (function () { // handle transitions link $transitionsLink.click(function () { - DataTable_RowActions_Transitions.launchForUrl(iframeCurrentPageNormalized); + var unescapedSegment = null; + if (segment) { + unescapedSegment = unescape(segment); + } + DataTable_RowActions_Transitions.launchForUrl(iframeCurrentPageNormalized, unescapedSegment); return false; }); diff --git a/plugins/Overlay/javascripts/rowaction.js b/plugins/Overlay/javascripts/rowaction.js index c84e60a33b4194f555f4bf659c93e8d3bd5714b6..de063b990e14ac57028c5f9e1abc32d4ecc0a812 100644 --- a/plugins/Overlay/javascripts/rowaction.js +++ b/plugins/Overlay/javascripts/rowaction.js @@ -15,17 +15,47 @@ function DataTable_RowActions_Overlay(dataTable) { DataTable_RowActions_Overlay.prototype = new DataTable_RowAction; +DataTable_RowActions_Overlay.registeredReports = []; +DataTable_RowActions_Overlay.registerReport = function (handler) { + DataTable_RowActions_Overlay.registeredReports.push(handler); +} + + DataTable_RowActions_Overlay.prototype.onClick = function (actionA, tr, e) { if (!actionA.data('overlay-manipulated')) { actionA.data('overlay-manipulated', 1); - var link = tr.find('> td:first > a').attr('href'); - link = $('<textarea>').html(link).val(); // remove html entities + var segment, link; + + var i = 0; + for (i; i < DataTable_RowActions_Overlay.registeredReports.length; i++) { + var report = DataTable_RowActions_Overlay.registeredReports[i]; + if (report + && report.onClick + && report.isAvailableOnReport + && report.isAvailableOnReport(this.dataTable.param)) { + var result = report.onClick.apply(this, arguments); + + if (!result || !result.link) { + return; + } + + link = result.link; + if (result.segment) { + segment = result.segment; + } + break; + } + } + + if (link) { + var href = Overlay_Helper.getOverlayLink(this.dataTable.param.idSite, 'month', 'today', segment, link); - actionA.attr({ - target: '_blank', - href: Overlay_Helper.getOverlayLink(this.dataTable.param.idSite, 'month', 'today', link) - }); + actionA.attr({ + target: '_blank', + href: href + }); + } } return true; @@ -54,7 +84,18 @@ DataTable_RowActions_Registry.register({ if (!window.DataTable_RowActions_Transitions) { return false; } - return DataTable_RowActions_Transitions.isPageUrlReport(dataTableParams.module, dataTableParams.action); + + var i = 0; + for (i; i < DataTable_RowActions_Overlay.registeredReports.length; i++) { + var report = DataTable_RowActions_Overlay.registeredReports[i]; + if (report + && report.isAvailableOnReport + && report.isAvailableOnReport(dataTableParams)) { + return true; + } + } + + return false; }, isAvailableOnRow: function (dataTableParams, tr) { diff --git a/plugins/Overlay/lang/ja.json b/plugins/Overlay/lang/ja.json index 952ea205acf18d6effc647683224f63680faa350..3c99e23c55c5a8032f5f149e3698248a28bfa431 100644 --- a/plugins/Overlay/lang/ja.json +++ b/plugins/Overlay/lang/ja.json @@ -15,6 +15,7 @@ "Overlay": "ページオーãƒãƒ¼ãƒ¬ã‚¤", "PluginDescription": "実際㮠web サイト上ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ¬ã‚¤åˆ†æžãƒ‡ãƒ¼ã‚¿ã‚’å‚ç…§ã—ã¦ãã ã•ã„。ユーザーãŒå„リンクをクリックã—ãŸå›žæ•°ãŒè¡¨ç¤ºã•れã¾ã™ã€‚注: 有効ãªãƒˆãƒ©ãƒ³ã‚¸ã‚·ãƒ§ãƒ³ãƒ—ラグインãŒå¿…è¦ã§ã™ã€‚", "RedirectUrlError": "URL \"%s\" ã«å¯¾ã™ã‚‹ãƒšãƒ¼ã‚¸ã‚ªãƒ¼ãƒãƒ¼ãƒ¬ã‚¤ã‚’é–‹ã“ã†ã¨ã—ã¦ã„ã¾ã™ã€‚%s Piwik è¨å®šã®ãƒ‰ãƒ¡ã‚¤ãƒ³ãŒã€ã™ã¹ã¦ãƒªãƒ³ã‚¯ã«ä¸€è‡´ã—ã¾ã›ã‚“。", + "RedirectUrlErrorAdmin": "%s è¨å®šã§ %s è¿½åŠ ã® URL ã¨ã—ã¦ãƒ‰ãƒ¡ã‚¤ãƒ³ã‚’è¿½åŠ ã§ãã¾ã™ã€‚", "RedirectUrlErrorUser": "管ç†è€…ã«ã€ä»»æ„ã®ãƒ‰ãƒ¡ã‚¤ãƒ³ã‚’è¿½åŠ URL ã¨ã—ã¦è¿½åŠ ã™ã‚‹ã‚ˆã†ç®¡ç†è€…ã«ä¾é ¼ã—ã¦ãã ã•ã„。" } } \ No newline at end of file diff --git a/plugins/Overlay/lang/ko.json b/plugins/Overlay/lang/ko.json index 4b761eaf5e91b07ed63bc6bde5f06ad1dabafdc6..1c2ebbc404450236058aec3b6c19e8dbd3293dee 100644 --- a/plugins/Overlay/lang/ko.json +++ b/plugins/Overlay/lang/ko.json @@ -13,6 +13,7 @@ "OneClick": "1회 í´ë¦", "OpenFullScreen": "ì „ì²´ 화면 (사ì´ë“œë°” 아님)으로 ì´ë™", "Overlay": "페ì´ì§€ ì˜¤ë²„ë ˆì´", + "PluginDescription": "ë‹¹ì‹ ì˜ ì›¹ì‚¬ì´íЏ ë¶„ì„ ë°ì´í„°ë¥¼ ì˜¤ë²„ë ˆì´ í˜•ì‹ìœ¼ë¡œ ë³¼ 수 있습니다. 사용ìžê°€ 얼마나 ê° ë§í¬ë¥¼ í´ë¦í–ˆëŠ”ì§€ 확ì¸í•´ë³´ì„¸ìš”. ì°¸ê³ : Transitions 플러그ì¸ì´ 활성화 ë˜ì–´ 있어야 합니다.", "RedirectUrlError": "URL \"%s\"ì— ëŒ€í•œ 페ì´ì§€ ì˜¤ë²„ë ˆì´ë¥¼ ì—´ë ¤ê³ ì‹œë„합니다. %sì€ Piwik ì„¤ì •í•œ ë„ë©”ì¸ê³¼ ì–´ë–¤ ë§í¬ë„ ì¼ì¹˜í•˜ì§€ 않습니다.", "RedirectUrlErrorAdmin": "ë‹¹ì‹ ì€ %sì„¤ì •%sì—서 추가ì ì¸ URL로 ë„ë©”ì¸ì„ ì¶”ê°€í• ìˆ˜ 있습니다.", "RedirectUrlErrorUser": "ë„ë©”ì¸ì— 추가ì ì¸ URLì„ ì¶”ê°€í•˜ë ¤ë©´ 관리ìžì—게 문ì˜í•˜ì„¸ìš”." diff --git a/plugins/Overlay/stylesheets/overlay.css b/plugins/Overlay/stylesheets/overlay.css index 4e30660775036addd2274c0ebe53360a7eb96364..a13dd67a469a7300f351e12d1f6da75d1ecdacd8 100644 --- a/plugins/Overlay/stylesheets/overlay.css +++ b/plugins/Overlay/stylesheets/overlay.css @@ -35,12 +35,20 @@ a#overlayTitle .icon-help { margin: 20px 10px; } -#overlayLocation { +#overlayLocation, .overlaySegment { width: 200px; - margin: 0 0 30px 10px; font-size: 12px; } +#overlayLocation { + margin: 0 0 10px 10px; +} + +.overlaySegment { + margin: 0 0 30px 0; + word-break: break-all; +} + #overlayLoading { background: url(../../Morpheus/images/loading-blue.gif) no-repeat center 10px; width: 190px; diff --git a/plugins/Overlay/templates/index.twig b/plugins/Overlay/templates/index.twig index 10a0b40d7617430ab41a0084d036c3e6a430fb47..effe5fbadedb6ccd94fb5de13f2d0d9c452e17a8 100644 --- a/plugins/Overlay/templates/index.twig +++ b/plugins/Overlay/templates/index.twig @@ -61,8 +61,8 @@ <script type="text/javascript"> broadcast._isInit = true; $(function () { - var iframeSrc = 'index.php?module=Overlay&action=startOverlaySession&idSite={{ idSite }}&period={{ period }}&date={{ rawDate }}'; - Piwik_Overlay.init(iframeSrc, '{{ idSite }}', '{{ period }}', '{{ rawDate }}'); + var iframeSrc = 'index.php?module=Overlay&action=startOverlaySession&idSite={{ idSite }}&period={{ period }}&date={{ rawDate }}&segment={{ segment }}'; + Piwik_Overlay.init(iframeSrc, '{{ idSite }}', '{{ period }}', '{{ rawDate }}', '{{ segment }}'); window.Piwik_Overlay_Translations = { domain: "{{ 'Overlay_Domain'|translate }}" diff --git a/plugins/Overlay/templates/index_noframe.twig b/plugins/Overlay/templates/index_noframe.twig index 0478715edb75e311e2a651c685c016e44378e685..f3c9e61579184965c9d7f98071d96d1221a3d56a 100644 --- a/plugins/Overlay/templates/index_noframe.twig +++ b/plugins/Overlay/templates/index_noframe.twig @@ -6,7 +6,7 @@ <div id="overlayNoFrame"> <script type="text/javascript"> - var newLocation = 'index.php?module=Overlay&action=startOverlaySession&idSite={{ idSite }}&period={{ period }}&date={{ date }}'; + var newLocation = 'index.php?module=Overlay&action=startOverlaySession&idSite={{ idSite }}&period={{ period }}&date={{ date }}&segment={{ segment }}'; var locationParts = window.location.href.split('#'); if (locationParts.length > 1) { diff --git a/plugins/Overlay/templates/renderSidebar.twig b/plugins/Overlay/templates/renderSidebar.twig index 09d8cf0d40131fec2bd19f09d1a8ffe8d7b6e7b5..36ff9c8ba1d725162cc10bbed21c2bb961cbd825 100644 --- a/plugins/Overlay/templates/renderSidebar.twig +++ b/plugins/Overlay/templates/renderSidebar.twig @@ -8,6 +8,11 @@ </span> </div> + <div class="overlaySegment"> + <strong>{{ 'General_Segment'|translate }}:</strong> + <span>{{ segmentDescription }}</span> + </div> + {% if data|length > 0 %} <h2 class="overlayMainMetrics">{{ 'General_MainMetrics'|translate }}</h2> <ul class="overlayMetrics"> diff --git a/plugins/Overlay/templates/startOverlaySession.twig b/plugins/Overlay/templates/startOverlaySession.twig new file mode 100644 index 0000000000000000000000000000000000000000..b1db8ce5b298e1d9679632392fd5bee37425c977 --- /dev/null +++ b/plugins/Overlay/templates/startOverlaySession.twig @@ -0,0 +1,50 @@ +<html><head><title></title></head><body> +<script type="text/javascript"> + function handleProtocol(url) { + if ({% if isHttps %}true{% else %}false{% endif %}) { + return url.replace(/http:\/\//i, "https://"); + } else { + return url.replace(/https:\/\//i, "http://"); + } + } + + function removeUrlPrefix(url) { + return url.replace(/http(s)?:\/\/(www\.)?/i, ""); + } + + if (window.location.hash) { + var match = false; + + var urlToRedirect = window.location.hash.substr(1); + var urlToRedirectWithoutPrefix = removeUrlPrefix(urlToRedirect); + + var knownUrls = {{ knownUrls|raw }}; + for (var i = 0; i < knownUrls.length; i++) { + var testUrl = removeUrlPrefix(knownUrls[i]); + if (urlToRedirectWithoutPrefix.substr(0, testUrl.length) == testUrl) { + match = true; + if (navigator.appName == "Microsoft Internet Explorer") { + // internet explorer loses the referrer if we use window.location.href=X + var referLink = document.createElement("a"); + referLink.href = handleProtocol(urlToRedirect); + document.body.appendChild(referLink); + referLink.click(); + } else { + window.location.href = handleProtocol(urlToRedirect); + } + break; + } + } + + if (!match) { + var idSite = window.location.href.match(/idSite=([0-9]+)/i)[1]; + window.location.href = "index.php?module=Overlay&action=showErrorWrongDomain" + + "&idSite=" + idSite + + "&url=" + encodeURIComponent(urlToRedirect); + } + } + else { + window.location.href = handleProtocol("{{ mainUrl|e('js') }}"); + }; +</script> +</body></html> \ No newline at end of file diff --git a/plugins/PrivacyManager/lang/cs.json b/plugins/PrivacyManager/lang/cs.json index 45881dd4873d510ecc8d4c26289ed5297cd6738c..1677ed1252b75080f78b3294b50d3f3e576cc56d 100644 --- a/plugins/PrivacyManager/lang/cs.json +++ b/plugins/PrivacyManager/lang/cs.json @@ -2,7 +2,7 @@ "PrivacyManager": { "AnonymizeIpDescription": "Zvolte \"ano\", pokud nemá Piwik sledovat plnÄ› kvalifikované IP adresy.", "AnonymizeIpInlineHelp": "Skryje poslednà byte IP adresy návÅ¡tÄ›vnÃka, aby souhlasila se zákony vašà zemÄ›.", - "AnonymizeIpExtendedHelp": "Když uživatelé navÅ¡tÃvà vaÅ¡e stránky, Piwik neuložà jejich plnou IP adresu(jako %s), ale nejprve bude anonymizována (na %s). Anonymizace IP adres je jeden z požadavků práva na ochranu soukromà v nÄ›kterých zemÃ, jako je tÅ™eba NÄ›mecko.", + "AnonymizeIpExtendedHelp": "Když uživatelé navÅ¡tÃvà vaÅ¡e stránky, Piwik neuložà jejich plnou IP adresu (jako %s), ale nejprve bude anonymizována (na %s). Anonymizace IP adres je jednÃm z požadavků práva na ochranu soukromà v nÄ›kterých zemÃ, jako je tÅ™eba NÄ›mecko.", "AnonymizeIpMaskLengtDescription": "Zvolte, kolik bitů z návÅ¡tÄ›vnÃkovy IP adresy má být maskováno.", "AnonymizeIpMaskLength": "%s bitů - napÅ™. %s", "CannotLockSoDeleteLogActions": "Tabulka log_action nebude vyprázdnÄ›na: dejte Mysql uživateli %s privilegium LOCK TABLES.", diff --git a/plugins/PrivacyManager/lang/ja.json b/plugins/PrivacyManager/lang/ja.json index ed8f1a4bf773e547c627bf242275c334b999b8e6..aee8d4f8981ba4554bc291d99b69224f7801846e 100644 --- a/plugins/PrivacyManager/lang/ja.json +++ b/plugins/PrivacyManager/lang/ja.json @@ -13,6 +13,8 @@ "DeleteDataDescription": "データベースã®ã‚µã‚¤ã‚ºã‚’å°ã•ãä¿ã¤ãŸã‚ã«ã€å¤ã„訪å•者ã®ãƒã‚°ã€ã‹ã¤\/ã¾ãŸã¯ç”Ÿæˆã•れãŸãƒ¬ãƒãƒ¼ãƒˆã‚’定期的ã«å‰Šé™¤ã™ã‚‹ã‚ˆã†Piwikã‚’è¨å®šã§ãã¾ã™ã€‚", "DeleteDataDescription2": "å¿…è¦ã§ã‚れã°ã€äº‹å‰å‡¦ç†ã•れãŸãƒ¬ãƒãƒ¼ãƒˆã¯å‰Šé™¤ã›ãšã€ãƒ“ジットã¨ãƒšãƒ¼ã‚¸ãƒ“ューã¨ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒã‚°ãƒ‡ãƒ¼ã‚¿ã®ã¿ã®å‰Šé™¤ã‚‚ã§ãã¾ã™ã€‚ã‚ã‚‹ã„ã¯ã€äº‹å‰å‡¦ç†ã•れãŸãƒ¬ãƒãƒ¼ãƒˆã‚’削除ã—ã€ãƒã‚°ãƒ‡ãƒ¼ã‚¿ã‚’ä¿å˜ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚", "DeleteDataInterval": "å¤ã„データを削除:毎", + "DeleteOldVisitorLogs": "å¤ã„ビジターãƒã‚°ã‚’削除", + "DeleteOldArchivedReports": "å¤ã„アーカイブレãƒãƒ¼ãƒˆã‚’削除", "DeleteLogDescription2": "自動ãƒã‚°å‰Šé™¤ã‚’有効ã«ã™ã‚‹æ™‚ã¯ã€ãƒ‡ãƒ¼ã‚¿ãŒå¤±ã‚れãªã„よã†ã«ã€ä»¥å‰ã®ã™ã¹ã¦ã®æ—¥æ¬¡ãƒ¬ãƒãƒ¼ãƒˆãŒå‡¦ç†ã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚", "DeleteLogInfo": "以下ã®ãƒ†ãƒ¼ãƒ–ルã®ãƒã‚°ãŒå‰Šé™¤ã•れã¾ã™: %s", "DeleteLogsConfirm": "ã‚ãªãŸã¯ã€ãƒã‚°ãƒ‡ãƒ¼ã‚¿ã®å‰Šé™¤ã‚’有効ã«ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚å¤ã„ãƒã‚°ãƒ‡ãƒ¼ã‚¿ãŒå‰Šé™¤ã•れã€ãƒ¬ãƒãƒ¼ãƒˆãŒæ—¢ã«ä½œæˆã•れã¦ã„ãªã„å ´åˆã«ã¯ã€æ´å²çš„ãªéŽåŽ»ã®åˆ†æžãƒ‡ãƒ¼ã‚¿ã‚’見るã“ã¨ã¯ã§ãã¾ã›ã‚“。ã‚ãªãŸã¯æœ¬å½“ã«ã“れをã—ãŸã„ã§ã™ã‹ï¼Ÿ", @@ -25,6 +27,7 @@ "DeleteReportsInfo2": "\"%s\"ãŒæœ‰åйã§ãªã„å ´åˆã¯ã€è¦æ±‚ã•れれã°ã€å¤ã„レãƒãƒ¼ãƒˆãŒè‡ªå‹•çš„ã«å†ä½œæˆã•れã¾ã™ã€‚", "DeleteReportsInfo3": "\"%s\" を有効ã«ã™ã‚‹ã¨ã€ãƒ‡ãƒ¼ã‚¿ã¯æ°¸ä¹…ã«å¤±ã‚れã¾ã™ã€‚", "DeleteReportsOlderThan": "ã“ã®æœˆæ•°ã‚ˆã‚Šå¤ã„リãƒãƒ¼ãƒˆã‚’削除", + "DeleteSchedulingSettings": "å¤ã„データã®å‰Šé™¤ã‚’スケジュールã—ã¾ã™ã€‚", "DeleteDataSettings": "å¤ã„ビジターã®ãƒã‚°ã¨ãƒªãƒãƒ¼ãƒˆã‚’削除", "DoNotTrack_Description": "「トラック(追跡)ã—ãªã„ã€æ©Ÿèƒ½ã¯ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒè¨ªå•ã—ãªã„ウェブサイト(分æžã‚µãƒ¼ãƒ“スã€åºƒå‘Šãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã€ã‚½ãƒ¼ã‚·ãƒ£ãƒ«ãƒ—ラットフォームをå«ã‚€)ã«ã‚ˆã‚‹ãƒˆãƒ©ãƒƒã‚ングã®ã‚ªãƒ—トアウトをå¯èƒ½ã«ã™ã‚‹ãŸã‚ã®ãƒ†ã‚¯ãƒŽãƒã‚¸ãƒ¼ã¨ãƒãƒªã‚·ãƒ¼ã®æè¨€ã§ã™ã€‚", "DoNotTrack_Disable": "「トラック(追跡)ã—ãªã„ã€æ©Ÿèƒ½ã®ã‚µãƒãƒ¼ãƒˆã‚’無効ã«ã™ã‚‹", @@ -39,15 +42,18 @@ "GeolocationAnonymizeIpNote": "注) ä½ç½®æƒ…å ±æŽ¢ç´¢æ©Ÿèƒ½ã¯ã€åŒ¿å化ã•れ㟠1byte ã®å ´åˆã¨ã»ã¼åŒã˜çµæžœã«ãªã‚Šã¾ã™ã€‚2byte 以上を使用ã™ã‚‹ã¨ã€ä½ç½®æƒ…å ±æŽ¢ç´¢æ©Ÿèƒ½ãŒä¸æ£ç¢ºã«ãªã‚Šã¾ã™ã€‚", "GetPurgeEstimate": "パージ推定値をå–å¾—", "KeepBasicMetrics": "基本ã®ãƒ¡ãƒˆãƒªãƒƒã‚¯ã‚¹ã‚’ä¿æŒ(ビジットã€ãƒšãƒ¼ã‚¸ãƒ“ューã€ç›´å¸°çއã€ç›®æ¨™ã‚³ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€eコマースコンãƒãƒ¼ã‚¸ãƒ§ãƒ³ç‰)", + "KeepDataFor": "ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ã‚’ä¿æŒ", "KeepReportSegments": "上記ã®ä¿æŒã•れるデータã«ã¤ã„ã¦ã¯ã€ãƒ¬ãƒãƒ¼ãƒˆã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚‚ä¿æŒã™ã‚‹", "LastDelete": "最後ã«å‰Šé™¤ã—ãŸã®ã¯", "LeastDaysInput": "日数㯠%s より大ãã„æ•°ã‚’指定ã—ã¦ãã ã•ã„。", "LeastMonthsInput": "月数㯠%s より大ãã„æ•°ã‚’指定ã—ã¦ãã ã•ã„。", "MenuPrivacySettings": "プライãƒã‚·ãƒ¼", "NextDelete": "次回ã®å‰Šé™¤ã¾ã§", + "PluginDescription": "ユーザーã®ãƒ—ライãƒã‚·ãƒ¼ã‚’増強ã—ã€Piwik インスタンス プライãƒã‚·ãƒ¼ã‚’åœ°åŸŸã®æ³•å¾‹ã«æº–æ‹ ã•ã›ã¾ã™ã€‚", "PurgeNow": "今DBを削除ã™ã‚‹", "PurgeNowConfirm": "データベースã‹ã‚‰æ°¸ä¹…ã«ãƒ‡ãƒ¼ã‚¿ã‚’削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ç¶šã‘ã¾ã™ã‹ï¼Ÿ", "PurgingData": "データを削除ã—ã¦ã„ã¾ã™...", + "RecommendedForPrivacy": "プライãƒã‚·ãƒ¼æŽ¨å¥¨", "ReportsDataSavedEstimate": "データベースサイズ", "SaveSettingsBeforePurge": "データ削除è¨å®šã‚’変更ã—ã¾ã—ãŸã€‚削除ãŒé–‹å§‹ã•れるå‰ã«ä¿å˜ã—ã¦ãã ã•ã„。", "SeeAlsoOurOfficialGuidePrivacy": "ç§é”ã®ã‚ªãƒ•ィシャルガイドもã”確èªãã ã•ã„。%sWeb Analytics Privacy%s", diff --git a/plugins/PrivacyManager/lang/ko.json b/plugins/PrivacyManager/lang/ko.json index ff0c89f872f286ea605169e098fa3a6c47fecb1b..84987a600ad111ccd13a97f58ed8c8121ea44299 100644 --- a/plugins/PrivacyManager/lang/ko.json +++ b/plugins/PrivacyManager/lang/ko.json @@ -2,6 +2,7 @@ "PrivacyManager": { "AnonymizeIpDescription": "ì™„ì „ížˆ í™•ì¸ ëœ IP 주소를 ì¶”ì 하지 않ë„ë¡í•˜ë ¤ë©´ \"예\"를 ì„ íƒí•©ë‹ˆë‹¤.", "AnonymizeIpInlineHelp": "ê°œì¸ì´ ì„¤ì •í•œ ë‚´ë¶€ 규칙 ë° ì§€ì¹¨ì— ë”°ë¼ ë°©ë¬¸ìžì˜ IPì£¼ì†Œì˜ ë§ˆì§€ë§‰ ë°”ì´íŠ¸ë¥¼ 숨ê¹ë‹ˆë‹¤.", + "AnonymizeIpExtendedHelp": "ìœ ì €ë“¤ì´ ì›¹ì‚¬ì´íŠ¸ì— ì ‘ì†í• 때, Piwik는 ëª¨ë“ IP 주소(예: %s)를 사용하지 ì•Šê³ ì¼ë¶€ë¥¼ 숨ê¹ë‹ˆë‹¤(예: %s). IP 주소 ìµëª… 처리는 ë…ì¼ê³¼ ê°™ì´ íŠ¹ì • êµê°€ì—서 프ë¼ì´ë²„시 ë²•ë¥ ì— ë”°ë¼ ìš”êµ¬ë˜ëŠ” 것 중 하나입니다.", "AnonymizeIpMaskLengtDescription": "방문ìžì˜ IP 주소ì—서 몇 ë°”ì´íŠ¸ë¥¼ ìˆ¨ê¸°ë ¤ë©´ ì„ íƒí•˜ì„¸ìš”.", "AnonymizeIpMaskLength": "%s ë°”ì´íЏ - 예) %s", "CannotLockSoDeleteLogActions": "log_action í…Œì´ë¸”ì„ ë¹„ìš¸ 수 없습니다: '%s' MYSQL 사용ìžì—게 LOCK í…Œì´ë¸” ê¶Œí•œì„ ë¶€ì—¬í•˜ì„¸ìš”.", @@ -12,6 +13,8 @@ "DeleteDataDescription": "ë°ì´í„°ë² ì´ìФ í¬ê¸°ë¥¼ 작게 ìœ ì§€í•˜ê¸° 위해 기존 방문ìžì˜ 로그와 ìƒì„±ëœ ë³´ê³ ì„œë¥¼ ì •ê¸°ì 으로 ì‚ì œí•˜ë„ë¡ Piwikì„ ì„¤ì •í• ìˆ˜ 있습니다.", "DeleteDataDescription2": "필요한 경우, ì‚¬ì „ ì²˜ë¦¬ëœ ë³´ê³ ì„œëŠ” ì‚ì œí•˜ì§€ ì•Šê³ , 방문과 페ì´ì§€ë·° ë° ì „í™˜ 로그 ë°ì´í„°ë§Œ ì‚ì œí• ìˆ˜ 있습니다. ë˜ëŠ” ì‚¬ì „ ì²˜ë¦¬ëœ ë³´ê³ ì„œë¥¼ ì œê±°í•˜ê³ ë¡œê·¸ ë°ì´í„°ë¥¼ ì €ìž¥í• ìˆ˜ 있습니다.", "DeleteDataInterval": "ì˜¤ëž˜ëœ ë°ì´í„° ì‚ì œ", + "DeleteOldVisitorLogs": "ì˜¤ëž˜ëœ ë°©ë¬¸ìž ë¡œê·¸ ì‚ì œ", + "DeleteOldArchivedReports": "ì˜¤ëž˜ëœ ì•„ì¹´ì´ë¸Œëœ ë³´ê³ ì„œ ì‚ì œ", "DeleteLogDescription2": "ìžë™ìœ¼ë¡œ 로그 ì‚ì œë¥¼ í™œì„±í™”í• ë•Œ ë°ì´í„°ê°€ ì†ì‹¤ë˜ì§€ 않ë„ë¡ ëª¨ë“ ì´ì „ì˜ ì¼ì¼ ë³´ê³ ì„œê°€ 처리ë˜ê³ 있는지 확ì¸í•´ì•¼í•©ë‹ˆë‹¤.", "DeleteLogInfo": "ë‹¤ìŒ í…Œì´ë¸”ì˜ ë¡œê·¸ê°€ ì‚ì œë©ë‹ˆë‹¤: %s", "DeleteLogsConfirm": "ë‹¹ì‹ ì€ ë¡œê·¸ ë°ì´í„°ì˜ ì‚ì œë¥¼ ì‚¬ìš©í•˜ë ¤ê³ í•©ë‹ˆë‹¤. ì´ì „ 로그 ë°ì´í„°ê°€ ì‚ì œë˜ê³ ë³´ê³ ì„œê°€ ì´ë¯¸ ìƒì„±ë˜ì–´ 있지 ì•Šì€ ê²½ìš°ì—는 과거 ì´ë ¥ ë¶„ì„ ë°ì´í„°ë¥¼ ë³¼ 수 없습니다. ì •ë§ ì‹¤í–‰í• ê¹Œìš”?", @@ -24,12 +27,13 @@ "DeleteReportsInfo2": "\"%s\"ê°€ ìœ íš¨í•˜ì§€ ì•Šì€ ê²½ìš°, 요구ë˜ëŠ” 경우, ì´ì „ ë³´ê³ ì„œê°€ ìžë™ìœ¼ë¡œ 다시 만들어집니다.", "DeleteReportsInfo3": "\"%s\"를 사용하면 ë°ì´í„°ê°€ ì˜êµ¬ì 으로 ì†ì‹¤ë©ë‹ˆë‹¤.", "DeleteReportsOlderThan": "ì˜¤ëž˜ëœ ë³´ê³ ì„œ ì‚ì œ", + "DeleteSchedulingSettings": "ì˜¤ëž˜ëœ ë°ì´í„° ì‚ì œ 계íší•˜ê¸°", "DeleteDataSettings": "ì˜¤ëž˜ëœ ë°©ë¬¸ìž ê¸°ë¡ ë° ë³´ê³ ì„œ ì‚ì œ", "DoNotTrack_Description": "\"ì¶”ì 않함\"ê¸°ëŠ¥ì€ ì‚¬ìš©ìžê°€ 방문한 웹사ì´íЏ (ë¶„ì„ ì„œë¹„ìŠ¤, ê´‘ê³ ë„¤íŠ¸ì›Œí¬, 소셜 í”Œëž«í¼ ë“±)ì— ì˜í•œ ì¶”ì ì°¨ë‹¨ì„ ê°€ëŠ¥í•˜ê²Œí•˜ëŠ” ê¸°ìˆ ê³¼ ì •ì±… ì œì–¸ìž…ë‹ˆë‹¤.", "DoNotTrack_Disable": "\"ì¶”ì 하지 않ìŒ\"기능 ì§€ì› ë¹„í™œì„±í™”", "DoNotTrack_Disabled": "Piwikì€ í˜„ìž¬ 브ë¼ìš°ì €ì—서 \"ì¶”ì ë‹¹í•˜ê³ ì‹¶ì§€ 않ìŒ\"ì´ ì§€ì •ëœ ê²½ìš°ì—ë„ ëª¨ë“ ë°©ë¬¸ìžë¥¼ ì¶”ì í•˜ê³ ìžˆìŠµë‹ˆë‹¤.", "DoNotTrack_DisabledMoreInfo": "방문ìžì˜ 프ë¼ì´ë²„시를 ì¡´ì¤‘í•˜ê³ \"ì¶”ì 하지 않기\"기능 ì§€ì›ì„ 활성화하는 ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤.", - "DoNotTrack_Enable": "\"ì¶”ì 않함\"기능 활성화", + "DoNotTrack_Enable": "\"ì¶”ì 하지 않ìŒ\"기능 활성화", "DoNotTrack_Enabled": "ë‹¹ì‹ ì€ í˜„ìž¬ 사용ìžì˜ 프ë¼ì´ë²„시를 존중합니다. 브ë¼ë³´!", "DoNotTrack_EnabledMoreInfo": "브ë¼ìš°ì €ì—서 사용ìžê°€ \"ì¶”ì ë‹¹í•˜ê³ ì‹¶ì§€ 않ìŒ\"ì„ ì„¤ì •í•œ 경우, (\"ì¶”ì 하지 않ìŒ\"ê¸°ëŠ¥ì´ í™œì„±í™”ë˜ì–´ 있으면) Piwik ì´ëŸ¬í•œ 방문ìžë¥¼ ì¶”ì 하지 않습니다.", "DoNotTrack_SupportDNTPreference": "\"ì¶”ì 하지 않ìŒ\" ì§€ì› ê¸°ëŠ¥ ì„¤ì •", @@ -38,19 +42,25 @@ "GeolocationAnonymizeIpNote": "ì°¸ê³ : 위치 ì •ë³´ëŠ” 대략 1ë°”ì´íŠ¸ë¡œ ìµëª…으로 처리ë˜ëŠ” 것과 ê°™ì€ ê²°ê³¼ë¥¼ 얻습니다. 2ë°”ì´íЏ ë˜ëŠ” ì´ìƒì´ë©´ 위치 ì •ë³´ê°€ ì •í™•í•˜ì§€ ì•Šì„ ìˆ˜ 있습니다.", "GetPurgeEstimate": "비운 ì¶”ì •ì¹˜ 받기", "KeepBasicMetrics": "기본 지표 ìœ ì§€ (방문, 페ì´ì§€ë·°, ë°˜ì†¡ë¥ , ëª©í‘œì „í™˜, ì „ìžìƒê±°ëž˜ ì „í™˜ 등)", + "KeepDataFor": "ëª¨ë“ ë°ì´í„°ë¥¼ ìœ ì§€í•©ë‹ˆë‹¤:", "KeepReportSegments": "위 ìœ ì§€ë˜ëŠ” ë°ì´í„°ëŠ” ë³´ê³ ì„œì˜ ì„¸ê·¸ë¨¼íŠ¸ì—ë„ ìœ ì§€", "LastDelete": "마지막으로 ì‚ì œí•œ 것ì€", "LeastDaysInput": "ì¼ ìˆ˜ëŠ” %s보다 커야합니다.", - "LeastMonthsInput": "ë‹¬ì€ %s보다 커야합니다.", + "LeastMonthsInput": "ê°œì›”ì€ %s보다 커야합니다.", "MenuPrivacySettings": "ê°œì¸ ì •ë³´ 보호", "NextDelete": "ë‹¤ìŒ ì œê±°ê¹Œì§€", + "PluginDescription": "ìœ ì € 프ë¼ì´ë²„시를 높ì´ê³ , ë˜í•œ 프ë¼ì´ë²„시와 ê´€ë ¨í•œ êµë‚´ ë²•ë¥ ì„ ë”°ë¥´ë„ë¡ ë§Œë“œì„¸ìš”.", "PurgeNow": "지금 DB ì‚ì œ", "PurgeNowConfirm": "ì˜êµ¬ì 으로 ë°ì´í„°ë² ì´ìŠ¤ì˜ ë°ì´í„°ë¥¼ ì‚ì œí•˜ë ¤ê³ í•©ë‹ˆë‹¤. ê³„ì† í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", "PurgingData": "ë°ì´í„°ë¥¼ ì‚ì œí•©ë‹ˆë‹¤...", + "RecommendedForPrivacy": "프ë¼ì´ë²„시를 위해 권장함", "ReportsDataSavedEstimate": "ë°ì´í„°ë² ì´ìФ í¬ê¸°", "SaveSettingsBeforePurge": "ë°ì´í„° ì‚ì œ ì„¤ì •ì„ ë³€ê²½í–ˆìŠµë‹ˆë‹¤. ì‚ì œê°€ 시작ë˜ê¸° ì „ì— ì €ìž¥í•˜ì„¸ìš”.", + "SeeAlsoOurOfficialGuidePrivacy": "ê³µì‹ ê°€ì´ë“œì¸ %sWeb Analytics Privacy%sì„ ì°¸ê³ í•´ì£¼ì„¸ìš”.", "Teaser": "ì´ íŽ˜ì´ì§€ì—서는 ê¸°ì¡´ì˜ ë²•ë¥ ì— ë”°ë¼, Piwikì´ ê°œì¸ì— ë§žë„ë¡ ì •ì˜í• 수 있습니다: %s ìµëª… 방문ìžì˜ IP 주소 %s, %s ìžë™ìœ¼ë¡œ ë°ì´í„°ë² ì´ìФì—서 ì˜¤ëž˜ëœ ë°©ë¬¸ìžì˜ 로그를 ì‚ì œ %s, %s 웹사ì´íŠ¸ë¥¼ 탈퇴하는 ë°©ë²•ì„ ì œê³µ %sì— ë”°ë¦„.", "TeaserHeadline": "ê°œì¸ ì •ë³´ 보호 ì„¤ì •", + "UseAnonymizedIpForVisitEnrichment": "ë˜í•œ, ë°©ë¬¸ì´ ë§Žì„ ë•Œ ìµëª…í™”ëœ IP 주소를 사용합니다.", + "UseAnonymizedIpForVisitEnrichmentNote": "IP 주소와 공급ìžë¥¼ 통하여 방문ìžì˜ ì§€ì— ì •ë³´ë¥¼ 알아내는 것 ê°™ì€ í”ŒëŸ¬ê·¸ì¸ì€ 방문ìžì˜ 메타ë°ì´í„°ë¥¼ í–¥ìƒì‹œí‚µë‹ˆë‹¤. 기본ì 으로 ì´ëŸ° 플러그ì¸ì€ ìµëª…í™”ëœ IP 주소를 사용합니다. 만약 '아니오'를 ì„ íƒí• 경우, ìµëª…처리ë˜ì§€ ì•Šì€ ì „ì²´ IP 주소를 ëŒ€ì‹ ì‚¬ìš©í•˜ê²Œ ë˜ì–´ 프ë¼ì´ë²„시는 낮추지만 ëŒ€ì‹ ë°ì´í„° ì •í™•ë„를 ë†’ì¼ ê²ƒìž…ë‹ˆë‹¤.", "UseAnonymizeIp": "ìµëª… 방문ìžì˜ IP 주소", "UseDeleteLog": "ì •ê¸°ì 으로 ë°ì´í„°ë² ì´ìФì—서 ì˜¤ëž˜ëœ ë°©ë¬¸ìžì˜ 로그를 ì‚ì œí•¨", "UseDeleteReports": "ì •ê¸°ì 으로 ë°ì´í„°ë² ì´ìФì—서 ì˜¤ëž˜ëœ ë³´ê³ ì„œë¥¼ ì‚ì œ" diff --git a/plugins/PrivacyManager/lang/tr.json b/plugins/PrivacyManager/lang/tr.json index 22d6df66b6be0f79dc513ade950f98ec759cbc7a..a863ba7e52374a77bbc09ad60d824168e7f3441f 100644 --- a/plugins/PrivacyManager/lang/tr.json +++ b/plugins/PrivacyManager/lang/tr.json @@ -1,6 +1,13 @@ { "PrivacyManager": { "AnonymizeIpInlineHelp": "Yerel gizlilik kurallarına uymak için ziyaretçi IP adreslerini gizleyin.", + "CurrentDBSize": "Güncel veritabanı boyutu", + "DeleteOldVisitorLogs": "Eski ziyaretçi kayıtlarını sil", + "DeleteOldArchivedReports": "ArÅŸivlenen eski raporları sil", + "DeleteMaxRowsNoLimit": "Limit yok", + "DeleteDataSettings": "Eski ziyaretçi kayıtlarını ve raporları sil", + "MenuPrivacySettings": "Gizlilik", + "ReportsDataSavedEstimate": "Veritabanı boyutu", "TeaserHeadline": "Gizlilik Ayarları" } } \ No newline at end of file diff --git a/plugins/Provider/lang/ja.json b/plugins/Provider/lang/ja.json index 8f34448bfcaa38716b0c2cf22b5fe493f22b764a..4ac0948932f11b8e5a2b19cfcd1d83632e345416 100644 --- a/plugins/Provider/lang/ja.json +++ b/plugins/Provider/lang/ja.json @@ -1,6 +1,7 @@ { "Provider": { "ColumnProvider": "プãƒãƒã‚¤ãƒ€", + "PluginDescription": "ビジターã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆã‚µãƒ¼ãƒ“スプãƒãƒã‚¤ãƒ€ã‚’å ±å‘Šã—ã¾ã™", "ProviderReportDocumentation": "ã“ã®ãƒªãƒãƒ¼ãƒˆã¯ã€ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãƒ“ジターãŒä½¿ã£ã¦ã„るインターãƒãƒƒãƒˆã‚µãƒ¼ãƒ“スプãƒãƒã‚¤ãƒ€ã‚’示ã—ã¦ã„ã¾ã™ã€‚詳細ã«ã¤ã„ã¦ã¯ã€ãƒ—ãƒãƒã‚¤ãƒ€åをクリックã—ã¦ãã ã•ã„。 %s Piwik ãŒãƒ“ジターã®ãƒ—ãƒãƒã‚¤ãƒ€ã‚’判別ã§ããªã„å ´åˆã¯ã€IPã¨ã—ã¦è¡¨ç¤ºã•れã¾ã™ã€‚", "WidgetProviders": "プãƒãƒã‚¤ãƒ€", "ProviderReportFooter": "未知ã®ãƒ—ãƒãƒã‚¤ãƒ€ãƒ¼ã¨ã¯ IP ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒæ¤œç´¢ã§ããªã‹ã£ãŸã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚" diff --git a/plugins/Provider/lang/sl.json b/plugins/Provider/lang/sl.json index c13e93cdc95fb3fe4120d9fd63565e80ce84a623..8f5a09e04695e04405a9ba2e9f9020f67d91435d 100644 --- a/plugins/Provider/lang/sl.json +++ b/plugins/Provider/lang/sl.json @@ -1,6 +1,8 @@ { "Provider": { "ColumnProvider": "Ponudnik", + "PluginDescription": "PoroÄilo o obiskovalÄevem ponudniku dostopa do internetnih storitev.", + "ProviderReportDocumentation": "To poroÄilo prikazuje ponudnike dostopa do internetnih storitve prek katerih so obiskovalci dostopali do vaÅ¡e spletne strani. Za podrobnosti lahko kliknete na ime posameznega ponudnika. %s ÄŒe Piwik ne more doloÄiti obiskovalÄevega ponudnika, je le-ta naveden kot IP naslov.", "WidgetProviders": "Ponudniki", "ProviderReportFooter": "Neznan ponudnik pomeni, da IP Å¡tevilke ni bilo mogoÄe povezati s ponudnikom." } diff --git a/plugins/QueuedTracking b/plugins/QueuedTracking index 35288ec165fc085360ec77b441dc25f51e04cd5f..972fb6cc1953f7c21439c901fb87ab471eaf6b62 160000 --- a/plugins/QueuedTracking +++ b/plugins/QueuedTracking @@ -1 +1 @@ -Subproject commit 35288ec165fc085360ec77b441dc25f51e04cd5f +Subproject commit 972fb6cc1953f7c21439c901fb87ab471eaf6b62 diff --git a/plugins/Referrers/API.php b/plugins/Referrers/API.php index d1c08ac20ca4fddb9c6c219502cf8a7004db22de..befd651fbee27be31c1e5fa2d005e1f9c104f310 100644 --- a/plugins/Referrers/API.php +++ b/plugins/Referrers/API.php @@ -230,14 +230,14 @@ class API extends \Piwik\Plugin\API $dataTable = Archive::createDataTableFromArchive(Archiver::SEARCH_ENGINES_RECORD_NAME, $idSite, $period, $date, $segment, $expanded, $flat); if ($flat) { - $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'url', __NAMESPACE__ . '\getSearchEngineUrlFromName')); - $dataTable->filter('MetadataCallbackAddMetadata', array('url', 'logo', __NAMESPACE__ . '\getSearchEngineLogoFromUrl')); + $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'url', function ($url) { return SearchEngine::getInstance()->getUrlFromName($url); })); + $dataTable->filter('MetadataCallbackAddMetadata', array('url', 'logo', function ($url) { return SearchEngine::getInstance()->getLogoFromUrl($url); })); $dataTable->filterSubtables('Piwik\Plugins\Referrers\DataTable\Filter\KeywordsFromSearchEngineId', array($dataTable)); } else { $dataTable->filter('AddSegmentByLabel', array('referrerName')); $dataTable->queueFilter('PrependSegment', array('referrerType==search;')); - $dataTable->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', __NAMESPACE__ . '\getSearchEngineUrlFromName')); - $dataTable->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', __NAMESPACE__ . '\getSearchEngineLogoFromUrl')); + $dataTable->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', function ($url) { return SearchEngine::getInstance()->getUrlFromName($url); })); + $dataTable->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', function ($url) { return SearchEngine::getInstance()->getLogoFromUrl($url); })); } return $dataTable; @@ -309,9 +309,9 @@ class API extends \Piwik\Plugin\API { $dataTable = Archive::createDataTableFromArchive(Archiver::WEBSITES_RECORD_NAME, $idSite, $period, $date, $segment, $expanded, false); - $dataTable->filter('ColumnCallbackDeleteRow', array('label', function ($url) { return !isSocialUrl($url); })); - $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'url', __NAMESPACE__ . '\getSocialMainUrl')); - $dataTable->filter('GroupBy', array('label', __NAMESPACE__ . '\getSocialNetworkFromDomain')); + $dataTable->filter('ColumnCallbackDeleteRow', array('label', function ($url) { return !Social::getInstance()->isSocialUrl($url); })); + $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'url', function ($url) { return Social::getInstance()->getMainUrl($url); })); + $dataTable->filter('GroupBy', array('label', function ($url) { return Social::getInstance()->getSocialNetworkFromDomain($url); })); $this->setSocialIdSubtables($dataTable); $this->removeSubtableMetadata($dataTable); @@ -320,7 +320,7 @@ class API extends \Piwik\Plugin\API $this->buildExpandedTableForFlattenGetSocials($idSite, $period, $date, $segment, $expanded, $dataTable); } - $dataTable->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', __NAMESPACE__ . '\getSocialsLogoFromUrl')); + $dataTable->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', function ($url) { return Social::getInstance()->getLogoFromUrl($url); })); return $dataTable; } @@ -334,7 +334,7 @@ class API extends \Piwik\Plugin\API * @param string $date * @param bool|string $segment * @param bool|int $idSubtable This ID does not reference a real DataTable record. Instead, it - * is the array index of an item in the /core/DataFiles/Socials.php file. + * is the array index of an item in the Socials list file. * The urls are filtered by the social network at this index. * If false, no filtering is done and every social URL is returned. * @return DataTable @@ -344,7 +344,7 @@ class API extends \Piwik\Plugin\API $dataTable = $this->getDataTable(Archiver::WEBSITES_RECORD_NAME, $idSite, $period, $date, $segment, $expanded = true); // get the social network domain referred to by $idSubtable - $socialNetworks = Common::getSocialUrls(); + $socialNetworks = Social::getInstance()->getDefinitions(); $social = false; if ($idSubtable !== false) { @@ -362,7 +362,7 @@ class API extends \Piwik\Plugin\API $dataTable->filter( 'ColumnCallbackDeleteRow', array('label', - function ($url) use ($social) { return !isSocialUrl($url, $social); } + function ($url) use ($social) { return !Social::getInstance()->isSocialUrl($url, $social); } ) ); @@ -428,7 +428,7 @@ class API extends \Piwik\Plugin\API /** * Sets the subtable IDs for the DataTable returned by getSocial. * - * The IDs are int indexes into the array in /core/DataFiles/Socials.php. + * The IDs are int indexes into the array in of defined socials. * * @param DataTable $dataTable */ @@ -443,7 +443,7 @@ class API extends \Piwik\Plugin\API $socialName = $row->getColumn('label'); $i = 1; // start at one because idSubtable=0 is equivalent to idSubtable=false - foreach (Common::getSocialUrls() as $name) { + foreach (Social::getInstance()->getDefinitions() as $name) { if ($name == $socialName) { $row->setNonLoadedSubtableId($i); break; @@ -491,7 +491,7 @@ class API extends \Piwik\Plugin\API { $urlsTable = Archive::createDataTableFromArchive(Archiver::WEBSITES_RECORD_NAME, $idSite, $period, $date, $segment, $expanded, $flat = true); $urlsTable->filter('ColumnCallbackDeleteRow', array('label', function ($url) { - return !isSocialUrl($url); + return !Social::getInstance()->isSocialUrl($url); })); $urlsTable = $urlsTable->mergeSubtables(); @@ -504,7 +504,7 @@ class API extends \Piwik\Plugin\API $rows = $urlsTable->getRows(); foreach ($rows as $id => $urlsTableRow) { $url = $urlsTableRow->getColumn('label'); - if (isSocialUrl($url, $social)) { + if (Social::getInstance()->isSocialUrl($url, $social)) { $newTable->addRow($urlsTableRow); $urlsTable->deleteRow($id); } diff --git a/plugins/Referrers/Columns/Base.php b/plugins/Referrers/Columns/Base.php index 78fe27516c489d21929708e35d763ca26aa19e8c..a4da79d3899c5030563d63143074dfd62fff1674 100644 --- a/plugins/Referrers/Columns/Base.php +++ b/plugins/Referrers/Columns/Base.php @@ -11,6 +11,9 @@ namespace Piwik\Plugins\Referrers\Columns; use Piwik\Common; use Piwik\Piwik; use Piwik\Plugin\Dimension\VisitDimension; +use Piwik\Plugins\Referrers\SearchEngine AS SearchEngineDetection; +use Piwik\Plugins\SitesManager\SiteUrls; +use Piwik\Tracker\Cache; use Piwik\Tracker\PageUrl; use Piwik\Tracker\Request; use Piwik\Tracker\Visit; @@ -111,6 +114,14 @@ abstract class Base extends VisitDimension if (!$referrerDetected && !empty($this->referrerHost)) { $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_WEBSITE; $this->nameReferrerAnalyzed = Common::mb_strtolower($this->referrerHost); + + $urlsByHost = $this->getCachedUrlsByHostAndIdSite(); + + $directEntry = new SiteUrls(); + $path = $directEntry->getPathMatchingUrl($this->referrerUrlParse, $urlsByHost); + if (!empty($path) && $path !== '/') { + $this->nameReferrerAnalyzed .= rtrim($path, '/'); + } } $referrerInformation = array( @@ -139,7 +150,7 @@ abstract class Base extends VisitDimension */ protected function detectReferrerSearchEngine() { - $searchEngineInformation = UrlHelper::extractSearchEngineInformationFromUrl($this->referrerUrl); + $searchEngineInformation = SearchEngineDetection::getInstance()->extractInformationFromUrl($this->referrerUrl); /** * Triggered when detecting the search engine of a referrer URL. @@ -241,6 +252,17 @@ abstract class Base extends VisitDimension return true; } + private function getCachedUrlsByHostAndIdSite() + { + $cache = Cache::getCacheGeneral(); + + if (!empty($cache['allUrlsByHostAndIdSite'])) { + return $cache['allUrlsByHostAndIdSite']; + } + + return array(); + } + /** * We have previously tried to detect the campaign variables in the URL * so at this stage, if the referrer host is the current host, @@ -250,20 +272,32 @@ abstract class Base extends VisitDimension */ protected function detectReferrerDirectEntry() { - if (!empty($this->referrerHost)) { - // is the referrer host the current host? - if (isset($this->currentUrlParse['host'])) { - $currentHost = Common::mb_strtolower($this->currentUrlParse['host'], 'UTF-8'); - if ($currentHost == Common::mb_strtolower($this->referrerHost, 'UTF-8')) { - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY; - return true; - } - } - if (Visit::isHostKnownAliasHost($this->referrerHost, $this->idsite)) { + if (empty($this->referrerHost)) { + return false; + } + + $urlsByHost = $this->getCachedUrlsByHostAndIdSite(); + + $directEntry = new SiteUrls(); + $matchingSites = $directEntry->getIdSitesMatchingUrl($this->referrerUrlParse, $urlsByHost); + + if (isset($matchingSites) && is_array($matchingSites) && in_array($this->idsite, $matchingSites)) { + $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY; + return true; + } elseif (isset($matchingSites)) { + return false; + } + + // fallback logic if the referrer domain is not known to any site to not break BC + if (isset($this->currentUrlParse['host'])) { + // this might be actually buggy if first thing tracked is eg an outlink and referrer is from that site + $currentHost = Common::mb_strtolower($this->currentUrlParse['host']); + if ($currentHost == Common::mb_strtolower($this->referrerHost)) { $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY; return true; } } + return false; } @@ -277,7 +311,7 @@ abstract class Base extends VisitDimension // Set the Campaign keyword to the keyword found in the Referrer URL if any if (!empty($this->nameReferrerAnalyzed)) { - $referrerUrlInfo = UrlHelper::extractSearchEngineInformationFromUrl($this->referrerUrl); + $referrerUrlInfo = SearchEngineDetection::getInstance()->extractInformationFromUrl($this->referrerUrl); if (!empty($referrerUrlInfo['keywords'])) { $this->keywordReferrerAnalyzed = $referrerUrlInfo['keywords']; } @@ -448,7 +482,7 @@ abstract class Base extends VisitDimension protected function hasReferrerColumnChanged(Visitor $visitor, $information, $infoName) { - return Common::mb_strtolower($visitor->getVisitorColumn($infoName)) != $information[$infoName]; + return Common::mb_strtolower($visitor->getVisitorColumn($infoName)) != Common::mb_strtolower($information[$infoName]); } protected function doesLastActionHaveSameReferrer(Visitor $visitor, $referrerType) diff --git a/plugins/Referrers/Columns/Campaign.php b/plugins/Referrers/Columns/Campaign.php index ff2d5c24012b20586be770a5a9172df7d874083a..c29b62233688834756c3769801bcb996eaf83237 100644 --- a/plugins/Referrers/Columns/Campaign.php +++ b/plugins/Referrers/Columns/Campaign.php @@ -37,7 +37,7 @@ class Campaign extends Base /** * If we should create a new visit when the campaign changes, check if the campaign info changed and if so - * force the tracker to create a new visit. + * force the tracker to create a new visit.i * * @param Request $request * @param Visitor $visitor diff --git a/plugins/Referrers/Columns/Keyword.php b/plugins/Referrers/Columns/Keyword.php index 78605c9d94a4f742119e05be62870d9ee916165a..b3bfc374b1c0ee5198d0a3227f15af807b908552 100644 --- a/plugins/Referrers/Columns/Keyword.php +++ b/plugins/Referrers/Columns/Keyword.php @@ -8,6 +8,7 @@ */ namespace Piwik\Plugins\Referrers\Columns; +use Piwik\Common; use Piwik\Piwik; use Piwik\Plugins\Referrers\Segment; use Piwik\Tracker\Request; @@ -44,7 +45,7 @@ class Keyword extends Base $information = $this->getReferrerInformationFromRequest($request); if (!empty($information['referer_keyword'])) { - return substr($information['referer_keyword'], 0, 255); + return Common::mb_substr($information['referer_keyword'], 0, 255); } return $information['referer_keyword']; diff --git a/plugins/Referrers/Columns/ReferrerName.php b/plugins/Referrers/Columns/ReferrerName.php index 7bdb0732a67d855ecefb9ccba21e753c564922a5..ded0a48f9e8907d87c2aaa1bf433700f0dfee3fb 100644 --- a/plugins/Referrers/Columns/ReferrerName.php +++ b/plugins/Referrers/Columns/ReferrerName.php @@ -8,6 +8,7 @@ */ namespace Piwik\Plugins\Referrers\Columns; +use Piwik\Common; use Piwik\Plugins\Referrers\Segment; use Piwik\Tracker\Request; use Piwik\Tracker\Visitor; @@ -38,10 +39,8 @@ class ReferrerName extends Base $information = $this->getReferrerInformationFromRequest($request); if (!empty($information['referer_name'])) { - - return substr($information['referer_name'], 0, 70); + return Common::mb_substr($information['referer_name'], 0, 70); } - return $information['referer_name']; } diff --git a/plugins/Referrers/DataTable/Filter/KeywordsFromSearchEngineId.php b/plugins/Referrers/DataTable/Filter/KeywordsFromSearchEngineId.php index 1688713a860b0d4f5e58c31f06e0a2b66f441168..789a1b1a6a6b26fd4842ed76e82e69c82cb354f5 100644 --- a/plugins/Referrers/DataTable/Filter/KeywordsFromSearchEngineId.php +++ b/plugins/Referrers/DataTable/Filter/KeywordsFromSearchEngineId.php @@ -11,6 +11,7 @@ namespace Piwik\Plugins\Referrers\DataTable\Filter; use Piwik\DataTable\BaseFilter; use Piwik\DataTable\Row; use Piwik\DataTable; +use Piwik\Plugins\Referrers\SearchEngine; class KeywordsFromSearchEngineId extends BaseFilter { @@ -47,7 +48,7 @@ class KeywordsFromSearchEngineId extends BaseFilter if (!empty($subTableRow)) { $searchEngineUrl = $subTableRow->getMetadata('url'); - $table->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', 'Piwik\Plugins\Referrers\getSearchEngineUrlFromKeywordAndUrl', array($searchEngineUrl))); + $table->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', function ($keyword, $url) { return SearchEngine::getInstance()->getBackLinkFromUrlAndKeyword($url, $keyword); }, array($searchEngineUrl))); $table->queueFilter(function (DataTable $table) { $row = $table->getRowFromId(DataTable::ID_SUMMARY_ROW); if ($row) { diff --git a/plugins/Referrers/DataTable/Filter/SearchEnginesFromKeywordId.php b/plugins/Referrers/DataTable/Filter/SearchEnginesFromKeywordId.php index feab8636af46582c0d4f506bc92c4c9d21f576e2..6d395abba04baa54030b375cb257b9cd0075ff28 100644 --- a/plugins/Referrers/DataTable/Filter/SearchEnginesFromKeywordId.php +++ b/plugins/Referrers/DataTable/Filter/SearchEnginesFromKeywordId.php @@ -11,6 +11,7 @@ namespace Piwik\Plugins\Referrers\DataTable\Filter; use Piwik\DataTable\BaseFilter; use Piwik\DataTable\Row; use Piwik\DataTable; +use Piwik\Plugins\Referrers\SearchEngine; class SearchEnginesFromKeywordId extends BaseFilter { @@ -44,14 +45,14 @@ class SearchEnginesFromKeywordId extends BaseFilter { $idSubtable = $this->idSubtable ? : $table->getId(); - $table->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', 'Piwik\Plugins\Referrers\getSearchEngineUrlFromName')); - $table->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', 'Piwik\Plugins\Referrers\getSearchEngineLogoFromUrl')); + $table->queueFilter('ColumnCallbackAddMetadata', array('label', 'url', function ($url) { return SearchEngine::getInstance()->getUrlFromName($url); })); + $table->queueFilter('MetadataCallbackAddMetadata', array('url', 'logo', function ($url) { return SearchEngine::getInstance()->getLogoFromUrl($url); })); // get the keyword and create the URL to the search result page $rootRow = $this->firstLevelKeywordTable->getRowFromIdSubDataTable($idSubtable); if ($rootRow) { $keyword = $rootRow->getColumn('label'); - $table->queueFilter('MetadataCallbackReplace', array('url', 'Piwik\Plugins\Referrers\getSearchEngineUrlFromUrlAndKeyword', array($keyword))); + $table->queueFilter('MetadataCallbackReplace', array('url', function ($url, $keyword) { return SearchEngine::getInstance()->getBackLinkFromUrlAndKeyword($url, $keyword); }, array($keyword))); $table->queueFilter(function (DataTable $table) { $row = $table->getRowFromId(DataTable::ID_SUMMARY_ROW); if ($row) { diff --git a/plugins/Referrers/Referrers.php b/plugins/Referrers/Referrers.php index ce8667929bba3a117deea4383021060d4a43cce4..d262c792247f6008381ed09c8cff4196f9c05026 100644 --- a/plugins/Referrers/Referrers.php +++ b/plugins/Referrers/Referrers.php @@ -12,6 +12,7 @@ use Piwik\ArchiveProcessor; use Piwik\Common; use Piwik\Piwik; use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable; +use Piwik\Plugins\SitesManager\SiteUrls; /** * @see plugins/Referrers/functions.php @@ -31,9 +32,18 @@ class Referrers extends \Piwik\Plugin 'Insights.addReportToOverview' => 'addReportToInsightsOverview', 'Live.getAllVisitorDetails' => 'extendVisitorDetails', 'Request.getRenamedModuleAndAction' => 'renameDeprecatedModuleAndAction', + 'Tracker.setTrackerCacheGeneral' => 'setTrackerCacheGeneral' ); } + public function setTrackerCacheGeneral(&$cacheContent) + { + $siteUrls = new SiteUrls(); + $urls = $siteUrls->getAllCachedSiteUrls(); + + return $cacheContent['allUrlsByHostAndIdSite'] = $siteUrls->groupUrlsByHost($urls); + } + public function renameDeprecatedModuleAndAction(&$module, &$action) { if($module == 'Referers') { diff --git a/plugins/Referrers/SearchEngine.php b/plugins/Referrers/SearchEngine.php new file mode 100644 index 0000000000000000000000000000000000000000..14009a90297854f38222eb19a153d2a85d44ce3f --- /dev/null +++ b/plugins/Referrers/SearchEngine.php @@ -0,0 +1,485 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Referrers; + +use Piwik\Cache; +use Piwik\Common; +use Piwik\Option; +use Piwik\Piwik; +use Piwik\Singleton; +use Piwik\UrlHelper; + +/** + * Contains methods to access search engine definition data. + */ +class SearchEngine extends Singleton +{ + const OPTION_STORAGE_NAME = 'SearchEngineDefinitions'; + + /** @var string location of definition file (relative to PIWIK_INCLUDE_PATH) */ + const DEFINITION_FILE = '/vendor/piwik/searchengine-and-social-list/SearchEngines.yml'; + + protected $definitionList = null; + + /** + * Returns list of search engines by URL + * + * @return array Array of ( URL => array( searchEngineName, keywordParameter, path, charset ) ) + */ + public function getDefinitions() + { + $cache = Cache::getEagerCache(); + $cacheId = 'SearchEngine-' . self::OPTION_STORAGE_NAME; + + if ($cache->contains($cacheId)) { + $list = $cache->fetch($cacheId); + } else { + $list = $this->loadDefinitions(); + $cache->save($cacheId, $list); + } + + return $list; + } + + private function loadDefinitions() + { + if (empty($this->definitionList)) { + // Read first from the auto-updated list in database + $list = Option::get(self::OPTION_STORAGE_NAME); + + if ($list) { + $this->definitionList = unserialize(base64_decode($list)); + } else { + // Fallback to reading the bundled list + $yml = file_get_contents(PIWIK_INCLUDE_PATH . self::DEFINITION_FILE); + $this->definitionList = $this->loadYmlData($yml); + Option::set(self::OPTION_STORAGE_NAME, base64_encode(serialize($this->definitionList))); + } + } + + Piwik::postEvent('Referrer.addSearchEngineUrls', array(&$this->definitionList)); + + $this->convertLegacyDefinitions(); + + return $this->definitionList; + } + + /** + * @deprecated remove in 3.0 + */ + protected function convertLegacyDefinitions() + { + foreach ($this->definitionList as $url => $definition) { + if (!array_key_exists('name', $definition) && isset($definition[0]) && isset($definition[1])) { + $this->definitionList[$url] = array( + 'name' => $definition[0], + 'params' => $definition[1], + 'backlink' => @$definition[2], + 'charsets' => @$definition[3] + ); + } + } + + } + + /** + * Parses the given YML string and caches the resulting definitions + * + * @param string $yml + * @return array + */ + public function loadYmlData($yml) + { + $searchEngines = \Spyc::YAMLLoadString($yml); + + $this->definitionList = $this->transformData($searchEngines); + + return $this->definitionList; + } + + protected function transformData($searchEngines) + { + $urlToInfo = array(); + foreach ($searchEngines as $name => $info) { + foreach ($info as $urlDefinitions) { + foreach ($urlDefinitions['urls'] as $url) { + $searchEngineData = $urlDefinitions; + unset($searchEngineData['urls']); + $searchEngineData['name'] = $name; + $urlToInfo[$url] = $searchEngineData; + } + } + } + return $urlToInfo; + } + + /** + * Returns list of search engines by name + * + * @return array Array of ( searchEngineName => URL ) + */ + public function getNames() + { + $cacheId = 'SearchEngine.getSearchEngineNames'; + $cache = Cache::getTransientCache(); + $nameToUrl = $cache->fetch($cacheId); + + if (empty($nameToUrl)) { + $searchEngines = $this->getDefinitions(); + + $nameToUrl = array(); + foreach ($searchEngines as $url => $info) { + if (!isset($nameToUrl[$info['name']])) { + $nameToUrl[$info['name']] = $url; + } + } + $cache->save($cacheId, $nameToUrl); + } + + return $nameToUrl; + } + + /** + * Returns definitions for the given search engine host + * + * @param string $host + * @return array + */ + public function getDefinitionByHost($host) + { + $searchEngines = $this->getDefinitions(); + + if (!array_key_exists($host, $searchEngines)) { + return array(); + } + + return $searchEngines[$host]; + } + + /** + * Extracts a keyword from a raw not encoded URL. + * Will only extract keyword if a known search engine has been detected. + * Returns the keyword: + * - in UTF8: automatically converted from other charsets when applicable + * - strtolowered: "QUErY test!" will return "query test!" + * - trimmed: extra spaces before and after are removed + * + * The function returns false when a keyword couldn't be found. + * eg. if the url is "http://www.google.com/partners.html" this will return false, + * as the google keyword parameter couldn't be found. + * + * @see unit tests in /tests/core/Common.test.php + * @param string $referrerUrl URL referrer URL, eg. $_SERVER['HTTP_REFERER'] + * @return array|bool false if a keyword couldn't be extracted, + * or array( + * 'name' => 'Google', + * 'keywords' => 'my searched keywords') + */ + public function extractInformationFromUrl($referrerUrl) + { + $referrerParsed = @parse_url($referrerUrl); + $referrerHost = ''; + if (isset($referrerParsed['host'])) { + $referrerHost = $referrerParsed['host']; + } + if (empty($referrerHost)) { + return false; + } + // some search engines (eg. Bing Images) use the same domain + // as an existing search engine (eg. Bing), we must also use the url path + $referrerPath = ''; + if (isset($referrerParsed['path'])) { + $referrerPath = $referrerParsed['path']; + } + + $query = ''; + if (isset($referrerParsed['query'])) { + $query = $referrerParsed['query']; + } + + // Google Referrers URLs sometimes have the fragment which contains the keyword + if (!empty($referrerParsed['fragment'])) { + $query .= '&' . $referrerParsed['fragment']; + } + + $referrerHost = $this->getEngineHostFromUrl($referrerHost, $referrerPath, $query); + + if (empty($referrerHost)) { + return false; + } + + $definitions = $this->getDefinitionByHost($referrerHost); + + $searchEngineName = $definitions['name']; + $variableNames = $definitions['params']; + + $key = null; + if ($searchEngineName === 'Google Images' + || ($searchEngineName === 'Google' && strpos($referrerUrl, '/imgres') !== false) + ) { + if (strpos($query, '&prev') !== false) { + $query = urldecode(trim(UrlHelper::getParameterFromQueryString($query, 'prev'))); + $query = str_replace('&', '&', strstr($query, '?')); + } + $searchEngineName = 'Google Images'; + } elseif ($searchEngineName === 'Google' + && (strpos($query, '&as_') !== false || strpos($query, 'as_') === 0) + ) { + $keys = array(); + $key = UrlHelper::getParameterFromQueryString($query, 'as_q'); + if (!empty($key)) { + array_push($keys, $key); + } + $key = UrlHelper::getParameterFromQueryString($query, 'as_oq'); + if (!empty($key)) { + array_push($keys, str_replace('+', ' OR ', $key)); + } + $key = UrlHelper::getParameterFromQueryString($query, 'as_epq'); + if (!empty($key)) { + array_push($keys, "\"$key\""); + } + $key = UrlHelper::getParameterFromQueryString($query, 'as_eq'); + if (!empty($key)) { + array_push($keys, "-$key"); + } + $key = trim(urldecode(implode(' ', $keys))); + } + + if ($searchEngineName === 'Google') { + // top bar menu + $tbm = UrlHelper::getParameterFromQueryString($query, 'tbm'); + switch ($tbm) { + case 'isch': + $searchEngineName = 'Google Images'; + break; + case 'vid': + $searchEngineName = 'Google Video'; + break; + case 'shop': + $searchEngineName = 'Google Shopping'; + break; + } + } + + if (empty($key)) { + foreach ($variableNames as $variableName) { + if ($variableName[0] == '/') { + // regular expression match + if (preg_match($variableName, $referrerUrl, $matches)) { + $key = trim(urldecode($matches[1])); + break; + } + } else { + // search for keywords now &vname=keyword + $key = UrlHelper::getParameterFromQueryString($query, $variableName); + $key = trim(urldecode($key)); + + // Special cases: empty or no keywords + if (empty($key) + && ( + // Google search with no keyword + ($searchEngineName == 'Google' + && (empty($query) && (empty($referrerPath) || $referrerPath == '/') && empty($referrerParsed['fragment'])) + ) + + // Yahoo search with no keyword + || ($searchEngineName == 'Yahoo!' + && ($referrerParsed['host'] == 'r.search.yahoo.com') + ) + + // empty keyword parameter + || strpos($query, sprintf('&%s=', $variableName)) !== false + || strpos($query, sprintf('?%s=', $variableName)) !== false + + // search engines with no keyword + || $searchEngineName == 'Ixquick' + || $searchEngineName == 'Google Images' + || $searchEngineName == 'DuckDuckGo') + ) { + $key = false; + } + if (!empty($key) + || $key === false + ) { + break; + } + } + } + } + + // $key === false is the special case "No keyword provided" which is a Search engine match + if ($key === null || $key === '') { + return false; + } + + if (!empty($key)) { + if (!empty($definitions['charsets'])) { + $key = $this->convertCharset($key, $definitions['charsets']); + } + $key = Common::mb_strtolower($key); + } + + return array( + 'name' => $searchEngineName, + 'keywords' => $key, + ); + } + + protected function getEngineHostFromUrl($host, $path, $query) + { + $searchEngines = $this->getDefinitions(); + + $hostPattern = UrlHelper::getLossyUrl($host); + /* + * Try to get the best matching 'host' in definitions + * 1. check if host + path matches an definition + * 2. check if host only matches + * 3. check if host pattern + path matches + * 4. check if host pattern matches + * 5. special handling + */ + if (array_key_exists($host . $path, $searchEngines)) { + $host = $host . $path; + } elseif (array_key_exists($host, $searchEngines)) { + // no need to change host + } elseif (array_key_exists($hostPattern . $path, $searchEngines)) { + $host = $hostPattern . $path; + } elseif (array_key_exists($hostPattern, $searchEngines)) { + $host = $hostPattern; + } elseif (!array_key_exists($host, $searchEngines)) { + if (!strncmp($query, 'cx=partner-pub-', 15)) { + // Google custom search engine + $host = 'google.com/cse'; + } elseif (!strncmp($path, '/pemonitorhosted/ws/results/', 28)) { + // private-label search powered by InfoSpace Metasearch + $host = 'wsdsold.infospace.com'; + } elseif (strpos($host, '.images.search.yahoo.com') != false) { + // Yahoo! Images + $host = 'images.search.yahoo.com'; + } elseif (strpos($host, '.search.yahoo.com') != false) { + // Yahoo! + $host = 'search.yahoo.com'; + } else { + return false; + } + } + + return $host; + } + + /** + * Tries to convert the given string from one of the given charsets to UTF-8 + * @param string $string + * @param array $charsets + * @return string + */ + protected function convertCharset($string, $charsets) + { + if (function_exists('iconv') + && !empty($charsets) + ) { + $charset = $charsets[0]; + if (count($charsets) > 1 + && function_exists('mb_detect_encoding') + ) { + $charset = mb_detect_encoding($string, $charsets); + if ($charset === false) { + $charset = $charsets[0]; + } + } + + $newKey = @iconv($charset, 'UTF-8//IGNORE', $string); + if (!empty($newKey)) { + $string = $newKey; + } + } + + return $string; + } + + /** + * Return search engine URL by name + * + * @see core/DataFiles/SearchEnginges.php + * + * @param string $name + * @return string URL + */ + public function getUrlFromName($name) + { + $searchEngineNames = $this->getNames(); + if (isset($searchEngineNames[$name])) { + $url = 'http://' . $searchEngineNames[$name]; + } else { + $url = 'URL unknown!'; + } + return $url; + } + + /** + * Return search engine host in URL + * + * @param string $url + * @return string host + */ + private function getHostFromUrl($url) + { + if (strpos($url, '//')) { + $url = substr($url, strpos($url, '//') + 2); + } + if (($p = strpos($url, '/')) !== false) { + $url = substr($url, 0, $p); + } + return $url; + } + + + /** + * Return search engine logo path by URL + * + * @param string $url + * @return string path + * @see plugins/Referrers/images/searchEnginges/ + */ + public function getLogoFromUrl($url) + { + $pathInPiwik = 'plugins/Referrers/images/searchEngines/%s.png'; + $pathWithCode = sprintf($pathInPiwik, $this->getHostFromUrl($url)); + $absolutePath = PIWIK_INCLUDE_PATH . '/' . $pathWithCode; + if (file_exists($absolutePath)) { + return $pathWithCode; + } + return sprintf($pathInPiwik, 'xx'); + } + + /** + * Return search engine URL for URL and keyword + * + * @see core/DataFiles/SearchEnginges.php + * + * @param string $url Domain name, e.g., search.piwik.org + * @param string $keyword Keyword, e.g., web+analytics + * @return string URL, e.g., http://search.piwik.org/q=web+analytics + */ + public function getBackLinkFromUrlAndKeyword($url, $keyword) + { + if ($keyword === API::LABEL_KEYWORD_NOT_DEFINED) { + return 'http://piwik.org/faq/general/#faq_144'; + } + $keyword = urlencode($keyword); + $keyword = str_replace(urlencode('+'), urlencode(' '), $keyword); + $host = substr($url, strpos($url, '//') + 2); + $definition = $this->getDefinitionByHost($host); + if (empty($definition['backlink'])) { + return false; + } + $path = str_replace("{k}", $keyword, $definition['backlink']); + return $url . (substr($url, -1) != '/' ? '/' : '') . $path; + } +} diff --git a/plugins/Referrers/Social.php b/plugins/Referrers/Social.php new file mode 100644 index 0000000000000000000000000000000000000000..71badc3357a3e7b7eba58ef0e2b3a481929819cc --- /dev/null +++ b/plugins/Referrers/Social.php @@ -0,0 +1,181 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Referrers; +use Piwik\Cache; +use Piwik\Common; +use Piwik\Option; +use Piwik\Piwik; +use Piwik\Singleton; +use Piwik\UrlHelper; + +/** + * Contains methods to access search engine definition data. + */ +class Social extends Singleton +{ + const OPTION_STORAGE_NAME = 'SocialDefinitions'; + + /** @var string location of definition file (relative to PIWIK_INCLUDE_PATH) */ + const DEFINITION_FILE = '/vendor/piwik/searchengine-and-social-list/Socials.yml'; + + protected $definitionList = null; + + /** + * Returns list of search engines by URL + * + * @return array Array of ( URL => array( searchEngineName, keywordParameter, path, charset ) ) + */ + public function getDefinitions() + { + $cache = Cache::getEagerCache(); + $cacheId = 'Social-' . self::OPTION_STORAGE_NAME; + + if ($cache->contains($cacheId)) { + $list = $cache->fetch($cacheId); + } else { + $list = $this->loadDefinitions(); + $cache->save($cacheId, $list); + } + + return $list; + } + + private function loadDefinitions() + { + if ($this->definitionList === null) { + // Read first from the auto-updated list in database + $list = Option::get(self::OPTION_STORAGE_NAME); + + if ($list) { + $this->definitionList = unserialize(base64_decode($list)); + } else { + // Fallback to reading the bundled list + $yml = file_get_contents(PIWIK_INCLUDE_PATH . self::DEFINITION_FILE); + $this->definitionList = $this->loadYmlData($yml); + Option::set(self::OPTION_STORAGE_NAME, base64_encode(serialize($this->definitionList))); + } + } + + Piwik::postEvent('Referrer.addSocialUrls', array(&$this->definitionList)); + + return $this->definitionList; + } + + /** + * Parses the given YML string and caches the resulting definitions + * + * @param string $yml + * @return array + */ + public function loadYmlData($yml) + { + $searchEngines = \Spyc::YAMLLoadString($yml); + + $this->definitionList = $this->transformData($searchEngines); + + return $this->definitionList; + } + + protected function transformData($socials) + { + $urlToName = array(); + foreach ($socials as $name => $urls) { + foreach ($urls as $url) { + $urlToName[$url] = $name; + } + } + return $urlToName; + } + + /** + * Returns true if a URL belongs to a social network, false if otherwise. + * + * @param string $url The URL to check. + * @param string|bool $socialName The social network's name to check for, or false to check + * for any. + * @return bool + */ + public function isSocialUrl($url, $socialName = false) + { + foreach ($this->getDefinitions() as $domain => $name) { + + if (preg_match('/(^|[\.\/])'.$domain.'([\.\/]|$)/', $url) && ($socialName === false || $name == $socialName)) { + + return true; + } + } + + return false; + } + + + /** + * Get's social network name from URL. + * + * @param string $url + * @return string + */ + public function getSocialNetworkFromDomain($url) + { + foreach ($this->getDefinitions() as $domain => $name) { + + if (preg_match('/(^|[\.\/])'.$domain.'([\.\/]|$)/', $url)) { + + return $name; + } + } + + return Piwik::translate('General_Unknown'); + } + + /** + * Returns the main url of the social network the given url matches + * + * @param string $url + * + * @return string + */ + public function getMainUrl($url) + { + $social = $this->getSocialNetworkFromDomain($url); + foreach ($this->getDefinitions() as $domain => $name) { + + if ($name == $social) { + + return $domain; + } + } + return $url; + } + + + /** + * Return social network logo path by URL + * + * @param string $domain + * @return string path + * @see plugins/Referrers/images/socials/ + */ + public function getLogoFromUrl($domain) + { + $social = $this->getSocialNetworkFromDomain($domain); + $socialNetworks = $this->getDefinitions(); + + $filePattern = 'plugins/Referrers/images/socials/%s.png'; + + $socialDomains = array_keys($socialNetworks, $social); + foreach ($socialDomains as $domain) { + if (file_exists(PIWIK_INCLUDE_PATH . '/' . sprintf($filePattern, $domain))) { + return sprintf($filePattern, $domain); + } + } + + return sprintf($filePattern, 'xx'); + } +} diff --git a/plugins/Referrers/Tasks.php b/plugins/Referrers/Tasks.php new file mode 100644 index 0000000000000000000000000000000000000000..da9cad13217708441b8bd5da73eac8ead9bc440f --- /dev/null +++ b/plugins/Referrers/Tasks.php @@ -0,0 +1,54 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Referrers; + + +use Piwik\Http; +use Piwik\Option; + +class Tasks extends \Piwik\Plugin\Tasks +{ + public function schedule() + { + $this->weekly('updateSearchEngines'); + $this->weekly('updateSocials'); + } + + /** + * Update the search engine definitions + * + * @see https://github.com/piwik/searchengine-and-social-list + */ + public function updateSearchEngines() + { + $url = 'https://raw.githubusercontent.com/piwik/searchengine-and-social-list/master/SearchEngines.yml'; + $list = Http::sendHttpRequest($url, 30); + $searchEngines = SearchEngine::getInstance()->loadYmlData($list); + if (count($searchEngines) < 200) { + return; + } + Option::set(SearchEngine::OPTION_STORAGE_NAME, base64_encode(serialize($searchEngines))); + } + + /** + * Update the social definitions + * + * @see https://github.com/piwik/searchengine-and-social-list + */ + public function updateSocials() + { + $url = 'https://raw.githubusercontent.com/piwik/searchengine-and-social-list/master/Socials.yml'; + $list = Http::sendHttpRequest($url, 30); + $socials = Social::getInstance()->loadYmlData($list); + if (count($socials) < 50) { + return; + } + Option::set(Social::OPTION_STORAGE_NAME, base64_encode(serialize($socials))); + } +} \ No newline at end of file diff --git a/plugins/Referrers/Visitor.php b/plugins/Referrers/Visitor.php index 308c7b08f865b50d49ff838f88aa0cbb8bdddb77..b10b9b953d7a616f4e647138eacb1d9abfcc33e3 100644 --- a/plugins/Referrers/Visitor.php +++ b/plugins/Referrers/Visitor.php @@ -62,7 +62,7 @@ class Visitor ) { $refUrl = @parse_url($this->details['referer_url']); if (isset($refUrl['host'])) { - $url = getSearchEngineUrlFromUrlAndKeyword('http://google.com', $this->getKeyword()); + $url = SearchEngine::getInstance()->getBackLinkFromUrlAndKeyword('http://google.com', $this->getKeyword()); $url = str_replace('google.com', $refUrl['host'], $url); return $url; @@ -109,7 +109,7 @@ class Visitor && !empty($this->details['referer_name']) ) { - return getSearchEngineUrlFromName($this->details['referer_name']); + return SearchEngine::getInstance()->getUrlFromName($this->details['referer_name']); } return null; @@ -121,7 +121,7 @@ class Visitor if (!is_null($searchEngineUrl)) { - return getSearchEngineLogoFromUrl($searchEngineUrl); + return SearchEngine::getInstance()->getLogoFromUrl($searchEngineUrl); } return null; diff --git a/plugins/Referrers/functions.php b/plugins/Referrers/functions.php index e0fee308336f492e8f7c90b6f11fe14424415a64..c91ebc816d8b25ad4297a2a5d797b2763c714358 100644 --- a/plugins/Referrers/functions.php +++ b/plugins/Referrers/functions.php @@ -27,194 +27,6 @@ function getPathFromUrl($url) return $path; } -/** - * Returns the main url of the social network the given url matches - * - * @param string $url - * - * @return string - */ -function getSocialMainUrl($url) -{ - $social = getSocialNetworkFromDomain($url); - foreach (Common::getSocialUrls() as $domain => $name) { - - if ($name == $social) { - - return $domain; - } - } - return $url; -} - -/** - * Get's social network name from URL. - * - * @param string $url - * @return string - */ -function getSocialNetworkFromDomain($url) -{ - foreach (Common::getSocialUrls() as $domain => $name) { - - if (preg_match('/(^|[\.\/])'.$domain.'([\.\/]|$)/', $url)) { - - return $name; - } - } - - return Piwik::translate('General_Unknown'); -} - -/** - * Returns true if a URL belongs to a social network, false if otherwise. - * - * @param string $url The URL to check. - * @param string|bool $socialName The social network's name to check for, or false to check - * for any. - * @return bool - */ -function isSocialUrl($url, $socialName = false) -{ - foreach (Common::getSocialUrls() as $domain => $name) { - - if (preg_match('/(^|[\.\/])'.$domain.'([\.\/]|$)/', $url) && ($socialName === false || $name == $socialName)) { - - return true; - } - } - - return false; -} - -/** - * Return social network logo path by URL - * - * @param string $domain - * @return string path - * @see plugins/Referrers/images/socials/ - */ -function getSocialsLogoFromUrl($domain) -{ - $social = getSocialNetworkFromDomain($domain); - $socialNetworks = Common::getSocialUrls(); - - $filePattern = 'plugins/Referrers/images/socials/%s.png'; - - foreach ($socialNetworks as $domainKey => $name) { - if ($social == $socialNetworks[$domainKey] && file_exists(PIWIK_INCLUDE_PATH . '/' . sprintf($filePattern, $domainKey))) { - return sprintf($filePattern, $domainKey); - } - } - - return sprintf($filePattern, 'xx'); -} - -/** - * Return search engine URL by name - * - * @see core/DataFiles/SearchEnginges.php - * - * @param string $name - * @return string URL - */ -function getSearchEngineUrlFromName($name) -{ - $searchEngineNames = Common::getSearchEngineNames(); - if (isset($searchEngineNames[$name])) { - $url = 'http://' . $searchEngineNames[$name]; - } else { - $url = 'URL unknown!'; - } - return $url; -} - -/** - * Return search engine host in URL - * - * @param string $url - * @return string host - */ -function getSearchEngineHostFromUrl($url) -{ - if (strpos($url, '//')) { - $url = substr($url, strpos($url, '//') + 2); - } - if (($p = strpos($url, '/')) !== false) { - $url = substr($url, 0, $p); - } - return $url; -} - -/** - * Return search engine logo path by URL - * - * @param string $url - * @return string path - * @see plugins/Referrers/images/searchEnginges/ - */ -function getSearchEngineLogoFromUrl($url) -{ - $pathInPiwik = 'plugins/Referrers/images/searchEngines/%s.png'; - $pathWithCode = sprintf($pathInPiwik, getSearchEngineHostFromUrl($url)); - $absolutePath = PIWIK_INCLUDE_PATH . '/' . $pathWithCode; - if (file_exists($absolutePath)) { - return $pathWithCode; - } - return sprintf($pathInPiwik, 'xx'); -} - -/** - * Return search engine host and path in URL - * - * @param string $url - * @return string host - */ -function getSearchEngineHostPathFromUrl($url) -{ - $url = substr($url, strpos($url, '//') + 2); - return $url; -} - -/** - * Return search engine URL for URL and keyword - * - * @see core/DataFiles/SearchEnginges.php - * - * @param string $url Domain name, e.g., search.piwik.org - * @param string $keyword Keyword, e.g., web+analytics - * @return string URL, e.g., http://search.piwik.org/q=web+analytics - */ -function getSearchEngineUrlFromUrlAndKeyword($url, $keyword) -{ - if ($keyword === API::LABEL_KEYWORD_NOT_DEFINED) { - return 'http://piwik.org/faq/general/#faq_144'; - } - $searchEngineUrls = Common::getSearchEngineUrls(); - $keyword = urlencode($keyword); - $keyword = str_replace(urlencode('+'), urlencode(' '), $keyword); - $path = @$searchEngineUrls[getSearchEngineHostPathFromUrl($url)][2]; - if (empty($path)) { - return false; - } - $path = str_replace("{k}", $keyword, $path); - return $url . (substr($url, -1) != '/' ? '/' : '') . $path; -} - -/** - * Return search engine URL for keyword and URL - * - * @see \Piwik\Plugins\Referrers\getSearchEngineUrlFromUrlAndKeyword - * - * @param string $keyword Keyword, e.g., web+analytics - * @param string $url Domain name, e.g., search.piwik.org - * @return string URL, e.g., http://search.piwik.org/q=web+analytics - */ -function getSearchEngineUrlFromKeywordAndUrl($keyword, $url) -{ - return getSearchEngineUrlFromUrlAndKeyword($url, $keyword); -} - /** * Return translated referrer type * @@ -223,7 +35,6 @@ function getSearchEngineUrlFromKeywordAndUrl($keyword, $url) */ function getReferrerTypeLabel($label) { - $indexTranslation = ''; switch ($label) { case Common::REFERRER_TYPE_DIRECT_ENTRY: $indexTranslation = 'Referrers_DirectEntry'; diff --git a/plugins/Referrers/lang/cs.json b/plugins/Referrers/lang/cs.json index 740d25a38bcfa3ea547dd2978887ebb97421235e..052a054161bb1ede3f343ce1ad672fe4d23a865a 100644 --- a/plugins/Referrers/lang/cs.json +++ b/plugins/Referrers/lang/cs.json @@ -3,9 +3,9 @@ "AllReferrersReportDocumentation": "Toto hlášenà zobrazuje vÅ¡echny referrery v jednom uceleném hlášenÃ, kde zobrazuje vÅ¡echny webové stránky, klÃÄová slova a kampanÄ›, které vaÅ¡i návÅ¡tÄ›vnÃci pÅ™i hledánà vaÅ¡ich webových stránek použili.", "Campaigns": "KampanÄ›", "CampaignsDocumentation": "NávÅ¡tÄ›vnÃci, kteřà pÅ™iÅ¡li na vaÅ¡e webové stránky jako výsledek kampanÄ›. %s Pro vÃce informacà si prohlédnÄ›te hlášenà %s.", - "CampaignsReportDocumentation": "Toto hlášenà zobrazuje, jaké kampanÄ› pÅ™ivedly návÅ¡tÄ›vnÃky na vaÅ¡e stránky. %s Pro vÃce informacà o sledovánà kampanà si %spÅ™eÄtÄ›te dokumentaci kampanà na piwik.org%s.", + "CampaignsReportDocumentation": "Toto hlášenà zobrazuje, které kampanÄ› pÅ™ivedly návÅ¡tÄ›vnÃky na vaÅ¡e stránky. %s Pro vÃce informacà o sledovánà kampanà si %spÅ™eÄtÄ›te dokumentaci kampanà na piwik.org%s.", "ColumnCampaign": "Kampaň", - "ColumnSearchEngine": "Vyhledávacà stroj", + "ColumnSearchEngine": "VyhledávaÄ", "ColumnSocial": "Sociálnà sÃÅ¥", "ColumnWebsite": "Web stránky", "ColumnWebsitePage": "Web stránka", @@ -15,7 +15,7 @@ "DistinctCampaigns": "jedineÄné kampanÄ›", "DistinctKeywords": "jedineÄná klÃÄová slova", "DistinctSearchEngines": "jedineÄné vyhledávaÄe", - "DistinctWebsites": "jedineÄná weby", + "DistinctWebsites": "jedineÄné weby", "EvolutionDocumentation": "Toto je pÅ™ehled referrerů, které vedly návÅ¡tÄ›vnÃky na vaÅ¡e webové stránky.", "EvolutionDocumentationMoreInfo": "Pro vÃce informacà o rozdÃlných typech referrerů nahlédnÄ›te do dokumentace tabulky %s.", "Keywords": "KlÃÄová slova", @@ -26,13 +26,13 @@ "Referrers": "DoporuÄenÃ", "ReferrersOverview": "PÅ™ehled referrerů", "ReferrerTypes": "Typy referrerů", - "SearchEngines": "VyhledávacÃch strojů", + "SearchEngines": "VyhledávaÄe", "SearchEnginesDocumentation": "NávÅ¡tÄ›vnÃk byl na vaÅ¡e stránky odkázán vyhledávaÄem. %s Pro vÃce informacà si prohlédnÄ›te hlášenà %s.", "SearchEnginesReportDocumentation": "Toto hlášenà zobrazuje, které vyhledávaÄe odkázali návÅ¡tÄ›vnÃky na vaÅ¡e stránky. %s KliknutÃm na řádek v tabulce zobrazÃte, co uživatelé na daném vyhledávaÄi hledali.", - "SocialFooterMessage": "Toto je podmnožina hlášenà webových stránek zobrazeného vlevo. Filtruje ostatnà stránky, takže můžete pÅ™Ãmo porovnat referrery ze sociálnÃch sÃtÃ.", + "SocialFooterMessage": "Toto je podmnožina hlášenà zobrazeného vlevo. Filtruje ostatnà stránky, takže můžete pÅ™Ãmo porovnat referrery ze sociálnÃch sÃtÃ.", "Socials": "Sociálnà sÃtÄ›", "SocialsReportDocumentation": "Toto hlášenà zobrazuje, jaké sociálnà sÃtÄ› pÅ™ivedly návÅ¡tÄ›vnÃky na vaÅ¡e stránky. <br\/> KliknutÃm na KliknutÃm na řádek tabulky zobrazÃte stránky sociálnà sÃtÄ›, ze kterých návÅ¡tÄ›vnÃci pÅ™iÅ¡li.", - "SubmenuSearchEngines": "VyhledávaÄe & klÃÄová slova", + "SubmenuSearchEngines": "VyhledávaÄe a klÃÄová slova", "SubmenuWebsites": "Web", "Type": "Typ refereru", "TypeCampaigns": "%s z kampanÃ", diff --git a/plugins/Referrers/lang/ko.json b/plugins/Referrers/lang/ko.json index f5f309c895496470024be6a8d05c45ff9c5324d7..28c132386aac6bab278e4ac7cbadbdf125db003b 100644 --- a/plugins/Referrers/lang/ko.json +++ b/plugins/Referrers/lang/ko.json @@ -20,10 +20,12 @@ "EvolutionDocumentationMoreInfo": "다른 참조 ìœ í˜•ì— ëŒ€í•œ ìžì„¸í•œ ë‚´ìš©ì€ %s í…Œì´ë¸”ì˜ ë¬¸ì„œë¥¼ 참조하세요.", "Keywords": "검색어", "KeywordsReportDocumentation": "ì´ ë³´ê³ ì„œëŠ” 사용ìžê°€ 웹사ì´íŠ¸ë¥¼ 방문하는 ë° ì‚¬ìš©í•˜ëŠ” 검색어를 나타냅니다. %s í…Œì´ë¸”ì˜ í–‰ì„ í´ë¦í•˜ë©´ ê²€ìƒ‰ì–´ì— ì¡°íšŒëœ ê²€ìƒ‰ ì—”ì§„ì˜ ë¶„í¬ë¥¼ ë³¼ 수 있습니다.", + "PluginDescription": "리í¼í„° ë°ì´í„° ë³´ê³ ì„œ: 검색 엔진, 키워드, 웹사ì´íЏ, ìº íŽ˜ì¸, 소셜 미디어, ì§ì ‘ ìž…ë ¥", "Referrer": "리í¼ëŸ¬", "ReferrerName": "리í¼ëŸ¬ ì´ë¦„", "Referrers": "참조", "ReferrersOverview": "리í¼ëŸ¬ 개요", + "ReferrerTypes": "리í¼ëŸ¬ 타입", "SearchEngines": "검색엔진", "SearchEnginesDocumentation": "검색 ì—”ì§„ì„ ì°¸ì¡°í•˜ì—¬ 웹사ì´íŠ¸ë¡œ ì ‘ì†í•œ 방문ìžìž…니다. ìƒì„¸ ë³´ê³ ì„œëŠ” %s 여기 %sì— ìžˆìŠµë‹ˆë‹¤.", "SearchEnginesReportDocumentation": "ì´ ë³´ê³ ì„œëŠ” ì–´ë–¤ 검색 엔진으로 웹사ì´íŠ¸ì— ì‚¬ìš©ìžê°€ ìœ ìž…ë˜ì—ˆëŠ” 지를 ë³´ì—¬ì¤ë‹ˆë‹¤. %s í…Œì´ë¸”ì˜ í–‰ì„ í´ë¦í•˜ë©´ 사용ìžê°€ íŠ¹ì • 검색 ì—”ì§„ì„ ì‚¬ìš©í•˜ì—¬ ë¬´ì—‡ì„ ì°¾ê³ ìžˆì—ˆëŠ”ì§€ë¥¼ 확ì¸í• 수 있습니다.", @@ -47,6 +49,7 @@ "WidgetExternalWebsites": "외부 웹사ì´íЏ 목ë¡", "WidgetGetAll": "ëª¨ë“ ë¦¬í¼ëŸ¬", "WidgetSocials": "소셜 네트워í¬ì˜ 목ë¡", - "WidgetTopKeywordsForPages": "패지 URLì˜ ìƒìœ„ 키워드" + "WidgetTopKeywordsForPages": "패지 URLì˜ ìƒìœ„ 키워드", + "XPercentOfVisits": "%s 번" } } \ No newline at end of file diff --git a/plugins/Referrers/tests/Integration/Columns/ReferrerNameTest.php b/plugins/Referrers/tests/Integration/Columns/ReferrerNameTest.php new file mode 100644 index 0000000000000000000000000000000000000000..db34a25c46cfc5b57547cdbae0be39bb2a8e1bdc --- /dev/null +++ b/plugins/Referrers/tests/Integration/Columns/ReferrerNameTest.php @@ -0,0 +1,130 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\Referrers\tests\Integration\Columns; + +use Piwik\Common; +use Piwik\Plugins\Referrers\Columns\ReferrerName; +use Piwik\Plugins\Referrers\Columns\ReferrerType; +use Piwik\Tests\Framework\Fixture; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; +use Piwik\Tracker\Cache; +use Piwik\Tracker\Request; +use Piwik\Tracker\Visit\VisitProperties; +use Piwik\Tracker\Visitor; + +/** + * @group Referrers + * @group ReferrerNameTest + * @group ReferrerName + * @group Plugins + */ +class ReferrerNameTest extends IntegrationTestCase +{ + /** + * @var ReferrerType + */ + private $referrerName; + private $idSite1 = 1; + private $idSite2 = 2; + private $idSite3 = 3; + + public function setUp() + { + parent::setUp(); + + Cache::clearCacheGeneral(); + + $date = '2012-01-01 00:00:00'; + $ecommerce = false; + + Fixture::createWebsite($date, $ecommerce, $name = 'test1', $url = 'http://piwik.org/foo/bar'); + Fixture::createWebsite($date, $ecommerce, $name = 'test2', $url = 'http://piwik.org/'); + Fixture::createWebsite($date, $ecommerce, $name = 'test3', $url = 'http://piwik.pro/'); + + $this->referrerName = new ReferrerName(); + } + + public function tearDown() + { + // clean up your test here if needed + Cache::clearCacheGeneral(); + + parent::tearDown(); + } + + /** + * @dataProvider getReferrerUrls + */ + public function test_onNewVisit_shouldDetectCorrectReferrerType($expectedType, $idSite, $url, $referrerUrl) + { + $request = $this->getRequest(array('idsite' => $idSite, 'url' => $url, 'urlref' => $referrerUrl)); + $type = $this->referrerName->onNewVisit($request, $this->getNewVisitor(), $action = null); + + $this->assertSame($expectedType, $type); + } + + public function getReferrerUrls() + { + $url = 'http://piwik.org/foo/bar'; + $referrer = 'http://piwik.org'; + + $directEntryReferrerName = ''; + + return array( + // domain matches but path does not match for idsite1 + array('piwik.org', $this->idSite1, $url, $referrer), + array('piwik.org', $this->idSite1, $url, $referrer . '/'), + // idSite2 matches any piwik.org path so this is a direct entry for it + array($directEntryReferrerName, $this->idSite2, $url, $referrer), + array($directEntryReferrerName, $this->idSite2, $url, $referrer . '/'), + // idSite3 has different domain so it is coming from different website + array('piwik.org', $this->idSite3, $url, $referrer), + array('piwik.org', $this->idSite3, $url, $referrer . '/'), + + array($directEntryReferrerName, $this->idSite1, $url, $referrer . '/foo/bar/baz'), + array($directEntryReferrerName, $this->idSite1, $url, $referrer . '/foo/bar/baz/'), + array($directEntryReferrerName, $this->idSite1, $url, $referrer . '/foo/bar/baz?x=5'), + array($directEntryReferrerName, $this->idSite1, $url, $referrer . '/fOo/BaR/baz?x=5'), + // /not/xyz belongs to different website + array('piwik.org', $this->idSite1, $url, $referrer . '/not/xyz'), + array($directEntryReferrerName, $this->idSite2, $url, $referrer . '/not/xyz'), + + // /foo/bar/baz belongs to different website + array('piwik.org/foo/bar', $this->idSite2, $url, $referrer . '/foo/bar/baz'), + array('piwik.org/foo/bar', $this->idSite3, $url, $referrer . '/foo/bar'), + array('piwik.org/foo/bar', $this->idSite3, $url, $referrer . '/fOo/BaR'), + + // should detect campaign independent of domain / path + array('test', $this->idSite1, $url . '?pk_campaign=test', $referrer), + array('testfoobar', $this->idSite2, $url . '?pk_campaign=testfoobar', $referrer), + array('test', $this->idSite3, $url . '?pk_campaign=test', $referrer), + + array('Google', $this->idSite3, $url, 'http://google.com/search?q=piwik'), + + // testing case for backwards compatibility where url has same domain as urlref but the domain is not known to any website + array($directEntryReferrerName, $this->idSite3, 'http://example.com/foo', 'http://example.com/bar'), + array($directEntryReferrerName, $this->idSite3, 'http://example.com/foo', 'http://example.com'), + array($directEntryReferrerName, $this->idSite3, 'http://example.com', 'http://example.com/bar'), + + // testing case where domain of referrer is not known to any site but neither is the URL, url != urlref + array('example.com', $this->idSite3, 'http://example.org', 'http://example.com/bar'), + ); + } + + private function getRequest($params) + { + return new Request($params); + } + + private function getNewVisitor() + { + return new Visitor(new VisitProperties()); + } + +} diff --git a/plugins/Referrers/tests/Integration/Columns/ReferrerTypeTest.php b/plugins/Referrers/tests/Integration/Columns/ReferrerTypeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5925dbc5c0a3ef5096bdda81d69b1bdc1164b0df --- /dev/null +++ b/plugins/Referrers/tests/Integration/Columns/ReferrerTypeTest.php @@ -0,0 +1,128 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\Referrers\tests\Integration\Columns; + +use Piwik\Common; +use Piwik\Plugins\Referrers\Columns\ReferrerType; +use Piwik\Tests\Framework\Fixture; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; +use Piwik\Tracker\Cache; +use Piwik\Tracker\Request; +use Piwik\Tracker\Visit\VisitProperties; +use Piwik\Tracker\Visitor; + +/** + * @group Referrers + * @group ReferrerTypeTest + * @group ReferrerType + * @group Plugins + */ +class ReferrerTypeTest extends IntegrationTestCase +{ + /** + * @var ReferrerType + */ + private $referrerType; + private $idSite1 = 1; + private $idSite2 = 2; + private $idSite3 = 3; + + public function setUp() + { + parent::setUp(); + + Cache::clearCacheGeneral(); + + $date = '2012-01-01 00:00:00'; + $ecommerce = false; + + Fixture::createWebsite($date, $ecommerce, $name = 'test1', $url = 'http://piwik.org/foo/bar'); + Fixture::createWebsite($date, $ecommerce, $name = 'test2', $url = 'http://piwik.org/'); + Fixture::createWebsite($date, $ecommerce, $name = 'test3', $url = 'http://piwik.pro/'); + + $this->referrerType = new ReferrerType(); + } + + public function tearDown() + { + // clean up your test here if needed + Cache::clearCacheGeneral(); + + parent::tearDown(); + } + + /** + * @dataProvider getReferrerUrls + */ + public function test_onNewVisit_shouldDetectCorrectReferrerType($expectedType, $idSite, $url, $referrerUrl) + { + $request = $this->getRequest(array('idsite' => $idSite, 'url' => $url, 'urlref' => $referrerUrl)); + $type = $this->referrerType->onNewVisit($request, $this->getNewVisitor(), $action = null); + + $this->assertSame($expectedType, $type); + } + + public function getReferrerUrls() + { + $url = 'http://piwik.org/foo/bar'; + $referrer = 'http://piwik.org'; + + // $expectedType, $idSite, $url, $referrerUrl + return array( + // domain matches but path does not match for idsite1 + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite1, $url, $referrer), + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite1, $url, $referrer . '/'), + // idSite2 matches any piwik.org path so this is a direct entry for it + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite2, $url, $referrer), + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite2, $url, $referrer . '/'), + // idSite3 has different domain so it is coming from different website + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, $url, $referrer), + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, $url, $referrer . '/'), + + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite1, $url, $referrer . '/foo/bar/baz'), + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite1, $url, $referrer . '/foo/bar/baz/'), + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite1, $url, $referrer . '/foo/bar/baz?x=5'), + // /not/xyz belongs to different website + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite1, $url, $referrer . '/not/xyz'), + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite2, $url, $referrer . '/not/xyz'), + + // /foo/bar/baz belongs to different website + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite2, $url, $referrer . '/foo/bar/baz'), + + // website as it is from different domain anyway + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, $url, $referrer . '/foo/bar/baz'), + + // should detect campaign independent of domain / path + array(Common::REFERRER_TYPE_CAMPAIGN, $this->idSite1, $url . '?pk_campaign=test', $referrer), + array(Common::REFERRER_TYPE_CAMPAIGN, $this->idSite2, $url . '?pk_campaign=test', $referrer), + array(Common::REFERRER_TYPE_CAMPAIGN, $this->idSite3, $url . '?pk_campaign=test', $referrer), + + array(Common::REFERRER_TYPE_SEARCH_ENGINE, $this->idSite3, $url, 'http://google.com/search?q=piwik'), + + // testing case for backwards compatibility where url has same domain as urlref but the domain is not known to any website + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite3, 'http://example.com/foo', 'http://example.com/bar'), + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite3, 'http://example.com/foo', 'http://example.com'), + array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite3, 'http://example.com', 'http://example.com/bar'), + + // testing case where domain of referrer is not known to any site but neither is the URL, url != urlref + array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, 'http://example.org', 'http://example.com/bar'), + ); + } + + private function getRequest($params) + { + return new Request($params); + } + + private function getNewVisitor() + { + return new Visitor(new VisitProperties()); + } + +} diff --git a/plugins/Referrers/tests/System/expected/test_Referrers_getReferrerType__API.getProcessedReport_day.xml b/plugins/Referrers/tests/System/expected/test_Referrers_getReferrerType__API.getProcessedReport_day.xml index edc1bd40ffbb221a650009e23e2edb633604c786..58601dc41be0f5aee04abb3fab8c889415910d49 100644 --- a/plugins/Referrers/tests/System/expected/test_Referrers_getReferrerType__API.getProcessedReport_day.xml +++ b/plugins/Referrers/tests/System/expected/test_Referrers_getReferrerType__API.getProcessedReport_day.xml @@ -874,7 +874,7 @@ <result prettyDate="Tuesday, February 2, 2010"/> <result prettyDate="Wednesday, February 3, 2010"/> <result prettyDate="Thursday, February 4, 2010"> - <row> + <row> <idsubdatatable>2</idsubdatatable> </row> <row> diff --git a/plugins/Referrers/tests/Unit/ReferrersTest.php b/plugins/Referrers/tests/Unit/ReferrersTest.php index 909e6bf65e60cc6edb244be1eb4dcfbcbb01368f..e5dea866e90bc4fa1d3266aefdf5aa592c397364 100644 --- a/plugins/Referrers/tests/Unit/ReferrersTest.php +++ b/plugins/Referrers/tests/Unit/ReferrersTest.php @@ -11,217 +11,15 @@ namespace Piwik\Plugins\Referrers\tests; use Piwik\DataTable; use Piwik\DataTable\Row; use Piwik\Period; +use Piwik\Plugins\Referrers\SearchEngine; require_once PIWIK_INCLUDE_PATH . '/plugins/Referrers/Referrers.php'; +/** + * @group Plugin + */ class ReferrersTest extends \PHPUnit_Framework_TestCase { - /** - * Dataprovider serving all search engine data - */ - public function getSearchEngines() - { - include PIWIK_PATH_TEST_TO_ROOT . '/core/DataFiles/SearchEngines.php'; - - $searchEngines = array(); - foreach ($GLOBALS['Piwik_SearchEngines'] as $url => $searchEngine) { - $searchEngines[] = array($url, $searchEngine); - } - return $searchEngines; - } - - /** - * search engine has at least one keyword - * - * @group Plugins - * - * @dataProvider getSearchEngines - */ - public function testMissingSearchEngineKeyword($url, $searchEngine) - { - // Get list of search engines and first appearing URL - static $searchEngines = array(); - - $name = parse_url('http://' . $url); - if (!array_key_exists($searchEngine[0], $searchEngines)) { - $searchEngines[$searchEngine[0]] = $url; - - $this->assertTrue(!empty($searchEngine[1]), $name['host']); - } - } - - /** - * search engine is defined in DataFiles/SearchEngines.php but there's no favicon - * - * @group Plugins - * - * @dataProvider getSearchEngines - */ - public function testMissingSearchEngineIcons($url, $searchEngine) - { - // Get list of existing favicons - $favicons = scandir(PIWIK_PATH_TEST_TO_ROOT . '/plugins/Referrers/images/searchEngines/'); - - // Get list of search engines and first appearing URL - static $searchEngines = array(); - - $name = parse_url('http://' . $url); - if (!array_key_exists($searchEngine[0], $searchEngines)) { - $searchEngines[$searchEngine[0]] = $url; - - $this->assertTrue(in_array($name['host'] . '.png', $favicons), $name['host']); - } - } - - /** - * favicon exists but there's no corresponding search engine defined in DataFiles/SearchEngines.php - * - * @group Plugins - */ - public function testObsoleteSearchEngineIcons() - { - include PIWIK_PATH_TEST_TO_ROOT . '/core/DataFiles/SearchEngines.php'; - - // Get list of search engines and first appearing URL - $searchEngines = array(); - foreach ($GLOBALS['Piwik_SearchEngines'] as $url => $searchEngine) { - $name = parse_url('http://' . $url); - if (!array_key_exists($name['host'], $searchEngines)) { - $searchEngines[$name['host']] = true; - } - } - - // Get list of existing favicons - $favicons = scandir(PIWIK_PATH_TEST_TO_ROOT . '/plugins/Referrers/images/searchEngines/'); - foreach ($favicons as $name) { - if ($name[0] == '.' || strpos($name, 'xx.') === 0) { - continue; - } - - $host = substr($name, 0, -4); - $this->assertTrue(array_key_exists($host, $searchEngines), $host); - } - } - - /** - * get search engine host from url - * - * @group Plugins - */ - public function testGetSearchEngineHostFromUrl() - { - $data = array( - 'http://www.google.com/cse' => array('www.google.com', 'www.google.com/cse'), - 'http://www.google.com' => array('www.google.com', 'www.google.com'), - ); - - foreach ($data as $url => $expected) { - $this->assertEquals($expected[0], \Piwik\Plugins\Referrers\getSearchEngineHostFromUrl($url)); - $this->assertEquals($expected[1], \Piwik\Plugins\Referrers\getSearchEngineHostPathFromUrl($url)); - } - } - - /** - * Dataprovider for testGetSearchEngineUrlFromUrlAndKeyword - */ - public function getSearchEngineUrlFromUrlAndKeywordTestData() - { - return array( - array('http://apollo.lv/portal/search/', 'piwik', 'http://apollo.lv/portal/search/?cof=FORID%3A11&q=piwik&search_where=www'), - array('http://bing.com/images/search', 'piwik', 'http://bing.com/images/search/?q=piwik'), - array('http://google.com', 'piwik', 'http://google.com/search?q=piwik'), - ); - } - - /** - * get search engine url from name and keyword - * - * @group Plugins - * - * @dataProvider getSearchEngineUrlFromUrlAndKeywordTestData - */ - public function testGetSearchEngineUrlFromUrlAndKeyword($url, $keyword, $expected) - { - include PIWIK_PATH_TEST_TO_ROOT . '/core/DataFiles/SearchEngines.php'; - $this->assertEquals($expected, \Piwik\Plugins\Referrers\getSearchEngineUrlFromUrlAndKeyword($url, $keyword)); - } - - /** - * Dataprovider for getSocialNetworkFromDomainTestData - */ - public function getSocialNetworkFromDomainTestData() - { - return array( - array('http://www.facebook.com', 'Facebook'), - array('http://www.facebook.com/piwik', 'Facebook'), - array('http://m.facebook.com', 'Facebook'), - array('https://m.facebook.com', 'Facebook'), - array('m.facebook.com', 'Facebook'), - array('http://lastfm.com.tr', 'Last.fm'), - array('http://t.co/test', 'Twitter'), - array('http://xxt.co/test', \Piwik\Piwik::translate('General_Unknown')), - array('asdfasdfadsf.com', \Piwik\Piwik::translate('General_Unknown')), - array('http://xwayn.com', \Piwik\Piwik::translate('General_Unknown')), - array('http://live.com/test', \Piwik\Piwik::translate('General_Unknown')), - ); - } - - /** - * @group Plugins - * - * @dataProvider getSocialNetworkFromDomainTestData - */ - public function testGetSocialNetworkFromDomain($url, $expected) - { - include PIWIK_INCLUDE_PATH . '/core/DataFiles/Socials.php'; - $this->assertEquals($expected, \Piwik\Plugins\Referrers\getSocialNetworkFromDomain($url)); - } - - public function getSocialsLogoFromUrlTestData() - { - return array( - array('http://www.facebook.com', 'facebook.com.png'), - array('www.facebook.com', 'facebook.com.png',), - array('http://lastfm.com.tr', 'last.fm.png'), - array('http://asdfasdf.org/test', 'xx.png'), - array('http://www.google.com', 'xx.png'), - ); - } - - /** - * @group Plugins - * - * @dataProvider getSocialsLogoFromUrlTestData - */ - public function testGetSocialsLogoFromUrl($url, $expected) - { - include PIWIK_INCLUDE_PATH . '/core/DataFiles/Socials.php'; - $this->assertContains($expected, \Piwik\Plugins\Referrers\getSocialsLogoFromUrl($url)); - } - - public function isSocialUrlTestData() - { - return array( - array('http://www.facebook.com', 'Facebook', true), - array('http://www.facebook.com', 'Twitter', false), - array('http://m.facebook.com', false, true), - array('http://lastfm.com.tr', 'Last.fm', true), - array('http://asdfasdf.org/test', false, false), - array('http://asdfasdf.com/test', 'Facebook', false), - ); - } - - /** - * @group Plugins - * - * @dataProvider isSocialUrlTestData - */ - public function testIsSocialUrl($url, $assumedSocial, $expected) - { - include PIWIK_INCLUDE_PATH . '/core/DataFiles/Socials.php'; - $this->assertEquals($expected, \Piwik\Plugins\Referrers\isSocialUrl($url, $assumedSocial)); - } - public function removeUrlProtocolTestData() { return array( diff --git a/plugins/Referrers/tests/Unit/SearchEngineTest.php b/plugins/Referrers/tests/Unit/SearchEngineTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e9f0c926ea4cc068018c6de5ea379eedd1e3b5df --- /dev/null +++ b/plugins/Referrers/tests/Unit/SearchEngineTest.php @@ -0,0 +1,173 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\Referrers\tests; + +use Piwik\Plugins\Referrers\SearchEngine; +use Spyc; + +/** + * @group SearchEngine + */ +class SearchEngineTest extends \PHPUnit_Framework_TestCase +{ + public static function setUpBeforeClass() + { + // inject definitions to avoid database usage + $yml = file_get_contents(PIWIK_PATH_TEST_TO_ROOT . SearchEngine::DEFINITION_FILE); + SearchEngine::getInstance()->loadYmlData($yml); + parent::setUpBeforeClass(); + } + + public function getSearchEngineUrls() + { + return Spyc::YAMLLoad(PIWIK_PATH_TEST_TO_ROOT .'/tests/resources/extractSearchEngineInformationFromUrlTests.yml'); + } + + /** + * @dataProvider getSearchEngineUrls + */ + public function testExtractInformationFromUrl($url, $engine, $keywords) + { + $returnedValue = SearchEngine::getInstance()->extractInformationFromUrl($url); + + $expectedValue = false; + + if (!empty($engine)) { + $expectedValue = array('name' => $engine, 'keywords' => $keywords); + } + + $this->assertEquals($expectedValue, $returnedValue); + } + + public function testSearchEnginesDefinedCorrectly() + { + $searchEngines = array(); + foreach (SearchEngine::getInstance()->getDefinitions() as $host => $info) { + if (isset($info['backlink']) && $info['backlink'] !== false) { + $this->assertTrue(strrpos($info['backlink'], "{k}") !== false, $host . " search URL is not defined correctly, must contain the macro {k}"); + } + + if (!array_key_exists($info['name'], $searchEngines)) { + $searchEngines[$info['name']] = true; + + $this->assertTrue(strpos($host, '{}') === false, $host . " search URL is the master record and should not contain {}"); + } + + if (isset($info['charsets']) && $info['charsets'] !== false) { + $this->assertTrue(is_array($info['charsets']) || is_string($info['charsets']), $host . ' charsets must be either a string or an array'); + + if (is_string($info['charsets'])) { + $this->assertTrue(trim($info['charsets']) !== '', $host . ' charsets cannot be an empty string'); + $this->assertTrue(strpos($info['charsets'], ' ') === false, $host . ' charsets cannot contain spaces'); + + } + + if (is_array($info['charsets'])) { + $this->assertTrue(count($info['charsets']) > 0, $host . ' charsets cannot be an empty array'); + $this->assertTrue(strpos(serialize($info['charsets']), '""') === false, $host . ' charsets in array cannot be empty stringss'); + $this->assertTrue(strpos(serialize($info['charsets']), ' ') === false, $host . ' charsets in array cannot contain spaces'); + } + } + } + } + + /** + * Dataprovider for testGetBackLinkFromUrlAndKeyword + */ + public function getBackLinkFromUrlAndKeywordTestData() + { + return array( + array('http://apollo.lv/portal/search/', 'piwik', 'http://apollo.lv/portal/search/?cof=FORID%3A11&q=piwik&search_where=www'), + array('http://bing.com/images/search', 'piwik', 'http://bing.com/images/search/?q=piwik'), + array('http://google.com', 'piwik', 'http://google.com/search?q=piwik'), + ); + } + + /** + * get search engine url from name and keyword + * + * @dataProvider getBackLinkFromUrlAndKeywordTestData + */ + public function testGetBackLinkFromUrlAndKeyword($url, $keyword, $expected) + { + $this->assertEquals($expected, SearchEngine::getInstance()->getBackLinkFromUrlAndKeyword($url, $keyword)); + } + + /** + * Dataprovider serving all search engine data + */ + public function getAllSearchEngines() + { + $yml = file_get_contents(PIWIK_PATH_TEST_TO_ROOT . SearchEngine::DEFINITION_FILE); + SearchEngine::getInstance()->loadYmlData($yml); + $searchEngines = array(); + foreach (SearchEngine::getInstance()->getDefinitions() as $url => $searchEngine) { + $searchEngines[] = array($url, $searchEngine); + } + return $searchEngines; + } + + /** + * search engine has at least one keyword + * + * @dataProvider getAllSearchEngines + */ + public function testMissingSearchEngineKeyword($url, $searchEngine) + { + $name = parse_url('http://' . $url); + $this->assertTrue(!empty($searchEngine['params']), $name['host']); + } + + /** + * search engine is defined but there's no favicon + * + * @dataProvider getAllSearchEngines + */ + public function testMissingSearchEngineIcons($url, $searchEngine) + { + // Get list of existing favicons + $favicons = scandir(PIWIK_PATH_TEST_TO_ROOT . '/plugins/Referrers/images/searchEngines/'); + + // Get list of search engines and first appearing URL + static $searchEngines = array(); + + $name = parse_url('http://' . $url); + if (!array_key_exists($searchEngine['name'], $searchEngines)) { + $searchEngines[$searchEngine['name']] = $url; + + $this->assertTrue(in_array($name['host'] . '.png', $favicons), $name['host']); + } + } + + /** + * favicon exists but there's no corresponding search engine defined + */ + public function testObsoleteSearchEngineIcons() + { + // Get list of search engines and first appearing URL + $searchEngines = array(); + foreach (SearchEngine::getInstance()->getDefinitions() as $url => $searchEngine) { + $name = parse_url('http://' . $url); + if (!array_key_exists($name['host'], $searchEngines)) { + $searchEngines[$name['host']] = true; + } + } + + // Get list of existing favicons + $favicons = scandir(PIWIK_PATH_TEST_TO_ROOT . '/plugins/Referrers/images/searchEngines/'); + foreach ($favicons as $name) { + if ($name[0] == '.' || strpos($name, 'xx.') === 0) { + continue; + } + + $host = substr($name, 0, -4); + $this->assertTrue(array_key_exists($host, $searchEngines), $host); + } + } +} \ No newline at end of file diff --git a/plugins/Referrers/tests/Unit/SocialTest.php b/plugins/Referrers/tests/Unit/SocialTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8e8f35e0f9ac7217f353c7a96d688a715a4332a8 --- /dev/null +++ b/plugins/Referrers/tests/Unit/SocialTest.php @@ -0,0 +1,97 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\Referrers\tests; + +use Piwik\Plugins\Referrers\Social; +use Spyc; + +/** + * @group Social + * @group Plugins + */ +class SocialTest extends \PHPUnit_Framework_TestCase +{ + public static function setUpBeforeClass() + { + // inject definitions to avoid database usage + $yml = file_get_contents(PIWIK_PATH_TEST_TO_ROOT . Social::DEFINITION_FILE); + Social::getInstance()->loadYmlData($yml); + parent::setUpBeforeClass(); + } + + public function isSocialUrlTestData() + { + return array( + array('http://www.facebook.com', 'Facebook', true), + array('http://www.facebook.com', 'Twitter', false), + array('http://m.facebook.com', false, true), + array('http://lastfm.com.tr', 'Last.fm', true), + array('http://asdfasdf.org/test', false, false), + array('http://asdfasdf.com/test', 'Facebook', false), + ); + } + + /** + * @dataProvider isSocialUrlTestData + */ + public function testIsSocialUrl($url, $assumedSocial, $expected) + { + $this->assertEquals($expected, Social::getInstance()->isSocialUrl($url, $assumedSocial)); + } + + + /** + * Dataprovider for getSocialNetworkFromDomainTestData + */ + public function getSocialNetworkFromDomainTestData() + { + return array( + array('http://www.facebook.com', 'Facebook'), + array('http://www.facebook.com/piwik', 'Facebook'), + array('http://m.facebook.com', 'Facebook'), + array('https://m.facebook.com', 'Facebook'), + array('m.facebook.com', 'Facebook'), + array('http://lastfm.com.tr', 'Last.fm'), + array('http://t.co/test', 'Twitter'), + array('http://xxt.co/test', \Piwik\Piwik::translate('General_Unknown')), + array('asdfasdfadsf.com', \Piwik\Piwik::translate('General_Unknown')), + array('http://xwayn.com', \Piwik\Piwik::translate('General_Unknown')), + array('http://live.com/test', \Piwik\Piwik::translate('General_Unknown')), + ); + } + + /** + * @dataProvider getSocialNetworkFromDomainTestData + */ + public function testGetSocialNetworkFromDomain($url, $expected) + { + $this->assertEquals($expected, Social::getInstance()->getSocialNetworkFromDomain($url)); + } + + public function getLogoFromUrlTestData() + { + return array( + array('http://www.facebook.com', 'facebook.com.png'), + array('www.facebook.com', 'facebook.com.png',), + array('http://lastfm.com.tr', 'last.fm.png'), + array('http://asdfasdf.org/test', 'xx.png'), + array('http://www.google.com', 'xx.png'), + ); + } + + /** + * @group Plugins + * + * @dataProvider getLogoFromUrlTestData + */ + public function testGetLogoFromUrl($url, $expected) + { + $this->assertContains($expected, Social::getInstance()->getLogoFromUrl($url)); + } +} \ No newline at end of file diff --git a/plugins/Resolution/lang/ko.json b/plugins/Resolution/lang/ko.json index d76113b7af88ff073dd7c9301833701ea6de2dba..19be5c511dba6a638d88d29fc00532684e0ff122 100644 --- a/plugins/Resolution/lang/ko.json +++ b/plugins/Resolution/lang/ko.json @@ -3,6 +3,7 @@ "ColumnConfiguration": "구성", "ColumnResolution": "í•´ìƒë„", "Configurations": "구성", + "PluginDescription": "방문ìžì˜ 화면 í•´ìƒë„를 기ë¡\/ë³´ê³ í•©ë‹ˆë‹¤.", "Resolutions": "í•´ìƒë„", "WidgetGlobalVisitors": "글로벌 ë°©ë¬¸ìž êµ¬ì„±", "WidgetGlobalVisitorsDocumentation": "방문ìžì˜ 가장 ì¼ë°˜ì ì¸ ì‚¬ìš© í™˜ê²½ì— ëŒ€í•œ ë³´ê³ ì„œìž…ë‹ˆë‹¤. ìš´ì˜ ì²´ì œ, 브ë¼ìš°ì € 종류와 화면 í•´ìƒë„ì˜ ì¡°í•©ìœ¼ë¡œ 표시합니다.", diff --git a/plugins/SEO/Metric/Alexa.php b/plugins/SEO/Metric/Alexa.php index 87c5785d366f23111338a8ccacfc8a8bf97350c1..e8f795624139505ddb06ac2cac2453bf6e1bf4ec 100644 --- a/plugins/SEO/Metric/Alexa.php +++ b/plugins/SEO/Metric/Alexa.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\SEO\Metric; use Piwik\Http; use Piwik\NumberFormatter; +use Piwik\Plugins\Referrers\SearchEngine; use Psr\Log\LoggerInterface; /** @@ -42,7 +43,7 @@ class Alexa implements MetricsProvider $value = null; } - $logo = \Piwik\Plugins\Referrers\getSearchEngineLogoFromUrl('http://alexa.com'); + $logo = SearchEngine::getInstance()->getLogoFromUrl('http://alexa.com'); $link = self::LINK . urlencode($domain); return array( diff --git a/plugins/SEO/Metric/Bing.php b/plugins/SEO/Metric/Bing.php index e85d585c132740d25193d20bdd64d91a590f37d8..71553ffc6ea46761e8e5e8fb2d7f967e922b11e7 100644 --- a/plugins/SEO/Metric/Bing.php +++ b/plugins/SEO/Metric/Bing.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\SEO\Metric; use Piwik\Http; use Piwik\NumberFormatter; +use Piwik\Plugins\Referrers\SearchEngine; use Psr\Log\LoggerInterface; /** @@ -46,7 +47,7 @@ class Bing implements MetricsProvider $pageCount = null; } - $logo = \Piwik\Plugins\Referrers\getSearchEngineLogoFromUrl('http://bing.com'); + $logo = SearchEngine::getInstance()->getLogoFromUrl('http://bing.com'); return array( new Metric('bing-index', 'SEO_Bing_IndexedPages', $pageCount, $logo, null, null, 'General_Pages') diff --git a/plugins/SEO/Metric/Dmoz.php b/plugins/SEO/Metric/Dmoz.php index d21be1e5ca3cbade46c702e8bb288805e01bf8c0..c7b8860a892f7fa8d0dd6b0256ca48b58e51abc4 100644 --- a/plugins/SEO/Metric/Dmoz.php +++ b/plugins/SEO/Metric/Dmoz.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\SEO\Metric; use Piwik\Http; use Piwik\NumberFormatter; +use Piwik\Plugins\Referrers\SearchEngine; use Psr\Log\LoggerInterface; /** @@ -53,7 +54,7 @@ class Dmoz implements MetricsProvider $value = null; } - $logo = \Piwik\Plugins\Referrers\getSearchEngineLogoFromUrl('http://dmoz.org'); + $logo = SearchEngine::getInstance()->getLogoFromUrl('http://dmoz.org'); return array( new Metric('dmoz', 'SEO_Dmoz', $value, $logo) diff --git a/plugins/SEO/Metric/Google.php b/plugins/SEO/Metric/Google.php index cec1d96af946d4ba6f1820865c552004450320c0..7abd82b371c775ed3ca0bc7ea8516ed7bff73e66 100644 --- a/plugins/SEO/Metric/Google.php +++ b/plugins/SEO/Metric/Google.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\SEO\Metric; use Piwik\Http; use Piwik\NumberFormatter; +use Piwik\Plugins\Referrers\SearchEngine; use Psr\Log\LoggerInterface; /** @@ -37,7 +38,7 @@ class Google implements MetricsProvider $pageCount = $this->fetchIndexedPagesCount($domain); $pageRank = $this->fetchPageRank($domain); - $logo = \Piwik\Plugins\Referrers\getSearchEngineLogoFromUrl('http://google.com'); + $logo = SearchEngine::getInstance()->getLogoFromUrl('http://google.com'); return array( new Metric('google-index', 'SEO_Google_IndexedPages', $pageCount, $logo, null, null, 'General_Pages'), diff --git a/plugins/SEO/lang/ja.json b/plugins/SEO/lang/ja.json index e0496470df8404d5c9d300bfab86c840198b95a4..e4459709a2dd3fd4c2916c43fd084527886f5ea7 100644 --- a/plugins/SEO/lang/ja.json +++ b/plugins/SEO/lang/ja.json @@ -1,5 +1,6 @@ { "SEO": { + "PluginDescription": "ã“ã®ãƒ—ラグイン㯠SEO メトリクスを抽出ã—ã€è¡¨ç¤ºã—ã¾ã™ã€‚: Alexa web ランã‚ング, Google ページランク,インデックスã•れãŸãƒšãƒ¼ã‚¸æ•°ã‚„ãƒãƒƒã‚¯ãƒªãƒ³ã‚¯ã®æ•°ã€‚", "AlexaRank": "Alexa ランク", "Bing_IndexedPages": "Bing インデックスページ", "Dmoz": "DMOZ エントリー", diff --git a/plugins/SEO/lang/ko.json b/plugins/SEO/lang/ko.json index 55f71074cb5e7fee6e3dba22f3e477dc07f04102..de4e2b2bd62bd5b7cf76c496aab1bf7fbc76036f 100644 --- a/plugins/SEO/lang/ko.json +++ b/plugins/SEO/lang/ko.json @@ -1,5 +1,6 @@ { "SEO": { + "PluginDescription": "ì´ í”ŒëŸ¬ê·¸ì¸ì€ Alexa 웹 ëží‚¹, 구글 페ì´ì§€ëží¬, 색ì¸ëœ 페ì´ì§€ 수, ì„ íƒëœ 웹사ì´íŠ¸ì˜ ë°±ë§í¬ì™€ ê°™ì€ SEO ì¸¡ì • ê¸°ì¤€ì„ ì¶”ì¶œí•˜ê³ ë³´ì—¬ì¤ë‹ˆë‹¤.", "AlexaRank": "Alexa ëží¬", "Bing_IndexedPages": "Bingì— ìƒ‰ì¸ëœ 페ì´ì§€", "Dmoz": "DMOZ í•목", diff --git a/plugins/ScheduledReports/config/tcpdf_config.php b/plugins/ScheduledReports/config/tcpdf_config.php index 0fd19a1232401d3c291a061056cdf35df4520870..26b33b7da72066183b125f82a1b73cd9ef66473d 100644 --- a/plugins/ScheduledReports/config/tcpdf_config.php +++ b/plugins/ScheduledReports/config/tcpdf_config.php @@ -13,7 +13,7 @@ use Piwik\Container\StaticContainer; * */ -define('K_PATH_MAIN', PIWIK_VENDOR_PATH . '/tecnick.com/tcpdf/'); +define('K_PATH_MAIN', PIWIK_VENDOR_PATH . '/tecnickcom/tcpdf/'); $pathTmpTCPDF = StaticContainer::get('path.tmp') . '/tcpdf/'; diff --git a/plugins/ScheduledReports/lang/cs.json b/plugins/ScheduledReports/lang/cs.json index 836eb47133deeda2e101c726fc384ac61cbc78fb..caa1cb992e4066ffef44746424f64df62ff7340c 100644 --- a/plugins/ScheduledReports/lang/cs.json +++ b/plugins/ScheduledReports/lang/cs.json @@ -4,7 +4,7 @@ "AggregateReportsFormat_GraphsOnly": "Pouze zobrazit grafy (ne tabulky hlášenÃ)", "AggregateReportsFormat_TablesAndGraphs": "Zobrazit tabulky hlášenà a grafy pro vÅ¡echna hlášenÃ", "AggregateReportsFormat_TablesOnly": "(VýchozÃ) zobrazit tabulky hlášenà (grafy pouze pro klÃÄová měřenÃ)", - "AlsoSendReportToTheseEmails": "OdesÃlat hlášenà také na tyto e-maily (jeden e-mail na řádek):", + "AlsoSendReportToTheseEmails": "OdesÃlat hlášenà také na tyto emaily (jeden email na řádek):", "AreYouSureDeleteReport": "Opravdu chcete odstranit toto hlášenà a jeho plán?", "CancelAndReturnToReports": "ZruÅ¡it a %svrátit se k seznamu hlášenÃ%s", "CreateAndScheduleReport": "VytvoÅ™it a naplánovat hlášenÃ", @@ -13,7 +13,7 @@ "DescriptionOnFirstPage": "Popis hlášenà bude zobrazen na prvnà jeho stranÄ›.", "DisplayFormat_TablesOnly": "Pouze zobrazit tabulky (žádné grafy)", "EmailHello": "Ahoj,", - "EmailReports": "Poslat hlášenà na e-mail", + "EmailReports": "Poslat hlášenà na email", "EmailSchedule": "Plánovánà zasÃlánà hlášenÃ", "EvolutionGraph": "Zobrazit historické grafy pro %s nejvyššÃch hodnot", "FrontPage": "Hlavnà strana", @@ -34,15 +34,15 @@ "ReportsIncluded": "Zahrnuté statistiky", "ReportType": "Odeslat hlášenà pomocÃ", "ReportUpdated": "Hlášenà aktualizováno", - "Segment_Deletion_Error": "Tento segment nemůže být smazán nebo zneviditelnÄ›n, protože se použÃvá k vytvářenà e-mailových hlášenà %s. Zkuste to znovu poté, co ho z tÄ›chto hlášenà odstranÃte.", - "Segment_Help": "Můžete zvolit existujÃcà segment, který bude aplikován na data v tomto e-mailovém hlášenÃ. Segmenty můžete vytvářet a upravovat vlastnà segmenty na vašà nástÄ›nce %s(kliknÄ›te zde pro otevÅ™enÃ)%s, pak kliknÄ›te na box \"%s\", pak \"%s\".", + "Segment_Deletion_Error": "Tento segment nemůže být smazán nebo zneviditelnÄ›n, protože se použÃvá k vytvářenà emailových hlášenà %s. Zkuste to znovu poté, co ho z tÄ›chto hlášenà odstranÃte.", + "Segment_Help": "Můžete zvolit existujÃcà segment, který bude aplikován na data v tomto emailovém hlášenÃ. Segmenty můžete vytvářet a upravovat vlastnà segmenty na vašà nástÄ›nce %s(kliknÄ›te zde pro otevÅ™enÃ)%s, pak kliknÄ›te na box \"%s\", pak \"%s\".", "SegmentAppliedToReports": "Segment %s je aplikován na hlášenÃ.", "SendReportNow": "Odeslat hlášenà ihned", "SendReportTo": "Odeslat hlášenÃ", "SentToMe": "Odeslat hlášenà mnÄ›", "TableOfContent": "Seznam hlášenÃ", "ThereIsNoReportToManage": "Pro stránky %s neexistuje žádné hlášenÃ, které lze spravovat", - "TopLinkTooltip": "Vytvářejte vlastnà hlášenÃ, která budou automaticky doruÄena na vaÅ¡i nebo zákaznÃkovu e-mailovou adresu.", + "TopLinkTooltip": "Vytvářejte vlastnà hlášenÃ, která budou automaticky doruÄena na vaÅ¡i nebo zákaznÃkovu emailovou adresu.", "TopOfReport": "ZpÄ›t nahoru", "UpdateReport": "Aktualizovat hlášenÃ", "WeeklyScheduleHelp": "Týdennà plán: hlášenà bude odesláno každé pondÄ›lÃ" diff --git a/plugins/ScheduledReports/lang/it.json b/plugins/ScheduledReports/lang/it.json index 5f9e17ee17f2828a4a2446094e0d2c80b4ee0aca..bf796fd1c3aa8cbd3972aa74c112701869b99f20 100644 --- a/plugins/ScheduledReports/lang/it.json +++ b/plugins/ScheduledReports/lang/it.json @@ -25,7 +25,7 @@ "PiwikReports": "Report di Piwik", "PleaseFindAttachedFile": "Potete trovare nel file allegato il tuo %1$s report per %2$s.", "SentFromX": "Inviato da %s", - "PleaseFindBelow": "Di seguito trovi il tuo %1$s report per %2$s.", + "PleaseFindBelow": "Di seguito trovi il tuo report %1$s per %2$s.", "PluginDescription": "Crea dei report personalizzati e li programma per l'invio tramite email ogni giorno, settimana o mese a una o più persone. Sono supportati svariati formati (html, pdf, csv, immagini).", "ReportFormat": "Formato report", "ReportHour": "Invia report alle %s", diff --git a/plugins/ScheduledReports/lang/ja.json b/plugins/ScheduledReports/lang/ja.json index 15e24efd811574735c64ab36e505121c27b5f468..677a7780174b485673ed79a59e58e235e84236d2 100644 --- a/plugins/ScheduledReports/lang/ja.json +++ b/plugins/ScheduledReports/lang/ja.json @@ -24,9 +24,11 @@ "Pagination": "%s ã® %s ページ", "PiwikReports": "Piwik リãƒãƒ¼ãƒˆ", "PleaseFindAttachedFile": "%2$s ã® %1$s ã®ãƒªãƒãƒ¼ãƒˆã‚’添付ã—ã¦ã„ã¾ã™ã€‚", + "SentFromX": "%s ã‹ã‚‰é€ä¿¡ã•れã¾ã™ã€‚", "PleaseFindBelow": "%2$s ã® %1$s ã®ãƒªãƒãƒ¼ãƒˆã‚’ãŠå±Šã‘ã—ã¾ã™ã€‚", "PluginDescription": "カスタムレãƒãƒ¼ãƒˆã‚’作æˆã—ã€æ¯Žæ—¥ã€æ¯Žé€±ã€æ¯Žæœˆç‰ã€ 1 ã¤ã¾ãŸã¯è¤‡æ•°ã®äººã«ãƒ¡ãƒ¼ãƒ«ã§é€ä¿¡ã™ã‚‹ã‚ˆã†ã«ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã—ã¾ã™ã€‚サãƒãƒ¼ãƒˆã•れã¦ã„るレãƒãƒ¼ãƒˆå½¢å¼ ( htmlã€pdfã€csvã€ç”»åƒ)。", "ReportFormat": "リãƒãƒ¼ãƒˆã®ãƒ•ォーマット", + "ReportHour": "%s 時ã«ãƒ¬ãƒãƒ¼ãƒˆã‚’é€ä¿¡ã—ã¾ã™", "ReportIncludeNWebsites": "ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã¯ã€ç¾åœ¨åˆ©ç”¨å¯èƒ½ãª %s ウェブサイトã‹ã‚‰ã€å°‘ãªãã¨ã‚‚ 1 訪å•以上ã‚る全ウェブサイトã®ä¸»ãªãƒ¡ãƒˆãƒªã‚¯ã‚¹ã‚’å«ã¿ã¾ã™ã€‚", "ReportSent": "é€ä¿¡ã•れãŸãƒ¬ãƒãƒ¼ãƒˆ", "ReportsIncluded": "リãƒãƒ¼ãƒˆã«å«ã‚ã‚‹æƒ…å ±", diff --git a/plugins/ScheduledReports/lang/tr.json b/plugins/ScheduledReports/lang/tr.json index 818cb4378bae1323350b398f1e75a689ec453446..04e359c5a458b091b7855508b19b7a8363e2c37b 100644 --- a/plugins/ScheduledReports/lang/tr.json +++ b/plugins/ScheduledReports/lang/tr.json @@ -1,8 +1,12 @@ { "ScheduledReports": { + "AggregateReportsFormat": "Ekran seçenekleri (isteÄŸe baÄŸlı)", "CreateReport": "Rapor OluÅŸtur", "EmailHello": "Merhaba,", "EmailReports": "Raporları epostala", + "ReportFormat": "Rapor Formatı", + "ReportUpdated": "Rapor güncellendi", + "SendReportNow": "Raporu ÅŸimdi gönder", "TableOfContent": "Rapor listesi", "TopOfReport": "BaÅŸa dön", "UpdateReport": "Raporu Güncelle" diff --git a/plugins/SecurityInfo b/plugins/SecurityInfo index 65c7b5a1693b99dc97b78df015df1f606b2ef8b2..ffbc301bf148481b7896f685847ada3bc9734b58 160000 --- a/plugins/SecurityInfo +++ b/plugins/SecurityInfo @@ -1 +1 @@ -Subproject commit 65c7b5a1693b99dc97b78df015df1f606b2ef8b2 +Subproject commit ffbc301bf148481b7896f685847ada3bc9734b58 diff --git a/plugins/SegmentEditor/SegmentEditor.php b/plugins/SegmentEditor/SegmentEditor.php index 9107935e7307fe74d7c163033a348b98c72dd776..a46be068bc869e6d651314402db0088a906ac7e3 100644 --- a/plugins/SegmentEditor/SegmentEditor.php +++ b/plugins/SegmentEditor/SegmentEditor.php @@ -28,6 +28,7 @@ class SegmentEditor extends \Piwik\Plugin 'AssetManager.getJavaScriptFiles' => 'getJsFiles', 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles', 'Template.nextToCalendar' => 'getSegmentEditorHtml', + 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys', ); } @@ -85,4 +86,9 @@ class SegmentEditor extends \Piwik\Plugin { return Config::getInstance()->General['allow_adding_segments_for_all_websites'] == 1; } + + public function getClientSideTranslationKeys(&$translationKeys) + { + $translationKeys[] = 'SegmentEditor_CustomSegment'; + } } diff --git a/plugins/SegmentEditor/SegmentFormatter.php b/plugins/SegmentEditor/SegmentFormatter.php new file mode 100644 index 0000000000000000000000000000000000000000..19838d46d563cdcbbcd755c48d01e87bed8063d7 --- /dev/null +++ b/plugins/SegmentEditor/SegmentFormatter.php @@ -0,0 +1,147 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\SegmentEditor; + +use Exception; +use Piwik\Config; +use Piwik\Db; +use Piwik\Piwik; +use Piwik\Segment; +use Piwik\Segment\SegmentExpression; + +/** + */ +class SegmentFormatter +{ + /** + * @var SegmentList + */ + private $segmentList; + + private $matchesMetric = array( + SegmentExpression::MATCH_EQUAL => 'General_OperationEquals', + SegmentExpression::MATCH_NOT_EQUAL => 'General_OperationNotEquals', + SegmentExpression::MATCH_LESS_OR_EQUAL => 'General_OperationAtMost', + SegmentExpression::MATCH_GREATER_OR_EQUAL => 'General_OperationAtLeast', + SegmentExpression::MATCH_LESS => 'General_OperationLessThan', + SegmentExpression::MATCH_GREATER => 'General_OperationGreaterThan', + ); + + private $matchesDimension = array( + SegmentExpression::MATCH_EQUAL => 'General_OperationIs', + SegmentExpression::MATCH_NOT_EQUAL => 'General_OperationIsNot', + SegmentExpression::MATCH_CONTAINS => 'General_OperationContains', + SegmentExpression::MATCH_DOES_NOT_CONTAIN => 'General_OperationDoesNotContain', + SegmentExpression::MATCH_STARTS_WITH => 'General_OperationStartsWith', + SegmentExpression::MATCH_ENDS_WITH => 'General_OperationEndsWith' + ); + + private $operators = array( + SegmentExpression::BOOL_OPERATOR_AND => 'General_And', + SegmentExpression::BOOL_OPERATOR_OR => 'General_Or', + SegmentExpression::BOOL_OPERATOR_END => '', + ); + + public function __construct(SegmentList $segmentList) + { + $this->segmentList = $segmentList; + } + + public function getHumanReadable($segmentString, $idSite) + { + if (empty($segmentString)) { + return Piwik::translate('SegmentEditor_DefaultAllVisits'); + } + + try { + $segment = new SegmentExpression(urldecode($segmentString)); + $expressions = $segment->parseSubExpressions(); + } catch (Exception $e) { + $segment = new SegmentExpression($segmentString); + $expressions = $segment->parseSubExpressions(); + } + + $readable = ''; + foreach ($expressions as $expression) { + $operator = $expression[SegmentExpression::INDEX_BOOL_OPERATOR]; + $operand = $expression[SegmentExpression::INDEX_OPERAND]; + $name = $operand[SegmentExpression::INDEX_OPERAND_NAME]; + + $segment = $this->segmentList->findSegment($name, $idSite); + + if (empty($segment)) { + throw new Exception(sprintf("The segment '%s' does not exist.", $name)); + } + + $readable .= $segment['name'] . ' '; + $readable .= $this->getTranslationForComparison($operand, $segment['type']) . ' '; + $readable .= $this->getFormattedValue($operand); + $readable .= $this->getTranslationForBoolOperator($operator) . ' '; + } + + $readable = trim($readable); + + return $readable; + } + + private function getTranslationForComparison($operand, $segmentType) + { + $operator = $operand[SegmentExpression::INDEX_OPERAND_OPERATOR]; + + $translation = $operator; + + if ($operator === SegmentExpression::MATCH_IS_NULL_OR_EMPTY) { + return Piwik::translate('SegmentEditor_SegmentOperatorIsNullOrEmpty'); + } + + if ($operator === SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY) { + return Piwik::translate('SegmentEditor_SegmentOperatorIsNotNullNorEmpty'); + } + + if ($segmentType === 'dimension' && !empty($this->matchesDimension[$operator])) { + $translation = Piwik::translate($this->matchesDimension[$operator]); + } + if ($segmentType === 'metric' && !empty($this->matchesMetric[$operator])) { + $translation = Piwik::translate($this->matchesMetric[$operator]); + } + + return strtolower($translation); + } + + private function getFormattedValue($operand) + { + $operator = $operand[SegmentExpression::INDEX_OPERAND_OPERATOR]; + + if ($operator === SegmentExpression::MATCH_IS_NULL_OR_EMPTY + || $operator === SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY) { + return ''; + } + + $value = $operand[SegmentExpression::INDEX_OPERAND_VALUE]; + + if (empty($value)) { + $value = ''; + } + + return '"' . $value . '" '; + } + + private function getTranslationForBoolOperator($operator) + { + $translation = ''; + + if (!empty($this->operators[$operator])) { + $translation = Piwik::translate($this->operators[$operator]); + } elseif (!empty($operator)) { + $translation = $operator; + } + + return $translation; + } +} diff --git a/plugins/SegmentEditor/SegmentList.php b/plugins/SegmentEditor/SegmentList.php new file mode 100644 index 0000000000000000000000000000000000000000..e7094d4793367debe98885cdcd454ae904e9a47e --- /dev/null +++ b/plugins/SegmentEditor/SegmentList.php @@ -0,0 +1,32 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\SegmentEditor; + +use Piwik\API\Request; +use Piwik\Config; +use Piwik\Db; + +/** + */ +class SegmentList +{ + public function findSegment($segmentName, $idSite) + { + $segments = Request::processRequest('API.getSegmentsMetadata', array( + 'idSites' => array($idSite), + )); + + foreach ($segments as $segment) { + if ($segment['segment'] == $segmentName && !empty($segmentName)) { + return $segment; + } + } + } + +} diff --git a/plugins/SegmentEditor/SegmentSelectorControl.php b/plugins/SegmentEditor/SegmentSelectorControl.php index e37354e1cd8a0ac81f82d9012c98cc91357ebaa7..72be071e5e7b309b4f439bd563607994be23319f 100644 --- a/plugins/SegmentEditor/SegmentSelectorControl.php +++ b/plugins/SegmentEditor/SegmentSelectorControl.php @@ -8,8 +8,10 @@ */ namespace Piwik\Plugins\SegmentEditor; +use Piwik\API\Request; use Piwik\Common; use Piwik\Config; +use Piwik\Container\StaticContainer; use Piwik\Piwik; use Piwik\Plugins\API\API as APIMetadata; use Piwik\View\UIControl; @@ -37,13 +39,17 @@ class SegmentSelectorControl extends UIControl $this->selectedSegment = Common::getRequestVar('segment', false, 'string'); + $formatter = StaticContainer::get('Piwik\Plugins\SegmentEditor\SegmentFormatter'); + $this->segmentDescription = $formatter->getHumanReadable(Request::getRawSegmentFromRequest(), $this->idSite); + $this->isAddingSegmentsForAllWebsitesEnabled = SegmentEditor::isAddingSegmentsForAllWebsitesEnabled(); $segments = APIMetadata::getInstance()->getSegmentsMetadata($this->idSite); + $visitTitle = Piwik::translate('General_Visit'); $segmentsByCategory = array(); foreach ($segments as $segment) { - if ($segment['category'] == Piwik::translate('General_Visit') + if ($segment['category'] == $visitTitle && ($segment['type'] == 'metric' && $segment['segment'] != 'visitIp') ) { $metricsLabel = Piwik::translate('General_Metrics'); @@ -52,7 +58,6 @@ class SegmentSelectorControl extends UIControl } $segmentsByCategory[$segment['category']][] = $segment; } - uksort($segmentsByCategory, array($this, 'sortSegmentCategories')); $this->createRealTimeSegmentsIsEnabled = Config::getInstance()->General['enable_create_realtime_segments']; $this->segmentsByCategory = $segmentsByCategory; @@ -95,15 +100,6 @@ class SegmentSelectorControl extends UIControl return (bool) $savedSegment['auto_archive']; } - public function sortSegmentCategories($a, $b) - { - // Custom Variables last - if ($a == Piwik::translate('CustomVariables_CustomVariables')) { - return 1; - } - return 0; - } - private function getTranslations() { $translationKeys = array( @@ -115,6 +111,8 @@ class SegmentSelectorControl extends UIControl 'General_OperationGreaterThan', 'General_OperationContains', 'General_OperationDoesNotContain', + 'General_OperationStartsWith', + 'General_OperationEndsWith', 'General_OperationIs', 'General_OperationIsNot', 'General_OperationContains', diff --git a/plugins/SegmentEditor/javascripts/Segmentation.js b/plugins/SegmentEditor/javascripts/Segmentation.js index 0e47bd7d195f1e8e58fd0928a8dce8ed9fc2b4ad..2ffd7dac57b062d00d24029bbe42aabf6bf659a7 100644 --- a/plugins/SegmentEditor/javascripts/Segmentation.js +++ b/plugins/SegmentEditor/javascripts/Segmentation.js @@ -49,6 +49,8 @@ Segmentation = (function($) { self.availableMatches["dimension"]["!="] = self.translations['General_OperationIsNot']; self.availableMatches["dimension"]["=@"] = self.translations['General_OperationContains']; self.availableMatches["dimension"]["!@"] = self.translations['General_OperationDoesNotContain']; + self.availableMatches["dimension"]["=^"] = self.translations['General_OperationStartsWith']; + self.availableMatches["dimension"]["=$"] = self.translations['General_OperationEndsWith']; segmentation.prototype.setAvailableSegments = function (segments) { this.availableSegments = segments; @@ -83,7 +85,7 @@ Segmentation = (function($) { var name = $(foundItems).first().find("span.segname").text(); title.text(name); } else { - title.text("Custom Segment"); + title.text(_pk_translate('SegmentEditor_CustomSegment')); } segmentationTitle.html(title); } @@ -264,7 +266,7 @@ Segmentation = (function($) { }; var findAndExplodeByMatch = function(metric){ - var matches = ["==" , "!=" , "<=", ">=", "=@" , "!@","<",">"]; + var matches = ["==" , "!=" , "<=", ">=", "=@" , "!@","<",">", "=^", "=$"]; var newMetric = {}; var minPos = metric.length; var match, index; diff --git a/plugins/SegmentEditor/lang/cs.json b/plugins/SegmentEditor/lang/cs.json index 36dd2084b373b4afa97249ab7d86665fac7f2373..c5752de9e29ac7646a8b3780b925f240b5268d97 100644 --- a/plugins/SegmentEditor/lang/cs.json +++ b/plugins/SegmentEditor/lang/cs.json @@ -7,13 +7,14 @@ "AutoArchivePreProcessed": "Segmentovaná hlášenà jsou pÅ™edzpracována rychleji (vyžadujà cron)", "AutoArchiveRealTime": "Segmentovaná hlášenà jsou zpracována v reálném Äase", "ChooseASegment": "Zvolte segment", + "CurrentlySelectedSegment": "AktuálnÄ› vybraný segment: %s", "DataAvailableAtLaterDate": "VaÅ¡e segmentovaná analytická hlášenà budou dostupná pozdÄ›ji. Omlouváme se za tuto nepÅ™Ãjemnost.", "DefaultAllVisits": "VÅ¡echny návÅ¡tÄ›vy", "DragDropCondition": "PÅ™etáhnÄ›te podmÃnku", "LoadingSegmentedDataMayTakeSomeTime": "Zpracovánà segmentovaných dat návÅ¡tÄ›vnÃků může pár minut trvat...", "OperatorAND": "AND", "OperatorOR": "OR", - "SaveAndApply": "Uložit & použÃt", + "SaveAndApply": "Uložit a použÃt", "SegmentDisplayedAllWebsites": "VÅ¡echny webové stránky", "SegmentDisplayedThisWebsiteOnly": "Pouze tyto webové stránky", "SegmentIsDisplayedForWebsite": "A zobrazený po", @@ -26,6 +27,10 @@ "YouMayChangeSetting": "Jinak můžete nastavenà zmÄ›nit v souboru %s, nebo můžete upravit tento segment a zvolit %s.", "YouMustBeLoggedInToCreateSegments": "Pro vytvářenà a úpravu vlastnÃch segmentů návÅ¡tÄ›vnÃků musÃte být pÅ™ihlášen.", "YouDontHaveAccessToCreateSegments": "Pro vytvářenà a úpravu segmentů nemáte požadovanou pÅ™Ãstupovou úroveň.", - "AddingSegmentForAllWebsitesDisabled": "PÅ™idávánà segmentů pro vÅ¡echny stránky bylo zakázáno." + "AddingSegmentForAllWebsitesDisabled": "PÅ™idávánà segmentů pro vÅ¡echny stránky bylo zakázáno.", + "SegmentXIsAUnionOf": "%s je propojenà tÄ›chto segmentů:", + "CustomSegment": "Vlastnà segment", + "SegmentOperatorIsNullOrEmpty": "je nulový nebo prázdný", + "SegmentOperatorIsNotNullNorEmpty": "nenà nulový nebo prázdný" } } \ No newline at end of file diff --git a/plugins/SegmentEditor/lang/el.json b/plugins/SegmentEditor/lang/el.json index e0a9f14a6a8a54aac6ad31a40459b23a140589b8..72d3659543724b6542a37bf5992e6ca8031dd1d2 100644 --- a/plugins/SegmentEditor/lang/el.json +++ b/plugins/SegmentEditor/lang/el.json @@ -7,6 +7,7 @@ "AutoArchivePreProcessed": "οι αναφοÏÎÏ‚ τμημάτων Ï€ÏοεπεξεÏγάζονται (γÏηγοÏότεÏα, απαιτείται το archive.php με cron)", "AutoArchiveRealTime": "οι αναφοÏÎÏ‚ τμημάτων επεξεÏγάζονται σε Ï€Ïαγματικό χÏόνο", "ChooseASegment": "ΕπιλÎξτε Îνα τμήμα", + "CurrentlySelectedSegment": "ΕπιλεγμÎνο τμήμα αυτή τη στιγμή: %s", "DataAvailableAtLaterDate": "Οι τμηματικÎÏ‚ αναφοÏÎÏ‚ αναλυτικών θα είναι αÏγότεÏα διαθÎσιμες. ΖητοÏμε συγγνώμη για την ταλαιπωÏία.", "DefaultAllVisits": "Όλες οι επισκÎψεις", "DragDropCondition": "Συνθήκη με ΣÏÏε & Άσε", @@ -26,6 +27,10 @@ "YouMayChangeSetting": "Εναλλακτικά, μποÏείτε να αλλάξετε τη ÏÏθμιση στο αÏχείο Ïυθμίσεων (%s), ή να Ï„Ïοποποιήσετε το Τμήμα αυτό και να επιλÎξετε '%s'.", "YouMustBeLoggedInToCreateSegments": "Θα Ï€ÏÎπει να Îχετε κάνει είσοδο για να δημιουÏγήσετε και να επεξεÏγαστείτε Ï€ÏοσαÏμοσμÎνα τμήματα επισκεπτών.", "YouDontHaveAccessToCreateSegments": "Δεν διαθÎτετε την απαιτοÏμενη Ï€Ïόσβαση ασφαλείας για να δημιουÏγείτε και να Ï„Ïοποποιείτε τμήματα.", - "AddingSegmentForAllWebsitesDisabled": "Η Ï€Ïοσθήκη τμημάτων Îχει απενεÏγοποιηθεί για όλους τους ιστοτόπους." + "AddingSegmentForAllWebsitesDisabled": "Η Ï€Ïοσθήκη τμημάτων Îχει απενεÏγοποιηθεί για όλους τους ιστοτόπους.", + "SegmentXIsAUnionOf": "Το %s είναι η Îνωση αυτών των τμημάτων:", + "CustomSegment": "Î ÏοσαÏμοσμÎνο τμήμα", + "SegmentOperatorIsNullOrEmpty": "είναι άκυÏο (null) ή κενό", + "SegmentOperatorIsNotNullNorEmpty": "δεν είναι άκυÏο (null) ή άδειο" } } \ No newline at end of file diff --git a/plugins/SegmentEditor/lang/en.json b/plugins/SegmentEditor/lang/en.json index 46bdf5fef27fae956549c1d0d9268bb391d30762..8651afeecd041ca1d6b2fb16831199028ac8341b 100644 --- a/plugins/SegmentEditor/lang/en.json +++ b/plugins/SegmentEditor/lang/en.json @@ -7,6 +7,7 @@ "AutoArchivePreProcessed": "segmented reports are pre-processed (faster, requires cron)", "AutoArchiveRealTime": "segmented reports are processed in real time", "ChooseASegment": "Choose a segment", + "CurrentlySelectedSegment": "Currently selected segment: %s", "DataAvailableAtLaterDate": "Your segmented analytics reports will be available later. We apologize for the inconvenience.", "DefaultAllVisits": "All visits", "DragDropCondition": "Drag & Drop condition", @@ -26,6 +27,10 @@ "YouMayChangeSetting": "Alternatively you may change the setting in the config file (%s), or edit this Segment and choose '%s'.", "YouMustBeLoggedInToCreateSegments": "You must be logged in to create and edit custom visitor segments.", "YouDontHaveAccessToCreateSegments": "You don't have the required access level to create and edit segments.", - "AddingSegmentForAllWebsitesDisabled": "Adding segments for all websites has been disabled." + "AddingSegmentForAllWebsitesDisabled": "Adding segments for all websites has been disabled.", + "SegmentXIsAUnionOf": "%s is a union of these segments:", + "CustomSegment": "Custom Segment", + "SegmentOperatorIsNullOrEmpty": "is null or empty", + "SegmentOperatorIsNotNullNorEmpty": "is not null nor empty" } } \ No newline at end of file diff --git a/plugins/SegmentEditor/lang/it.json b/plugins/SegmentEditor/lang/it.json index 63b0ec0ce2f3e90fc6fb941ef532e4648c7d6550..28b4b9f3ed34f0c78fc2d607a70d6d7408a3c773 100644 --- a/plugins/SegmentEditor/lang/it.json +++ b/plugins/SegmentEditor/lang/it.json @@ -7,6 +7,7 @@ "AutoArchivePreProcessed": "i reports segmentati sono pre-elaborati (più veloce, richiede un cron-job)", "AutoArchiveRealTime": "i reports segmentati sono elaborati in tempo reale", "ChooseASegment": "Scegli un segmento", + "CurrentlySelectedSegment": "Segmento attualmente selezionato: %s", "DataAvailableAtLaterDate": "I report segmentati delle statistiche saranno disponibili più tardi. Ci scusiamo per l'inconveniente.", "DefaultAllVisits": "Tutte le visite", "DragDropCondition": "Copia & Incolla condizione", @@ -26,6 +27,10 @@ "YouMayChangeSetting": "In alternativa, puoi cambiare le impostazioni nel file di configurazione (%s) o modificare questo Segmento e scegliere '%s'.", "YouMustBeLoggedInToCreateSegments": "Devi avere effettuato l'accesso per creare e modificare i segmenti personalizzati dei visitatori.", "YouDontHaveAccessToCreateSegments": "Non hai un livello d'accesso adeguato per creare e modificare i segmenti.", - "AddingSegmentForAllWebsitesDisabled": "L'aggiunta di segmenti per tutti i siti è stata disabilitata." + "AddingSegmentForAllWebsitesDisabled": "L'aggiunta di segmenti per tutti i siti è stata disabilitata.", + "SegmentXIsAUnionOf": "%s è un'unione di questi segmenti:", + "CustomSegment": "Segmento Speciale", + "SegmentOperatorIsNullOrEmpty": "è nullo o vuoto", + "SegmentOperatorIsNotNullNorEmpty": "non è nullo nè vuoto" } } \ No newline at end of file diff --git a/plugins/SegmentEditor/lang/ja.json b/plugins/SegmentEditor/lang/ja.json index 8c65a9c7cf76ea3f850b9756d4dd0aced3be3ee6..0156de56ab1bcd6d7081d8b6859fb237162ab4da 100644 --- a/plugins/SegmentEditor/lang/ja.json +++ b/plugins/SegmentEditor/lang/ja.json @@ -1,5 +1,6 @@ { "SegmentEditor": { + "PluginDescription": "セグメントエディターã§ã‚«ã‚¹ã‚¿ãƒ ユーザー セグメントを作æˆã€ç·¨é›†ã§ãã¾ã™ã€‚", "AddANDorORCondition": "%s ã®æ¡ä»¶ã‚’è¿½åŠ ", "AddNewSegment": "æ–°ã—ã„ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚’è¿½åŠ ", "AreYouSureDeleteSegment": "ã“ã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ", @@ -25,6 +26,7 @@ "YouMayChangeSetting": "åˆ¥ã®æ–¹æ³•ã¨ã—ã¦ã¯è¨å®šãƒ•ァイル (%s) ã§è¨å®šã‚’変更ã™ã‚‹ã‹ã€ã“ã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ '%s' ã‚’é¸æŠžã—編集ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚", "YouMustBeLoggedInToCreateSegments": "ビジターã®ã‚«ã‚¹ã‚¿ãƒ セグメントã®ä½œæˆã¨ç·¨é›†ã«ã¯ãƒã‚°ã‚¤ãƒ³ãŒå¿…è¦ã§ã™ã€‚", "YouDontHaveAccessToCreateSegments": "セグメントã®ä½œæˆãŠã‚ˆã³ç·¨é›†ã«å¿…è¦ãªãƒ¬ãƒ™ãƒ«ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã‚’æŒã£ã¦ã„ã¾ã›ã‚“。", - "AddingSegmentForAllWebsitesDisabled": "全ウェブサイトã«å¯¾ã™ã‚‹ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã¯è¿½åŠ ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" + "AddingSegmentForAllWebsitesDisabled": "全ウェブサイトã«å¯¾ã™ã‚‹ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã¯è¿½åŠ ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚", + "CustomSegment": "カスタムセグメント" } } \ No newline at end of file diff --git a/plugins/SegmentEditor/lang/pt-br.json b/plugins/SegmentEditor/lang/pt-br.json index a5f8df59f2501f9adca0fa0bb7500280b01d63d2..eb7a8919d2eb3f514210ca927fd90ce86758f591 100644 --- a/plugins/SegmentEditor/lang/pt-br.json +++ b/plugins/SegmentEditor/lang/pt-br.json @@ -7,6 +7,7 @@ "AutoArchivePreProcessed": "Relatórios segmentados são pré-processados ​​(Para agilizar, é necessário usar o cron em: archive.php)", "AutoArchiveRealTime": "Relatórios segmentados são processados em tempo real", "ChooseASegment": "Escolha um segmento", + "CurrentlySelectedSegment": "Segmento atualmente selecionado: %s", "DataAvailableAtLaterDate": "Os seus relatórios de análise segmentados estarão disponÃveis mais tarde. Pedimos desculpas pela inconveniência.", "DefaultAllVisits": "Todas as visitas", "DragDropCondition": "Condição Drag & Drop", @@ -23,8 +24,13 @@ "ThisSegmentIsVisibleTo": "Este segmento é visÃvel para:", "VisibleToAllUsers": "Todos os Usuários", "VisibleToMe": "mim", + "YouMayChangeSetting": "Alternativamente, você pode alterar a configuração no arquivo de configuração (%s), ou editar este Segmento e escolher %s.", "YouMustBeLoggedInToCreateSegments": "Você precisa estar logado para criar e editar segmentos personalizados de visitantes.", "YouDontHaveAccessToCreateSegments": "Você não tem o nÃvel de acesso necessário para criar e editar segmentos.", - "AddingSegmentForAllWebsitesDisabled": "Adicionar segmentos para todos os sites foi desativado." + "AddingSegmentForAllWebsitesDisabled": "Adicionar segmentos para todos os sites foi desativado.", + "SegmentXIsAUnionOf": "%s é uma união destes segmentos:", + "CustomSegment": "Segmento Personalizado", + "SegmentOperatorIsNullOrEmpty": "está nulo ou vazio", + "SegmentOperatorIsNotNullNorEmpty": "não está nulo nem vazio" } } \ No newline at end of file diff --git a/plugins/SegmentEditor/lang/tr.json b/plugins/SegmentEditor/lang/tr.json new file mode 100644 index 0000000000000000000000000000000000000000..3541941a618c3328b7b5b931615d9fa7192cf0f3 --- /dev/null +++ b/plugins/SegmentEditor/lang/tr.json @@ -0,0 +1,8 @@ +{ + "SegmentEditor": { + "OperatorAND": "VE", + "OperatorOR": "VEYA", + "SaveAndApply": "Kaydet & Uygula", + "VisibleToAllUsers": "tüm kullanıcılar" + } +} \ No newline at end of file diff --git a/plugins/SegmentEditor/templates/_segmentSelector.twig b/plugins/SegmentEditor/templates/_segmentSelector.twig index 7a8019d37e8bf8d978ec949c978057cec5642517..dc269dc8b9096c4e25b4fa04caa35152de55efc1 100644 --- a/plugins/SegmentEditor/templates/_segmentSelector.twig +++ b/plugins/SegmentEditor/templates/_segmentSelector.twig @@ -1,5 +1,5 @@ <div class="SegmentEditor" style="display:none;"> - <div class="segmentationContainer listHtml" title="{{ 'SegmentEditor_ChooseASegment'|translate|e('html_attr') }}"> + <div class="segmentationContainer listHtml" title="{{ 'SegmentEditor_ChooseASegment'|translate|e('html_attr') }}. {{ 'SegmentEditor_CurrentlySelectedSegment'|translate(segmentDescription)|e('html_attr') }}"> <a class="title"><span class="icon icon-segment"></span><span class="segmentationTitle"></span></a> <div class="dropdown dropdown-body"> <div class="segmentFilterContainer"> @@ -61,6 +61,8 @@ <option value=">">{{ 'General_OperationGreaterThan'|translate }}</option> <option value="=@">{{ 'General_OperationContains'|translate }}</option> <option value="!@">{{ 'General_OperationDoesNotContain'|translate }}</option> + <option value="=^">{{ 'General_OperationStartsWith'|translate }}</option> + <option value="=$">{{ 'General_OperationEndsWith'|translate }}</option> </select> </div> <div class="segment-input metricValueBlock"> @@ -99,7 +101,17 @@ <a class="metric_category" href="#">{{ category }}</a> <ul style="display:none;"> {% for segmentInCategory in segmentsInCategory %} - <li data-metric="{{ segmentInCategory.segment }}"><a class="ddmetric" href="#">{{ segmentInCategory.name }}</a></li> + {% set title = segmentInCategory.name %} + {% if segmentInCategory.unionOfSegments is defined and segmentInCategory.unionOfSegments %} + {% set title = 'SegmentEditor_SegmentXIsAUnionOf'|translate(title) %} + {% for unionSegment in segmentInCategory.unionOfSegments %} + {% set title = title ~ ' ' ~ unionSegment %} + {% if not loop.last %} + {% set title = title ~ ',' %} + {% endif %} + {% endfor %} + {% endif %} + <li data-metric="{{ segmentInCategory.segment }}" title="{{ title|e('html_attr') }}"><a class="ddmetric" href="#">{{ segmentInCategory.name }}</a></li> {% endfor %} </ul> </li> diff --git a/plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php b/plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ca37e0775b9a944d04074fabe4ad92b3fb335b33 --- /dev/null +++ b/plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php @@ -0,0 +1,116 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\SegmentEditor\tests\Integration; + +use Piwik\Plugins\SegmentEditor\SegmentFormatter; +use Piwik\Plugins\SegmentEditor\SegmentList; +use Piwik\Tests\Framework\Fixture; +use Piwik\Tests\Framework\Mock\FakeAccess; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; +use Piwik\Translate; +use Exception; + +/** + * @group SegmentFormatterTest + * @group SegmentFormatter + * @group SegmentEditor + * @group Plugins + */ +class SegmentFormatterTest extends IntegrationTestCase +{ + /** + * @var SegmentFormatter + */ + private $formatter; + + private $idSite; + + public function setUp() + { + parent::setUp(); + + $this->idSite = Fixture::createWebsite('2012-01-01 00:00:00'); + $this->formatter = new SegmentFormatter(new SegmentList()); + + Translate::loadAllTranslations(); + } + + public function tearDown() + { + Translate::reset(); + } + + public function test_getHumanReadable_noSegmentGiven_ShouldReturnDefaultSegment() + { + $readable = $this->formatter->getHumanReadable($segment = '', $this->idSite); + $this->assertSame('All visits', $readable); + } + + public function test_getHumanReadable_ShouldTranslateAMetric() + { + $readable = $this->formatter->getHumanReadable($segment = 'visitCount>5', $this->idSite); + $this->assertSame('Number of visits greater than "5"', $readable); + + $readable = $this->formatter->getHumanReadable($segment = 'visitCount==5', $this->idSite); + $this->assertSame('Number of visits equals "5"', $readable); + } + + public function test_getHumanReadable_ShouldTranslateADimension() + { + $readable = $this->formatter->getHumanReadable($segment = 'resolution=@1024', $this->idSite); + $this->assertSame('Resolution contains "1024"', $readable); + + $readable = $this->formatter->getHumanReadable($segment = 'resolution==1024x768', $this->idSite); + $this->assertSame('Resolution is "1024x768"', $readable); + } + + public function test_getHumanReadable_ShouldCombineMultipleSegmentDefinitionsWithBooleanOperator() + { + $readable = $this->formatter->getHumanReadable($segment = 'browserVersion!=1.0;browserEngine=$Trident', $this->idSite); + $this->assertSame('Browser version is not "1.0" and Browser engine ends with "Trident"', $readable); + + $readable = $this->formatter->getHumanReadable($segment = 'browserVersion!=1.0,browserEngine=$Trident', $this->idSite); + $this->assertSame('Browser version is not "1.0" or Browser engine ends with "Trident"', $readable); + } + + public function test_getHumanReadable_ShouldHandleAMissingValue() + { + $readable = $this->formatter->getHumanReadable($segment = 'browserVersion==', $this->idSite); + $this->assertSame('Browser version is null or empty', $readable); + + $readable = $this->formatter->getHumanReadable($segment = 'browserVersion!=', $this->idSite); + $this->assertSame('Browser version is not null nor empty', $readable); + } + + public function test_getHumanReadable_ShouldHandleAUrlDecodedSegment() + { + $readable = $this->formatter->getHumanReadable($segment = 'pageUrl%3D%40piwik%2CvisitId!%3D1', $this->idSite); + $this->assertSame('Page URL contains "piwik" or Visit ID is not "1"', $readable); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage The segment 'noTexisTinG' does not exist + */ + public function test_getHumanReadable_ShouldThrowAnException_IfTheGivenSegmentNameDoesNotExist() + { + $this->formatter->getHumanReadable($segment = 'noTexisTinG==1.0', $this->idSite); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage The segment 'pageUrl=!1.0' is not valid. + */ + public function test_getHumanReadable_ShouldThrowAnException_IfSegmentCannotBeParsedBecauseOfInvalidFormat() + { + $invalidOperator = '=!'; + $this->formatter->getHumanReadable($segment = 'pageUrl' . $invalidOperator . '1.0', $this->idSite); + } + +} diff --git a/plugins/SegmentEditor/tests/Integration/SegmentListTest.php b/plugins/SegmentEditor/tests/Integration/SegmentListTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3a90bb95eec66bc8bf9612467a7aeda102842255 --- /dev/null +++ b/plugins/SegmentEditor/tests/Integration/SegmentListTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\SegmentEditor\tests\Integration; + +use Piwik\Plugins\SegmentEditor\SegmentList; +use Piwik\Tests\Framework\Fixture; +use Piwik\Tests\Framework\Mock\FakeAccess; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; +use Exception; + +/** + * @group SegmentListTest + * @group SegmentList + * @group SegmentEditor + * @group Plugins + */ +class SegmentListTest extends IntegrationTestCase +{ + /** + * @var SegmentList + */ + private $list; + + private $idSite; + + public function setUp() + { + parent::setUp(); + + $this->idSite = Fixture::createWebsite('2012-01-01 00:00:00'); + $this->list = new SegmentList(); + } + + public function test_findSegment_shouldFindSegmentByName_IfNameExists() + { + $segmentName = 'pageUrl'; + + $segment = $this->list->findSegment($segmentName, $this->idSite); + $this->assertInternalType('array', $segment); + $this->assertSame($segmentName, $segment['segment']); + } + + public function test_findSegment_shouldNotFindSegmentByName_IfNameDoesNotExist() + { + $segment = $this->list->findSegment('aNyNotExisTinGSegmEnt', $this->idSite); + $this->assertNull($segment); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage checkUserHasViewAccess + */ + public function test_findSegment_ShouldThrowException_IfNotEnoughPermission() + { + FakeAccess::clearAccess($superUser = false, array(1)); + + $segment = $this->list->findSegment('pageUrl', 999); + $this->assertNull($segment); + } + + public function provideContainerConfig() + { + return array( + 'Piwik\Access' => new FakeAccess() + ); + } + +} diff --git a/plugins/SitesManager/API.php b/plugins/SitesManager/API.php index 4a67c45c2cb11aa0cbc0d2c53e294c10421625ba..739af7d5e9c17123cad7f8ef49b8c479908f9066 100644 --- a/plugins/SitesManager/API.php +++ b/plugins/SitesManager/API.php @@ -585,7 +585,7 @@ class API extends \Piwik\Plugin\API } if (!empty($settings)) { - $this->validateMeasurableSettings($bind['type'], $settings); + $this->validateMeasurableSettings(0, $bind['type'], $settings); } $idSite = $this->getModel()->createSite($bind); @@ -611,9 +611,9 @@ class API extends \Piwik\Plugin\API return (int) $idSite; } - private function validateMeasurableSettings($idType, $settings) + private function validateMeasurableSettings($idSite, $idType, $settings) { - $measurableSettings = new MeasurableSettings(0, $idType); + $measurableSettings = new MeasurableSettings($idSite, $idType); foreach ($measurableSettings->getSettingsForCurrentUser() as $measurableSetting) { $name = $measurableSetting->getName(); @@ -645,6 +645,7 @@ class API extends \Piwik\Plugin\API { Site::clearCache(); Cache::regenerateCacheWebsiteAttributes($idSite); + Cache::clearCacheGeneral(); SiteUrls::clearSitesCache(); } @@ -1184,7 +1185,7 @@ class API extends \Piwik\Plugin\API } if (!empty($settings)) { - $this->validateMeasurableSettings(Site::getTypeFor($idSite), $settings); + $this->validateMeasurableSettings($idSite, Site::getTypeFor($idSite), $settings); } $this->getModel()->updateSite($bind, $idSite); diff --git a/plugins/SitesManager/Model.php b/plugins/SitesManager/Model.php index 93ddb01d8f3bca80e7a28ce3db06469508a0fee5..96062b608ae1cef23b71f29dd3ba1ca2382b6e69 100644 --- a/plugins/SitesManager/Model.php +++ b/plugins/SitesManager/Model.php @@ -286,6 +286,22 @@ class Model return $urls; } + /** + * Returns the list of alias URLs registered for the given idSite. + * The website ID must be valid when calling this method! + * + * @param int $idSite + * @return array list of alias URLs + */ + public function getAllKnownUrlsForAllSites() + { + $db = $this->getDb(); + $mainUrls = $db->fetchAll("SELECT idsite, main_url as url FROM " . Common::prefixTable("site")); + $aliasUrls = $db->fetchAll("SELECT idsite, url FROM " . Common::prefixTable("site_url")); + + return array_merge($mainUrls, $aliasUrls); + } + public function updateSite($site, $idSite) { $idSite = (int) $idSite; diff --git a/plugins/SitesManager/SiteUrls.php b/plugins/SitesManager/SiteUrls.php index a1fac67a89e349c96238935d409177f3a3eeb020..33e2e4844a44eaff8a0428fe998032d497d20fcc 100644 --- a/plugins/SitesManager/SiteUrls.php +++ b/plugins/SitesManager/SiteUrls.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\SitesManager; use Piwik\Cache; +use Piwik\Common; class SiteUrls { @@ -19,6 +20,117 @@ class SiteUrls self::getCache()->delete(self::$cacheId); } + /** + * Groups all URLs by host, path and idsite. + * + * @param array $urls An array containing URLs by idsite, + * eg array(array($idSite = 1 => array('apache.piwik', 'apache2.piwik'), 2 => array(), ...)) + * as returned by {@link getAllCachedSiteUrls()} and {@link getAllSiteUrls} + * @return array All urls grouped by host => path => idSites. Path having the most '/' will be listed first + * array( + 'apache.piwik' => array( + '/test/two' => $idsite = array(3), + '/test' => $idsite = array(1), + '/' => $idsite = array(2), + ), + 'test.apache.piwik' => array( + '/test/two' => $idsite = array(3), + '/test' => $idsite = array(1), + '/' => $idsite = array(2, 3), + ), + ); + */ + public function groupUrlsByHost($siteUrls) + { + if (empty($siteUrls)) { + return array(); + } + + $allUrls = array(); + + foreach ($siteUrls as $idSite => $urls) { + $idSite = (int) $idSite; + foreach ($urls as $url) { + $urlParsed = @parse_url($url); + + if ($urlParsed === false || !isset($urlParsed['host'])) { + continue; + } + + $host = $this->toCanonicalHost($urlParsed['host']); + $path = $this->getCanonicalPathFromParsedUrl($urlParsed); + + if (!isset($allUrls[$host])) { + $allUrls[$host] = array(); + } + + if (!isset($allUrls[$host][$path])) { + $allUrls[$host][$path] = array(); + } + + if (!in_array($idSite, $allUrls[$host][$path])) { + $allUrls[$host][$path][] = $idSite; + } + } + } + + foreach ($allUrls as $host => $paths) { + uksort($paths, array($this, 'sortByPathDepth')); + $allUrls[$host] = $paths; + } + + return $allUrls; + } + + public function getIdSitesMatchingUrl($parsedUrl, $urlsGroupedByHost) + { + if (empty($parsedUrl['host'])) { + return null; + } + + $urlHost = $this->toCanonicalHost($parsedUrl['host']); + $urlPath = $this->getCanonicalPathFromParsedUrl($parsedUrl); + + $matchingSites = null; + if (isset($urlsGroupedByHost[$urlHost])) { + $paths = $urlsGroupedByHost[$urlHost]; + + foreach ($paths as $path => $idSites) { + if (0 === strpos($urlPath, $path)) { + $matchingSites = $idSites; + break; + } + } + + if (!isset($matchingSites) && isset($paths['/'])) { + $matchingSites = $paths['/']; + } + } + + return $matchingSites; + } + + public function getPathMatchingUrl($parsedUrl, $urlsGroupedByHost) + { + if (empty($parsedUrl['host'])) { + return null; + } + + $urlHost = $this->toCanonicalHost($parsedUrl['host']); + $urlPath = $this->getCanonicalPathFromParsedUrl($parsedUrl); + + $matchingSites = null; + if (isset($urlsGroupedByHost[$urlHost])) { + $paths = $urlsGroupedByHost[$urlHost]; + + foreach ($paths as $path => $idSites) { + if (0 === strpos($urlPath, $path)) { + return $path; + } + } + } + } + public function getAllCachedSiteUrls() { $cache = $this->getCache(); @@ -35,23 +147,66 @@ class SiteUrls public function getAllSiteUrls() { $model = new Model(); - $siteIds = $model->getSitesId(); - $siteUrls = array(); + $siteUrls = $model->getAllKnownUrlsForAllSites(); - if (empty($siteIds)) { + if (empty($siteUrls)) { return array(); } - foreach ($siteIds as $siteId) { - $siteId = (int) $siteId; - $siteUrls[$siteId] = $model->getSiteUrlsFromId($siteId); + $urls = array(); + foreach ($siteUrls as $siteUrl) { + $siteId = (int) $siteUrl['idsite']; + + if (!isset($urls[$siteId])) { + $urls[$siteId] = array(); + } + + $urls[$siteId][] = $siteUrl['url']; } - return $siteUrls; + return $urls; } private static function getCache() { return Cache::getLazyCache(); } + + private function sortByPathDepth($pathA, $pathB) + { + // list first the paths with most '/' , and list path = '/' last + $numSlashA = substr_count($pathA, '/'); + $numSlashB = substr_count($pathB, '/'); + + if ($numSlashA === $numSlashB) { + return -1 * strcmp($pathA, $pathB); + } + + return $numSlashA > $numSlashB ? -1 : 1; + } + + private function toCanonicalHost($host) + { + $host = Common::mb_strtolower($host); + if (strpos($host, 'www.') === 0) { + $host = substr($host, 4); + } + + return $host; + } + + private function getCanonicalPathFromParsedUrl($urlParsed) + { + $path = '/'; + + if (isset($urlParsed['path'])) { + $path = Common::mb_strtolower($urlParsed['path']); + if (!Common::stringEndsWith($path, '/')) { + $path .= '/'; + } + } + + return $path; + } + } diff --git a/plugins/SitesManager/SitesManager.php b/plugins/SitesManager/SitesManager.php index 4b686e2bdefbacce85fa5f0e1df51a4e6b8cae89..ca3f2757b93cf1305a7966cb0df570e987dacf83 100644 --- a/plugins/SitesManager/SitesManager.php +++ b/plugins/SitesManager/SitesManager.php @@ -114,8 +114,11 @@ class SitesManager extends \Piwik\Plugin { $idSite = (int) $idSite; + $urls = API::getInstance()->getSiteUrlsFromId($idSite); + // add the 'hosts' entry in the website array - $array['hosts'] = $this->getTrackerHosts($idSite); + $array['urls'] = $urls; + $array['hosts'] = $this->getTrackerHosts($urls); $website = API::getInstance()->getSiteFromId($idSite); $array['exclude_unknown_urls'] = $website['exclude_unknown_urls']; @@ -252,9 +255,8 @@ class SitesManager extends \Piwik\Plugin * @param int $idSite * @return array */ - private function getTrackerHosts($idSite) + private function getTrackerHosts($urls) { - $urls = API::getInstance()->getSiteUrlsFromId($idSite); $hosts = array(); foreach ($urls as $url) { $url = parse_url($url); diff --git a/plugins/SitesManager/config/config.php b/plugins/SitesManager/config/config.php deleted file mode 100644 index 0855c39329f0ce8f038489f3de3a260f39b50154..0000000000000000000000000000000000000000 --- a/plugins/SitesManager/config/config.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php - -return array( - - 'tracker.request.processors' => DI\add(array( - DI\get('Piwik\Plugins\SitesManager\Tracker\SitesManagerRequestProcessor'), - )), - -); diff --git a/plugins/SitesManager/lang/cs.json b/plugins/SitesManager/lang/cs.json index 014c9f88f2327123f9b282221534d12d0e1bef55..6854eadf75669889558a1afcf2592ee895cb7f31 100644 --- a/plugins/SitesManager/lang/cs.json +++ b/plugins/SitesManager/lang/cs.json @@ -68,13 +68,13 @@ "SiteWithoutDataTitle": "ZatÃm nebyla zaznamenána žádná data", "SiteWithoutDataDescription": "Pro tuto stránku nebyla zatÃm zaznamenána žádná analytická data.", "SiteWithoutDataSetupTracking": "ProsÃm, nastavte %1$ssledovacà javascriptový kód %2$s na vaÅ¡ich webových stránkách, a pak stránku obnovte.", - "SuperUserAccessCan": "eUživatel se super uživatelským pÅ™Ãstupem může také %sspecifikovat globálnà nastavenÃ%s pro nové webové stránky.", + "SuperUserAccessCan": "Uživatel se super uživatelským pÅ™Ãstupem může také %sspecifikovat globálnà nastavenÃ%s pro nové webové stránky.", "Timezone": "ÄŒasová zóna", "TrackingSiteSearch": "Sledovánà internÃho vyhledávánà na stránkách", "TrackingTags": "Zaznamenávacà tagy pro %s", "Urls": "URL", "UTCTimeIs": "UTC Äas je %s", - "OnlyMatchedUrlsAllowed": "Sledovat návÅ¡tÄ›vy a akce pouze tehdy, když URL akce zaÄÃná jednou z výše uvedených URL.", + "OnlyMatchedUrlsAllowed": "Sledovat návÅ¡tÄ›vy a akce pouze tehdy, pokud URL akce zaÄÃná jednou z výše uvedených URL.", "OnlyMatchedUrlsAllowedHelp": "Pokud je povoleno, Piwik bude sledovat internà akce pouze tehdy, když je URL stránky jednou ze známých URL vaÅ¡ich webových stránek. To zabránà lidem, aby zahltili analýzu URL jiných stránek.", "WebsitesManagement": "Nastavenà Web sÃdel", "XManagement": "Spravovat %s", diff --git a/plugins/SitesManager/lang/fr.json b/plugins/SitesManager/lang/fr.json index 283f77c0f3467640d7194f52f62be512eec230a3..2372187f6ca73e231cb2871cebbbe6c1cc45a3ca 100644 --- a/plugins/SitesManager/lang/fr.json +++ b/plugins/SitesManager/lang/fr.json @@ -74,8 +74,8 @@ "TrackingTags": "Code de suivi pour %s", "Urls": "URLs", "UTCTimeIs": "L'heure UTC est %s.", - "OnlyMatchedUrlsAllowed": "Effectue le suivit des visites et actions uniquement quand l'URL d'action commence avec une des URL's ci-dessus.", - "OnlyMatchedUrlsAllowedHelp": "Quand activé, Piwik va effectuer le suivit des actions uniquement quand l'URL de la page est une des URL's de votre site web. Ceci empêche les gens de spammer vos données d'analyse avec des URL's d'autres sites web.", + "OnlyMatchedUrlsAllowed": "Effectue le suivi des visites et actions uniquement quand l'URL d'action commence avec une des URLs ci-dessus.", + "OnlyMatchedUrlsAllowedHelp": "Quand activé, Piwik va effectuer le suivi des actions uniquement quand l'URL de la page est une des URLs de votre site web. Ceci empêche les gens de spammer vos données d'analyse avec des URLs d'autres sites web.", "WebsitesManagement": "Gestion des sites", "XManagement": "Gérer %s", "ChooseMeasurableTypeHeadline": "Que voudriez-vous mesurer ?", diff --git a/plugins/SitesManager/lang/ja.json b/plugins/SitesManager/lang/ja.json index 56cc2b469750d4a775c959407cd54c93b7a7d7a5..b1d3a73a83d7b292b0ecbacbaa676e0d8d1efc18 100644 --- a/plugins/SitesManager/lang/ja.json +++ b/plugins/SitesManager/lang/ja.json @@ -1,6 +1,7 @@ { "SitesManager": { "AddSite": "æ–°ã—ã„サイトã®è¿½åŠ ", + "AddMeasurable": "æ–°è¦ã®æ¸¬å®šå¯¾è±¡ã‚’è¿½åŠ ", "AdvancedTimezoneSupportNotFound": "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã® PHP ã§ã¯æ‹¡å¼µã‚¿ã‚¤ãƒ ゾーンãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“(PHP>=5.2 ã§ã‚µãƒãƒ¼ãƒˆï¼‰ã€‚ 手作æ¥ã§ UTC オフセットを指定ã—ã¾ã™ã€‚", "AliasUrlHelp": "ã“ã‚Œã¯æŽ¨å¥¨ã•れã¾ã™ãŒã€å¿…é ˆã§ã¯ã‚りã¾ã›ã‚“。 ビジターãŒã“ã®ã‚¦ã‚§ãƒ–サイトã®ã‚¢ã‚¯ã‚»ã‚¹ã«ä½¿ç”¨ã™ã‚‹ã•ã¾ã–ã¾ãª URL を指定ã™ã‚‹ã«ã¯ã€1行ã«1ã¤ã® URL を入力ã—ã¾ã™ã€‚ ウェブサイト㮠URL エイリアスã¯ã€[å‚ç…§å…ƒ]>[ウェブサイト]ã®ãƒªãƒãƒ¼ãƒˆã«ã¯è¡¨ç¤ºã•れã¾ã›ã‚“。 URL ã® 'www' ã®æœ‰ç„¡ã¯ã€Piwik ãŒä¸¡æ–¹ã¨ã‚‚考慮ã™ã‚‹ãŸã‚ã€æŒ‡å®šã™ã‚‹å¿…è¦ãŒãªã„ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。", "ChangingYourTimezoneWillOnlyAffectDataForward": "タイムゾーンã®å¤‰æ›´ã¯ã€ä»Šå¾Œã®ãƒ‡ãƒ¼ã‚¿ã«ã®ã¿åæ˜ ã•れã€éŽåŽ»ã®ãƒ‡ãƒ¼ã‚¿ã«ã¯é©ç”¨ã•れã¾ã›ã‚“。", @@ -49,6 +50,7 @@ "OnlyOneSiteAtTime": "一度ã«ã‚¦ã‚§ãƒ–サイトã¯ä¸€ã¤ã ã‘編集ã§ãã¾ã™ã€‚ウェブサイト %s ã¸ã®å¤‰æ›´ã‚’ä¿å˜ã™ã‚‹ã‹ã€ã‚ャンセルã—ã¦ãã ã•ã„。", "PiwikOffersEcommerceAnalytics": "Piwikã¯ã€é«˜åº¦ãªeコマース分æžã€ãƒˆãƒ©ãƒƒã‚ング&リãƒãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã€ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚%s eã‚³ãƒžãƒ¼ã‚¹åˆ†æž %s ã«ã¤ã„ã¦è©³ã—ã知る。", "PiwikWillAutomaticallyExcludeCommonSessionParameters": "一般的ãªã‚»ãƒƒã‚·ãƒ§ãƒ³ãƒ‘ラメータ(%s)ã¯ã€Piwik ãŒè‡ªå‹•çš„ã«é™¤å¤–ã—ã¾ã™ã€‚", + "PluginDescription": "Web サイト管ç†ã§ã¯ã€æ–°ã—ã„ web ã‚µã‚¤ãƒˆã‚’è¿½åŠ ã—ã€æ—¢å˜ã® web サイトを編集ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚", "SearchCategoryDesc": "Piwik ã¯ã€å„内部サイト内検索ã‚ーワードã«å¯¾ã™ã‚‹æ¤œç´¢ã‚«ãƒ†ã‚´ãƒªã‚’追跡ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚", "SearchCategoryLabel": "カテゴリーパラメーター", "SearchCategoryParametersDesc": "検索カテゴリを指定ã™ã‚‹ã‚¯ã‚¨ãƒªãƒ‘ラメーターリストをã€ã‚³ãƒ³ãƒžåŒºåˆ‡ã‚Šã§å…¥åŠ›ã§ãã¾ã™ã€‚", @@ -72,7 +74,11 @@ "TrackingTags": "%s 用トラッã‚ングタグ", "Urls": "URL", "UTCTimeIs": "UTC 時間㯠%s ã§ã™ã€‚", + "OnlyMatchedUrlsAllowed": "アクション URL ã¯ã€ä¸Šè¨˜ã®ã„ãšã‚Œã‹ã® URLã§å§‹ã¾ã‚‹å ´åˆã«ã®ã¿ãƒ“ジットやアクションを追跡ã—ã¾ã™ã€‚", + "OnlyMatchedUrlsAllowedHelp": "有効ã«ã™ã‚‹ã¨ã€Piwik ã¯ãƒšãƒ¼ã‚¸ URL ãŒã‚ãªãŸã®ã‚¦ã‚§ãƒ–サイト㮠URL ã¨ã—ã¦çŸ¥ã‚‰ã‚ŒãŸã‚‚ã®ã§ã‚る時ã«å†…部ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’追跡ã—ã¾ã™ã€‚ã“れã¯ä»–ã®ã‚¦ã‚§ãƒ–サイト㮠URL を使用ã—ã¦åˆ†æžã‚’スパムã™ã‚‹ã“ã¨ã‹ã‚‰äººã€…を防ãŽã¾ã™ã€‚", "WebsitesManagement": "ウェブサイトã®ç®¡ç†", + "XManagement": "ç®¡ç† %s", + "ChooseMeasurableTypeHeadline": "何を測定ã—ã¾ã™ã‹ï¼Ÿ", "YouCurrentlyHaveAccessToNWebsites": "ç¾åœ¨ %s ã¤ã®ã‚¦ã‚§ãƒ–ã‚µã‚¤ãƒˆã«æŽ¥ç¶šã—ã¦ã„ã¾ã™ã€‚", "YourCurrentIpAddressIs": "ã‚ãªãŸã®ç¾åœ¨ã® IP アドレス㯠%s ã§ã™ã€‚" } diff --git a/plugins/SitesManager/tests/Integration/ModelTest.php b/plugins/SitesManager/tests/Integration/ModelTest.php index 45ebce2be82871c0a42256fdbf06feaf2d52342f..7291ac346f9908dfae1c6b9dddeada2fcc9ade4f 100644 --- a/plugins/SitesManager/tests/Integration/ModelTest.php +++ b/plugins/SitesManager/tests/Integration/ModelTest.php @@ -56,10 +56,56 @@ class ModelTest extends IntegrationTestCase $this->assertSame(array('website', 'universal', 'mobileapp'), $this->model->getUsedTypeIds()); } - private function createMeasurable($type) + public function test_getAllKnownUrlsForAllSites_shouldReturnAllUrls() { - Fixture::createWebsite('2015-01-01 00:00:00', - $ecommerce = 0, $siteName = false, $siteUrl = false, + $idSite = $this->createMeasurable('website', 'http://apache.piwik'); + $this->model->insertSiteUrl($idSite, 'http://example.apache.piwik'); + $this->model->insertSiteUrl($idSite, 'http://example.org'); + + $idSite2 = $this->createMeasurable('website'); + $this->model->insertSiteUrl($idSite2, 'http://example.org'); + $this->model->insertSiteUrl($idSite2, 'http://example.com'); + + $idSite3 = $this->createMeasurable('website', 'http://example.pro'); + + $expected = array( + array( + 'idsite' => $idSite, + 'url' => 'http://apache.piwik' + ), + array( + 'idsite' => $idSite2, + 'url' => 'http://piwik.net' + ), + array( + 'idsite' => $idSite3, + 'url' => 'http://example.pro' + ), + array( + 'idsite' => $idSite, + 'url' => 'http://example.apache.piwik' + ), + array( + 'idsite' => $idSite, + 'url' => 'http://example.org' + ), + array( + 'idsite' => $idSite2, + 'url' => 'http://example.com' + ), + array( + 'idsite' => $idSite2, + 'url' => 'http://example.org' + ) + + ); + $this->assertEquals($expected, $this->model->getAllKnownUrlsForAllSites()); + } + + private function createMeasurable($type, $siteUrl = false) + { + return Fixture::createWebsite('2015-01-01 00:00:00', + $ecommerce = 0, $siteName = false, $siteUrl, $siteSearch = 1, $searchKeywordParameters = null, $searchCategoryParameters = null, $timezone = null, $type); } diff --git a/plugins/SitesManager/tests/Integration/SiteUrlsTest.php b/plugins/SitesManager/tests/Integration/SiteUrlsTest.php index f9362ae2f4b32bab59f4fef058ecc81dc3f3d4b5..3db34199fbf93bdaa3b0df798d1b91ee875e9f60 100644 --- a/plugins/SitesManager/tests/Integration/SiteUrlsTest.php +++ b/plugins/SitesManager/tests/Integration/SiteUrlsTest.php @@ -119,6 +119,176 @@ class SiteUrlsTest extends IntegrationTestCase $this->assertEquals($urlsToFake, $actual); } + public function test_groupUrlsByHost_shouldReturnEmptyArray_WhenNoUrlsGiven() + { + $this->assertSame(array(), $this->siteUrls->groupUrlsByHost(array())); + $this->assertSame(array(), $this->siteUrls->groupUrlsByHost(null)); + } + + public function test_groupUrlsByHost_shouldGroupByHost_WithOneSiteAndDifferentDomains_shouldRemoveWwwAndDefaultToPathSlash() + { + $idSite = 1; + $oneSite = array( + $idSite => array( + 'http://apache.piwik', + 'http://www.example.com', // should remove www. + 'https://example.org', // should handle https or other protocol + 'http://apache.piwik/', // same as initial one but with slash at the end, should not add idsite twice + 'http://third.www.com' // should not remove www. in the middle of a domain + ) + ); + + $expected = array( + 'apache.piwik' => array('/' => array($idSite)), + 'example.com' => array('/' => array($idSite)), + 'example.org' => array('/' => array($idSite)), + 'third.www.com' => array('/' => array($idSite)), + ); + + $this->assertSame($expected, $this->siteUrls->groupUrlsByHost($oneSite)); + } + + public function test_groupUrlsByHost_shouldGroupByHost_WithDifferentDomainsAndPathsShouldListPathByNumberOfDirectoriesAndConvertToLowerCase() + { + $idSite = 1; + $idSite2 = 2; + $idSite3 = 3; + $idSite4 = 4; + $idSite5 = 5; + + $urls = array( + $idSite => array( + 'http://apache.piwik/test', 'http://apache.piWik', 'http://apache.piwik/foo/bAr/', 'http://apache.piwik/Foo/SECOND' + ), + $idSite2 => array( + 'http://apache.piwik/test/', 'http://example.oRg', 'http://apache.piwik/foo/secOnd' + ), + $idSite3 => array( + 'http://apache.piwik/', 'http://apache.piwik/third', 'http://exampLe.com', 'http://example.org/foo/test/two' + ), + $idSite4 => array(), + $idSite5 => array('invalidUrl', 'ftp://example.org/'), + ); + + $expected = array( + 'apache.piwik' => array( + '/foo/second/' => array($idSite, $idSite2), + '/foo/bar/' => array($idSite), + '/third/' => array($idSite3), + '/test/' => array($idSite, $idSite2), + '/' => array($idSite, $idSite3) + ), + 'example.org' => array( + '/foo/test/two/' => array($idSite3), + '/' => array($idSite2, $idSite5) + ), + 'example.com' => array( + '/' => array($idSite3) + ), + ); + + $this->assertSame($expected, $this->siteUrls->groupUrlsByHost($urls)); + } + + /** + * @dataProvider getTestIdSitesMatchingUrl + */ + public function test_getIdSitesMatchingUrl($expectedMatchSites, $parsedUrl) + { + $urlsGroupedByHost = array( + 'apache.piwik' => array( + '/foo/second/' => array(2), + '/foo/sec/' => array(4), + '/foo/bar/' => array(1), + '/third/' => array(3), + '/test/' => array(1, 2), + '/' => array(1, 3) + ), + 'example.org' => array( + '/foo/test/two/' => array(3), + '/foo/second/' => array(6), + '/' => array(2, 5) + ), + 'example.com' => array( + '/' => array(3) + ), + ); + $matchedSites = $this->siteUrls->getIdSitesMatchingUrl($parsedUrl, $urlsGroupedByHost); + + $this->assertSame($expectedMatchSites, $matchedSites); + } + + public function getTestIdSitesMatchingUrl() + { + return array( + array(array(1,3), array('host' => 'apache.piwik')), + array(array(1,3), array('host' => 'apache.piwik', 'path' => '/')), + array(array(1,3), array('host' => 'apache.piwik', 'path' => 'nomatch')), // no other URL matches a site so we fall back to domain match + array(array(1,3), array('host' => 'apache.piwik', 'path' => '/nomatch')), + array(array(2), array('host' => 'apache.piwik', 'path' => '/foo/second')), + array(array(2), array('host' => 'apache.piwik', 'path' => '/foo/second/')), // it shouldn't matter if slash is at end or not + array(array(2), array('host' => 'apache.piwik', 'path' => '/foo/second/test')), // it should find best match + array(array(4), array('host' => 'apache.piwik', 'path' => '/foo/sec/test')), // it should not use /foo/second for these + array(array(4), array('host' => 'apache.piwik', 'path' => '/foo/sec/')), + array(array(4), array('host' => 'apache.piwik', 'path' => '/foo/sec')), + array(array(1,3), array('host' => 'apache.piwik', 'path' => '/foo')), + array(array(2,5), array('host' => 'example.org')), + array(array(2,5), array('host' => 'example.org', 'path' => '/')), + array(array(2,5), array('host' => 'example.org', 'path' => 'any/nonmatching/path')), + array(array(6), array('host' => 'example.org', 'path' => '/foo/second')), + array(array(6), array('host' => 'example.org', 'path' => '/foo/second/test')), + array(array(3), array('host' => 'example.com')), + array(null, array('host' => 'example.pro')), + array(null, array('host' => 'example.pro', 'path' => '/any')), + ); + } + + /** + * @dataProvider getTestPathMatchingUrl + */ + public function test_getPathMatchingUrl($expectedMatchSites, $parsedUrl) + { + $urlsGroupedByHost = array( + 'apache.piwik' => array( + '/foo/second/' => array(2), + '/foo/sec/' => array(4), + '/foo/bar/' => array(1), + '/third/' => array(3), + '/test/' => array(1, 2), + '/' => array(1, 3) + ), + 'example.org' => array( + '/foo/test/two/' => array(3), + '/foo/second/' => array(6), + '/' => array(2, 5) + ), + ); + $matchedSites = $this->siteUrls->getPathMatchingUrl($parsedUrl, $urlsGroupedByHost); + + $this->assertSame($expectedMatchSites, $matchedSites); + } + + public function getTestPathMatchingUrl() + { + return array( + array('/', array('host' => 'apache.piwik')), + array('/', array('host' => 'apache.piwik', 'path' => '/')), + array('/', array('host' => 'apache.piwik', 'path' => '')), + array(null, array('host' => 'test.piwik')), + array(null, array('host' => 'test.apache.piwik')), // we do not match subdomains, only exact domain match + + array('/foo/bar/', array('host' => 'apache.piwik', 'path' => '/foo/bar')), + array('/foo/bar/', array('host' => 'apache.piwik', 'path' => '/foo/bar/')), + array('/foo/bar/', array('host' => 'apache.piwik', 'path' => '/foo/bar/baz/')), + array('/', array('host' => 'apache.piwik', 'path' => '/foo/baz/bar/')), + array('/third/', array('host' => 'apache.piwik', 'path' => '/third/bar/baz/')), + + array('/foo/second/', array('host' => 'example.org', 'path' => '/foo/second/')), + array('/', array('host' => 'example.org', 'path' => '/foo/secon')), + array(null, array('host' => 'example.pro', 'path' => '/foo/second/')), + ); + } + private function assertSiteUrls($expectedUrls) { $urls = $this->siteUrls->getAllSiteUrls(); diff --git a/plugins/TasksTimetable b/plugins/TasksTimetable index 32915362e3f90f8e98929108ccc13695a820c2fd..67c1119ff385f153439e81555d7d3e4a799ebe51 160000 --- a/plugins/TasksTimetable +++ b/plugins/TasksTimetable @@ -1 +1 @@ -Subproject commit 32915362e3f90f8e98929108ccc13695a820c2fd +Subproject commit 67c1119ff385f153439e81555d7d3e4a799ebe51 diff --git a/plugins/TestRunner/Commands/GenerateTravisYmlFile.php b/plugins/TestRunner/Commands/GenerateTravisYmlFile.php index 5e1ac7d1819138f91caf63342062e230e66f5c80..a99c3ae4f0234a5280c6936bc6a593e217ffac1e 100644 --- a/plugins/TestRunner/Commands/GenerateTravisYmlFile.php +++ b/plugins/TestRunner/Commands/GenerateTravisYmlFile.php @@ -39,7 +39,10 @@ class GenerateTravisYmlFile extends ConsoleCommand ->addOption('php-versions', null, InputOption::VALUE_OPTIONAL, "List of PHP versions to test against, ie, 5.4,5.5,5.6. Defaults to: 5.3.3,5.4,5.5,5.6.") ->addOption('dump', null, InputOption::VALUE_REQUIRED, "Debugging option. Saves the output .travis.yml to the specified file.") - ->addOption('repo-root-dir', null, InputOption::VALUE_REQUIRED, "Path to the repo for whom a .travis.yml file will be generated for."); + ->addOption('repo-root-dir', null, InputOption::VALUE_REQUIRED, "Path to the repo for whom a .travis.yml file will be generated for.") + ->addOption('force-php-tests', null, InputOption::VALUE_NONE, "Forces the presence of the PHP tests jobs for plugin builds.") + ->addOption('force-ui-tests', null, InputOption::VALUE_NONE, "Forces the presence of the UI tests jobs for plugin builds.") + ->addOption('sudo-false', null, InputOption::VALUE_NONE, "If supplied, the .travis.yml file will use travis' new infrastructure."); } protected function execute(InputInterface $input, OutputInterface $output) diff --git a/plugins/TestRunner/Commands/TestsRun.php b/plugins/TestRunner/Commands/TestsRun.php index 08e456da1985af8cfe90678dcf37ad3016d15b5a..8a12c07e3b199de27aa35535afc04b5f7f9f5776 100644 --- a/plugins/TestRunner/Commands/TestsRun.php +++ b/plugins/TestRunner/Commands/TestsRun.php @@ -47,10 +47,6 @@ class TestsRun extends ConsoleCommand // bin is the composer executeable directory, where all vendors (should) place their executables $command = PIWIK_VENDOR_PATH . '/bin/phpunit'; - if (version_compare(PHP_VERSION, '5.4.0', '<')) { - $command = 'php -dzend.enable_gc=0 ' . $command; - } - if (!$this->isCoverageEnabled($options) && $this->isXdebugLoaded()) { $message = 'Did you know? You can run tests faster by disabling xdebug'; if($this->isXdebugCodeCoverageEnabled()) { diff --git a/plugins/TestRunner/Commands/TestsRunUI.php b/plugins/TestRunner/Commands/TestsRunUI.php index faf436a8af8bb72e2a590cfaec3df3b981d7491d..3a9a06c080caf628af349c8e51976986f1faddbd 100644 --- a/plugins/TestRunner/Commands/TestsRunUI.php +++ b/plugins/TestRunner/Commands/TestsRunUI.php @@ -26,7 +26,7 @@ class TestsRunUI extends ConsoleCommand \nRun one spec: \n./console tests:run-ui UIIntegrationTest "); - $this->addArgument('specs', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Run only a specific test spec. Separate multiple specs by comma, for instance core,integration', array()); + $this->addArgument('specs', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Run only a specific test spec. Separate multiple specs by a space, for instance UIIntegrationTest ', array()); $this->addOption("persist-fixture-data", null, InputOption::VALUE_NONE, "Persist test data in a database and do not execute tear down."); $this->addOption('keep-symlinks', null, InputOption::VALUE_NONE, "Keep recursive directory symlinks so test pages can be viewed in a browser."); $this->addOption('print-logs', null, InputOption::VALUE_NONE, "Print webpage logs even if tests succeed."); @@ -35,6 +35,9 @@ class TestsRunUI extends ConsoleCommand $this->addOption('plugin', null, InputOption::VALUE_REQUIRED, "Execute all tests for a plugin."); $this->addOption('core', null, InputOption::VALUE_NONE, "Execute only tests for Piwik core & core plugins."); $this->addOption('skip-delete-assets', null, InputOption::VALUE_NONE, "Skip deleting of merged assets (will speed up a test run, but not by a lot)."); + $this->addOption('screenshot-repo', null, InputOption::VALUE_NONE, "For tests"); + $this->addOption('store-in-ui-tests-repo', null, InputOption::VALUE_NONE, "For tests"); + $this->addOption('extra-options', null, InputOption::VALUE_REQUIRED, "Extra options to pass to phantomjs."); } protected function execute(InputInterface $input, OutputInterface $output) @@ -48,6 +51,9 @@ class TestsRunUI extends ConsoleCommand $plugin = $input->getOption('plugin'); $skipDeleteAssets = $input->getOption('skip-delete-assets'); $core = $input->getOption('core'); + $extraOptions = $input->getOption('extra-options'); + $storeInUiTestsRepo = $input->getOption('store-in-ui-tests-repo'); + $screenshotRepo = $input->getOption('screenshot-repo'); if (!$skipDeleteAssets) { AssetManager::getInstance()->removeMergedAssets(); @@ -84,6 +90,18 @@ class TestsRunUI extends ConsoleCommand $options[] = "--core"; } + if ($storeInUiTestsRepo) { + $options[] = "--store-in-ui-tests-repo"; + } + + if ($screenshotRepo) { + $options[] = "--screenshot-repo"; + } + + if ($extraOptions) { + $options[] = $extraOptions; + } + $options = implode(" ", $options); $specs = implode(" ", $specs); @@ -93,7 +111,9 @@ class TestsRunUI extends ConsoleCommand $output->writeln('Executing command: <info>' . $cmd . '</info>'); $output->writeln(''); - passthru($cmd); + passthru($cmd, $returnCode); + + return $returnCode; } /** diff --git a/plugins/TestRunner/Commands/TestsSetupFixture.php b/plugins/TestRunner/Commands/TestsSetupFixture.php index 510578cb76ddae119556f95b4330b3e9a7caa052..565a81122ac150bc0f900762de4abd7da47c92de 100644 --- a/plugins/TestRunner/Commands/TestsSetupFixture.php +++ b/plugins/TestRunner/Commands/TestsSetupFixture.php @@ -154,7 +154,7 @@ class TestsSetupFixture extends ConsoleCommand private function createSymbolicLinksForUITests() { // make sure symbolic links exist (phantomjs doesn't support symlink-ing yet) - foreach (array('libs', 'plugins', 'tests', 'piwik.js') as $linkName) { + foreach (array('libs', 'plugins', 'tests', 'misc', 'piwik.js') as $linkName) { $linkPath = PIWIK_INCLUDE_PATH . '/tests/PHPUnit/proxy/' . $linkName; if (!file_exists($linkPath)) { symlink(PIWIK_INCLUDE_PATH . '/' . $linkName, $linkPath); @@ -192,10 +192,7 @@ class TestsSetupFixture extends ConsoleCommand ); foreach ($optionsToOverride as $configOption => $value) { if ($value) { - $configOverride = $testingEnvironment->configOverride; - $configOverride['database_tests'][$configOption] = $configOverride['database'][$configOption] = $value; - $testingEnvironment->configOverride = $configOverride; - + $testingEnvironment->overrideConfig('database_tests', $configOption, $value); Config::getInstance()->database[$configOption] = $value; } } @@ -212,6 +209,7 @@ class TestsSetupFixture extends ConsoleCommand throw new \Exception("Cannot find fixture class '$fixtureClass'."); } + /** @var Fixture $fixture */ $fixture = new $fixtureClass(); $fixture->printToScreen = true; @@ -233,6 +231,8 @@ class TestsSetupFixture extends ConsoleCommand $fixture->extraPluginsToLoad = explode(',', $extraPluginsToLoad); } + $fixture->extraDiEnvironments = array('ui-test'); + return $fixture; } diff --git a/plugins/Transitions/javascripts/transitions.js b/plugins/Transitions/javascripts/transitions.js index cb98e3d045fe276ae994c3cf3dedda09eaf8fe1f..8461c89069c444d595baf48e85a67d651e5115ba 100644 --- a/plugins/Transitions/javascripts/transitions.js +++ b/plugins/Transitions/javascripts/transitions.js @@ -17,8 +17,12 @@ function DataTable_RowActions_Transitions(dataTable) { DataTable_RowActions_Transitions.prototype = new DataTable_RowAction; /** Static helper method to launch transitions from anywhere */ -DataTable_RowActions_Transitions.launchForUrl = function (url) { - broadcast.propagateNewPopoverParameter('RowAction', 'Transitions:url:' + url); +DataTable_RowActions_Transitions.launchForUrl = function (url, segment) { + var value = 'Transitions:url:' + url; + if (segment) { + value += ':segment:' + segment; + } + broadcast.propagateNewPopoverParameter('RowAction', value); }; DataTable_RowActions_Transitions.isPageUrlReport = function (module, action) { @@ -30,19 +34,25 @@ DataTable_RowActions_Transitions.isPageTitleReport = function (module, action) { return module == 'Actions' && (action == 'getPageTitles' || action == 'getPageTitlesFollowingSiteSearch'); }; +DataTable_RowActions_Transitions.registeredReports = []; +DataTable_RowActions_Transitions.registerReport = function (handler) { + DataTable_RowActions_Transitions.registeredReports.push(handler); +} + DataTable_RowActions_Transitions.prototype.trigger = function (tr, e, subTableLabel) { - var link = tr.find('> td:first > a').attr('href'); - link = $('<textarea>').html(link).val(); // remove html entities - - var module = this.dataTable.param.module; - var action = this.dataTable.param.action; - if (DataTable_RowActions_Transitions.isPageUrlReport(module, action)) { - this.openPopover('url:' + link); - } else if (DataTable_RowActions_Transitions.isPageTitleReport(module, action)) { - DataTable_RowAction.prototype.trigger.apply(this, [tr, e, subTableLabel]); - } else { - alert('Transitions can\'t be used on this report.'); + var i = 0; + for (i; i < DataTable_RowActions_Transitions.registeredReports.length; i++) { + var report = DataTable_RowActions_Transitions.registeredReports[i]; + if (report + && report.trigger + && report.isAvailableOnReport + && report.isAvailableOnReport(this.dataTable.param)) { + report.trigger.apply(this, arguments); + return; + } } + + alert('Transitions can\'t be used on this report.'); }; DataTable_RowActions_Transitions.prototype.performAction = function (label, tr, e) { @@ -57,6 +67,15 @@ DataTable_RowActions_Transitions.prototype.performAction = function (label, tr, }; DataTable_RowActions_Transitions.prototype.doOpenPopover = function (link) { + var posSegment = (link+'').indexOf(':segment:'); + var segment = null; + + // handle and remove ':segment:$SEGMENT' from link + if (posSegment && posSegment > 0) { + segment = link.substring(posSegment + (':segment:'.length)); + link = link.substring(0, posSegment); + } + var parts = link.split(':'); if (parts.length < 2) { return; @@ -67,9 +86,9 @@ DataTable_RowActions_Transitions.prototype.doOpenPopover = function (link) { var actionName = parts.join(':'); if (this.transitions === null) { - this.transitions = new Piwik_Transitions(actionType, actionName, this); + this.transitions = new Piwik_Transitions(actionType, actionName, this, segment); } else { - this.transitions.reset(actionType, actionName); + this.transitions.reset(actionType, actionName, segment); } this.transitions.showPopover(); }; @@ -93,10 +112,17 @@ DataTable_RowActions_Registry.register({ }, isAvailableOnReport: function (dataTableParams) { - return ( - DataTable_RowActions_Transitions.isPageUrlReport(dataTableParams.module, dataTableParams.action) || - DataTable_RowActions_Transitions.isPageTitleReport(dataTableParams.module, dataTableParams.action) - ); + var i = 0; + for (i; i < DataTable_RowActions_Transitions.registeredReports.length; i++) { + var report = DataTable_RowActions_Transitions.registeredReports[i]; + if (report + && report.isAvailableOnReport + && report.isAvailableOnReport(dataTableParams)) { + return true; + } + } + + return false; }, isAvailableOnRow: function (dataTableParams, tr) { @@ -104,11 +130,18 @@ DataTable_RowActions_Registry.register({ // not available on groups (i.e. folders) return false; } - if (DataTable_RowActions_Transitions.isPageUrlReport(dataTableParams.module, dataTableParams.action) - && !tr.find('> td:first span.label').parent().is('a')) { - // not on page url without link (i.e. "Page URL not defined") - return false; + + var i = 0; + for (i; i < DataTable_RowActions_Transitions.registeredReports.length; i++) { + var report = DataTable_RowActions_Transitions.registeredReports[i]; + if (report + && report.isAvailableOnRow + && report.isAvailableOnReport + && report.isAvailableOnReport(dataTableParams)) { + return report.isAvailableOnRow(dataTableParams, tr); + } } + return true; } @@ -118,8 +151,8 @@ DataTable_RowActions_Registry.register({ // TRANSITIONS IMPLEMENTATION // -function Piwik_Transitions(actionType, actionName, rowAction) { - this.reset(actionType, actionName); +function Piwik_Transitions(actionType, actionName, rowAction, segment) { + this.reset(actionType, actionName, segment); this.rowAction = rowAction; this.ajax = new Piwik_Transitions_Ajax(); @@ -129,9 +162,10 @@ function Piwik_Transitions(actionType, actionName, rowAction) { this.rightGroups = ['followingPages', 'followingSiteSearches', 'downloads', 'outlinks']; } -Piwik_Transitions.prototype.reset = function (actionType, actionName) { +Piwik_Transitions.prototype.reset = function (actionType, actionName, segment) { this.actionType = actionType; this.actionName = actionName; + this.segment = segment; this.popover = null; this.canvas = null; @@ -179,7 +213,7 @@ Piwik_Transitions.prototype.showPopover = function () { } // load the data - self.model.loadData(self.actionType, self.actionName, function () { + self.model.loadData(self.actionType, self.actionName, self.segment, function () { if (typeof Piwik_Transitions.popoverHtml == 'undefined') { // html not there yet callbackForHtml = bothLoaded; @@ -1249,7 +1283,7 @@ Piwik_Transitions_Model.prototype.htmlLoaded = function () { }; }; -Piwik_Transitions_Model.prototype.loadData = function (actionType, actionName, callback) { +Piwik_Transitions_Model.prototype.loadData = function (actionType, actionName, segment, callback) { var self = this; this.pageviews = 0; @@ -1287,11 +1321,16 @@ Piwik_Transitions_Model.prototype.loadData = function (actionType, actionName, c this.date = ''; - this.ajax.callApi('Transitions.getTransitionsForAction', { - actionType: actionType, - actionName: actionName, - expanded: 1 - }, + var params = { + actionType: actionType, + actionName: actionName, + expanded: 1 + }; + if (segment) { + params.segment = segment; + } + + this.ajax.callApi('Transitions.getTransitionsForAction', params, function (report) { self.date = report.date; diff --git a/plugins/Transitions/lang/ko.json b/plugins/Transitions/lang/ko.json index 468c039e52135fb016a48286091a4db618f21389..1acc59cff6c8de161ebae967afe74cd0c9828c33 100644 --- a/plugins/Transitions/lang/ko.json +++ b/plugins/Transitions/lang/ko.json @@ -16,6 +16,7 @@ "NoDataForAction": "%s ë°ì´í„° ì—†ìŒ", "NoDataForActionDetails": "íŠ¹ì • ë™ìž‘ì€ %sì„ í•˜ëŠ” 기간 ë™ì•ˆ 페ì´ì§€ë·°ê°€ ì¼ì–´ë‚˜ì§€ 않거나 ìœ íš¨í•˜ì§€ 않습니다.", "OutgoingTraffic": "나가는 트래픽", + "PluginDescription": "새로운 ë³€í™”ì— ëŒ€í•œ ë³´ê³ ì„œ ë‚´ ê° íŽ˜ì´ì§€ URLì— ëŒ€í•œ ì´ì „ ë° ë‹¤ìŒì˜ ë³´ê³ ì„œëŠ” 새 ì•„ì´ì½˜ì„ 통한 ë™ìž‘ ë³´ê³ ì„œì—서 확ì¸í• 수 있습니다.", "ShareOfAllPageviews": "ì´ íŽ˜ì´ì§€ì˜ 페ì´ì§€ë·° %s (ì „ì²´ 페ì´ì§€ë·° 수 %s)", "ToFollowingPages": "ë‚´ë¶€ 페ì´ì§€ë¡œ", "ToFollowingPagesInline": "%s ë‚´ë¶€ 페ì´ì§€", diff --git a/plugins/TreemapVisualization b/plugins/TreemapVisualization index 9640640f7b49374790330699c9985634ecb9c0ae..e487d14390a4b99504a38ba6237705c10317b127 160000 --- a/plugins/TreemapVisualization +++ b/plugins/TreemapVisualization @@ -1 +1 @@ -Subproject commit 9640640f7b49374790330699c9985634ecb9c0ae +Subproject commit e487d14390a4b99504a38ba6237705c10317b127 diff --git a/plugins/UserCountry/lang/cs.json b/plugins/UserCountry/lang/cs.json index d39b67ea08baeae3b4223d63e88485da7808b5f1..821069f8d49e56237ee94899bc9aa6c4b50ea635 100644 --- a/plugins/UserCountry/lang/cs.json +++ b/plugins/UserCountry/lang/cs.json @@ -6,7 +6,7 @@ "CannotFindPeclGeoIPDb": "NepodaÅ™ilo se najÃt databázi zemÃ, regionů nebo mÄ›st pro GEOIP modul PECl. UjistÄ›te se, že vaÅ¡e GEOIP databáze je umÃsÄ›na v adresáři %1$s a je pojmenována %2$s nebo %3$s, jinak si jà GEOIP modul PECl nevÅ¡imne.", "CannotListContent": "NepodaÅ™ilo se vypsat obsah pro %1$s: %2$s", "CannotLocalizeLocalIP": "IP adresa %s je mÃstnà a enemůže být geolokována.", - "CannotSetupGeoIPAutoUpdating": "Vypadá to, že vaÅ¡e GEOIP databáze ukládáte vnÄ› Piwiku (vÃme to, protože v podadresáři misc žádné databáze nejsou, ale gEOIP funguje). Piwik nemůže automaticky aktualizovat GEOIP databázi, když nenà uložena v podadresáři misc.", + "CannotSetupGeoIPAutoUpdating": "Vypadá to, že svoje GEOIP databáze ukládáte vnÄ› Piwiku (vÃme to, protože v podadresáři misc žádné databáze nejsou, ale gEOIP funguje). Piwik nemůže automaticky aktualizovat GEOIP databázi, pokud nenà uložena v podadresáři misc.", "CannotUnzipDatFile": "NepodaÅ™ilo se rozbalit dat soubor v %1$s: %2$s", "City": "MÄ›sto", "CityAndCountry": "%1$s, %2$s", @@ -84,7 +84,7 @@ "Region": "Region", "SetupAutomaticUpdatesOfGeoIP": "Nastavit automatické aktualizace GeoIP databázÃ", "SubmenuLocations": "UmÃstÄ›nÃ", - "TestIPLocatorFailed": "Piwik se pokusil zjistit mÃstÄ›nà námé IP adresy %1$s, ale server odpovÄ›dÄ›l %2$s. Kdyby byl tento poskytovatel nastaven správnÄ›, odpovÄ›dÄ›l by %3$s.", + "TestIPLocatorFailed": "Piwik se pokusil zjistit mÃstÄ›nà známé IP adresy %1$s, ale server odpovÄ›dÄ›l %2$s. Pokud by byl tento poskytovatel nastaven správnÄ›, odpovÄ›dÄ›l by %3$s.", "ThisUrlIsNotAValidGeoIPDB": "Stažený soubor nenà platná GeoIP databáze. Zkontrolujte URL, nebo soubor stáhnÄ›te ruÄnÄ›.", "ToGeolocateOldVisits": "Pokud chcete zÃskat data o umÃstÄ›nà pro staré návÅ¡tÄ›vy, použijte skript popisovaný %1$szde%2$s.", "UnsupportedArchiveType": "Nalezen nepodporovaný typ archivu %1$s.", diff --git a/plugins/UserCountry/lang/id.json b/plugins/UserCountry/lang/id.json index 5a49080dfcd067d03c3d4f8ea9f2d0d751defe81..efc27e6e38e893150aa1ac810fa37af0cdf5f06c 100644 --- a/plugins/UserCountry/lang/id.json +++ b/plugins/UserCountry/lang/id.json @@ -9,12 +9,14 @@ "CannotSetupGeoIPAutoUpdating": "Tampaknya Anda menyimpan basidata GeoIP Anda di luar Piwik (kami dapat katakan sejak tidak ada basisdata di subdirektori misc, tapi GeoIP Anda berkerja). Piwik tidak dapat otomatis memperbarui basisdata GeoIP Anda bila berada di luar direktori misc.", "CannotUnzipDatFile": "Tidak dapat melakukan unzip berkas dat di %1$s: %2$s", "City": "Kota", + "CityAndCountry": "%1$s, %2$s", "Continent": "Benua", "Country": "Negara", "country_a1": "Wali Anonim", "country_a2": "Penyedia Satelit", "country_cat": "Masyarakat berbahasa Katalan", "country_o1": "Negara Lain", + "country_ti": "Tibet", "CurrentLocationIntro": "Berdasar penyedia ini, lokasi Anda adalah", "DefaultLocationProviderDesc1": "Lokasi penyedia asali menebak negara pengunjung dari bahasa yang digunakan.", "DefaultLocationProviderDesc2": "Ini sangat tidak teliti, serta %1$skami menyarankan memasang dan menggunakan %2$sGeoIP%3$s.%4$s", @@ -23,6 +25,7 @@ "DownloadNewDatabasesEvery": "Perbarui basisdata setiap", "FatalErrorDuringDownload": "Galat fatal terjadi ketika mengunduh berkas ini. Kemungkinan ada yang salah dengan sambungan internet Anda, dengan basisdata GeoIP yang Anda unduh, atau Piwik. Silakan coba mengunduh dan memasang secara manual.", "FoundApacheModules": "Piwik menemukan modul Apache berikut", + "FromDifferentCities": "kota berbeda", "GeoIPCannotFindMbstringExtension": "Tidak dapat menemukan fungsi %1$s. Harap pastikan bahwa ekstensi %2$s telah terpasang dan termuat.", "GeoIPDatabases": "Basisdata GeoIP", "GeoIPDocumentationSuffix": "Agar dapat melihat data untuk laporan ini, Anda harus memasang GeoIP di tab pengelola Lokasi-Geo. Basisdata GeoIP %1$sMaxmind%2$s komersial lebih teliti daripada yang gratis. Untuk melihat seberapa teliti mereka, klik %3$sdi sini%4$s.", diff --git a/plugins/UserCountry/lang/ja.json b/plugins/UserCountry/lang/ja.json index f5d3a082148d06f96c009203cf6a7d6b5b07e05d..303595ae439ea1b9cff6c6ef45fb0d19832f5d4c 100644 --- a/plugins/UserCountry/lang/ja.json +++ b/plugins/UserCountry/lang/ja.json @@ -16,6 +16,7 @@ "country_a2": "衛星プãƒãƒã‚¤ãƒ€", "country_cat": "ã‚«ã‚¿ãƒãƒ‹ã‚¢èªžåœã®ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£", "country_o1": "ãã®ä»–ã®å›½", + "country_ti": "ãƒãƒ™ãƒƒãƒˆ", "CurrentLocationIntro": "ã“ã®ãƒ—ãƒãƒã‚¤ãƒ€ãƒ¼ã«ã‚ˆã‚‹ã¨ã€ã‚ãªãŸã®ç¾åœ¨åœ°ã¯", "DefaultLocationProviderDesc1": "デフォルトãƒã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒ—ãƒãƒã‚¤ãƒ€ãƒ¼ã§ã¯ã€ãƒ“ジターã®å›½ã¯ä½¿ç”¨è¨€èªžã«åŸºã¥ã„ã¦æŽ¨æ¸¬ã•れã¾ã™ã€‚", "DefaultLocationProviderDesc2": "ã“ã‚Œã¯æ£ç¢ºã§ã¯ã‚りã¾ã›ã‚“。%1$swe recommend installing and using %2$sGeoIP%3$s。%4$s", diff --git a/plugins/UserCountry/lang/ko.json b/plugins/UserCountry/lang/ko.json index 13a2f18b53886b6f570b710d8dbd9de04a7b12d6..0ef8232311ce88c06eeda83e20457be4cc79441f 100644 --- a/plugins/UserCountry/lang/ko.json +++ b/plugins/UserCountry/lang/ko.json @@ -2,38 +2,44 @@ "UserCountry": { "AssumingNonApache": "아파치 웹서버가 아니어서 apache_get_modulesì„ ì°¾ì„ ìˆ˜ 없습니다.", "CannotFindGeoIPDatabaseInArchive": "%2$s tar 압축파ì¼ì—서 %1$s 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다!", - "CannotFindGeoIPServerVar": "%sì— ë³€ìˆ˜ê°€ ì„¤ì •ë˜ì–´ 있지 않습니다. 서버가 올바르게 êµ¬ì„±ë˜ ì•Šì•˜ì„ ìˆ˜ 있습니다.", + "CannotFindGeoIPServerVar": "%sì— ë³€ìˆ˜ê°€ ì„¤ì •ë˜ì–´ 있지 않습니다. 서버가 올바르게 구성ë˜ì§€ ì•Šì•˜ì„ ìˆ˜ 있습니다.", "CannotFindPeclGeoIPDb": "GeoIP PECL 모듈ì—서 êµê°€, ì§€ì— ë˜ëŠ” ë„시 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ì°¾ì„ ìˆ˜ 없습니다. GeoIP ë°ì´í„°ë² ì´ìŠ¤ê°€ %1$sì— ìœ„ì¹˜í•˜ê³ íŒŒì¼ ì´ë¦„ì´ %2$s ë˜ëŠ” %3$sì¸ì§€ 확ì¸í•˜ì„¸ìš”. 틀린 ë¶€ë¶„ì´ ìžˆë‹¤ë©´ PECL ëª¨ë“ˆì„ ì¸ì‹í•˜ì§€ 못합니다.", "CannotListContent": "%1$sì— ëŒ€í•œ ë‚´ìš©ì„ ë‚˜ì—´ í• ìˆ˜ 없습니다: %2$s", "CannotLocalizeLocalIP": "IP 주소 %s는 로컬 주소ì´ê¸° ë•Œë¬¸ì— ìœ„ì¹˜ë¥¼ ì¶”ì í• ìˆ˜ 없습니다.", - "CannotSetupGeoIPAutoUpdating": "Piwikì˜ ì™¸ë¶€ì—서 GeoIP ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ì €ìž¥í•œ 것 같군요 (하위 ë””ë ‰í† ë¦¬ì¸ miscì— ë°ì´í„°ë² ì´ìŠ¤ê°€ 없지만, ë‹¹ì‹ ì˜ GeoIPê°€ 잘 ìž‘ë™í•˜ê³ 있어요) ì´ íŒŒì¼ë“¤ì´ misc ë””ë ‰í† ë¦¬ì˜ ë°–ì— ìžˆëŠ” 경우, Piwik는 ìžë™ìœ¼ë¡œ GeoIP ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ì—…ë°ì´íŠ¸í• ìˆ˜ 없습니다.", + "CannotSetupGeoIPAutoUpdating": "Piwikì˜ ì™¸ë¶€ì—서 GeoIP ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ì €ìž¥í•œ 것 같군요 (하위 ë””ë ‰í† ë¦¬ì¸ miscì— ë°ì´í„°ë² ì´ìŠ¤ê°€ 없지만, ë‹¹ì‹ ì˜ GeoIPê°€ 잘 ìž‘ë™í•˜ê³ 있어요). ì´ íŒŒì¼ë“¤ì´ misc ë””ë ‰í† ë¦¬ì˜ ë°–ì— ìžˆëŠ” 경우, Piwik는 ìžë™ìœ¼ë¡œ GeoIP ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ì—…ë°ì´íŠ¸í• ìˆ˜ 없습니다.", "CannotUnzipDatFile": "%1$sì˜ DAT íŒŒì¼ ì••ì¶•ì„ í’€ 수 없습니다: %2$s", "City": "ë„시", + "CityAndCountry": "%1$s, %2$s", "Continent": "대륙", "Country": "êµê°€", "country_a1": "ìµëª… 프ë¡ì‹œ", "country_a2": "위성 공급ìž", "country_cat": "카탈로니아 ì§€ì—ì˜ ì»¤ë®¤ë‹ˆí‹°", "country_o1": "기타 êµê°€", + "country_ti": "í‹°ë² íŠ¸", "CurrentLocationIntro": "ì´ ê³µê¸‰ìžì— 따르면, 현재 위치는", "DefaultLocationProviderDesc1": "방문ìžì˜ êµê°€ì— 기반하는 언어ì—서 추측하는 기본 위치 공급ìžìž…니다.", "DefaultLocationProviderDesc2": "ì´ê²ƒì€ 매우 ë¶€ì •í™•í•©ë‹ˆë‹¤. 그래서 %1$s우리는 %2$sGeoIP%3$s를 설치하여 사용하는 ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤.%4$s", + "DefaultLocationProviderExplanation": "ë‹¹ì‹ ì€ í˜„ìž¬ 기본 위치 공급ìžë¥¼ ì‚¬ìš©í•˜ê³ ìžˆì–´, Piwik는 방문ìžì˜ 위치를 ê·¸ë“¤ì´ ì‚¬ìš©í•˜ëŠ” ì–¸ì–´ì— ê¸°ë°˜í•˜ì—¬ ì¶”ì¸¡í•˜ê³ ìžˆìŠµë‹ˆë‹¤. %1$sì´ ë¬¸ì„œ%2$sì—서 어떻게 ë” ì •í™•í•œ 위치를 얻어낼 수 있는지 ì–˜ê¸°í•˜ê³ ìžˆìŠµë‹ˆë‹¤.", "DistinctCountries": "%sê°œ êµê°€", "DownloadingDb": "다운로드 중 %s", "DownloadNewDatabasesEvery": "ëª¨ë“ ë°ì´í„°ë² ì´ìФ ì—…ë°ì´íЏ", "FatalErrorDuringDownload": "파ì¼ì„ 다운로드하는 ë™ì•ˆ 치명ì ì¸ ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤. Piwikì—서 GeoIP ë°ì´í„°ë² ì´ìФ ë‹¤ìš´ë¡œë“œí•˜ëŠ”ë° ì¸í„°ë„· ì—°ê²°ì— ë¬¸ì œê°€ ìžˆì„ ìˆ˜ 있습니다, ì§ì ‘ 다운로드해서 수ë™ìœ¼ë¡œ 설치해 보세요.", "FoundApacheModules": "Piwikì€ ë‹¤ìŒì˜ 아파치 ëª¨ë“ˆì„ ì°¾ì„ ìˆ˜ ì—†ìŒ", - "GeoIPCannotFindMbstringExtension": "%1$s 함수를 ì°¾ì„ ìˆ˜ 없습니다. %2$s í™•ìž¥ì´ ì„¤ì¹˜ë˜ì—ˆê³ 로드ë˜ì—ˆëŠ”ì§€ 확ì¸í•˜ì„¸ìš”.", + "FromDifferentCities": "다른 ë„시", + "GeoIPCannotFindMbstringExtension": "%1$s 함수를 ì°¾ì„ ìˆ˜ 없습니다. %2$s í™•ìž¥ì´ ì„¤ì¹˜ ë° ë¡œë“œë˜ì—ˆëŠ”ì§€ 확ì¸í•˜ì„¸ìš”.", "GeoIPDatabases": "GeoIP ë°ì´í„°ë² ì´ìФ", "GeoIPDocumentationSuffix": "ì´ ë³´ê³ ì„œì— ëŒ€í•œ ë°ì´í„°ë¥¼ ë³¼ 수 있ë„ë¡ ë‹¹ì‹ ì€ ìœ„ì¹˜ ì •ë³´ê´€ë¦¬ íƒì—서 GeoIP를 ì„¤ì •í•´ì•¼í•©ë‹ˆë‹¤. ìƒì—…ìš© %1$sMaxmind%2$s GeoIP ë°ì´í„°ë² ì´ìŠ¤ëŠ” 무료로 ë²„ì „ë³´ë‹¤ ë” ì •í™•í•©ë‹ˆë‹¤. ì •í™•ë„를 높ì´ë ¤ë©´ %3$sê³µìœ %4$s를 í´ë¦í•˜ì„¸ìš”.", "GeoIPImplHasAccessTo": "ì´ GeoIP 구현ì—서 ì ‘ê·¼í•˜ëŠ” ë°ì´í„°ë² ì´ìФ ìœ í˜•ì€", + "GeoIPIncorrectDatabaseFormat": "ë‹¹ì‹ ì´ ì‚¬ìš©í•˜ëŠ” GeoIP ë°ì´í„°ë² ì´ìŠ¤ëŠ” 올바른 í¬ë©§ì„ ê°€ì§€ê³ ìžˆì§€ 않는 듯싶습니다. ì•„ë§ˆë„ ì†ìƒëœ 것으로 보입니다. ë°”ì´ë„ˆë¦¬ ë²„ì „ì„ ì‚¬ìš©í•˜ëŠ”ì§€ 확ì¸í•˜ì‹œê³ 다른 복사본으로 바꿔 다시 진행해보세요.", "GeoIpLocationProviderDesc_Pecl1": "ì´ ìœ„ì¹˜ 공급ìžëŠ” PECL 모듈과 GeoIP ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 사용하여 ì •í™•í•˜ê³ íš¨ìœ¨ì 으로 방문ìžì˜ 위치를 â€‹â€‹ê²°ì •í•©ë‹ˆë‹¤.", - "GeoIpLocationProviderDesc_Pecl2": "ì œí•œì´ ì—†ëŠ” 공급ìžìž…니다. 그래서 우리는 ì´ê²ƒì´ 사용ë˜ëŠ” ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤.", + "GeoIpLocationProviderDesc_Pecl2": "ì œí•œì´ ì—†ëŠ” 공급ìžìž…니다. 그래서 우리는 ì´ë¥¼ 사용하는 ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤.", "GeoIpLocationProviderDesc_Php1": "ì´ ìœ„ì¹˜ 공급ìžëŠ” ì„œë²„ì— ì„¤ì¹˜ ë° êµ¬ì„±ì„ ìš”êµ¬í•˜ì§€ 않기 ë•Œë¬¸ì— ê°€ìž¥ 간단합니다 (ê³µìœ í˜¸ìŠ¤íŒ…ì— ì í•©!). GeoIP ë°ì´í„°ë² ì´ìФ ë° MaxMindì˜ PHP API를 사용하여 ì •í™•í•˜ê²Œ 방문ìžì˜ 위치를 â€‹â€‹ê²°ì •í•©ë‹ˆë‹¤.", "GeoIpLocationProviderDesc_Php2": "웹사ì´íЏ íŠ¸ëž˜í”½ì´ ë†’ì€ ê²½ìš°ì— ì´ ìœ„ì¹˜ 공급ìžëŠ” 너무 ëŠë¦½ë‹ˆë‹¤. ì´ ê²½ìš°ëŠ” %1$sPECL 확장%2$sì´ë‚˜ %3$s서버 모듈%4$sì„ ì„¤ì¹˜í•˜ëŠ” ê²ƒì´ ì¢‹ìŠµë‹ˆë‹¤.", "GeoIpLocationProviderDesc_ServerBased1": "ì´ ìœ„ì¹˜ 공급ìžëŠ” HTTP ì„œë²„ì— ì„¤ì¹˜ë˜ëŠ” GeoIP ëª¨ë“ˆì„ ì‚¬ìš©í•©ë‹ˆë‹¤. ì´ ê²ƒì€ ë¹ ë¥´ê³ ì •í™•í•˜ì§€ë§Œ, %1$sì¼ë°˜ 브ë¼ìš°ì €ì˜ ì¶”ì ë§Œ ì‚¬ìš©í• ìˆ˜ 있습니다.%2$s", "GeoIpLocationProviderDesc_ServerBased2": "로그 파ì¼ì„ ê°€ì ¸ì˜¤ê±°ë‚˜ IP 주소 ì„¤ì •ì„ í•„ìš”ë¡œí•˜ëŠ” 경우 %1$sPECL GeoIP 구현 (권장)%2$s ë˜ëŠ” %3$sPHP GeoIP 구현%4$sì„ ì‚¬ìš©í•©ë‹ˆë‹¤.", "GeoIpLocationProviderDesc_ServerBasedAnonWarn": "ì°¸ê³ : IP를 ìµëª…화하면 공급ìžê°€ ë³´ê³ ìžˆëŠ” ìœ„ì¹˜ì— ì•„ë¬´ëŸ° ì˜í–¥ì„ 미치지 않습니다. IP를 ìµëª…í™” 하지 않으면, ê°œì¸ ì •ë³´ ë³´í˜¸ë²•ì„ ìœ„ë°˜ì´ ë 수 있으므로 주ì˜í•˜ì„¸ìš”.", + "GeoIpLocationProviderNotRecomnended": "지리ì 위치 플러그ì¸ì€ ë™ìž‘하지만, 현재 ë‹¹ì‹ ì€ ì¶”ì²œí•˜ëŠ” 공급ìžë¥¼ ì‚¬ìš©í•˜ê³ ìžˆì§€ 않습니다.", "GeoIPNoServerVars": "Piwikì€ GeoIP %s 변수를 ì°¾ì„ ìˆ˜ 없습니다.", "GeoIPPeclCustomDirNotSet": "%s PHP ini ì˜µì…˜ì´ ì„¤ì •ë˜ì–´ 있지 않습니다.", "GeoIPServerVarsFound": "Piwikì€ ë‹¤ìŒì˜ GeoIP %s 변수를 ê°ì§€í•¨", @@ -52,7 +58,7 @@ "HowToInstallNginxModule": "Nginxì— GeoIP ëª¨ë“ˆì„ ì„¤ì¹˜í•˜ë ¤ë©´ 어떻게해야합니까?", "HowToSetupGeoIP": "GeoIP로 ì •í™•í•œ 위치 ì •ë³´ë¥¼ ì„¤ì •í•˜ëŠ” 방법", "HowToSetupGeoIP_Step1": "%3$sMaxMind%4$sì—서 GeoLite ë„시 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ %1$s다운로드%2$s 합니다.", - "HowToSetupGeoIP_Step2": "ì´ íŒŒì¼ì˜ ì••ì¶•ì„ í’€ê³ %1$s 파ì¼ì„ Piwik 하위 ë””ë ‰í† ë¦¬ì¸ %2$smisc%3$s로 복사합니다 (FTP나 SSH를 ì´ìš©í•˜ì—¬).", + "HowToSetupGeoIP_Step2": "(FTP나 SSH를 ì´ìš©í•˜ì—¬) ì´ íŒŒì¼ì˜ ì••ì¶•ì„ í’€ê³ %1$s 파ì¼ì„ Piwik 하위 ë””ë ‰í† ë¦¬ì¸ %2$smisc%3$s로 복사합니다.", "HowToSetupGeoIP_Step3": "í™”ë©´ì„ ìƒˆë¡œ ê³ ì¹¨í•©ë‹ˆë‹¤. %1$sGeoIP (PHP)%2$s 공급ìžê°€ %3$s설치ë¨%4$s으로 ë‚˜íƒ€ë‚ ê²ƒìž…ë‹ˆë‹¤. ì´ê²ƒì„ ì„ íƒí•©ë‹ˆë‹¤.", "HowToSetupGeoIP_Step4": "작업 완료! ì´ì œ Piwikì€ GeoIP를 사용하ë„ë¡ ì„¤ì •ë˜ì—ˆìœ¼ë©°, ì´ê²ƒì€ 방문ìžì˜ ì •í™•í•œ êµê°€ì™€ ë„시 ì§€ì— ì •ë³´ë¥¼ ë³¼ 수 있ìŒì„ ì˜ë¯¸í•©ë‹ˆë‹¤.", "HowToSetupGeoIPIntro": "위치 ì •ë³´ë¥¼ ì •í™•í•˜ê²Œ ì„¤ì •í•˜ì§€ 않으면 방문ìžì˜ 위치 ì •ë³´ ë° ì´ì™€ ê´€ë ¨í•œ ìœ ìš©í•œ ê¸°ëŠ¥ì´ í‘œì‹œë˜ì§€ 않습니다. ë‹¤ìŒ ë°©ë²•ì„ ì°¸ê³ í•˜ì—¬ 어서 ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì„¸ìš”:", @@ -64,7 +70,7 @@ "Latitude": "위ë„", "Location": "위치", "LocationDatabase": "위치 ë°ì´í„°ë² ì´ìФ", - "LocationDatabaseHint": "위치 ë°ì´í„°ë² ì´ìФ 중 하나 êµê°€, ì§€ì— ë˜ëŠ” ë„시 ë°ì´í„°ë² ì´ìŠ¤ìž…ë‹ˆë‹¤.", + "LocationDatabaseHint": "위치 ë°ì´í„°ë² ì´ìŠ¤ëŠ” êµê°€, ì§€ì— ë˜ëŠ” ë„시 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ë§í•©ë‹ˆë‹¤.", "LocationProvider": "위치 공급ìž", "Longitude": "ê²½ë„", "NoDataForGeoIPReport1": "ì´ ë³´ê³ ì„œì— ëŒ€í•œ ë°ì´í„°ê°€ 없습니다. ì–´ë– í•œ 위치 ë°ì´í„°ë„ ì‚¬ìš©í• ìˆ˜ 없거나, 방문ìžì˜ IP 주소ì—서 ì§€ì—ì •ë³´ë¥¼ ì°¾ì„ ìˆ˜ 없기 때문입니다.", @@ -74,6 +80,7 @@ "PeclGeoIPNoDBDir": "PECL ëª¨ë“ˆì´ %1$s 경로ì—서 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 찾았지만, ë””ë ‰í† ë¦¬ê°€ 존재하지 않습니다. ë””ë ‰í† ë¦¬ë¥¼ ë§Œë“¤ê³ ì—¬ê¸°ì— GeoIP ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 추가하세요. 대안으로, php.ini 파ì¼ì— 올바른 ë””ë ‰í† ë¦¬ë¥¼ %2$s 경로를 ì„¤ì •í• ìˆ˜ 있습니다.", "PeclGeoLiteError": "%1$sì— ìžˆëŠ” GeoIP ë°ì´í„°ë² ì´ìФ ì´ë¦„ì€ %2$s입니다. 안타ê¹ê²Œë„, PECL ëª¨ë“ˆì€ ì´ ì´ë¦„으로 ì¸ì‹í•˜ì§€ 않습니다. ì´ë¦„ì„ %3$s로 변경해 주세요.", "PiwikNotManagingGeoIPDBs": "Piwikì€ í˜„ìž¬ ëª¨ë“ GeoIP ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 관리하지 않습니다.", + "PluginDescription": "ë°©ë¬¸ìž ìœ„ì¹˜ ë³´ê³ ì„œ: êµê°€, ì§€ì—, ë„시, 지리ì 좌표(위ë„\/ê²½ë„)", "Region": "ì§€ì—", "SetupAutomaticUpdatesOfGeoIP": "GeoIP ë°ì´í„°ë² ì´ìŠ¤ì˜ ìžë™ ì—…ë°ì´íЏ ì„¤ì •", "SubmenuLocations": "위치", @@ -81,7 +88,11 @@ "ThisUrlIsNotAValidGeoIPDB": "다운로드 한 파ì¼ì€ ìœ íš¨í•œ GeoIP ë°ì´í„°ë² ì´ìŠ¤ê°€ 아닙니다. URLì„ ë‹¤ì‹œ 확ì¸í•˜ê±°ë‚˜ 수ë™ìœ¼ë¡œ 파ì¼ì„ 다운로드하기 ë°”ëžë‹ˆë‹¤.", "ToGeolocateOldVisits": "ê¸°ì¡´ì˜ ë°©ë¬¸ì˜ ìœ„ì¹˜ ë°ì´í„°ë¥¼ ì–»ìœ¼ë ¤ë©´ %1$sì´ ê³³%2$sì— ìžˆëŠ” 스í¬ë¦½íЏ ì„¤ëª…ì„ ì‚¬ìš©í•˜ì„¸ìš”.", "UnsupportedArchiveType": "ì§€ì›ë˜ì§€ 않는 ì••ì¶• í˜•ì‹ %1$s 입니다.", + "UpdaterHasNotBeenRun": "ì—…ë°ì´í„°ê°€ 한 ë²ˆë„ ì‹¤í–‰ë˜ì§€ 않았습니다.", + "UpdaterIsNotScheduledToRun": "향후 ì‹¤í–‰í• ê³„íšì´ 없습니다.", + "UpdaterScheduledForNextRun": "ë‹¤ìŒ cron core:archive ëª…ë ¹ 수행시 실행ë©ë‹ˆë‹¤.", "UpdaterWasLastRun": "%sì— ë§ˆì§€ë§‰ ì—…ë°ì´íЏ 확ì¸", + "UpdaterWillRunNext": "%sì— ì‹¤í–‰ì´ ê³„íšë˜ì–´ 있습니다.", "WidgetLocation": "ë°©ë¬¸ìž ìœ„ì¹˜" } } \ No newline at end of file diff --git a/plugins/UserCountry/lang/tr.json b/plugins/UserCountry/lang/tr.json index 58b4148923ac0e55a1b91c5a945c8a751324bb42..16fa632c4920b79a6a372f399a2432fd04863e43 100644 --- a/plugins/UserCountry/lang/tr.json +++ b/plugins/UserCountry/lang/tr.json @@ -4,11 +4,13 @@ "Continent": "Kıta", "Country": "Ülke", "country_o1": "DiÄŸer Ükle", + "DownloadingDb": "Karşıdan Yükleme %s", "Geolocation": "CoÄŸrafi Lokasyon", "GeolocationPageDesc": "Bu sayfada Piwik'in ziyaretçi lokasyonunu nasıl bulacağını ayarlayabilirsiniz.", "Latitude": "Enlem", "Location": "Konum", "Longitude": "Boylam", + "Organization": "Organizasyon", "Region": "Bölge", "SubmenuLocations": "Konumlar" } diff --git a/plugins/UserCountryMap/lang/id.json b/plugins/UserCountryMap/lang/id.json index dc6cddf74374818f78671872c4997b724abc1acf..84fce004d8f2d43f6c46dd771d30507e74dc2712 100644 --- a/plugins/UserCountryMap/lang/id.json +++ b/plugins/UserCountryMap/lang/id.json @@ -1,5 +1,6 @@ { "UserCountryMap": { + "PluginDescription": "Pengaya ini menyediakan gawit Peta Pengunjung dan Peta Waktu-Nyata. Catatan: Membutuhkan pengaya NegaraPengguna diaktifkan.", "AndNOthers": "dan %s lain", "Cities": "Kita", "Countries": "Negara", @@ -17,6 +18,8 @@ "ShowingVisits": "Kunjungan Lokasi-Geo terakhir", "Unlocated": "<b>%s<\/b> %p kunjungan dari %c lokasi-geo tidak diketahui.", "VisitorMap": "Peta Pengunjung", - "WorldWide": "Seluruh Dunia" + "WorldWide": "Seluruh Dunia", + "WithUnknownRegion": "%s dengan wilayah tidak dikenal", + "WithUnknownCity": "%s dengan kota tidak dikenal" } } \ No newline at end of file diff --git a/plugins/UserCountryMap/lang/ja.json b/plugins/UserCountryMap/lang/ja.json index ef083246b59123424ce45f6b879ce2a836e85916..55de4296c166958d682a5ea6faa2e74d86db23fe 100644 --- a/plugins/UserCountryMap/lang/ja.json +++ b/plugins/UserCountryMap/lang/ja.json @@ -1,5 +1,6 @@ { "UserCountryMap": { + "PluginDescription": "ã“ã®ãƒ—ラグインã§ã¯ã€ãƒ“ジターマップã¨ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ マップウィジェットをæä¾›ã—ã¾ã™ã€‚注:利用å¯èƒ½ãªãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚«ãƒ³ãƒˆãƒªãƒ¼ãƒ—ラグインãŒå¿…è¦ã€‚", "AndNOthers": "ã¨ã€%s ã»ã‹", "Cities": "都市", "Countries": "国", diff --git a/plugins/UserCountryMap/lang/ko.json b/plugins/UserCountryMap/lang/ko.json index e21ff537a517d2c6e398c560241ce591b023f9d2..d599797a57ca2daa1c141adc9dea8bbea96304e1 100644 --- a/plugins/UserCountryMap/lang/ko.json +++ b/plugins/UserCountryMap/lang/ko.json @@ -1,5 +1,6 @@ { "UserCountryMap": { + "PluginDescription": "ì´ í”ŒëŸ¬ê·¸ì¸ì€ ë°©ë¬¸ìž ì§€ë„ ë° ì‹¤ì‹œê°„ ì§€ë„ ìœ„ì ¯ì„ ì œê³µí•©ë‹ˆë‹¤. 주ì˜: UserCountry 플러그ì¸ì´ 활성화 ë˜ì–´ 있어야 합니다.", "AndNOthers": ", 기타 %s", "Cities": "ë„시", "Countries": "êµê°€", @@ -17,6 +18,8 @@ "ShowingVisits": "최근 ë°©ë¬¸ì˜ ì§€ë¦¬ì 위치", "Unlocated": "<b>%s<\/b> %c 방문ì—서 %pì˜ ì§€ë¦¬ì 위치를 ì°¾ì„ ìˆ˜ 없습니다.", "VisitorMap": "ë°©ë¬¸ìž ì§€ë„", - "WorldWide": "ì „ì„¸ê³„" + "WorldWide": "ì „ì„¸ê³„", + "WithUnknownRegion": "%s 알 수 없는 ì§€ì—", + "WithUnknownCity": "%s 알 수 없는 ë„시" } } \ No newline at end of file diff --git a/plugins/UserLanguage/lang/id.json b/plugins/UserLanguage/lang/id.json index 7a9cc30d700c321f76c310afad8d752b5ebe15fa..8d359ebf78e1c382fccb096f9e0f01bb5f5516b7 100644 --- a/plugins/UserLanguage/lang/id.json +++ b/plugins/UserLanguage/lang/id.json @@ -1,6 +1,7 @@ { "UserLanguage": { "BrowserLanguage": "Bahasa Peramban", - "LanguageCode": "Kode Bahasa" + "LanguageCode": "Kode Bahasa", + "PluginDescription": "Laporan bahasa yang digunakan oleh peramban pengguna" } } \ No newline at end of file diff --git a/plugins/UserLanguage/lang/ko.json b/plugins/UserLanguage/lang/ko.json index 5cd9ae7a9fd195d1daf7db770414db211b8b6fda..9b50bdaf2a2356525e62affdd3f5ab7a036aced6 100644 --- a/plugins/UserLanguage/lang/ko.json +++ b/plugins/UserLanguage/lang/ko.json @@ -1,6 +1,7 @@ { "UserLanguage": { "BrowserLanguage": "브ë¼ìš°ì € 언어", - "LanguageCode": "언어 코드" + "LanguageCode": "언어 코드", + "PluginDescription": "방문ìžì˜ 브ë¼ìš°ì €ë¥¼ 통해 언어 기ë¡" } } \ No newline at end of file diff --git a/plugins/UsersManager/Controller.php b/plugins/UsersManager/Controller.php index 105d795036aeae2e1de90cfdd18d3fbeb5a8e19b..37e13fcefab24f7d3cb0d9c85abe0c1d30944aa2 100644 --- a/plugins/UsersManager/Controller.php +++ b/plugins/UsersManager/Controller.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\UsersManager; use Exception; +use Piwik\API\Request; use Piwik\API\ResponseBuilder; use Piwik\Common; use Piwik\Container\StaticContainer; @@ -19,7 +20,6 @@ use Piwik\Plugin\ControllerAdmin; use Piwik\Plugins\LanguagesManager\API as APILanguagesManager; use Piwik\Plugins\LanguagesManager\LanguagesManager; use Piwik\Plugins\Login\SessionInitializer; -use Piwik\Plugins\SitesManager\API as APISitesManager; use Piwik\Plugins\UsersManager\API as APIUsersManager; use Piwik\SettingsPiwik; use Piwik\Site; @@ -56,7 +56,7 @@ class Controller extends ControllerAdmin $view = new View('@UsersManager/index'); - $IdSitesAdmin = APISitesManager::getInstance()->getSitesIdWithAdminAccess(); + $IdSitesAdmin = Request::processRequest('SitesManager.getSitesIdWithAdminAccess'); $idSiteSelected = 1; if (count($IdSitesAdmin) > 0) { @@ -70,7 +70,7 @@ class Controller extends ControllerAdmin } else { $defaultReportSiteName = Site::getNameFor($idSiteSelected); try { - $usersAccessByWebsite = APIUsersManager::getInstance()->getUsersAccessFromSite($idSiteSelected); + $usersAccessByWebsite = Request::processRequest('UsersManager.getUsersAccessFromSite', array('idSite' => $idSiteSelected)); } catch (NoAccessException $e) { return $this->noAdminAccessToWebsite($idSiteSelected, $defaultReportSiteName, $e->getMessage()); } @@ -78,7 +78,7 @@ class Controller extends ControllerAdmin // we dont want to display the user currently logged so that the user can't change his settings from admin to view... $currentlyLogged = Piwik::getCurrentUserLogin(); - $usersLogin = APIUsersManager::getInstance()->getUsersLogin(); + $usersLogin = Request::processRequest('UsersManager.getUsersLogin'); foreach ($usersLogin as $login) { if (!isset($usersAccessByWebsite[$login])) { $usersAccessByWebsite[$login] = 'noaccess'; @@ -105,7 +105,7 @@ class Controller extends ControllerAdmin if (Piwik::isUserHasSomeAdminAccess()) { $view->showLastSeen = true; - $users = APIUsersManager::getInstance()->getUsers(); + $users = Request::processRequest('UsersManager.getUsers'); foreach ($users as $index => $user) { $usersAliasByLogin[$user['login']] = $user['alias']; @@ -131,7 +131,8 @@ class Controller extends ControllerAdmin $view->usersAliasByLogin = $usersAliasByLogin; $view->usersCount = count($users) - 1; $view->usersAccessByWebsite = $usersAccessByWebsite; - $websites = APISitesManager::getInstance()->getSitesWithAdminAccess(); + + $websites = Request::processRequest('SitesManager.getSitesWithAdminAccess'); uasort($websites, array('Piwik\Plugins\UsersManager\Controller', 'orderByName')); $view->websites = $websites; $this->setBasicVariablesView($view); @@ -228,7 +229,7 @@ class Controller extends ControllerAdmin $view = new View('@UsersManager/userSettings'); $userLogin = Piwik::getCurrentUserLogin(); - $user = APIUsersManager::getInstance()->getUser($userLogin); + $user = Request::processRequest('UsersManager.getUser', array('userLogin' => $userLogin)); $view->userAlias = $user['alias']; $view->userEmail = $user['email']; @@ -259,6 +260,7 @@ class Controller extends ControllerAdmin $view->languages = APILanguagesManager::getInstance()->getAvailableLanguageNames(); $view->currentLanguageCode = LanguagesManager::getLanguageCodeForCurrentUser(); + $view->currentTimeformat = LanguagesManager::uses12HourClockForCurrentUser(); $view->ignoreCookieSet = IgnoreCookie::isIgnoreCookieFound(); $view->piwikHost = Url::getCurrentHost(); $this->setBasicVariablesView($view); @@ -309,11 +311,13 @@ class Controller extends ControllerAdmin $userLogin = 'anonymous'; // Which websites are available to the anonymous users? - $anonymousSitesAccess = APIUsersManager::getInstance()->getSitesAccessFromUser($userLogin); + + $anonymousSitesAccess = Request::processRequest('UsersManager.getSitesAccessFromUser', array('userLogin' => $userLogin)); $anonymousSites = array(); foreach ($anonymousSitesAccess as $info) { $idSite = $info['site']; - $site = APISitesManager::getInstance()->getSiteFromId($idSite); + + $site = Request::processRequest('SitesManager.getSiteFromId', array('idSite' => $idSite)); // Work around manual website deletion if (!empty($site)) { $anonymousSites[$idSite] = $site; @@ -322,7 +326,7 @@ class Controller extends ControllerAdmin $view->anonymousSites = $anonymousSites; // Which report is displayed by default to the anonymous user? - $anonymousDefaultReport = APIUsersManager::getInstance()->getUserPreference($userLogin, APIUsersManager::PREFERENCE_DEFAULT_REPORT); + $anonymousDefaultReport = Request::processRequest('UsersManager.getUserPreference', array('userLogin' => $userLogin, 'preferenceName' => APIUsersManager::PREFERENCE_DEFAULT_REPORT)); if ($anonymousDefaultReport === false) { if (empty($anonymousSites)) { $anonymousDefaultReport = Piwik::getLoginPluginName(); @@ -379,12 +383,14 @@ class Controller extends ControllerAdmin $defaultReport = Common::getRequestVar('defaultReport'); $defaultDate = Common::getRequestVar('defaultDate'); $language = Common::getRequestVar('language'); + $timeFormat = Common::getRequestVar('timeformat'); $userLogin = Piwik::getCurrentUserLogin(); $this->processPasswordChange($userLogin); LanguagesManager::setLanguageForSession($language); APILanguagesManager::getInstance()->setLanguageForUser($userLogin, $language); + APILanguagesManager::getInstance()->set12HourClockForUser($userLogin, $timeFormat); APIUsersManager::getInstance()->setUserPreference($userLogin, APIUsersManager::PREFERENCE_DEFAULT_REPORT, diff --git a/plugins/UsersManager/javascripts/usersSettings.js b/plugins/UsersManager/javascripts/usersSettings.js index 809b1309b7e65fc07f275de92bd66339198c16f8..1708e64bf7a141dc06a2306a7976775151d7a78c 100644 --- a/plugins/UsersManager/javascripts/usersSettings.js +++ b/plugins/UsersManager/javascripts/usersSettings.js @@ -38,6 +38,7 @@ function sendUserSettingsAJAX() { postParams.defaultReport = defaultReport; postParams.defaultDate = defaultDate; postParams.language = $('#userSettingsTable #language').val(); + postParams.timeformat = $('#userSettingsTable #timeformat').val(); var ajaxHandler = new ajaxHelper(); ajaxHandler.addParams({ diff --git a/plugins/UsersManager/lang/cs.json b/plugins/UsersManager/lang/cs.json index 3fd20a14e2e61baab936dd2e24893871413fec24..80aab2ca4cb94ee7bb666cd68c84e318dbb302c2 100644 --- a/plugins/UsersManager/lang/cs.json +++ b/plugins/UsersManager/lang/cs.json @@ -5,7 +5,7 @@ "AllWebsites": "VÅ¡echny weby", "AnonymousUser": "Anonymnà uživatel", "AnonymousUserHasViewAccess": "Poznámka: %1$s uživatel má právo k pÅ™Ãstupu k %2$s", - "AnonymousUserHasViewAccess2": "VaÅ¡e analytická hlášenà a informace o návÅ¡tÄ›vnÃcÃch je veÅ™ejnÄ› dostupná.", + "AnonymousUserHasViewAccess2": "VaÅ¡e analytická hlášenà a informace o návÅ¡tÄ›vnÃcÃch jsou veÅ™ejnÄ› dostupná.", "ApplyToAllWebsites": "PoužÃt na vÅ¡echny weby", "ChangeAllConfirm": "Jste si jistÃ, že chcete zmÄ›nit '%s' oprávnÄ›nà pro vÅ¡echny weby?", "ChangePasswordConfirm": "ZmÄ›na hesla také zmÄ›nà uživatelův token_auth. Opravdu chcete pokraÄovat?", @@ -15,8 +15,8 @@ "ConfirmProhibitMySuperUserAccess": "%s, opravdu chcete odstranit svůjvlastn à super uživatelský pÅ™Ãstup? PÅ™ijdete o vÅ¡echna oprávnÄ›nà a o pÅ™Ãstup k datům stránek a budete odhlášen z Piwiku.", "ConfirmProhibitOtherUsersSuperUserAccess": "Opravdu chcete odstranit super uživatelský pÅ™Ãstup pro %s? Tento uživatel pÅ™ijde o vÅ¡echna práva a o pÅ™Ãstup ke vÅ¡em stránkám. Nezapomeňte mu povolit pÅ™Ãstup k tÄ›m, které potÅ™ebuje, je-li to nutné.", "DeleteConfirm": "Jste si jistÃ, že chcete vymazat uživatele %s?", - "Email": "E-mail", - "EmailYourAdministrator": "%1$sPoÅ¡lete administrátorovi e-mail o tomto problému%2$s.", + "Email": "Email", + "EmailYourAdministrator": "%1$sPoÅ¡lete administrátorovi email o tomto problému%2$s.", "ExceptionAccessValues": "Parametr pÅ™Ãstupu musà mÃt jednu z následujÃcÃch hodnot: [ %s ]", "ExceptionAdminAnonymous": "Nemůžete dát 'admin' pÅ™Ãstup 'anonymous' uživateli.", "ExceptionDeleteDoesNotExist": "Uživatel '%s' neexistuje a proto nemůže být vymazán.", @@ -61,7 +61,7 @@ "User": "Uživatel", "UsersManagement": "Správa uživatelů", "UsersManagementMainDescription": "VytvoÅ™te nové uživatele, nebo aktualizujte existujÃcÃ. NÞe můžete nastavit jejich oprávnÄ›nÃ.", - "WhenUsersAreNotLoggedInAndVisitPiwikTheyShouldAccess": "Když uživatelé nejsou pÅ™ihlášenà do Piwiku, můžou mÃt pÅ™Ãstup k", + "WhenUsersAreNotLoggedInAndVisitPiwikTheyShouldAccess": "Když uživatelé nejsou pÅ™ihlášeni do Piwiku, mohou pÅ™istupovat k", "YourUsernameCannotBeChanged": "VaÅ¡e uživatelské jméno nemůže být zmÄ›nÄ›no", "YourVisitsAreIgnoredOnDomain": "%sVaÅ¡e návÅ¡tÄ›vy jsou vynechávány Piwikem na %s %s (cookie pro vynechánà byla nalezena ve vaÅ¡em prohlÞeÄi).", "YourVisitsAreNotIgnored": "%sVaÅ¡e návÅ¡tÄ›vy nejsou vynechávány Piwikem%s (cookie pro vynechánà nebyla nalezena ve vaÅ¡em prohlÞeÄi)." diff --git a/plugins/UsersManager/lang/ja.json b/plugins/UsersManager/lang/ja.json index 6f1b01a556e5240ccfc76e2e0ed30822f316d6aa..2d1bf2acb5b435e938d8863b2b4fe5543ba2f7da 100644 --- a/plugins/UsersManager/lang/ja.json +++ b/plugins/UsersManager/lang/ja.json @@ -42,8 +42,11 @@ "MenuAnonymousUserSettings": "anonymous ユーザーã®è¨å®š", "MenuUsers": "ユーザー", "MenuUserSettings": "ユーザーã®è¨å®š", + "MenuPersonal": "個人用", + "PersonalSettings": "個人è¨å®š", "NoteNoAnonymousUserAccessSettingsWontBeUsed2": "注) 匿åユーザーãŒã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ã‚¦ã‚§ãƒ–ã‚µã‚¤ãƒˆã‚’ãŠæŒã¡ã§ãªã„ãŸã‚ã€ã“ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã§ã¯è¨å®šã®å¤‰æ›´ãŒã§ãã¾ã›ã‚“。", "NoUsersExist": "ã¾ã ユーザーãŒã„ã¾ã›ã‚“。", + "PluginDescription": "ユーザー管ç†ã§ã¯ã€æ–°ã—ã„ユーザーã®è¿½åŠ ã€æ—¢å˜ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ç·¨é›†ã€ãŠã‚ˆã³ web サイトã®ç®¡ç†ã‚„é–²è¦§ã®æ¨©é™ã‚’è¨å®šã§ãã¾ã™ã€‚", "PrivAdmin": "管ç†", "PrivNone": "権é™ãªã—", "PrivView": "ビュー", diff --git a/plugins/UsersManager/templates/index.twig b/plugins/UsersManager/templates/index.twig index e2fb24dc9aca5c9f2cee433cce2ace6bb2f24ca2..6bf12d01e02af0dedd05f1359869031957cdb629 100644 --- a/plugins/UsersManager/templates/index.twig +++ b/plugins/UsersManager/templates/index.twig @@ -15,6 +15,7 @@ {% endset %} <div piwik-siteselector + show-selected-site="true" class="sites_autocomplete" siteid="{{ idSiteSelected }}" sitename="{{ defaultReportSiteName }}" diff --git a/plugins/UsersManager/templates/userSettings.twig b/plugins/UsersManager/templates/userSettings.twig index 57e04dff8593326a71724dca908fe18247eea570..6b075eda86b1296c14738686a09434a623551866 100644 --- a/plugins/UsersManager/templates/userSettings.twig +++ b/plugins/UsersManager/templates/userSettings.twig @@ -44,6 +44,14 @@ </select> </div> + <div class="form-group"> + <label for="timeformat">{{ 'General_TimeFormat'|translate }}</label> + <select name="timeformat" id="timeformat"> + <option value="1" {% if currentTimeformat == 1 %}selected="selected"{% endif %} title="{{ 'General_12HourClock'|translate }}">{{ 'General_12HourClock'|translate }}</option> + <option value="0" {% if currentTimeformat == 0 %}selected="selected"{% endif %} title="{{ 'General_24HourClock'|translate }}">{{ 'General_24HourClock'|translate }}</option> + </select> + </div> + <div class="form-group"> <label>{{ 'UsersManager_ReportToLoadByDefault'|translate }}</label> <label class="radio"> @@ -57,6 +65,7 @@ {{ 'General_DashboardForASpecificWebsite'|translate }} </label> <div piwik-siteselector + show-selected-site="true" class="sites_autocomplete" siteid="{{ defaultReportIdSite }}" sitename="{{ defaultReportSiteName }}" diff --git a/plugins/VisitFrequency/API.php b/plugins/VisitFrequency/API.php index a6f99714800f5e416ada5e6e288d3770595669a5..550212d9e37d0772424dd1de3074e15f358bbadb 100644 --- a/plugins/VisitFrequency/API.php +++ b/plugins/VisitFrequency/API.php @@ -45,7 +45,6 @@ class API extends \Piwik\Plugin\API 'segment' => $segment, 'columns' => implode(',', $columns), 'format' => 'original', - 'serialize' => 0, // tests set this to 1 'format_metrics' => 0 ); diff --git a/plugins/VisitFrequency/lang/id.json b/plugins/VisitFrequency/lang/id.json index 4149ae29fcac4ac58db98cedffa62c0af77f72e6..d44b555ef2c8ee9188e936170f683294c63564bc 100644 --- a/plugins/VisitFrequency/lang/id.json +++ b/plugins/VisitFrequency/lang/id.json @@ -10,6 +10,8 @@ "ColumnReturningVisits": "Kunjungan Kembali", "ColumnSumVisitLengthReturning": "Jumlah waktu digunakan oleh pengunjung kembali (dalam detik)", "ColumnUniqueReturningVisitors": "Pengnjung kembali unik", + "ColumnReturningUsers": "Penguna kembali", + "PluginDescription": "Laporan matriks mengenai pengunjung baru dan pengunjung kembali.", "ReturnActions": "%s tindakan tiap kunjungan kembali", "ReturnAverageVisitDuration": "%s rerata waktu kunjungan pengunjung kembali", "ReturnAvgActions": "%s tindakan tiap kunjungan kembali", diff --git a/plugins/VisitFrequency/lang/ko.json b/plugins/VisitFrequency/lang/ko.json index 41926875570905cd74f17d4ac915b25884f999e4..7a5880db1c4ac7a86cf0597d7b1107962d34439c 100644 --- a/plugins/VisitFrequency/lang/ko.json +++ b/plugins/VisitFrequency/lang/ko.json @@ -10,6 +10,8 @@ "ColumnReturningVisits": "ëŒì•„온 방문 수", "ColumnSumVisitLengthReturning": "ë¦¬í”¼í„°ì˜ ì´ ë¨¸ë¬¸ 시간 (ì´ˆ)", "ColumnUniqueReturningVisitors": "ê³ ìœ í•œ ëŒì•„온 방문ìž", + "ColumnReturningUsers": "ëŒì•„온 사용ìž", + "PluginDescription": "ì²˜ìŒ ë°©ë¬¸í•œ 방문ìžì™€ 다시 ëŒì•„온 방문ìžì— 대한", "ReturnActions": "%s ëŒì•„온 ë°©ë¬¸ì˜ í™œë™", "ReturnAverageVisitDuration": "%s ëŒì•„온 방문ìžì˜ í‰ê· 방문 시간", "ReturnAvgActions": "%s ëŒì•„온 방문당 활ë™", @@ -17,8 +19,8 @@ "ReturningVisitDocumentation": "ëŒì•„온 ë°©ë¬¸ì€ (ì‹ ê·œ 방문과는 대조ì 으로), ì ì–´ë„ í•œ ë²ˆì€ ì´ì „ì— ì›¹ 사ì´íŠ¸ë¥¼ 방문한 ì‚¬ëžŒì— ì˜í•´ ì´ë£¨ì–´ì§‘니다.", "ReturningVisitsDocumentation": "ëŒì•„온 방문 개요입니다.", "ReturnVisits": "%s ëŒì•„온 방문", - "SubmenuFrequency": "프리퀸시", + "SubmenuFrequency": "빈ë„", "WidgetGraphReturning": "ëŒì•„온 방문 수 그래프", - "WidgetOverview": "프리퀸시 개요" + "WidgetOverview": "ë¹ˆë„ ê°œìš”" } } \ No newline at end of file diff --git a/plugins/VisitTime/lang/cs.json b/plugins/VisitTime/lang/cs.json index ab1e8150f7b6c945f0bdeb507b2c7edfb18a00c7..c49f2bc6a6a74e93560ee19f5a3ada6d58b4efb5 100644 --- a/plugins/VisitTime/lang/cs.json +++ b/plugins/VisitTime/lang/cs.json @@ -6,13 +6,13 @@ "LocalTime": "NávÅ¡tÄ›vy podle lokálnÃho Äasu", "NHour": "%sh", "PluginDescription": "Hlásà mÃstnà a serverový Äas, kdy vaÅ¡i návÅ¡tÄ›vnÃci zobrazujà stránky nebo aplikaci.", - "ServerTime": "NávÅ¡tÄ›vy podle serverového Äasu", + "ServerTime": "NávÅ¡tÄ›vy podle Äasu na serveru", "SubmenuTimes": "ÄŒasy", "VisitsByDayOfWeek": "NávÅ¡tÄ›vy podle dnů v týdnu", "WidgetByDayOfWeekDocumentation": "Tento graf zobrazuje, kolik návÅ¡tÄ›v obdržela vaÅ¡e stránka každý den v týdnu.", "WidgetLocalTime": "NávÅ¡tÄ›vy podle lokálnÃho Äasu", "WidgetLocalTimeDocumentation": "Tento graf ukazuje Äas v %s návÅ¡tÄ›vnÃkovo Äasové zónÄ› %s bÄ›hem jÄ›ho návÅ¡tÄ›vy.", - "WidgetServerTime": "NávÅ¡tÄ›vy podle serverového Äasu", + "WidgetServerTime": "NávÅ¡tÄ›vy podle Äasu na serveru", "WidgetServerTimeDocumentation": "Tento graf ukazuje jaký Äas byl na %s serveru Äasové zóny %s bÄ›hem návstÄ›vy." } } \ No newline at end of file diff --git a/plugins/VisitTime/lang/ko.json b/plugins/VisitTime/lang/ko.json index c83bd88aacb585a3a1af6ff4cb732ab97d010dd5..216933c951c4e0c767667cbfca22214ecb40358b 100644 --- a/plugins/VisitTime/lang/ko.json +++ b/plugins/VisitTime/lang/ko.json @@ -5,6 +5,7 @@ "DayOfWeek": "ìš”ì¼", "LocalTime": "현지 시간 기준 방문 수", "NHour": "%s시", + "PluginDescription": "방문ìžê°€ 웹사ì´íŠ¸ë‚˜ ì•±ì„ ë³¼ 때 현지 시간 ë° ì„œë²„ ì‹œê°„ì„ ì•Œë ¤ì¤ë‹ˆë‹¤.", "ServerTime": "서버 시간 기준 방문 수", "SubmenuTimes": "방문시간", "VisitsByDayOfWeek": "ìš”ì¼ë³„ 방문수", diff --git a/plugins/VisitorGenerator b/plugins/VisitorGenerator index 6ef251bbe316882c010408180c293af3b2a2ef2a..c3abd090cf8a89894ce427b56312920f794e6125 160000 --- a/plugins/VisitorGenerator +++ b/plugins/VisitorGenerator @@ -1 +1 @@ -Subproject commit 6ef251bbe316882c010408180c293af3b2a2ef2a +Subproject commit c3abd090cf8a89894ce427b56312920f794e6125 diff --git a/plugins/VisitorInterest/lang/cs.json b/plugins/VisitorInterest/lang/cs.json index 151191809e8c9257c6fa8cbae1250b841fbf0ba7..6ee78b7b7e86d6af8302ac39d3556c185e3edebc 100644 --- a/plugins/VisitorInterest/lang/cs.json +++ b/plugins/VisitorInterest/lang/cs.json @@ -8,17 +8,17 @@ "NPages": "%s stránek", "OnePage": "1 stránka", "PluginDescription": "Hlásà zájem vaÅ¡ich návÅ¡tÄ›vnÃků: poÄet zobrazených stránek, Äas na stránkách, dny od poslednà návÅ¡tÄ›vy aj.", - "VisitNum": "ÄŒÃslo návstÄ›vnÃka", - "VisitsByDaysSinceLast": "NávstÄ›v po dnech od poslednà návÅ¡tÄ›vy", + "VisitNum": "ÄŒÃslo návÅ¡tÄ›vnÃka", + "VisitsByDaysSinceLast": "NávÅ¡tÄ›vy po dnech od poslednÃho navÅ¡tÃvenÃ", "visitsByVisitCount": "NávstÄ›vy podle poÅ™adÃ", - "VisitsPerDuration": "NávÅ¡tÄ›v za dobu návÅ¡tÄ›vy", - "VisitsPerNbOfPages": "NávÅ¡tÄ›v za poÄet stránek", + "VisitsPerDuration": "Doba zobrazenà na návÅ¡tÄ›vnÃka", + "VisitsPerNbOfPages": "PoÄet stránek na návÅ¡tÄ›vnÃka", "WidgetLengths": "Doba návÅ¡tÄ›v", "WidgetLengthsDocumentation": "V tomto hlášenà vidÃte, kolik návÅ¡tÄ›v mÄ›lo urÄitou celkovou délku. NejdÅ™Ãve je toto hlášenà zobrazeno jako tag cloud, ÄastÄ›jšà doby jsou vÄ›tÅ¡Ãm pÃsmem.", "WidgetPages": "Stránek za návÅ¡tÄ›vu", "WidgetPagesDocumentation": "V tomto hlášenà je zobrazeno, kolik návÅ¡tÄ›v provedlo urÄité množstvà zobrazenà stránek. NejdÅ™Ãve je toto hlášenà zobrazeno jako tag cloud, ÄastÄ›jšà ÄÃsla majà vÄ›tšà pÃsmo.", "WidgetVisitsByDaysSinceLast": "NávÅ¡tÄ›vy podle dnů od poslednà návÅ¡tÄ›vy", - "WidgetVisitsByDaysSinceLastDocumentation": "V hlášenà můžete vidÄ›t kolik návstÄ›v bylo od návstÄ›vnÃků, kteřà již v minulosti po nÄ›kolika dnech stránku navstÃvili.", + "WidgetVisitsByDaysSinceLastDocumentation": "V tomto hlášenà vidÃte kolik návÅ¡tÄ›v provedli návÅ¡tÄ›vnÃci, kteřà v minulosti stránku navÅ¡tÃvili opakovanÄ›.", "WidgetVisitsByNumDocumentation": "V tomto hlášenà vidÃte, kolik návÅ¡tÄ›v bylo n-tou návÅ¡tÄ›vou, t. j. návÅ¡tÄ›vnÃky, kteřà navÅ¡tÃvili vaÅ¡e stránky aspoň n-krát." } } \ No newline at end of file diff --git a/plugins/VisitorInterest/lang/ja.json b/plugins/VisitorInterest/lang/ja.json index fab4023ba23ad6224f95eb1de9fb43237fa6746c..521c594e903493e21868370c469d7e5c7dfc83db 100644 --- a/plugins/VisitorInterest/lang/ja.json +++ b/plugins/VisitorInterest/lang/ja.json @@ -7,6 +7,7 @@ "Engagement": "利用状æ³", "NPages": "%s ページ", "OnePage": "1 ページ", + "PluginDescription": "ビジターã®é–¢å¿ƒã«ã¤ã„ã¦ã®ãƒ¬ãƒãƒ¼ãƒˆï¼šé–²è¦§ã—ãŸãƒšãƒ¼ã‚¸æ•°ã€ã‚¦ã‚§ãƒ–サイトã«è²»ã‚„ã•ã‚ŒãŸæ™‚é–“ã€æœ€å¾Œã®è¨ªå•以æ¥ã®æ—¥æ•°ã€ãã®ä»–", "VisitNum": "訪å•回数", "VisitsByDaysSinceLast": "最後ã®è¨ªå•ã‹ã‚‰ã®æ—¥æ•°åˆ¥ã®ãƒ“ジット", "visitsByVisitCount": "訪å•回数別ã®ãƒ“ジット", diff --git a/plugins/VisitorInterest/lang/ko.json b/plugins/VisitorInterest/lang/ko.json index be803fec1166b1866b250a5dedd4ecdc22266732..75b9e8c7ce3e1723c799852136221c7999408b2d 100644 --- a/plugins/VisitorInterest/lang/ko.json +++ b/plugins/VisitorInterest/lang/ko.json @@ -7,6 +7,7 @@ "Engagement": "ì´ìš©ìƒí™©", "NPages": "%s페ì´ì§€", "OnePage": "1페ì´ì§€", + "PluginDescription": "방문ìžì˜ ê´€ì‹¬ì— ëŒ€í•œ ë³´ê³ ì„œ: ì½ì€ 페ì´ì§€ 수, 웹사ì´íЏ 방문 시간, 지난 마지막 방문으로부터 ë©°ì¹ ë“±", "VisitNum": "방문 횟수", "VisitsByDaysSinceLast": "마지막 방문ì¼ë¡œë¶€í„° 방문", "visitsByVisitCount": "방문 빈ë„", diff --git a/plugins/VisitsSummary/lang/cs.json b/plugins/VisitsSummary/lang/cs.json index 54a409e23d3cc185ccde23f80e2d1ab05d298147..004245c9e41cca1a653f6545a29134edc329d6da 100644 --- a/plugins/VisitsSummary/lang/cs.json +++ b/plugins/VisitsSummary/lang/cs.json @@ -6,7 +6,7 @@ "GenerateTime": "%s sekund k vygenerovánà stránky", "MaxNbActions": "%s maximálnà poÄet akcà na návÅ¡tÄ›vu", "NbActionsDescription": "%s akcà (zobrazenà stránek, staženà a odchodů)", - "NbActionsPerVisit": "%s akcà za návÅ¡tÄ›vu", + "NbActionsPerVisit": "%s akcà (zobrazenà stránek, staženÃ, odkazů a vyhledávánÃ) na návÅ¡tÄ›vu", "NbDownloadsDescription": "%s staženÃ", "NbKeywordsDescription": "%s unikátnà klÃÄová slova", "NbOutlinksDescription": "%s externÃch odkazů", diff --git a/plugins/VisitsSummary/lang/ko.json b/plugins/VisitsSummary/lang/ko.json index c7b22f205b607e0a3cd7c4453e5fae97682e9815..ec21c7d19e7afd7622d2f337c16b758243bd58d3 100644 --- a/plugins/VisitsSummary/lang/ko.json +++ b/plugins/VisitsSummary/lang/ko.json @@ -1,5 +1,6 @@ { "VisitsSummary": { + "AverageGenerationTime": "%s í‰ê· 페ì´ì§€ ìƒì„± 시간", "AverageVisitDuration": "%s ë°©ë¬¸ì˜ í‰ê· ì§€ì† ì‹œê°„", "GenerateQueries": "%s 쿼리 실행ë¨", "GenerateTime": "페ì´ì§€ ìƒì„±ì— %s ì´ˆ 걸림", @@ -16,6 +17,7 @@ "NbUniquePageviewsDescription": "%s ê³ ìœ íŽ˜ì´ì§€ë·°", "NbUniqueVisitors": "%s ê³ ìœ ë°©ë¬¸ìž", "NbVisitsBounced": "%s ë°˜ì†¡ë¥ (첫 페ì´ì§€ì—서 ì´íƒˆ)", + "PluginDescription": "ë³´ê³ ì„œ 기본 ë¶„ì„ ì¸¡ì • 기준: 방문횟수, ê³ ìœ ë°©ë¬¸ìž, í™œë™ íšŸìˆ˜, ë°˜ì†¡ë¥ ë“±", "VisitsSummary": "방문 개요", "VisitsSummaryDocumentation": "방문 ì¶”ì´ ê°œìš”ìž…ë‹ˆë‹¤.", "WidgetLastVisits": "최근 방문 그래프", diff --git a/plugins/WebsiteMeasurable/lang/ja.json b/plugins/WebsiteMeasurable/lang/ja.json new file mode 100644 index 0000000000000000000000000000000000000000..51f760f6aca80362e441688e9f3f1d30fc0fde6a --- /dev/null +++ b/plugins/WebsiteMeasurable/lang/ja.json @@ -0,0 +1,7 @@ +{ + "WebsiteMeasurable": { + "Website": "ウェブサイト", + "Websites": "ウェブサイト", + "WebsiteDescription": "Web サイトã¯ã€é€šå¸¸å˜ä¸€ã® web ドメインã‹ã‚‰æä¾›ã•れる web ãƒšãƒ¼ã‚¸ã§æ§‹æˆã•れã¦ã„ã¾ã™ã€‚" + } +} \ No newline at end of file diff --git a/plugins/WebsiteMeasurable/lang/ko.json b/plugins/WebsiteMeasurable/lang/ko.json new file mode 100644 index 0000000000000000000000000000000000000000..769d1388fe35a5cb2bfc7232576c4be66c562254 --- /dev/null +++ b/plugins/WebsiteMeasurable/lang/ko.json @@ -0,0 +1,7 @@ +{ + "WebsiteMeasurable": { + "Website": "웹사ì´íЏ", + "Websites": "웹사ì´íЏ", + "WebsiteDescription": "웹 페ì´ì§€ê°€ í¬í•¨ëœ 웹사ì´íŠ¸ëŠ” 대체로 í•˜ë‚˜ì˜ ì›¹ ë„ë©”ì¸ì—서 ì œê³µë©ë‹ˆë‹¤." + } +} \ No newline at end of file diff --git a/plugins/Widgetize/lang/nb.json b/plugins/Widgetize/lang/nb.json index a448e5258f9fbeaa35f9357590f04f07b33aba71..659ed7e34facb41b94d69c767d59821e99f6d2e3 100644 --- a/plugins/Widgetize/lang/nb.json +++ b/plugins/Widgetize/lang/nb.json @@ -1,5 +1,6 @@ { "Widgetize": { - "OpenInNewWindow": "Ã…pne i nytt vindu" + "OpenInNewWindow": "Ã…pne i nytt vindu", + "TopLinkTooltip": "Eksporter Piwik-rapporter som widgeter og bygg dem inn kontrollpanelet i din app som en iframe." } } \ No newline at end of file diff --git a/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php b/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php index b516c85d65bd94e1e5ec3d2f8c728fa9ea351c6d..227e45bd4ade91f5f2486884ec0912dcf6a09499 100644 --- a/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php +++ b/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php @@ -57,6 +57,11 @@ class ManySitesImportedLogsWithXssAttempts extends ManySitesImportedLogs self::createWebsite($this->dateTime, $ecommerce = 0, $siteName = 'Piwik test two', $siteUrl = 'http://example-site-two.com'); } + + if (!self::siteCreated($idSite = 3)) { + self::createWebsite($this->dateTime, $ecommerce = 0, $siteName = 'Piwik test three', + $siteUrl = 'http://example-site-three.com'); + } } public function addAnnotations() diff --git a/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php b/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php index 9db794269d5d844d63c771d805062dbbe9cd382f..ce454b38d238199dc3093ff22a9221bc301961f9 100644 --- a/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php +++ b/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php @@ -265,9 +265,6 @@ class ManyVisitsWithGeoIP extends Fixture public static function unsetLocationProvider() { - // also fails on other PHP, is it really needed? - return; - try { LocationProvider::setCurrentProvider('default'); } catch(Exception $e) { diff --git a/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php b/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php index dd2a2c773caba3f507d3ff3ab2899c879db7778e..9fbd6f986de397b6ea9e00e2e2404fe2bf396f23 100644 --- a/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php +++ b/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php @@ -33,6 +33,8 @@ class ManyVisitsWithMockLocationProvider extends Fixture $this->setUpWebsitesAndGoals(); $this->setMockLocationProvider(); $this->trackVisits(); + + ManyVisitsWithGeoIP::unsetLocationProvider(); } public function tearDown() diff --git a/tests/PHPUnit/Fixtures/OmniFixture.php b/tests/PHPUnit/Fixtures/OmniFixture.php index dd680e9085f7b77e54f03cff26c3b0b7190e4d33..cd6fc0fb3423143ffb86e3f5496480f69992f451 100644 --- a/tests/PHPUnit/Fixtures/OmniFixture.php +++ b/tests/PHPUnit/Fixtures/OmniFixture.php @@ -32,11 +32,29 @@ class OmniFixture extends Fixture public $fixtures = array(); + private function requireAllFixtures() + { + $fixturesToLoad = array( + '/tests/PHPUnit/Fixtures/*.php', + '/tests/UI/Fixtures/*.php', + '/plugins/*/tests/Fixtures/*.php', + '/plugins/*/Test/Fixtures/*.php', + ); + + foreach($fixturesToLoad as $fixturePath) { + foreach (glob(PIWIK_INCLUDE_PATH . $fixturePath) as $file) { + require_once $file; + } + } + } + /** * Constructor. */ public function __construct() { + $this->requireAllFixtures(); + $date = $this->month . '-01'; $classes = get_declared_classes(); @@ -97,6 +115,8 @@ class OmniFixture extends Fixture public function setUp() { foreach ($this->fixtures as $fixture) { + echo "Setting up " . get_class($fixture) . "...\n"; + $fixture->setUp(); } @@ -111,6 +131,8 @@ class OmniFixture extends Fixture public function tearDown() { foreach ($this->fixtures as $fixture) { + echo "Tearing down " . get_class($fixture) . "...\n"; + $fixture->tearDown(); } } diff --git a/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php b/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php index 8ba755fabd661d136e1a8b904acd78a2b54675ee..a32129c93b6919707d093ff3a1986505a1f395e8 100644 --- a/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php +++ b/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php @@ -36,10 +36,9 @@ class SomeVisitsCustomVariablesCampaignsNotHeuristics extends Fixture private function setPiwikEnvironmentOverrides() { - $configOverride = $this->getTestEnvironment()->configOverride; - $configOverride['Tracker']['create_new_visit_when_website_referrer_changes'] = 1; - $this->getTestEnvironment()->configOverride = $configOverride; - $this->getTestEnvironment()->save(); + $env = $this->getTestEnvironment(); + $env->overrideConfig('Tracker', 'create_new_visit_when_website_referrer_changes', 1); + $env->save(); } private function setUpWebsitesAndGoals() diff --git a/tests/PHPUnit/Fixtures/TwoSitesManyVisitsOverSeveralDaysWithSearchEngineReferrers.php b/tests/PHPUnit/Fixtures/TwoSitesManyVisitsOverSeveralDaysWithSearchEngineReferrers.php index 8983d1eea558e138a09eec59ec37abfe50041362..d2740b8aba82dad7b0c7cc5f8977374bd713093b 100644 --- a/tests/PHPUnit/Fixtures/TwoSitesManyVisitsOverSeveralDaysWithSearchEngineReferrers.php +++ b/tests/PHPUnit/Fixtures/TwoSitesManyVisitsOverSeveralDaysWithSearchEngineReferrers.php @@ -23,7 +23,7 @@ class TwoSitesManyVisitsOverSeveralDaysWithSearchEngineReferrers extends Fixture public $keywords = array( 'free > proprietary', // testing a keyword containing > 'peace "," not war', // testing a keyword containing , - 'justice )(&^#%$ NOT corruption!', + 'justice )(&^#%$ NOT \'" corruption!', ); public function setUp() diff --git a/tests/PHPUnit/Fixtures/UITestFixture.php b/tests/PHPUnit/Fixtures/UITestFixture.php index 93ae92a6dd39e6af2e5b0f284a82c4e6b36013c1..623e7e388d94b57cf638d7c41b20fe2e34c0080a 100644 --- a/tests/PHPUnit/Fixtures/UITestFixture.php +++ b/tests/PHPUnit/Fixtures/UITestFixture.php @@ -24,6 +24,7 @@ use Piwik\Plugins\UsersManager\API as UsersManagerAPI; use Piwik\Plugins\SitesManager\API as SitesManagerAPI; use Piwik\Tests\Framework\Fixture; use Piwik\Plugins\VisitsSummary\API as VisitsSummaryAPI; +use Piwik\Config as PiwikConfig; /** * Fixture for UI tests. @@ -44,7 +45,9 @@ class UITestFixture extends SqlDump parent::setUp(); + self::resetPluginsInstalledConfig(); self::updateDatabase(); + self::installAndActivatePlugins($this->getTestEnvironment()); // make sure site has an early enough creation date (for period selector tests) Db::get()->update(Common::prefixTable("site"), diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php index acd2f5c9f409adf4cef5efbe9ae65b78d491b403..f421ba56583e87c1450355aced28f40f0bdcf70e 100644 --- a/tests/PHPUnit/Framework/Fixture.php +++ b/tests/PHPUnit/Framework/Fixture.php @@ -107,6 +107,7 @@ class Fixture extends \PHPUnit_Framework_Assert public $testCaseClass = false; public $extraPluginsToLoad = array(); + public $extraDiEnvironments = array(); public $testEnvironment = null; @@ -141,6 +142,11 @@ class Fixture extends \PHPUnit_Framework_Assert return 'python'; } + public static function getTestRootUrl() + { + return self::getRootUrl() . 'tests/PHPUnit/proxy/'; + } + public function loginAsSuperUser() { /** @var Auth $auth */ @@ -175,7 +181,7 @@ class Fixture extends \PHPUnit_Framework_Assert return $id; } - return Config::getInstance()->database_tests['dbname']; + return self::getConfig()->database_tests['dbname']; } public function performSetUp($setupEnvironmentOnly = false) @@ -196,6 +202,7 @@ class Fixture extends \PHPUnit_Framework_Assert $testEnv->testCaseClass = $this->testCaseClass; $testEnv->fixtureClass = get_class($this); $testEnv->dbName = $this->dbName; + $testEnv->extraDiEnvironments = $this->extraDiEnvironments; foreach ($this->extraTestEnvVars as $name => $value) { $testEnv->$name = $value; @@ -206,7 +213,7 @@ class Fixture extends \PHPUnit_Framework_Assert $this->createEnvironmentInstance(); if ($this->dbName === false) { // must be after test config is created - $this->dbName = Config::getInstance()->database['dbname']; + $this->dbName = self::getConfig()->database['dbname']; } try { @@ -223,21 +230,19 @@ class Fixture extends \PHPUnit_Framework_Assert Tracker::disconnectCachedDbConnection(); // reconnect once we're sure the database exists - Config::getInstance()->database['dbname'] = $this->dbName; + self::getConfig()->database['dbname'] = $this->dbName; Db::createDatabaseObject(); Db::get()->query("SET wait_timeout=28800;"); DbHelper::createTables(); - Manager::getInstance()->unloadPlugins(); + self::getPluginManager()->unloadPlugins(); } catch (Exception $e) { static::fail("TEST INITIALIZATION FAILED: " . $e->getMessage() . "\n" . $e->getTraceAsString()); } - include "DataFiles/SearchEngines.php"; - include "DataFiles/Socials.php"; include "DataFiles/Providers.php"; if (!$this->isFixtureSetUp()) { @@ -249,11 +254,12 @@ class Fixture extends \PHPUnit_Framework_Assert Cache::deleteTrackerCache(); - static::loadAllPlugins($this->getTestEnvironment(), $this->testCaseClass, $this->extraPluginsToLoad); + self::resetPluginsInstalledConfig(); + $testEnvironment = $this->getTestEnvironment(); + static::loadAllPlugins($testEnvironment, $this->testCaseClass, $this->extraPluginsToLoad); self::updateDatabase(); - - self::installAndActivatePlugins(); + self::installAndActivatePlugins($testEnvironment); $_GET = $_REQUEST = array(); $_SERVER['HTTP_REFERER'] = ''; @@ -277,7 +283,7 @@ class Fixture extends \PHPUnit_Framework_Assert APILanguageManager::getInstance()->setLanguageForUser('superUserLogin', 'en'); } - SettingsPiwik::overwritePiwikUrl(self::getRootUrl() . 'tests/PHPUnit/proxy/'); + SettingsPiwik::overwritePiwikUrl(self::getTestRootUrl()); if ($setupEnvironmentOnly) { return; @@ -359,10 +365,26 @@ class Fixture extends \PHPUnit_Framework_Assert $_GET = $_REQUEST = array(); Translate::reset(); - Config::getInstance()->Plugins; // make sure Plugins exists in a config object for next tests that use Plugin\Manager + self::getConfig()->Plugins; // make sure Plugins exists in a config object for next tests that use Plugin\Manager // since Plugin\Manager uses getFromGlobalConfig which doesn't init the config object } + protected static function resetPluginsInstalledConfig() + { + $config = self::getConfig(); + $installed = $config->PluginsInstalled; + $installed['PluginsInstalled'] = array(); + $config->PluginsInstalled = $installed; + } + + protected static function rememberCurrentlyInstalledPluginsAcrossRequests(TestingEnvironmentVariables $testEnvironment) + { + $plugins = self::getPluginManager()->getInstalledPluginsName(); + + $testEnvironment->overrideConfig('PluginsInstalled', 'PluginsInstalled', $plugins); + $testEnvironment->save(); + } + /** * @param \Piwik\Tests\Framework\TestingEnvironmentVariables|null $testEnvironment Ignored. * @param bool|false $testCaseClass Ignored. @@ -371,12 +393,12 @@ class Fixture extends \PHPUnit_Framework_Assert public static function loadAllPlugins(TestingEnvironmentVariables $testEnvironment = null, $testCaseClass = false, $extraPluginsToLoad = array()) { DbHelper::createTables(); - Plugin\Manager::getInstance()->loadActivatedPlugins(); + self::getPluginManager()->loadActivatedPlugins(); } - public static function installAndActivatePlugins() + public static function installAndActivatePlugins(TestingEnvironmentVariables $testEnvironment) { - $pluginsManager = Manager::getInstance(); + $pluginsManager = self::getPluginManager(); // Install plugins $messages = $pluginsManager->installLoadedPlugins(); @@ -393,19 +415,35 @@ class Fixture extends \PHPUnit_Framework_Assert } $pluginsManager->loadPluginTranslations(); + + self::rememberCurrentlyInstalledPluginsAcrossRequests($testEnvironment); + } + + private static function getPluginManager() + { + return Manager::getInstance(); + } + + private static function getConfig() + { + return Config::getInstance(); } public static function unloadAllPlugins() { try { - $manager = Manager::getInstance(); + $manager = self::getPluginManager(); $plugins = $manager->getLoadedPlugins(); foreach ($plugins as $plugin) { $plugin->uninstall(); } - Manager::getInstance()->unloadPlugins(); + + $manager->unloadPlugins(); } catch (Exception $e) { } + + self::resetPluginsInstalledConfig(); + self::rememberCurrentlyInstalledPluginsAcrossRequests(new TestingEnvironmentVariables()); } /** @@ -455,6 +493,7 @@ class Fixture extends \PHPUnit_Framework_Assert // Clear the memory Website cache Site::clearCache(); + Cache::deleteCacheWebsiteAttributes($idSite); return $idSite; } @@ -466,13 +505,19 @@ class Fixture extends \PHPUnit_Framework_Assert */ public static function getRootUrl() { - $piwikUrl = Config::getInstance()->tests['http_host']; - $piwikUri = Config::getInstance()->tests['request_uri']; + $config = self::getConfig(); + $piwikUrl = $config->tests['http_host']; + $piwikUri = $config->tests['request_uri']; + $piwikPort = $config->tests['port']; if($piwikUri == '@REQUEST_URI@') { throw new Exception("Piwik is mis-configured. Remove (or fix) the 'request_uri' entry below [tests] section in your config.ini.php. "); } + if (!empty($piwikPort)) { + $piwikUrl = $piwikUrl . ':' . $piwikPort; + } + if (strpos($piwikUrl, 'http://') !== 0) { $piwikUrl = 'http://' . $piwikUrl . '/'; } @@ -508,7 +553,7 @@ class Fixture extends \PHPUnit_Framework_Assert */ public static function getTrackerUrl() { - return self::getRootUrl() . 'tests/PHPUnit/proxy/piwik.php'; + return self::getTestRootUrl() . 'piwik.php'; } /** @@ -815,7 +860,7 @@ class Fixture extends \PHPUnit_Framework_Assert $cmd = $python . ' "' . PIWIK_INCLUDE_PATH . '/misc/log-analytics/import_logs.py" ' # script loc . '-ddd ' // debug - . '--url="' . self::getRootUrl() . 'tests/PHPUnit/proxy/" ' # proxy so that piwik uses test config files + . '--url="' . self::getTestRootUrl() . '" ' # proxy so that piwik uses test config files ; foreach ($options as $name => $values) { @@ -860,7 +905,7 @@ class Fixture extends \PHPUnit_Framework_Assert */ public static function connectWithoutDatabase() { - $dbConfig = Config::getInstance()->database; + $dbConfig = self::getConfig()->database; $oldDbName = $dbConfig['dbname']; $dbConfig['dbname'] = null; @@ -878,7 +923,7 @@ class Fixture extends \PHPUnit_Framework_Assert public function dropDatabase($dbName = null) { - $dbName = $dbName ?: $this->dbName ?: Config::getInstance()->database_tests['dbname']; + $dbName = $dbName ?: $this->dbName ?: self::getConfig()->database_tests['dbname']; $this->log("Dropping database '$dbName'..."); diff --git a/tests/PHPUnit/Framework/Mock/LocationProvider.php b/tests/PHPUnit/Framework/Mock/LocationProvider.php index 545f71130eadb34ff0092d877b10edcb5a9a2df5..3423c53a7ba5d8d8260e7c9b8857d33c717f6860 100755 --- a/tests/PHPUnit/Framework/Mock/LocationProvider.php +++ b/tests/PHPUnit/Framework/Mock/LocationProvider.php @@ -27,6 +27,11 @@ class LocationProvider extends CountryLocationProvider if (isset($this->ipToLocations[$ip])) { $result = $this->ipToLocations[$ip]; } else { + if (!isset(self::$locations[$this->currentLocation])) { + throw new \Exception("Unknown location index in mock LocationProvider {$this->currentLocation}. This " + . "shouldn't ever happen, it is likely something is using the mock LocationProvider when it should be using a real one."); + } + $result = self::$locations[$this->currentLocation]; $this->currentLocation = ($this->currentLocation + 1) % count(self::$locations); diff --git a/tests/PHPUnit/Framework/TestRequest/Response.php b/tests/PHPUnit/Framework/TestRequest/Response.php index 6d729ca941247c0bdc13797cc6ade15a9cf4013d..8a3ed5d39e569f02e550d1082f2ee9379d8aa507 100644 --- a/tests/PHPUnit/Framework/TestRequest/Response.php +++ b/tests/PHPUnit/Framework/TestRequest/Response.php @@ -11,6 +11,7 @@ namespace Piwik\Tests\Framework\TestRequest; use Piwik\API\Request; use PHPUnit_Framework_Assert as Asserts; use Exception; +use Piwik\Tests\Framework\Fixture; use Piwik\Tests\Framework\TestCase\SystemTestCase; /** @@ -114,6 +115,7 @@ class Response $apiResponse = $this->normalizeDecimalFields($apiResponse); $apiResponse = $this->normalizeEncodingPhp533($apiResponse); $apiResponse = $this->normalizeSpaces($apiResponse); + $apiResponse = $this->replacePiwikUrl($apiResponse); return $apiResponse; } @@ -258,4 +260,18 @@ class Response { return $this->removeXmlFields($apiResponse, array('idsubdatatable_in_db')); } + + /** + * To allow tests to pass no matter what port Piwik is on, we replace the test URL w/ another + * one in the response. We don't remove the URL outright, because then we would not be able + * to detect regressions where the root URL went missing. + * + * @param $apiResponse + * @return mixed + * @throws Exception + */ + private function replacePiwikUrl($apiResponse) + { + return str_replace(Fixture::getRootUrl(), "http://example.com/piwik/", $apiResponse); + } } diff --git a/tests/PHPUnit/Framework/TestingEnvironmentManipulator.php b/tests/PHPUnit/Framework/TestingEnvironmentManipulator.php index be1c17f95921e8dcc58c4da265d3459ccfe6dfed..df6a011af5778be916ead6128a2895615ff610d1 100644 --- a/tests/PHPUnit/Framework/TestingEnvironmentManipulator.php +++ b/tests/PHPUnit/Framework/TestingEnvironmentManipulator.php @@ -190,7 +190,12 @@ class TestingEnvironmentManipulator implements EnvironmentManipulator public function getExtraEnvironments() { - return array('test'); + $result = array('test'); + + $extraEnvironments = $this->vars->extraDiEnvironments ?: array(); + $result = array_merge($result, $extraEnvironments); + + return $result; } private function getPluginsToLoadDuringTest() @@ -234,4 +239,4 @@ class TestingEnvironmentManipulator implements EnvironmentManipulator . "Is the namespace correct? Is the file in the correct folder?"); } } -} \ No newline at end of file +} diff --git a/tests/PHPUnit/Framework/TestingEnvironmentVariables.php b/tests/PHPUnit/Framework/TestingEnvironmentVariables.php index 4b33a7fe07932f5e85cb49a4cea51739e3592e3a..60942d251056142b6ff0c294844fe74b5251dc8c 100644 --- a/tests/PHPUnit/Framework/TestingEnvironmentVariables.php +++ b/tests/PHPUnit/Framework/TestingEnvironmentVariables.php @@ -39,6 +39,45 @@ class TestingEnvironmentVariables return isset($this->behaviorOverrideProperties[$name]); } + /** + * Overrides a config entry. + * + * You can use this method either to set one specific config value `overrideConfig(group, name, value)` + * or you can set a whole group of values `overrideConfig(group, valueObject)`. + * + * @param string $group Eg 'General', 'log', or any other config group name + * @param string|array $name The name of the config within the group you want to overwrite. If you want to overwrite + * the whole group just leave `$value` empty and instead provide an array of key/value pairs + * here. + * @param string|int|array|null $value The value you want to set for the given config. + * @throws \Exception if no name is set + */ + public function overrideConfig($group, $name, $value = null) + { + if (empty($name) && !is_array($name)) { + throw new \Exception('No name set that needs to be overwritten'); + } + + $config = $this->configOverride; + + if (empty($config)) { + $config = array(); + } + + if (!isset($value) && is_array($name)) { + $config[$group] = $name; + $this->configOverride = $config; + return; + } + + if (!isset($config[$group])) { + $config[$group] = array(); + } + + $config[$group][$name] = $value; + $this->configOverride = $config; + } + public function save() { $includePath = __DIR__ . '/../../..'; diff --git a/tests/PHPUnit/Integration/DbTest.php b/tests/PHPUnit/Integration/DbTest.php index c21a2770618cd3e52dd03615542a9418dc279395..9a5595e29a14a5f57a33496a70b7d0098ad55ed2 100644 --- a/tests/PHPUnit/Integration/DbTest.php +++ b/tests/PHPUnit/Integration/DbTest.php @@ -52,7 +52,7 @@ class DbTest extends IntegrationTestCase $this->assertInstanceOf($expectedClass, $db); $result = $db->fetchOne('SELECT @@SESSION.sql_mode'); - $expected = 'NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'; + $expected = 'NO_AUTO_VALUE_ON_ZERO'; $this->assertSame($expected, $result); } diff --git a/tests/PHPUnit/Integration/Plugin/ManagerTest.php b/tests/PHPUnit/Integration/Plugin/ManagerTest.php index 924edecf0003f0d55c7d449746a88407a5ccc7ca..e05e3a021e24bc8559fdcea67fe94bf73cc801d9 100644 --- a/tests/PHPUnit/Integration/Plugin/ManagerTest.php +++ b/tests/PHPUnit/Integration/Plugin/ManagerTest.php @@ -15,6 +15,7 @@ use Piwik\Plugin; use Piwik\Settings\Storage; use Piwik\Cache as PiwikCache; use Piwik\Tests\Integration\Settings\IntegrationTestCase; +use Piwik\Widget\WidgetsList; /** * @group Plugin @@ -96,7 +97,7 @@ class ManagerTest extends IntegrationTestCase list($controller, $module, $action) = explode('.', $hook); try { - $resolver = new ControllerResolver(StaticContainer::getContainer()); + $resolver = new ControllerResolver(StaticContainer::getContainer(), new Plugin\Widgets($this->manager)); $params = array(); $controller = $resolver->getController($module, $action, $params); } catch (\Exception $e) { @@ -109,6 +110,36 @@ class ManagerTest extends IntegrationTestCase } } + /** + * @dataProvider getPluginNameProvider + */ + public function test_isValidPluginName($expectedIsValid, $pluginName) + { + $valid = $this->manager->isValidPluginName($pluginName); + $this->assertSame($expectedIsValid, $valid); + } + + public function getPluginNameProvider() + { + return array( + array(true, 'a'), + array(true, 'a0'), + array(true, 'pluginNameTest'), + array(true, 'PluginNameTest'), + array(true, 'PluginNameTest92323232eerwrwere938'), + array(false, ''), + array(false, '0'), + array(false, '0a'), + array(false, 'a.'), + array(false, 'a-'), + array(false, 'a_'), + array(false, 'a-ererer'), + array(false, 'a_ererer'), + array(false, '..'), + array(false, '/'), + ); + } + private function getCacheForTrackerPlugins() { return PiwikCache::getEagerCache(); diff --git a/tests/PHPUnit/Integration/ReleaseCheckListTest.php b/tests/PHPUnit/Integration/ReleaseCheckListTest.php index b33a7c19498ddd33fdeceab95ab7bcb8ca357ff5..58970199f078e8815fc627dbded0faa80f010900 100644 --- a/tests/PHPUnit/Integration/ReleaseCheckListTest.php +++ b/tests/PHPUnit/Integration/ReleaseCheckListTest.php @@ -528,35 +528,35 @@ class ReleaseCheckListTest extends \PHPUnit_Framework_TestCase 'vendor/mnapoli/php-di/website', 'vendor/mnapoli/php-di/news', 'vendor/mnapoli/php-di/doc', - 'vendor/tecnick.com/tcpdf/examples', - 'vendor/tecnick.com/tcpdf/CHANGELOG.txt', + 'vendor/tecnickcom/tcpdf/examples', + 'vendor/tecnickcom/tcpdf/CHANGELOG.txt', 'vendor/guzzle/guzzle/docs/', // deleted fonts folders - 'vendor/tecnick.com/tcpdf/fonts/ae_fonts_2.0', - 'vendor/tecnick.com/tcpdf/fonts/dejavu-fonts-ttf-2.33', - 'vendor/tecnick.com/tcpdf/fonts/dejavu-fonts-ttf-2.34', - 'vendor/tecnick.com/tcpdf/fonts/freefont-20100919', - 'vendor/tecnick.com/tcpdf/fonts/freefont-20120503', + 'vendor/tecnickcom/tcpdf/fonts/ae_fonts_2.0', + 'vendor/tecnickcom/tcpdf/fonts/dejavu-fonts-ttf-2.33', + 'vendor/tecnickcom/tcpdf/fonts/dejavu-fonts-ttf-2.34', + 'vendor/tecnickcom/tcpdf/fonts/freefont-20100919', + 'vendor/tecnickcom/tcpdf/fonts/freefont-20120503', // In the package script, there is a trailing * so any font matching will be deleted - 'vendor/tecnick.com/tcpdf/fonts/freemon', - 'vendor/tecnick.com/tcpdf/fonts/cid', - 'vendor/tecnick.com/tcpdf/fonts/courier', - 'vendor/tecnick.com/tcpdf/fonts/aefurat', - 'vendor/tecnick.com/tcpdf/fonts/dejavusansb', - 'vendor/tecnick.com/tcpdf/fonts/dejavusansi', - 'vendor/tecnick.com/tcpdf/fonts/dejavusansmono', - 'vendor/tecnick.com/tcpdf/fonts/dejavusanscondensed', - 'vendor/tecnick.com/tcpdf/fonts/dejavusansextralight', - 'vendor/tecnick.com/tcpdf/fonts/dejavuserif', - 'vendor/tecnick.com/tcpdf/fonts/freesansi', - 'vendor/tecnick.com/tcpdf/fonts/freesansb', - 'vendor/tecnick.com/tcpdf/fonts/freeserifb', - 'vendor/tecnick.com/tcpdf/fonts/freeserifi', - 'vendor/tecnick.com/tcpdf/fonts/pdf', - 'vendor/tecnick.com/tcpdf/fonts/times', - 'vendor/tecnick.com/tcpdf/fonts/uni2cid', + 'vendor/tecnickcom/tcpdf/fonts/freemon', + 'vendor/tecnickcom/tcpdf/fonts/cid', + 'vendor/tecnickcom/tcpdf/fonts/courier', + 'vendor/tecnickcom/tcpdf/fonts/aefurat', + 'vendor/tecnickcom/tcpdf/fonts/dejavusansb', + 'vendor/tecnickcom/tcpdf/fonts/dejavusansi', + 'vendor/tecnickcom/tcpdf/fonts/dejavusansmono', + 'vendor/tecnickcom/tcpdf/fonts/dejavusanscondensed', + 'vendor/tecnickcom/tcpdf/fonts/dejavusansextralight', + 'vendor/tecnickcom/tcpdf/fonts/dejavuserif', + 'vendor/tecnickcom/tcpdf/fonts/freesansi', + 'vendor/tecnickcom/tcpdf/fonts/freesansb', + 'vendor/tecnickcom/tcpdf/fonts/freeserifb', + 'vendor/tecnickcom/tcpdf/fonts/freeserifi', + 'vendor/tecnickcom/tcpdf/fonts/pdf', + 'vendor/tecnickcom/tcpdf/fonts/times', + 'vendor/tecnickcom/tcpdf/fonts/uni2cid', ); return $this->isFilePathFoundInArray($file, $filesDeletedFromPackage); diff --git a/tests/PHPUnit/Integration/ReportTest.php b/tests/PHPUnit/Integration/ReportTest.php index 3475cee9cfc51e7e3241c6ff7da2abe88565b224..036516bd917e78bbd465e773e8dd9c79f7aa6748 100644 --- a/tests/PHPUnit/Integration/ReportTest.php +++ b/tests/PHPUnit/Integration/ReportTest.php @@ -364,7 +364,8 @@ class ReportTest extends IntegrationTestCase 'format' => 'original', 'module' => 'API', 'method' => 'ExampleReport.getExampleReport', - 'format_metrics' => 'bc' + 'format_metrics' => 'bc', + 'serialize' => '0' ) )->willReturn("result"); Proxy::setSingletonInstance($proxyMock); @@ -387,7 +388,8 @@ class ReportTest extends IntegrationTestCase 'format' => 'original', 'module' => 'API', 'method' => 'Referrers.getSearchEnginesFromKeywordId', - 'format_metrics' => 'bc' + 'format_metrics' => 'bc', + 'serialize' => '0' ) )->willReturn("result"); Proxy::setSingletonInstance($proxyMock); diff --git a/tests/PHPUnit/Integration/SegmentTest.php b/tests/PHPUnit/Integration/SegmentTest.php index 9179c6d61a9b1e2770b4700283e5b1af8e498e94..eccd355ee30f2006697fe8c04f985036f1ab29a2 100644 --- a/tests/PHPUnit/Integration/SegmentTest.php +++ b/tests/PHPUnit/Integration/SegmentTest.php @@ -94,8 +94,7 @@ class SegmentTest extends IntegrationTestCase // test multiple column segments array('customVariableName==abc;customVariableValue==def', array( - 'where' => ' ((log_visit.custom_var_k1 = ?) OR (log_visit.custom_var_k2 = ?) OR (log_visit.custom_var_k3 = ?) OR (log_visit.custom_var_k4 = ?) OR (log_visit.custom_var_k5 = ?))' - . ' AND ((log_visit.custom_var_v1 = ?) OR (log_visit.custom_var_v2 = ?) OR (log_visit.custom_var_v3 = ?) OR (log_visit.custom_var_v4 = ?) OR (log_visit.custom_var_v5 = ?)) ', + 'where' => ' (log_visit.custom_var_k1 = ? OR log_visit.custom_var_k2 = ? OR log_visit.custom_var_k3 = ? OR log_visit.custom_var_k4 = ? OR log_visit.custom_var_k5 = ?) AND (log_visit.custom_var_v1 = ? OR log_visit.custom_var_v2 = ? OR log_visit.custom_var_v3 = ? OR log_visit.custom_var_v4 = ? OR log_visit.custom_var_v5 = ? )', 'bind' => array( 'abc', 'abc', 'abc', 'abc', 'abc', 'def', 'def', 'def', 'def', 'def', @@ -162,7 +161,7 @@ class SegmentTest extends IntegrationTestCase $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); } - public function test_getSelectQuery_whenJoinVisitOnAction() + public function test_getSelectQuery_whenJoinVisitOnLogLinkVisitAction() { $select = '*'; $from = 'log_link_visit_action'; @@ -226,7 +225,7 @@ class SegmentTest extends IntegrationTestCase $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); } - public function test_getSelectQuery_whenJoinConversionOnAction() + public function test_getSelectQuery_whenJoinConversionOnLogLinkVisitAction() { $select = '*'; $from = 'log_link_visit_action'; @@ -372,11 +371,106 @@ class SegmentTest extends IntegrationTestCase $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); } + public function test_getSelectQuery_whenJoinLogLinkVisitActionOnActionOnVisit_WithSameTableAlias() + { + $actionType = 3; + $idSite = 1; + $select = 'log_link_visit_action.custom_dimension_1, + log_action.name as url, + sum(log_link_visit_action.time_spent) as `13`, + sum(case log_visit.visit_total_actions when 1 then 1 when 0 then 1 else 0 end) as `6`'; + $from = array( + 'log_link_visit_action', + array('table' => 'log_visit', 'joinOn' => 'log_visit.idvisit = log_link_visit_action.idvisit'), + array('table' => 'log_action', 'joinOn' => 'log_link_visit_action.idaction_url = log_action.idaction'), + 'log_visit' + ); + $where = 'log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ?'; + $bind = array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite); + + $segment = 'actionType==' . $actionType; + $segment = new Segment($segment, $idSites = array()); + + $query = $segment->getSelectQuery($select, $from, $where, $bind); + + $logVisitTable = Common::prefixTable('log_visit'); + $logActionTable = Common::prefixTable('log_action'); + $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action'); + + $expected = array( + "sql" => " + SELECT log_link_visit_action.custom_dimension_1, + log_action.name as url, + sum(log_link_visit_action.time_spent) as `13`, + sum(case log_visit.visit_total_actions when 1 then 1 when 0 then 1 else 0 end) as `6` + FROM $logLinkVisitActionTable AS log_link_visit_action + LEFT JOIN $logVisitTable AS log_visit + ON log_visit.idvisit = log_link_visit_action.idvisit + LEFT JOIN $logActionTable AS log_action + ON log_link_visit_action.idaction_url = log_action.idaction + WHERE ( log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ? ) + AND ( log_action.type = ? )", + "bind" => array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite, $actionType)); + + $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); + } + + public function test_getSelectQuery_whenJoinLogLinkVisitActionOnActionOnVisit_WithSameTableAliasButDifferentJoin() + { + $actionType = 3; + $idSite = 1; + $select = 'log_link_visit_action.custom_dimension_1, + log_action.name as url, + sum(log_link_visit_action.time_spent) as `13`, + sum(case log_visit.visit_total_actions when 1 then 1 when 0 then 1 else 0 end) as `6`'; + $from = array( + 'log_link_visit_action', + array('table' => 'log_visit', 'joinOn' => 'log_visit.idvisit = log_link_visit_action.idvisit'), + array('table' => 'log_action', 'joinOn' => 'log_link_visit_action.idaction_name = log_action.idaction') + ); + $where = 'log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ?'; + $bind = array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite); + + $segment = 'actionType==' . $actionType; + $segment = new Segment($segment, $idSites = array()); + + $query = $segment->getSelectQuery($select, $from, $where, $bind); + + $logVisitTable = Common::prefixTable('log_visit'); + $logActionTable = Common::prefixTable('log_action'); + $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action'); + + $expected = array( + "sql" => " + SELECT log_link_visit_action.custom_dimension_1, + log_action.name as url, + sum(log_link_visit_action.time_spent) as `13`, + sum(case log_visit.visit_total_actions when 1 then 1 when 0 then 1 else 0 end) as `6` + FROM $logLinkVisitActionTable AS log_link_visit_action + LEFT JOIN $logVisitTable AS log_visit + ON log_visit.idvisit = log_link_visit_action.idvisit + LEFT JOIN $logActionTable AS log_action + ON (log_link_visit_action.idaction_name = log_action.idaction AND log_link_visit_action.idaction_url = log_action.idaction) + WHERE ( log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ? ) + AND ( log_action.type = ? )", + "bind" => array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite, $actionType)); + + $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); + } + /** * visit is joined on action, then conversion is joined * make sure that conversion is joined on action not visit */ - public function test_getSelectQuery_whenJoinVisitAndConversionOnAction() + public function test_getSelectQuery_whenJoinVisitAndConversionOnLogLinkVisitAction() { $select = '*'; $from = 'log_link_visit_action'; @@ -446,7 +540,201 @@ class SegmentTest extends IntegrationTestCase $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); } - public function test_getSelectQuery_whenJoinConversionOnAction_segmentUsesPageUrl() + public function test_getSelectQuery_whenJoinVisitOnAction() + { + $actionType = 3; + $idSite = 1; + $select = 'count(distinct log_visit.idvisitor) AS `1`, + count(*) AS `2`, + sum(log_visit.visit_total_actions) AS `3`'; + $from = 'log_visit'; + $where = 'log_visit.visit_last_action_time >= ? + AND log_visit.visit_last_action_time <= ? + AND log_visit.idsite IN (?)'; + $bind = array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite); + + $segment = 'actionType==' . $actionType; + $segment = new Segment($segment, $idSites = array()); + + $query = $segment->getSelectQuery($select, $from, $where, $bind); + + $logVisitTable = Common::prefixTable('log_visit'); + $logActionTable = Common::prefixTable('log_action'); + $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action'); + + $expected = array( + "sql" => " + SELECT count(distinct log_inner.idvisitor) AS `1`, count(*) AS `2`, sum(log_inner.visit_total_actions) AS `3` FROM ( SELECT log_visit.idvisitor, log_visit.visit_total_actions + FROM $logVisitTable AS log_visit + LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action + ON log_link_visit_action.idvisit = log_visit.idvisit + LEFT JOIN $logActionTable AS log_action + ON log_link_visit_action.idaction_url = log_action.idaction + WHERE ( log_visit.visit_last_action_time >= ? + AND log_visit.visit_last_action_time <= ? + AND log_visit.idsite IN (?) ) + AND ( log_action.type = ? ) + GROUP BY log_visit.idvisit + ORDER BY NULL ) AS log_inner", + "bind" => array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite, $actionType)); + + $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); + } + + public function test_getSelectQuery_whenJoinLogLinkVisitActionOnActionOnVisit() + { + $actionType = 3; + $idSite = 1; + $select = 'log_link_visit_action.custom_dimension_1, + actionAlias.name as url, + sum(log_link_visit_action.time_spent) as `13`, + sum(case visitAlias.visit_total_actions when 1 then 1 when 0 then 1 else 0 end) as `6`'; + $from = array( + 'log_link_visit_action', + array('table' => 'log_visit', 'tableAlias' => 'visitAlias', 'joinOn' => 'visitAlias.idvisit = log_link_visit_action.idvisit'), + array('table' => 'log_action', 'tableAlias' => 'actionAlias', 'joinOn' => 'log_link_visit_action.idaction_url = actionAlias.idaction') + ); + $where = 'log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ?'; + $bind = array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite); + + $segment = 'actionType==' . $actionType; + $segment = new Segment($segment, $idSites = array()); + + $query = $segment->getSelectQuery($select, $from, $where, $bind); + + $logVisitTable = Common::prefixTable('log_visit'); + $logActionTable = Common::prefixTable('log_action'); + $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action'); + + $expected = array( + "sql" => " + SELECT log_link_visit_action.custom_dimension_1, + actionAlias.name as url, + sum(log_link_visit_action.time_spent) as `13`, + sum(case visitAlias.visit_total_actions when 1 then 1 when 0 then 1 else 0 end) as `6` + FROM $logLinkVisitActionTable AS log_link_visit_action + LEFT JOIN $logVisitTable AS visitAlias + ON visitAlias.idvisit = log_link_visit_action.idvisit + LEFT JOIN $logActionTable AS actionAlias + ON log_link_visit_action.idaction_url = actionAlias.idaction + LEFT JOIN $logActionTable AS log_action + ON log_link_visit_action.idaction_url = log_action.idaction + WHERE ( log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ? ) + AND ( log_action.type = ? )", + "bind" => array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite, $actionType)); + + $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); + } + + public function test_getSelectQuery_whenJoinLogLinkVisitActionOnAction() + { + $actionType = 3; + $idSite = 1; + $select = 'log_link_visit_action.custom_dimension_1, + sum(log_link_visit_action.time_spent) as `13`'; + $from = 'log_link_visit_action'; + $where = 'log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ?'; + $bind = array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite); + + $segment = 'actionType==' . $actionType; + $segment = new Segment($segment, $idSites = array()); + + $query = $segment->getSelectQuery($select, $from, $where, $bind); + + $logActionTable = Common::prefixTable('log_action'); + $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action'); + + $expected = array( + "sql" => " + SELECT log_link_visit_action.custom_dimension_1, sum(log_link_visit_action.time_spent) as `13` + FROM $logLinkVisitActionTable AS log_link_visit_action + LEFT JOIN $logActionTable AS log_action + ON log_link_visit_action.idaction_url = log_action.idaction + WHERE ( log_link_visit_action.server_time >= ? + AND log_link_visit_action.server_time <= ? + AND log_link_visit_action.idsite = ? ) + AND ( log_action.type = ? )", + "bind" => array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite, $actionType)); + + $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); + } + + public function test_getSelectQuery_whenJoinConversionOnAction() + { + $actionType = 3; + $idSite = 1; + $select = 'log_conversion.idgoal AS `idgoal`, + log_conversion.custom_dimension_1 AS `custom_dimension_1`, + count(*) AS `1`, + count(distinct log_conversion.idvisit) AS `3`,'; + $from = 'log_conversion'; + $where = 'log_conversion.server_time >= ? + AND log_conversion.server_time <= ? + AND log_conversion.idsite IN (?)'; + $bind = array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite); + + $segment = 'actionType==' . $actionType; + $segment = new Segment($segment, $idSites = array()); + + $query = $segment->getSelectQuery($select, $from, $where, $bind); + + $logConversionsTable = Common::prefixTable('log_conversion'); + $logActionTable = Common::prefixTable('log_action'); + $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action'); + + $expected = array( + "sql" => " + SELECT log_conversion.idgoal AS `idgoal`, log_conversion.custom_dimension_1 AS `custom_dimension_1`, count(*) AS `1`, count(distinct log_conversion.idvisit) AS `3`, + FROM $logConversionsTable AS log_conversion + LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action + ON log_conversion.idvisit = log_link_visit_action.idvisit + LEFT JOIN $logActionTable AS log_action + ON log_link_visit_action.idaction_url = log_action.idaction + WHERE ( log_conversion.server_time >= ? + AND log_conversion.server_time <= ? + AND log_conversion.idsite IN (?) ) + AND ( log_action.type = ? )", + "bind" => array('2015-11-30 11:00:00', '2015-12-01 10:59:59', $idSite, $actionType)); + + $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); + } + + public function test_getSelectQuery_whenUnionOfSegmentsAreUsed() + { + $select = 'log_visit.*'; + $from = 'log_visit'; + $where = false; + $bind = array(); + + $segment = 'actionUrl=@myTestUrl'; + $segment = new Segment($segment, $idSites = array()); + + $logVisitTable = Common::prefixTable('log_visit'); + $logLinkVisitActionTable = Common::prefixTable('log_link_visit_action'); + + $query = $segment->getSelectQuery($select, $from, $where, $bind); + + $expected = array( + "sql" => " SELECT log_inner.* FROM ( + SELECT log_visit.* FROM $logVisitTable AS log_visit + LEFT JOIN $logLinkVisitActionTable AS log_link_visit_action + ON log_link_visit_action.idvisit = log_visit.idvisit + WHERE (( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 1 )) ) + OR ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 3 )) ) + OR ( log_link_visit_action.idaction_url IN (SELECT idaction FROM log_action WHERE ( name LIKE CONCAT('%', ?, '%') AND type = 2 )) ) ) + GROUP BY log_visit.idvisit ORDER BY NULL ) AS log_inner", + "bind" => array('myTestUrl', 'myTestUrl', 'myTestUrl')); + + $this->assertEquals($this->removeExtraWhiteSpaces($expected), $this->removeExtraWhiteSpaces($query)); + } + + public function test_getSelectQuery_whenJoinConversionOnLogLinkVisitAction_segmentUsesPageUrl() { $this->insertPageUrlAsAction('example.com/anypage'); $this->insertPageUrlAsAction('example.com/anypage_bis'); diff --git a/tests/PHPUnit/Integration/Tracker/VisitTest.php b/tests/PHPUnit/Integration/Tracker/VisitTest.php index e686146f73c49961185c5ec99648f390957aa566..f4bc1fd5edc52fe197a8493a6cab14d4579734df 100644 --- a/tests/PHPUnit/Integration/Tracker/VisitTest.php +++ b/tests/PHPUnit/Integration/Tracker/VisitTest.php @@ -118,15 +118,37 @@ class VisitTest extends IntegrationTestCase 'http://x.com' => true, )), array(array('http://test.com', 'http://sub.test2.com'), true, array( - 'http://sub.test.com' => true, - 'http://sub.sub.test.com' => true, + 'http://sub.test.com' => false, // we do not match subdomains + 'http://sub.sub.test.com' => false, 'http://subtest.com' => false, 'http://test.com.org' => false, + 'http://test2.com' => false, 'http://sub.test2.com' => true, - 'http://x.sub.test2.com' => true, + 'http://test.com' => true, + 'http://x.sub.test2.com' => false, 'http://xsub.test2.com' => false, 'http://sub.test2.com.org' => false, )), + array(array('http://test.com/path', 'http://test2.com/sub/dir'), true, array( + 'http://test.com/path' => true, // test matching path + 'http://test.com/path/' => true, + 'http://test.com/path/test' => true, + + 'http://test.com/path1' => false, + 'http://test.com/' => false, + 'http://test.com' => false, + 'http://test.com/foo' => false, + 'http://sub.test.com/path' => false, // we still do not match subdomains + + 'http://test2.com/sub/dir' => true, + 'http://test2.com/sub/dir/' => true, + 'http://test2.com/sub/dir/test' => true, + + 'http://test2.com/sub/foo/' => false, + 'http://test2.com/sub/' => false, + 'http://test2.com/' => false, + 'http://test2.com/dir/sub' => false, + )), ); } @@ -142,7 +164,7 @@ class VisitTest extends IntegrationTestCase 'rec' => 1, 'url' => $url ))); - $this->assertEquals($isTracked, !$visitExclude->isExcluded()); + $this->assertEquals($isTracked, !$visitExclude->isExcluded(), $url . ' is not returning expected result'); } } diff --git a/tests/PHPUnit/System/AutoSuggestAPITest.php b/tests/PHPUnit/System/AutoSuggestAPITest.php index 62a0175d010bfd77b0df8fab26d8069ed1c31e96..c1404e575785895b620cde6014d9a63f877a326e 100644 --- a/tests/PHPUnit/System/AutoSuggestAPITest.php +++ b/tests/PHPUnit/System/AutoSuggestAPITest.php @@ -17,7 +17,6 @@ use Piwik\Plugins\CustomVariables\Columns\CustomVariableValue; use Piwik\Plugins\CustomVariables\Model; use Piwik\Tests\Framework\TestCase\SystemTestCase; use Piwik\Tests\Fixtures\ManyVisitsWithGeoIP; -use Piwik\Tests\Framework\Fixture; use Piwik\Tracker\Cache; use Piwik\Cache as PiwikCache; diff --git a/tests/PHPUnit/System/BackwardsCompatibility1XTest.php b/tests/PHPUnit/System/BackwardsCompatibility1XTest.php index 74dbb05d7357b986eac51c3c562bab3aa09d69c9..12a60f3821f70fe907996417c7f6f8453bf5e14c 100644 --- a/tests/PHPUnit/System/BackwardsCompatibility1XTest.php +++ b/tests/PHPUnit/System/BackwardsCompatibility1XTest.php @@ -13,6 +13,7 @@ use Piwik\Plugins\VisitFrequency\API as VisitFrequencyApi; use Piwik\Tests\Framework\TestCase\SystemTestCase; use Piwik\Tests\Fixtures\SqlDump; use Piwik\Tests\Framework\Fixture; +use Piwik\Tests\Framework\TestingEnvironmentVariables; /** * Tests that Piwik 2.0 works w/ data from Piwik 1.12. @@ -32,6 +33,7 @@ class BackwardsCompatibility1XTest extends SystemTestCase // note: not sure why I have to manually install plugin \Piwik\Plugin\Manager::getInstance()->loadPlugin('CustomAlerts')->install(); + \Piwik\Plugin\Manager::getInstance()->loadPlugin('CustomDimensions')->install(); $result = Fixture::updateDatabase(); if ($result === false) { diff --git a/tests/PHPUnit/System/TrackerTest.php b/tests/PHPUnit/System/TrackerTest.php index 461b0a2385ff6a91f6989f97d91c785bb6747313..417b40f72a8be6c22c2bb6f70b1f63e289f33027 100644 --- a/tests/PHPUnit/System/TrackerTest.php +++ b/tests/PHPUnit/System/TrackerTest.php @@ -180,9 +180,7 @@ class TrackerTest extends IntegrationTestCase public function test_scheduledTasks_CanBeRunThroughTracker_WithOutputIncluded_IfDebugQueryParamUsed() { $environment = $this->setScheduledTasksToRunInTracker(); - $config = $environment->configOverride; - $config['log']['log_writers'] = array('screen'); - $environment->configOverride = $config; + $environment->overrideConfig('log', 'log_writers', array('screen')); $environment->save(); $urlToTest = $this->getSimpleTrackingUrl() . '&debug=1'; @@ -298,7 +296,8 @@ class TrackerTest extends IntegrationTestCase $testingEnvironment = new \Piwik\Tests\Framework\TestingEnvironmentVariables(); $testingEnvironment->testCaseClass = 'Piwik\Tests\System\TrackerTest'; $testingEnvironment->addScheduledTask = true; - $testingEnvironment->configOverride = array('Tracker' => array('scheduled_tasks_min_interval' => 1, 'debug_on_demand' => 1)); + $testingEnvironment->overrideConfig('Tracker', array('scheduled_tasks_min_interval' => 1, 'debug_on_demand' => 1)); + $testingEnvironment->overrideConfig('log', array()); $testingEnvironment->save(); return $testingEnvironment; diff --git a/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentContainsTest.php b/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentContainsTest.php index 92a4f2dde2e4d1860c6283a6720703bfa0d8d1e1..bad8cc45b3d230545d53f90473b886fe9553c4ab 100755 --- a/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentContainsTest.php +++ b/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentContainsTest.php @@ -48,6 +48,13 @@ class TwoVisitsWithCustomVariablesSegmentContainsTest extends SystemTestCase array("pageTitle=@Profile pa", '_SegmentPageTitleContains', $api), array("pageUrl!@user/profile", '_SegmentPageUrlExcludes', $api), array("pageTitle!@Profile pa", '_SegmentPageTitleExcludes', $api), + // starts with + array('pageUrl=^example.org/home', '_SegmentPageUrlStartsWith', array('Actions.getPageUrls')), + array('pageTitle=^Profile pa', '_SegmentPageTitleStartsWith', array('Actions.getPageTitles')), + + // ends with + array('pageUrl=$er/profile', '_SegmentPageUrlEndsWith', array('Actions.getPageUrls')), + array('pageTitle=$page', '_SegmentPageTitleEndsWith', array('Actions.getPageTitles')), ); foreach ($segmentsToTest as $segment) { diff --git a/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentMatchNONETest.php b/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentMatchNONETest.php index 3667f7f65b1d4928207250520d083dca78665c45..482b0d12d820ee115f2c95d6b6eb85f53d4b8bfc 100755 --- a/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentMatchNONETest.php +++ b/tests/PHPUnit/System/TwoVisitsWithCustomVariablesSegmentMatchNONETest.php @@ -64,10 +64,13 @@ class TwoVisitsWithCustomVariablesSegmentMatchNONETest extends SystemTestCase if ($segment == 'visitEcommerceStatus') { $value = 'none'; } + if ($segment == 'actionType') { + $value = 'pageviews'; + } $matchNone = $segment . '!=' . $value; // deviceType != campaign matches ALL visits, but we want to match None - if($segment == 'deviceType') { + if ($segment == 'deviceType') { $matchNone = $segment . '==car%20browser'; } $segmentExpression[] = $matchNone; diff --git a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionType__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionType__API.getSuggestedValuesForSegment.xml new file mode 100644 index 0000000000000000000000000000000000000000..cff62022a95115f0971db8f4da79a34b19a4afe5 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionType__API.getSuggestedValuesForSegment.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row>pageviews</row> + <row>contents</row> + <row>sitesearches</row> + <row>events</row> + <row>outlinks</row> + <row>downloads</row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionType__VisitsSummary.get_range.xml b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionType__VisitsSummary.get_range.xml new file mode 100644 index 0000000000000000000000000000000000000000..f3bee672d683be2b43b620ab4c4cfd76e9d2bba4 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionType__VisitsSummary.get_range.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <nb_visits>35</nb_visits> + <nb_actions>95</nb_actions> + <nb_visits_converted>35</nb_visits_converted> + <bounce_count>18</bounce_count> + <sum_visit_length>27557</sum_visit_length> + <max_actions>5</max_actions> + <bounce_rate>51%</bounce_rate> + <nb_actions_per_visit>2.7</nb_actions_per_visit> + <avg_time_on_site>787</avg_time_on_site> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionUrl__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionUrl__API.getSuggestedValuesForSegment.xml new file mode 100644 index 0000000000000000000000000000000000000000..2e03969e6dc36c540c171350206ff91ecd6a92db --- /dev/null +++ b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionUrl__API.getSuggestedValuesForSegment.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row>http://piwik.net/grue/lair</row> + <row>http://piwik.net/space/quest/iv</row> + <row>http://example-outlink.org/1.html</row> + <row>http://example.org/path/file1.zip</row> + <row>http://example.org/path/file0.zip</row> + <row>http://example-outlink.org/0.html</row> + <row>http://example.org/path/file2.zip</row> + <row>http://example.org/path/file3.zip</row> + <row>http://example-outlink.org/3.html</row> + <row>http://example-outlink.org/2.html</row> + <row>http://example.org/path/file4.zip</row> + <row>http://example.org/path/file5.zip</row> + <row>http://example.org/path/file8.zip</row> + <row>http://example-outlink.org/6.html</row> + <row>http://example-outlink.org/7.html</row> + <row>http://example-outlink.org/5.html</row> + <row>http://example-outlink.org/4.html</row> + <row>http://example.org/path/file7.zip</row> + <row>http://example-outlink.org/8.html</row> + <row>http://example.org/path/file6.zip</row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionUrl__VisitsSummary.get_range.xml b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionUrl__VisitsSummary.get_range.xml new file mode 100644 index 0000000000000000000000000000000000000000..7ace3fcbe7421cce6dce7bbfe3716507389dcb5f --- /dev/null +++ b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_actionUrl__VisitsSummary.get_range.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <nb_visits>18</nb_visits> + <nb_actions>18</nb_actions> + <nb_visits_converted>18</nb_visits_converted> + <bounce_count>18</bounce_count> + <sum_visit_length>0</sum_visit_length> + <max_actions>1</max_actions> + <bounce_rate>100%</bounce_rate> + <nb_actions_per_visit>1</nb_actions_per_visit> + <avg_time_on_site>0</avg_time_on_site> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableName__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableName__API.getSuggestedValuesForSegment.xml index b3e5836d323756f716a43f3ab629139b81982ddd..9c10ae8b3760d85e022f05399c5900f6e160a416 100644 --- a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableName__API.getSuggestedValuesForSegment.xml +++ b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableName__API.getSuggestedValuesForSegment.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <row>Cvar 5 name</row> <row>Cvar 1 name</row> + <row>Cvar 5 name</row> </result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariablePageValue__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariablePageValue__API.getSuggestedValuesForSegment.xml index fb3a6b641302bbbf5635b5d72e299abdc1b312fa..0ab1e3a74c91aa0579a8d058b968029f9fd60e29 100644 --- a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariablePageValue__API.getSuggestedValuesForSegment.xml +++ b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariablePageValue__API.getSuggestedValuesForSegment.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8" ?> <result> <row>CAT</row> + <row>Cvar5 PAGE value is 0</row> <row>Cvar5 PAGE value is 1</row> <row>Cvar2 PAGE value is 1</row> <row>Cvar2 PAGE value is 0</row> - <row>Cvar5 PAGE value is 0</row> - <row>Cvar5 PAGE value is 3</row> <row>Cvar2 PAGE value is 3</row> - <row>Cvar2 PAGE value is 2</row> <row>Cvar5 PAGE value is 2</row> - <row>Cvar5 PAGE value is 4</row> + <row>Cvar5 PAGE value is 3</row> + <row>Cvar2 PAGE value is 2</row> + <row>Cvar2 PAGE value is 5</row> <row>Cvar2 PAGE value is 4</row> - <row>Cvar2 PAGE value is 7</row> - <row>Cvar5 PAGE value is 8</row> - <row>Cvar2 PAGE value is 8</row> - <row>Cvar5 PAGE value is 7</row> <row>Cvar2 PAGE value is 6</row> - <row>Cvar2 PAGE value is 5</row> - <row>Cvar5 PAGE value is 6</row> + <row>Cvar5 PAGE value is 8</row> <row>Cvar5 PAGE value is 5</row> + <row>Cvar5 PAGE value is 6</row> + <row>Cvar5 PAGE value is 4</row> + <row>Cvar5 PAGE value is 7</row> + <row>Cvar2 PAGE value is 8</row> + <row>Cvar2 PAGE value is 7</row> </result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableValue__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableValue__API.getSuggestedValuesForSegment.xml index 662ed617b168196be45a118cff07124664f131be..6be328a177b676e4509809fe7fa4c9fb2f977905 100644 --- a/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableValue__API.getSuggestedValuesForSegment.xml +++ b/tests/PHPUnit/System/expected/test_AutoSuggestAPITest_customVariableValue__API.getSuggestedValuesForSegment.xml @@ -1,21 +1,21 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <row>Cvar5 value is 1</row> - <row>Cvar1 value is 0</row> <row>Cvar1 value is 1</row> + <row>Cvar1 value is 0</row> + <row>Cvar5 value is 1</row> <row>Cvar5 value is 0</row> <row>Cvar1 value is 3</row> - <row>Cvar5 value is 3</row> - <row>Cvar5 value is 2</row> <row>Cvar1 value is 2</row> - <row>Cvar5 value is 4</row> + <row>Cvar5 value is 2</row> + <row>Cvar5 value is 3</row> <row>Cvar1 value is 4</row> <row>Cvar5 value is 7</row> - <row>Cvar1 value is 7</row> - <row>Cvar5 value is 8</row> - <row>Cvar1 value is 6</row> + <row>Cvar1 value is 5</row> <row>Cvar5 value is 6</row> + <row>Cvar1 value is 7</row> <row>Cvar5 value is 5</row> - <row>Cvar1 value is 5</row> + <row>Cvar5 value is 8</row> <row>Cvar1 value is 8</row> + <row>Cvar5 value is 4</row> + <row>Cvar1 value is 6</row> </result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_day.xml b/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_day.xml index 38fec6a150bc881bf3080df8855f1a3b016a5394..c2c4ac7f78aafc387c1209579176bf4227b4f911 100644 --- a/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_day.xml +++ b/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_day.xml @@ -9,7 +9,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>21</pageId> <eventCategory>Movie</eventCategory> @@ -114,7 +114,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>20</pageId> <eventCategory>Movie</eventCategory> @@ -219,7 +219,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>16</pageId> <eventCategory>Movie</eventCategory> @@ -233,7 +233,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>17</pageId> <eventCategory>Movie</eventCategory> @@ -247,7 +247,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>19</pageId> <eventCategory>Movie</eventCategory> @@ -261,7 +261,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>22</pageId> <eventCategory>Movie</eventCategory> @@ -290,7 +290,7 @@ <row> <type>event</type> <url>http://example.org/finishedMovie</url> - <pageIdAction>23</pageIdAction> + <pageIdAction>25</pageIdAction> <pageId>24</pageId> <eventCategory>event category Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long ---> SHOULD APPEAR IN TEST OUTPUT NOT TRUNCATED <---</eventCategory> @@ -397,7 +397,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>18</pageId> <eventCategory>Movie</eventCategory> @@ -526,7 +526,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>2</pageId> <eventCategory>Music</eventCategory> @@ -546,7 +546,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>3</pageId> <eventCategory>Music</eventCategory> @@ -566,7 +566,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>4</pageId> <eventCategory>Music</eventCategory> @@ -586,7 +586,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>5</pageId> <eventCategory>Music</eventCategory> @@ -606,7 +606,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>6</pageId> <eventCategory>Music</eventCategory> @@ -626,7 +626,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>7</pageId> <eventCategory>Music</eventCategory> @@ -647,7 +647,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>8</pageId> <eventCategory>Music</eventCategory> @@ -669,7 +669,7 @@ <type>action</type> <url>http://example.org/movies</url> <pageTitle>Movie Theater</pageTitle> - <pageIdAction>12</pageIdAction> + <pageIdAction>13</pageIdAction> <pageId>9</pageId> <generationTime>0.67s</generationTime> @@ -681,7 +681,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>10</pageId> <eventCategory>Movie</eventCategory> @@ -695,7 +695,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>11</pageId> <eventCategory>Movie</eventCategory> @@ -709,7 +709,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>12</pageId> <eventCategory>Movie</eventCategory> @@ -723,7 +723,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>13</pageId> <eventCategory>Movie</eventCategory> @@ -737,7 +737,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>14</pageId> <eventCategory>Movie</eventCategory> @@ -751,7 +751,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>15</pageId> <eventCategory>Movie</eventCategory> @@ -857,7 +857,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>45</pageId> <eventCategory>Movie</eventCategory> @@ -958,7 +958,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>44</pageId> <eventCategory>Movie</eventCategory> @@ -1059,7 +1059,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>40</pageId> <eventCategory>Movie</eventCategory> @@ -1073,7 +1073,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>41</pageId> <eventCategory>Movie</eventCategory> @@ -1087,7 +1087,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>43</pageId> <eventCategory>Movie</eventCategory> @@ -1101,7 +1101,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>46</pageId> <eventCategory>Movie</eventCategory> @@ -1130,7 +1130,7 @@ <row> <type>event</type> <url>http://example.org/finishedMovie</url> - <pageIdAction>23</pageIdAction> + <pageIdAction>25</pageIdAction> <pageId>48</pageId> <eventCategory>event category Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long ---> SHOULD APPEAR IN TEST OUTPUT NOT TRUNCATED <---</eventCategory> @@ -1233,7 +1233,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>42</pageId> <eventCategory>Movie</eventCategory> @@ -1358,7 +1358,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>26</pageId> <eventCategory>Music</eventCategory> @@ -1378,7 +1378,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>27</pageId> <eventCategory>Music</eventCategory> @@ -1398,7 +1398,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>28</pageId> <eventCategory>Music</eventCategory> @@ -1418,7 +1418,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>29</pageId> <eventCategory>Music</eventCategory> @@ -1438,7 +1438,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>30</pageId> <eventCategory>Music</eventCategory> @@ -1458,7 +1458,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>31</pageId> <eventCategory>Music</eventCategory> @@ -1479,7 +1479,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>32</pageId> <eventCategory>Music</eventCategory> @@ -1501,7 +1501,7 @@ <type>action</type> <url>http://example.org/movies</url> <pageTitle>Movie Theater</pageTitle> - <pageIdAction>12</pageIdAction> + <pageIdAction>13</pageIdAction> <pageId>33</pageId> <generationTime>0.67s</generationTime> @@ -1513,7 +1513,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>34</pageId> <eventCategory>Movie</eventCategory> @@ -1527,7 +1527,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>35</pageId> <eventCategory>Movie</eventCategory> @@ -1541,7 +1541,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>36</pageId> <eventCategory>Movie</eventCategory> @@ -1555,7 +1555,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>37</pageId> <eventCategory>Movie</eventCategory> @@ -1569,7 +1569,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>38</pageId> <eventCategory>Movie</eventCategory> @@ -1583,7 +1583,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>39</pageId> <eventCategory>Movie</eventCategory> diff --git a/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_month.xml index 38fec6a150bc881bf3080df8855f1a3b016a5394..c2c4ac7f78aafc387c1209579176bf4227b4f911 100644 --- a/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_CustomEvents__Live.getLastVisitsDetails_month.xml @@ -9,7 +9,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>21</pageId> <eventCategory>Movie</eventCategory> @@ -114,7 +114,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>20</pageId> <eventCategory>Movie</eventCategory> @@ -219,7 +219,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>16</pageId> <eventCategory>Movie</eventCategory> @@ -233,7 +233,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>17</pageId> <eventCategory>Movie</eventCategory> @@ -247,7 +247,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>19</pageId> <eventCategory>Movie</eventCategory> @@ -261,7 +261,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>22</pageId> <eventCategory>Movie</eventCategory> @@ -290,7 +290,7 @@ <row> <type>event</type> <url>http://example.org/finishedMovie</url> - <pageIdAction>23</pageIdAction> + <pageIdAction>25</pageIdAction> <pageId>24</pageId> <eventCategory>event category Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long ---> SHOULD APPEAR IN TEST OUTPUT NOT TRUNCATED <---</eventCategory> @@ -397,7 +397,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>18</pageId> <eventCategory>Movie</eventCategory> @@ -526,7 +526,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>2</pageId> <eventCategory>Music</eventCategory> @@ -546,7 +546,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>3</pageId> <eventCategory>Music</eventCategory> @@ -566,7 +566,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>4</pageId> <eventCategory>Music</eventCategory> @@ -586,7 +586,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>5</pageId> <eventCategory>Music</eventCategory> @@ -606,7 +606,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>6</pageId> <eventCategory>Music</eventCategory> @@ -626,7 +626,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>7</pageId> <eventCategory>Music</eventCategory> @@ -647,7 +647,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>8</pageId> <eventCategory>Music</eventCategory> @@ -669,7 +669,7 @@ <type>action</type> <url>http://example.org/movies</url> <pageTitle>Movie Theater</pageTitle> - <pageIdAction>12</pageIdAction> + <pageIdAction>13</pageIdAction> <pageId>9</pageId> <generationTime>0.67s</generationTime> @@ -681,7 +681,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>10</pageId> <eventCategory>Movie</eventCategory> @@ -695,7 +695,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>11</pageId> <eventCategory>Movie</eventCategory> @@ -709,7 +709,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>12</pageId> <eventCategory>Movie</eventCategory> @@ -723,7 +723,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>13</pageId> <eventCategory>Movie</eventCategory> @@ -737,7 +737,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>14</pageId> <eventCategory>Movie</eventCategory> @@ -751,7 +751,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>15</pageId> <eventCategory>Movie</eventCategory> @@ -857,7 +857,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>45</pageId> <eventCategory>Movie</eventCategory> @@ -958,7 +958,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>44</pageId> <eventCategory>Movie</eventCategory> @@ -1059,7 +1059,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>40</pageId> <eventCategory>Movie</eventCategory> @@ -1073,7 +1073,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>41</pageId> <eventCategory>Movie</eventCategory> @@ -1087,7 +1087,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>43</pageId> <eventCategory>Movie</eventCategory> @@ -1101,7 +1101,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>46</pageId> <eventCategory>Movie</eventCategory> @@ -1130,7 +1130,7 @@ <row> <type>event</type> <url>http://example.org/finishedMovie</url> - <pageIdAction>23</pageIdAction> + <pageIdAction>25</pageIdAction> <pageId>48</pageId> <eventCategory>event category Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long Extremely long ---> SHOULD APPEAR IN TEST OUTPUT NOT TRUNCATED <---</eventCategory> @@ -1233,7 +1233,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>42</pageId> <eventCategory>Movie</eventCategory> @@ -1358,7 +1358,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>26</pageId> <eventCategory>Music</eventCategory> @@ -1378,7 +1378,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>27</pageId> <eventCategory>Music</eventCategory> @@ -1398,7 +1398,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>28</pageId> <eventCategory>Music</eventCategory> @@ -1418,7 +1418,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>29</pageId> <eventCategory>Music</eventCategory> @@ -1438,7 +1438,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>30</pageId> <eventCategory>Music</eventCategory> @@ -1458,7 +1458,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>31</pageId> <eventCategory>Music</eventCategory> @@ -1479,7 +1479,7 @@ <row> <type>event</type> <url>http://example.org/webradio</url> - <pageIdAction>2</pageIdAction> + <pageIdAction>3</pageIdAction> <pageId>32</pageId> <eventCategory>Music</eventCategory> @@ -1501,7 +1501,7 @@ <type>action</type> <url>http://example.org/movies</url> <pageTitle>Movie Theater</pageTitle> - <pageIdAction>12</pageIdAction> + <pageIdAction>13</pageIdAction> <pageId>33</pageId> <generationTime>0.67s</generationTime> @@ -1513,7 +1513,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>34</pageId> <eventCategory>Movie</eventCategory> @@ -1527,7 +1527,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>35</pageId> <eventCategory>Movie</eventCategory> @@ -1541,7 +1541,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>36</pageId> <eventCategory>Movie</eventCategory> @@ -1555,7 +1555,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>37</pageId> <eventCategory>Movie</eventCategory> @@ -1569,7 +1569,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>38</pageId> <eventCategory>Movie</eventCategory> @@ -1583,7 +1583,7 @@ <row> <type>event</type> <url>http://example.org/movies</url> - <pageIdAction>12</pageIdAction> + <pageIdAction>14</pageIdAction> <pageId>39</pageId> <eventCategory>Movie</eventCategory> diff --git a/tests/PHPUnit/System/expected/test_FlattenReports__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_FlattenReports__CustomVariables.getCustomVariables_day.xml index c2c0a93fff00dc868814136fc698c104f75ff85a..6d6e6128debfa4a938e31afb1d9ac2bce87ba4fe 100644 --- a/tests/PHPUnit/System/expected/test_FlattenReports__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_FlattenReports__CustomVariables.getCustomVariables_day.xml @@ -10,11 +10,23 @@ <sum_visit_length>6</sum_visit_length> <bounce_count>0</bounce_count> <nb_visits_converted>0</nb_visits_converted> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <is_aggregate>1</is_aggregate> </row> <row> <label>CustomVarPage</label> <nb_actions>18</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <is_aggregate>1</is_aggregate> </row> <row> @@ -68,6 +80,12 @@ <sum_visit_length>1</sum_visit_length> <bounce_count>0</bounce_count> <nb_visits_converted>0</nb_visits_converted> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <is_aggregate>1</is_aggregate> </row> <row> @@ -90,6 +108,12 @@ <row> <label>CustomVarPage</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <is_aggregate>1</is_aggregate> </row> </result> diff --git a/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getAvailableExtractionDimensions.xml b/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getAvailableExtractionDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..7a397597a0aacfd97d7cf23e0878b632d2c9a36b --- /dev/null +++ b/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getAvailableExtractionDimensions.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>url</value> + <name>Page URL</name> + </row> + <row> + <value>urlparam</value> + <name>Page URL Parameter</name> + </row> + <row> + <value>action_name</value> + <name>Page Title</name> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getAvailableScopes.xml b/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getAvailableScopes.xml new file mode 100644 index 0000000000000000000000000000000000000000..149cf8b31c946ff2733882ccf47b8e409437df9d --- /dev/null +++ b/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getAvailableScopes.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>visit</value> + <name>Visit</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>0</supportsExtractions> + </row> + <row> + <value>action</value> + <name>Action</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>1</supportsExtractions> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getConfiguredCustomDimensions.xml b/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getConfiguredCustomDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_ImportLogs__CustomDimensions.getConfiguredCustomDimensions.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result /> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_ImportLogs__CustomVariables.getCustomVariables_month.xml b/tests/PHPUnit/System/expected/test_ImportLogs__CustomVariables.getCustomVariables_month.xml index dc1a11ab2b33c15ead98f4153fd905c4979ed660..4582327ecc091808e837e79aec399232343b344b 100644 --- a/tests/PHPUnit/System/expected/test_ImportLogs__CustomVariables.getCustomVariables_month.xml +++ b/tests/PHPUnit/System/expected/test_ImportLogs__CustomVariables.getCustomVariables_month.xml @@ -3,6 +3,16 @@ <row> <label>HTTP-code</label> <nb_actions>43</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + <row> + <scope>page</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==HTTP-code</segment> <subtable> <row> @@ -61,6 +71,12 @@ <revenue>25</revenue> <sum_daily_nb_uniq_visitors>7</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Not-Bot</segment> <subtable> <row> @@ -151,6 +167,12 @@ <revenue>10</revenue> <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>1</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==User+Name</segment> <subtable> <row> @@ -196,6 +218,12 @@ <row> <label>Generation Time</label> <nb_actions>4</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Generation+Time</segment> <subtable> <row> @@ -221,6 +249,12 @@ <row> <label>Windows Status Code</label> <nb_actions>4</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Windows+Status+Code</segment> <subtable> <row> @@ -267,6 +301,12 @@ <revenue>5</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Bot</segment> <subtable> <row> @@ -308,6 +348,12 @@ <revenue>5</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Forum+status</segment> <subtable> <row> @@ -349,6 +395,12 @@ <revenue>5</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_ImportLogs__CustomVariables.getUsagesOfSlots.xml b/tests/PHPUnit/System/expected/test_ImportLogs__CustomVariables.getUsagesOfSlots.xml new file mode 100644 index 0000000000000000000000000000000000000000..4e74cbbfdfc17f67e3479daf6b54603a1b96ad81 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_ImportLogs__CustomVariables.getUsagesOfSlots.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <scope>visit</scope> + <index>1</index> + <usages> + <row> + <name>Domain landed</name> + <nb_visits>12</nb_visits> + <nb_actions>16</nb_actions> + </row> + <row> + <name>Not-Bot</name> + <nb_visits>7</nb_visits> + <nb_actions>10</nb_actions> + </row> + <row> + <name>User Name</name> + <nb_visits>3</nb_visits> + <nb_actions>5</nb_actions> + </row> + <row> + <name>Bot</name> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </usages> + </row> + <row> + <scope>visit</scope> + <index>2</index> + <usages> + <row> + <name>Demo language</name> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </usages> + </row> + <row> + <scope>visit</scope> + <index>3</index> + <usages> + <row> + <name>Forum status</name> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </usages> + </row> + <row> + <scope>visit</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>5</index> + <usages> + <row> + <name>VisitorType</name> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </usages> + </row> + <row> + <scope>page</scope> + <index>1</index> + <usages> + <row> + <name>HTTP-code</name> + <nb_visits>0</nb_visits> + <nb_actions>69</nb_actions> + </row> + <row> + <name>Generation Time</name> + <nb_visits>0</nb_visits> + <nb_actions>4</nb_actions> + </row> + </usages> + </row> + <row> + <scope>page</scope> + <index>2</index> + <usages> + <row> + <name>Windows Status Code</name> + <nb_visits>0</nb_visits> + <nb_actions>4</nb_actions> + </row> + </usages> + </row> + <row> + <scope>page</scope> + <index>3</index> + <usages> + <row> + <name>HTTP-code</name> + <nb_visits>0</nb_visits> + <nb_actions>69</nb_actions> + </row> + </usages> + </row> + <row> + <scope>page</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>5</index> + <usages> + </usages> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_1__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_1__Live.getLastVisitsDetails_month.xml index b1ce63330968bebac1f2eb555a58efde9798ab08..23daf4bf068c3005acaca985b8e9ac40edf3f161 100644 --- a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_1__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_1__Live.getLastVisitsDetails_month.xml @@ -62,7 +62,7 @@ <type>download</type> <url>http://example.org/path/file8.zip</url> <pageTitle /> - <pageIdAction>46</pageIdAction> + <pageIdAction>47</pageIdAction> <pageId>48</pageId> <timeSpent>180</timeSpent> @@ -74,7 +74,7 @@ <type>outlink</type> <url>http://example-outlink.org/8.html</url> <pageTitle /> - <pageIdAction>47</pageIdAction> + <pageIdAction>48</pageIdAction> <pageId>49</pageId> <timeSpent>180</timeSpent> @@ -85,7 +85,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>50</pageId> <eventCategory>Cat8</eventCategory> @@ -360,7 +360,7 @@ <type>download</type> <url>http://example.org/path/file7.zip</url> <pageTitle /> - <pageIdAction>41</pageIdAction> + <pageIdAction>42</pageIdAction> <pageId>42</pageId> <timeSpent>180</timeSpent> @@ -372,7 +372,7 @@ <type>outlink</type> <url>http://example-outlink.org/7.html</url> <pageTitle /> - <pageIdAction>42</pageIdAction> + <pageIdAction>43</pageIdAction> <pageId>43</pageId> <timeSpent>180</timeSpent> @@ -383,7 +383,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>44</pageId> <eventCategory>Cat7</eventCategory> diff --git a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_2__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_2__Live.getLastVisitsDetails_month.xml index 40321dd60b30b82e80b2016c0a02cec726dd67de..69d9272531ea57948d420ac12949c2d82218c089 100644 --- a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_2__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_offsetAndLimit_2__Live.getLastVisitsDetails_month.xml @@ -191,7 +191,7 @@ <type>download</type> <url>http://example.org/path/file6.zip</url> <pageTitle /> - <pageIdAction>36</pageIdAction> + <pageIdAction>37</pageIdAction> <pageId>37</pageId> <timeSpent>180</timeSpent> @@ -203,7 +203,7 @@ <type>outlink</type> <url>http://example-outlink.org/6.html</url> <pageTitle /> - <pageIdAction>37</pageIdAction> + <pageIdAction>38</pageIdAction> <pageId>38</pageId> <timeSpent>180</timeSpent> @@ -214,7 +214,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>39</pageId> <eventCategory>Cat6</eventCategory> diff --git a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortByIdVisit__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortByIdVisit__Live.getLastVisitsDetails_month.xml index 0f01c7764bfa1b65c9911ae583bddbee1b4ab612..0323bd788c6d249a9e78612c865a193300e1e2ea 100644 --- a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortByIdVisit__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortByIdVisit__Live.getLastVisitsDetails_month.xml @@ -173,7 +173,7 @@ <type>download</type> <url>http://example.org/path/file8.zip</url> <pageTitle /> - <pageIdAction>46</pageIdAction> + <pageIdAction>47</pageIdAction> <pageId>48</pageId> <timeSpent>180</timeSpent> @@ -185,7 +185,7 @@ <type>outlink</type> <url>http://example-outlink.org/8.html</url> <pageTitle /> - <pageIdAction>47</pageIdAction> + <pageIdAction>48</pageIdAction> <pageId>49</pageId> <timeSpent>180</timeSpent> @@ -196,7 +196,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>50</pageId> <eventCategory>Cat8</eventCategory> @@ -471,7 +471,7 @@ <type>download</type> <url>http://example.org/path/file7.zip</url> <pageTitle /> - <pageIdAction>41</pageIdAction> + <pageIdAction>42</pageIdAction> <pageId>42</pageId> <timeSpent>180</timeSpent> @@ -483,7 +483,7 @@ <type>outlink</type> <url>http://example-outlink.org/7.html</url> <pageTitle /> - <pageIdAction>42</pageIdAction> + <pageIdAction>43</pageIdAction> <pageId>43</pageId> <timeSpent>180</timeSpent> @@ -494,7 +494,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>44</pageId> <eventCategory>Cat7</eventCategory> @@ -787,7 +787,7 @@ <type>download</type> <url>http://example.org/path/file6.zip</url> <pageTitle /> - <pageIdAction>36</pageIdAction> + <pageIdAction>37</pageIdAction> <pageId>37</pageId> <timeSpent>180</timeSpent> @@ -799,7 +799,7 @@ <type>outlink</type> <url>http://example-outlink.org/6.html</url> <pageTitle /> - <pageIdAction>37</pageIdAction> + <pageIdAction>38</pageIdAction> <pageId>38</pageId> <timeSpent>180</timeSpent> @@ -810,7 +810,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>39</pageId> <eventCategory>Cat6</eventCategory> diff --git a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortDesc__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortDesc__Live.getLastVisitsDetails_month.xml index 0f01c7764bfa1b65c9911ae583bddbee1b4ab612..0323bd788c6d249a9e78612c865a193300e1e2ea 100644 --- a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortDesc__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest_Live.getLastVisitsDetails_sortDesc__Live.getLastVisitsDetails_month.xml @@ -173,7 +173,7 @@ <type>download</type> <url>http://example.org/path/file8.zip</url> <pageTitle /> - <pageIdAction>46</pageIdAction> + <pageIdAction>47</pageIdAction> <pageId>48</pageId> <timeSpent>180</timeSpent> @@ -185,7 +185,7 @@ <type>outlink</type> <url>http://example-outlink.org/8.html</url> <pageTitle /> - <pageIdAction>47</pageIdAction> + <pageIdAction>48</pageIdAction> <pageId>49</pageId> <timeSpent>180</timeSpent> @@ -196,7 +196,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>50</pageId> <eventCategory>Cat8</eventCategory> @@ -471,7 +471,7 @@ <type>download</type> <url>http://example.org/path/file7.zip</url> <pageTitle /> - <pageIdAction>41</pageIdAction> + <pageIdAction>42</pageIdAction> <pageId>42</pageId> <timeSpent>180</timeSpent> @@ -483,7 +483,7 @@ <type>outlink</type> <url>http://example-outlink.org/7.html</url> <pageTitle /> - <pageIdAction>42</pageIdAction> + <pageIdAction>43</pageIdAction> <pageId>43</pageId> <timeSpent>180</timeSpent> @@ -494,7 +494,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>44</pageId> <eventCategory>Cat7</eventCategory> @@ -787,7 +787,7 @@ <type>download</type> <url>http://example.org/path/file6.zip</url> <pageTitle /> - <pageIdAction>36</pageIdAction> + <pageIdAction>37</pageIdAction> <pageId>37</pageId> <timeSpent>180</timeSpent> @@ -799,7 +799,7 @@ <type>outlink</type> <url>http://example-outlink.org/6.html</url> <pageTitle /> - <pageIdAction>37</pageIdAction> + <pageIdAction>38</pageIdAction> <pageId>38</pageId> <timeSpent>180</timeSpent> @@ -810,7 +810,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>39</pageId> <eventCategory>Cat6</eventCategory> diff --git a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest__Live.getLastVisitsDetails_month.xml index 4b4f490f4445eff5f9b1894e0690c1403a442692..4665c485f0abb216634f2b8968345c840f8cc2a6 100644 --- a/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_ManyVisitorsOneWebsiteTest__Live.getLastVisitsDetails_month.xml @@ -173,7 +173,7 @@ <type>download</type> <url>http://example.org/path/file8.zip</url> <pageTitle /> - <pageIdAction>46</pageIdAction> + <pageIdAction>47</pageIdAction> <pageId>48</pageId> <timeSpent>180</timeSpent> @@ -185,7 +185,7 @@ <type>outlink</type> <url>http://example-outlink.org/8.html</url> <pageTitle /> - <pageIdAction>47</pageIdAction> + <pageIdAction>48</pageIdAction> <pageId>49</pageId> <timeSpent>180</timeSpent> @@ -196,7 +196,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>50</pageId> <eventCategory>Cat8</eventCategory> @@ -471,7 +471,7 @@ <type>download</type> <url>http://example.org/path/file7.zip</url> <pageTitle /> - <pageIdAction>41</pageIdAction> + <pageIdAction>42</pageIdAction> <pageId>42</pageId> <timeSpent>180</timeSpent> @@ -483,7 +483,7 @@ <type>outlink</type> <url>http://example-outlink.org/7.html</url> <pageTitle /> - <pageIdAction>42</pageIdAction> + <pageIdAction>43</pageIdAction> <pageId>43</pageId> <timeSpent>180</timeSpent> @@ -494,7 +494,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>44</pageId> <eventCategory>Cat7</eventCategory> @@ -787,7 +787,7 @@ <type>download</type> <url>http://example.org/path/file6.zip</url> <pageTitle /> - <pageIdAction>36</pageIdAction> + <pageIdAction>37</pageIdAction> <pageId>37</pageId> <timeSpent>180</timeSpent> @@ -799,7 +799,7 @@ <type>outlink</type> <url>http://example-outlink.org/6.html</url> <pageTitle /> - <pageIdAction>37</pageIdAction> + <pageIdAction>38</pageIdAction> <pageId>38</pageId> <timeSpent>180</timeSpent> @@ -810,7 +810,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>39</pageId> <eventCategory>Cat6</eventCategory> @@ -1085,7 +1085,7 @@ <type>download</type> <url>http://example.org/path/file5.zip</url> <pageTitle /> - <pageIdAction>31</pageIdAction> + <pageIdAction>32</pageIdAction> <pageId>31</pageId> <timeSpent>180</timeSpent> @@ -1097,7 +1097,7 @@ <type>outlink</type> <url>http://example-outlink.org/5.html</url> <pageTitle /> - <pageIdAction>32</pageIdAction> + <pageIdAction>33</pageIdAction> <pageId>32</pageId> <timeSpent>180</timeSpent> @@ -1108,7 +1108,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>33</pageId> <eventCategory>Cat5</eventCategory> @@ -1401,7 +1401,7 @@ <type>download</type> <url>http://example.org/path/file4.zip</url> <pageTitle /> - <pageIdAction>26</pageIdAction> + <pageIdAction>27</pageIdAction> <pageId>26</pageId> <timeSpent>180</timeSpent> @@ -1413,7 +1413,7 @@ <type>outlink</type> <url>http://example-outlink.org/4.html</url> <pageTitle /> - <pageIdAction>27</pageIdAction> + <pageIdAction>28</pageIdAction> <pageId>27</pageId> <timeSpent>180</timeSpent> @@ -1424,7 +1424,7 @@ <row> <type>event</type> <url>http://piwik.net/space/quest/iv</url> - <pageIdAction>4</pageIdAction> + <pageIdAction>8</pageIdAction> <pageId>28</pageId> <eventCategory>Cat4</eventCategory> diff --git a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getAvailableExtractionDimensions.xml b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getAvailableExtractionDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..7a397597a0aacfd97d7cf23e0878b632d2c9a36b --- /dev/null +++ b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getAvailableExtractionDimensions.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>url</value> + <name>Page URL</name> + </row> + <row> + <value>urlparam</value> + <name>Page URL Parameter</name> + </row> + <row> + <value>action_name</value> + <name>Page Title</name> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getAvailableScopes.xml b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getAvailableScopes.xml new file mode 100644 index 0000000000000000000000000000000000000000..149cf8b31c946ff2733882ccf47b8e409437df9d --- /dev/null +++ b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getAvailableScopes.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>visit</value> + <name>Visit</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>0</supportsExtractions> + </row> + <row> + <value>action</value> + <name>Action</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>1</supportsExtractions> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getConfiguredCustomDimensions.xml b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getConfiguredCustomDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomDimensions.getConfiguredCustomDimensions.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result /> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomVariables.getUsagesOfSlots.xml b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomVariables.getUsagesOfSlots.xml new file mode 100644 index 0000000000000000000000000000000000000000..81163427e5931b802fd0011c70cc3706ce2dd5b9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits__CustomVariables.getUsagesOfSlots.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <scope>visit</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>5</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>5</index> + <usages> + </usages> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml index 8202b69b0488424a88c47fe89ea9c460c5deef71..3ecc645c62ee1d9e2fc89636c2e4a5428c18a97f 100644 --- a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml +++ b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml @@ -58,7 +58,7 @@ <reportMetadata> <row> - <idsubdatatable>2078</idsubdatatable> + <idsubdatatable>5119</idsubdatatable> </row> </reportMetadata> <reportTotal> diff --git a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml index 450961285be30fac04ad64d206d22b6133efd6f9..96248d9ba3c6efcfdd6b35058a49f773ed1ee767 100644 --- a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml +++ b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml @@ -67,7 +67,7 @@ <reportMetadata> <row> - <idsubdatatable>2082</idsubdatatable> + <idsubdatatable>5123</idsubdatatable> </row> </reportMetadata> <reportTotal> diff --git a/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVariables.getUsagesOfSlots.xml b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVariables.getUsagesOfSlots.xml new file mode 100644 index 0000000000000000000000000000000000000000..81163427e5931b802fd0011c70cc3706ce2dd5b9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVariables.getUsagesOfSlots.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <scope>visit</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>5</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>5</index> + <usages> + </usages> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_OneVisitor_SeveralDays_ImportedInRandomOrderTest_shouldShowOneVisit_InEachOfThreeDays__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_OneVisitor_SeveralDays_ImportedInRandomOrderTest_shouldShowOneVisit_InEachOfThreeDays__Live.getLastVisitsDetails_month.xml index cc9433a13a85101f3ee667f951f0a3929b4cfa9f..73cc01ca740beec97635f5fdcbe7f555c0f6e729 100644 --- a/tests/PHPUnit/System/expected/test_OneVisitor_SeveralDays_ImportedInRandomOrderTest_shouldShowOneVisit_InEachOfThreeDays__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_OneVisitor_SeveralDays_ImportedInRandomOrderTest_shouldShowOneVisit_InEachOfThreeDays__Live.getLastVisitsDetails_month.xml @@ -10,7 +10,7 @@ <url>http://piwik.net/</url> <pageTitle /> <pageIdAction>1</pageIdAction> - <serverTimePretty>Apr 7, 2013 10:00:00 AM</serverTimePretty> + <serverTimePretty>Apr 7, 2013 10:00:00</serverTimePretty> <pageId>1</pageId> <customVariables> <row> @@ -91,10 +91,10 @@ <plugins /> <pluginsIcons /> <serverTimestamp>1365328800</serverTimestamp> - <serverTimePretty>10:00:00 AM</serverTimePretty> + <serverTimePretty>10:00:00</serverTimePretty> <serverDatePretty>Sunday, April 7, 2013</serverDatePretty> <serverDatePrettyFirstAction>Sunday, April 7, 2013</serverDatePrettyFirstAction> - <serverTimePrettyFirstAction>10:00:00 AM</serverTimePrettyFirstAction> + <serverTimePrettyFirstAction>10:00:00</serverTimePrettyFirstAction> </row> <row> <idSite>1</idSite> @@ -106,7 +106,7 @@ <url>http://piwik.net/</url> <pageTitle /> <pageIdAction>1</pageIdAction> - <serverTimePretty>Apr 6, 2013 11:00:00 AM</serverTimePretty> + <serverTimePretty>Apr 6, 2013 11:00:00</serverTimePretty> <pageId>2</pageId> <customVariables> <row> @@ -187,10 +187,10 @@ <plugins /> <pluginsIcons /> <serverTimestamp>1365246000</serverTimestamp> - <serverTimePretty>11:00:00 AM</serverTimePretty> + <serverTimePretty>11:00:00</serverTimePretty> <serverDatePretty>Saturday, April 6, 2013</serverDatePretty> <serverDatePrettyFirstAction>Saturday, April 6, 2013</serverDatePrettyFirstAction> - <serverTimePrettyFirstAction>11:00:00 AM</serverTimePrettyFirstAction> + <serverTimePrettyFirstAction>11:00:00</serverTimePrettyFirstAction> </row> <row> <idSite>1</idSite> @@ -202,7 +202,7 @@ <url>http://piwik.net/</url> <pageTitle /> <pageIdAction>1</pageIdAction> - <serverTimePretty>Apr 5, 2013 12:00:00 PM</serverTimePretty> + <serverTimePretty>Apr 5, 2013 12:00:00</serverTimePretty> <pageId>3</pageId> <customVariables> <row> @@ -283,9 +283,9 @@ <plugins /> <pluginsIcons /> <serverTimestamp>1365163200</serverTimestamp> - <serverTimePretty>12:00:00 PM</serverTimePretty> + <serverTimePretty>12:00:00</serverTimePretty> <serverDatePretty>Friday, April 5, 2013</serverDatePretty> <serverDatePrettyFirstAction>Friday, April 5, 2013</serverDatePrettyFirstAction> - <serverTimePrettyFirstAction>12:00:00 PM</serverTimePrettyFirstAction> + <serverTimePrettyFirstAction>12:00:00</serverTimePrettyFirstAction> </row> </result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_RowEvolution_LabelReservedCharactersHierarchical__API.getRowEvolution_day.xml b/tests/PHPUnit/System/expected/test_RowEvolution_LabelReservedCharactersHierarchical__API.getRowEvolution_day.xml index 7295efb5180c2033a4ad7e8c922a050cb14140cb..3b8bde90651c6e3d13acab2a91164510d46c001d 100644 --- a/tests/PHPUnit/System/expected/test_RowEvolution_LabelReservedCharactersHierarchical__API.getRowEvolution_day.xml +++ b/tests/PHPUnit/System/expected/test_RowEvolution_LabelReservedCharactersHierarchical__API.getRowEvolution_day.xml @@ -249,7 +249,7 @@ <change>-100%</change> </nb_visits_1> <nb_visits_2> - <name>Google - justice )(&^#%$ not corruption! (Visits)</name> + <name>Google - justice )(&^#%$ not &#039;" corruption! (Visits)</name> <min>0</min> <max>1</max> </nb_visits_2> diff --git a/tests/PHPUnit/System/expected/test_RowEvolution_flatFilters__Referrers.getSearchEngines_month.xml b/tests/PHPUnit/System/expected/test_RowEvolution_flatFilters__Referrers.getSearchEngines_month.xml index e1f0382dda515a7c8f7b8612ecc0dfd2f6f1dfae..d97e75695cbe99d309f2c44f9c4668cd5f862896 100644 --- a/tests/PHPUnit/System/expected/test_RowEvolution_flatFilters__Referrers.getSearchEngines_month.xml +++ b/tests/PHPUnit/System/expected/test_RowEvolution_flatFilters__Referrers.getSearchEngines_month.xml @@ -14,7 +14,7 @@ <logo>plugins/Referrers/images/searchEngines/google.com.png</logo> </row> <row> - <label>Google - justice )(&^#%$ not corruption!</label> + <label>Google - justice )(&^#%$ not &#039;" corruption!</label> <nb_visits>8</nb_visits> <nb_actions>8</nb_actions> <max_actions>1</max_actions> @@ -23,7 +23,7 @@ <nb_visits_converted>0</nb_visits_converted> <sum_daily_nb_uniq_visitors>8</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> - <url>http://google.com/search?q=justice+%29%28%26%5E%23%25%24+not+corruption%21</url> + <url>http://google.com/search?q=justice+%29%28%26%5E%23%25%24+not+%27%22+corruption%21</url> <logo>plugins/Referrers/images/searchEngines/google.com.png</logo> </row> <row> diff --git a/tests/PHPUnit/System/expected/test_RowEvolution_multipleDates_lastNoData__API.getRowEvolution_month.xml b/tests/PHPUnit/System/expected/test_RowEvolution_multipleDates_lastNoData__API.getRowEvolution_month.xml index ff4f69a79d7bc6f3319581d11b8ef99541b1a825..5730859763b7c7400f5ca150f7aafed36e714969 100644 --- a/tests/PHPUnit/System/expected/test_RowEvolution_multipleDates_lastNoData__API.getRowEvolution_month.xml +++ b/tests/PHPUnit/System/expected/test_RowEvolution_multipleDates_lastNoData__API.getRowEvolution_month.xml @@ -33,7 +33,7 @@ <change>-100%</change> </nb_visits_0> <nb_visits_1> - <name>justice )(&^#%$ not corruption! (Visits)</name> + <name>justice )(&^#%$ not &#039;" corruption! (Visits)</name> <min>0</min> <max>8</max> <change>-100%</change> diff --git a/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_day.xml index 9a056e87868d56fbf26bf8605d71517c8ecbf862..5b6b0bc2553ed723dffe40029126a7fa19e8441d 100644 --- a/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_day.xml @@ -6,6 +6,12 @@ <label>_pk_scount</label> <nb_visits>4</nb_visits> <nb_actions>6</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <subtable> <row> @@ -24,6 +30,12 @@ <label>_pk_scat</label> <nb_visits>2</nb_visits> <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <subtable> <row> @@ -39,6 +51,12 @@ <label>_pk_scount</label> <nb_visits>3</nb_visits> <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <subtable> <row> @@ -62,6 +80,12 @@ <label>_pk_scat</label> <nb_visits>2</nb_visits> <nb_actions>2</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <subtable> <row> @@ -89,6 +113,12 @@ <label>_pk_scount</label> <nb_visits>1</nb_visits> <nb_actions>2</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <subtable> <row> @@ -102,6 +132,12 @@ <label>_pk_scat</label> <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <subtable> <row> @@ -130,6 +166,12 @@ <sum_visit_length>541</sum_visit_length> <bounce_count>0</bounce_count> <nb_visits_converted>0</nb_visits_converted> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==test+cvar+name</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_month.xml b/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_month.xml index 50b6b4821e56512c7f67fe3019889a55a816fef4..76eae7c657388ae043f36aa2334e7288d6f68f56 100644 --- a/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_month.xml +++ b/tests/PHPUnit/System/expected/test_SiteSearch_AllSites__CustomVariables.getCustomVariables_month.xml @@ -7,6 +7,12 @@ <nb_visits>7</nb_visits> <nb_actions>9</nb_actions> <sum_daily_nb_uniq_visitors>7</sum_daily_nb_uniq_visitors> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <subtable> <row> @@ -34,6 +40,12 @@ <nb_visits>4</nb_visits> <nb_actions>5</nb_actions> <sum_daily_nb_uniq_visitors>4</sum_daily_nb_uniq_visitors> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <subtable> <row> @@ -71,6 +83,12 @@ <nb_visits>1</nb_visits> <nb_actions>2</nb_actions> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <subtable> <row> @@ -86,6 +104,12 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <subtable> <row> @@ -116,6 +140,12 @@ <nb_visits_converted>0</nb_visits_converted> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==test+cvar+name</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml index 8428ead295abdba5398b1434e5cc843276accb68..bd42dba25a99b391f2bdb8dee7732a87b33be28a 100644 --- a/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml @@ -112,11 +112,23 @@ <reportMetadata> <result prettyDate="Sunday, January 3, 2010"> <row> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <idsubdatatable>3173</idsubdatatable> </row> <row> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <idsubdatatable>3172</idsubdatatable> @@ -124,11 +136,23 @@ </result> <result prettyDate="Monday, January 4, 2010"> <row> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <idsubdatatable>3176</idsubdatatable> </row> <row> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <idsubdatatable>3175</idsubdatatable> diff --git a/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml index a849b60fd7759658e95d7f3a8c2fbe6b7586e9d8..4d86dedf9b7014844b38750ffb15b3a9f8d7fb30 100644 --- a/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml +++ b/tests/PHPUnit/System/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml @@ -81,11 +81,23 @@ <reportMetadata> <result prettyDate="January 2010"> <row> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pk_scount</segment> <idsubdatatable>3198</idsubdatatable> </row> <row> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pk_scat</segment> <idsubdatatable>3197</idsubdatatable> diff --git a/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_day.xml b/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_day.xml index 362ecce2926e4c4fdd0fc34d8ddc705e8ca46579..865d25db4e8a57c729071b0a1d9a89c4d327046c 100644 --- a/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_day.xml +++ b/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_day.xml @@ -25,7 +25,7 @@ <loops>2</loops> <pageviews>18</pageviews> <entries>4</entries> - <exits>6</exits> + <exits>7</exits> </pageMetrics> <followingPages> <row> @@ -38,7 +38,7 @@ </row> <row> <label>Others</label> - <referrals>4</referrals> + <referrals>3</referrals> </row> </followingPages> <followingSiteSearches> diff --git a/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_month.xml b/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_month.xml index 639a8ffa932b69e792bfc4f5ab99a7d93ee873c9..7e7b38175731e0ce0a4257a6617b9d9eb4c84ec9 100644 --- a/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_month.xml +++ b/tests/PHPUnit/System/expected/test_Transitions__Transitions.getTransitionsForPageUrl_month.xml @@ -25,7 +25,7 @@ <loops>2</loops> <pageviews>21</pageviews> <entries>4</entries> - <exits>7</exits> + <exits>9</exits> </pageMetrics> <followingPages> <row> @@ -38,7 +38,7 @@ </row> <row> <label>Others</label> - <referrals>5</referrals> + <referrals>3</referrals> </row> </followingPages> <followingSiteSearches> diff --git a/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_day.xml b/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_day.xml index c6b559a21cbafd3e311150093eacc8d2b5f32927..6233153f1cae531f2367408fb7615004722074e9 100644 --- a/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_day.xml +++ b/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_day.xml @@ -25,7 +25,7 @@ <loops>2</loops> <pageviews>18</pageviews> <entries>4</entries> - <exits>6</exits> + <exits>7</exits> </pageMetrics> <followingPages> <row> @@ -44,10 +44,6 @@ <label>example.org/page3.html</label> <referrals>1</referrals> </row> - <row> - <label>example.org/page/search.html</label> - <referrals>1</referrals> - </row> </followingPages> <followingSiteSearches> <row> diff --git a/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_month.xml b/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_month.xml index dd4aea11a78f02880ba2d86f03e3f98924264301..c782fbb7613e96876d81feb2ce260ec123d968f8 100644 --- a/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_month.xml +++ b/tests/PHPUnit/System/expected/test_Transitions_noLimit__Transitions.getTransitionsForPageUrl_month.xml @@ -25,7 +25,7 @@ <loops>2</loops> <pageviews>21</pageviews> <entries>4</entries> - <exits>7</exits> + <exits>9</exits> </pageMetrics> <followingPages> <row> @@ -40,10 +40,6 @@ <label>example.org/the/third_page.html?foo=bar</label> <referrals>2</referrals> </row> - <row> - <label>example.org/page/search.html</label> - <referrals>2</referrals> - </row> <row> <label>example.org/page3.html</label> <referrals>1</referrals> diff --git a/tests/PHPUnit/System/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html b/tests/PHPUnit/System/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html index 3ffd998150087c59b748bb8289cd7ea0dcbd10cc..cfb6f4e33366406dc69f4cb0b3330578403e785e 100644 --- a/tests/PHPUnit/System/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html +++ b/tests/PHPUnit/System/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html @@ -5,7 +5,7 @@ </head> <body style="font-family: dejavusans; color: rgb(13,13,13);line-height: 1.33;"> -<a id="reportTop" rel="noreferrer" target="_blank" href="http://localhost/tests/PHPUnit/proxy/"><img title="Go to Piwik" border="0" alt="Piwik" src='http://localhost/tests/PHPUnit/proxy/plugins/Morpheus/images/logo-header.png'/></a> +<a id="reportTop" rel="noreferrer" target="_blank" href="http://example.com/piwik/tests/PHPUnit/proxy/"><img title="Go to Piwik" border="0" alt="Piwik" src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/Morpheus/images/logo-header.png'/></a> <h1 style="font-weight:normal; color: rgb(13,13,13); font-size: 24pt;"> Site 1 @@ -2562,7 +2562,42 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Unique returning visitors </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/cookie.gif'> + + Cookie </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 11 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 100% + </td> + </tr> + + <tr style=";line-height: 22px;"> + <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/flash.gif'> + + Flash </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 11 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 100% + </td> + </tr> + + <tr style="background-color: rgb(242,242,242);line-height: 22px;"> + <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/java.gif'> + + Java </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 11 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 2 </td> @@ -2570,7 +2605,13 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Returning Users </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/director.gif'> + + Director </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 0 </td> @@ -2578,7 +2619,16 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Returning Visits </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/gears.gif'> + + Gears </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 9 </td> @@ -2586,7 +2636,16 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Actions by Returning Visits </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/pdf.gif'> + + Pdf </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 41 </td> @@ -2594,7 +2653,16 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Maximum actions in one returning visit </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/quicktime.gif'> + + Quicktime </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 5 </td> @@ -2602,7 +2670,16 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Bounce Rate for Returning Visits </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/realplayer.gif'> + + Realplayer </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 11% </td> @@ -2610,7 +2687,16 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Avg. Actions per Returning Visit </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/silverlight.gif'> + + Silverlight </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 4.6 </td> @@ -2618,7 +2704,16 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Avg. Duration of a Returning Visit (in sec) </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/windowsmedia.gif'> + + Windowsmedia </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 00:13:21 </td> @@ -3574,7 +3669,13 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD 14h </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/xx.png'> + + Unknown </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 0 </td> @@ -3597,7 +3698,13 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD 15h </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/fr.png'> + + France </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 0 </td> @@ -3666,7 +3773,13 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD 18h </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/xx.png'> + + Unknown </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 0 </td> @@ -3689,7 +3802,13 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD 19h </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/xx.png'> + + Unknown </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 0 </td> @@ -4507,7 +4626,22 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Pageviews </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/screens/unknown.gif'> + + Unknown </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 8 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 40 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 5 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 43 </td> @@ -4531,7 +4665,13 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Unique Downloads </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/screens/normal.gif'> + + Desktop </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 0 </td> @@ -4610,7 +4750,13 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD second visitor </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/UNK.gif'> + + Unknown </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 8 </td> @@ -4627,7 +4773,13 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD first page view </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/FF.gif'> + + Firefox </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 2 </td> @@ -4635,6 +4787,40 @@ 2 </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD +======= + 1 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 00:00:00 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 100% + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0% + </td> + </tr> + + <tr style="background-color: rgb(242,242,242);line-height: 22px;"> + <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/OP.gif'> + + Opera </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 1 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 1 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 1 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 00:00:00 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +>>>>>>> master 100% </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -4675,7 +4861,19 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Checkout </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/brand/Unknown.ico'> + + Unknown </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 11 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 43 + </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 8 </td> @@ -4746,7 +4944,13 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Websites </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/UNK.gif'> + + Unknown </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 6 </td> @@ -4769,7 +4973,13 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Campaigns </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/FF.gif'> + + Firefox 3.6 </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 4 </td> @@ -4792,7 +5002,13 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD Direct Entry </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/OP.gif'> + + Opera 9.63 </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 1 </td> @@ -4852,7 +5068,13 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD referrer.com </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/UNK.gif'> + + Unknown </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 6 </td> @@ -4875,7 +5097,13 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD goal-matching-url-parameter </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/WIN.gif'> + + Windows </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 4 </td> @@ -4945,7 +5173,38 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> +<<<<<<< HEAD referrer.com </td> +======= + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/UNK.gif'> + + Unknown </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 8 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 40 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 5 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 00:15:01 + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0% + </td> + <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + 0% + </td> + </tr> + + <tr style=";line-height: 22px;"> + <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/WIN.gif'> + + Windows XP </td> +>>>>>>> master <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> 6 </td> diff --git a/tests/PHPUnit/System/expected/test_UserId_VisitorId__Live.getLastVisitsDetails_month.xml b/tests/PHPUnit/System/expected/test_UserId_VisitorId__Live.getLastVisitsDetails_month.xml index c728abec68683e21b82558b66a98c0c33129d5b8..b83a3d071dca1b71f038f9c788871ca8b02fa37a 100644 --- a/tests/PHPUnit/System/expected/test_UserId_VisitorId__Live.getLastVisitsDetails_month.xml +++ b/tests/PHPUnit/System/expected/test_UserId_VisitorId__Live.getLastVisitsDetails_month.xml @@ -9,7 +9,7 @@ <url>http://example.org/index.htm</url> <pageTitle>incredible title!</pageTitle> <pageIdAction>2</pageIdAction> - <serverTimePretty>Mar 6, 2010 11:22:33 AM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 11:22:33</serverTimePretty> <pageId>1</pageId> <icon /> <timestamp>1267874553</timestamp> @@ -28,7 +28,7 @@ <url>http://example.org/index2.htm</url> <pageTitle>incredible title!</pageTitle> <pageIdAction>3</pageIdAction> - <serverTimePretty>Mar 6, 2010 11:25:33 AM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 11:25:33</serverTimePretty> <pageId>2</pageId> <timeSpent>180</timeSpent> <timeSpentPretty>3 min 0s</timeSpentPretty> @@ -40,7 +40,7 @@ <url>http://example.org/index3.htm</url> <pageTitle>incredible title!</pageTitle> <pageIdAction>4</pageIdAction> - <serverTimePretty>Mar 6, 2010 11:28:33 AM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 11:28:33</serverTimePretty> <pageId>3</pageId> <icon /> <timestamp>1267874913</timestamp> @@ -59,7 +59,7 @@ <url>http://example.org/no-user-id-set-but-should-appear-in-user-id-visit</url> <pageTitle>no User Id set but it should appear in email@example.com!</pageTitle> <pageIdAction>6</pageIdAction> - <serverTimePretty>Mar 6, 2010 1:16:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 13:16:33</serverTimePretty> <pageId>4</pageId> <timeSpent>360</timeSpent> <timeSpentPretty>6 min 0s</timeSpentPretty> @@ -71,7 +71,7 @@ <url>http://example.org/index.htm</url> <pageTitle>incredible title!</pageTitle> <pageIdAction>2</pageIdAction> - <serverTimePretty>Mar 6, 2010 1:22:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 13:22:33</serverTimePretty> <pageId>5</pageId> <timeSpent>360</timeSpent> <timeSpentPretty>6 min 0s</timeSpentPretty> @@ -83,7 +83,7 @@ <url>http://example.org/index.htm</url> <pageTitle>second page</pageTitle> <pageIdAction>2</pageIdAction> - <serverTimePretty>Mar 6, 2010 1:28:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 13:28:33</serverTimePretty> <pageId>6</pageId> <icon /> <timestamp>1267882113</timestamp> @@ -102,7 +102,7 @@ <url>http://example.org/index.htm</url> <pageTitle>a new user id was set -> new visit</pageTitle> <pageIdAction>2</pageIdAction> - <serverTimePretty>Mar 6, 2010 1:34:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 13:34:33</serverTimePretty> <pageId>7</pageId> <icon /> <timestamp>1267882473</timestamp> @@ -121,7 +121,7 @@ <url>http://example.org/home</url> <pageTitle>pageview - should not be tracked by our user id but in a new visit</pageTitle> <pageIdAction>10</pageIdAction> - <serverTimePretty>Mar 6, 2010 4:28:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 16:28:33</serverTimePretty> <pageId>10</pageId> <icon /> <timestamp>1267892913</timestamp> @@ -140,7 +140,7 @@ <url>http://example.org/home</url> <pageTitle>same user id was set -> this is the same unique user</pageTitle> <pageIdAction>10</pageIdAction> - <serverTimePretty>Mar 6, 2010 4:22:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 16:22:33</serverTimePretty> <pageId>8</pageId> <timeSpent>360</timeSpent> <timeSpentPretty>6 min 0s</timeSpentPretty> @@ -152,7 +152,7 @@ <url>http://example.org/home</url> <pageTitle>second pageview - by this user id</pageTitle> <pageIdAction>10</pageIdAction> - <serverTimePretty>Mar 6, 2010 4:28:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 16:28:33</serverTimePretty> <pageId>9</pageId> <timeSpent>720</timeSpent> <timeSpentPretty>12 min 0s</timeSpentPretty> @@ -165,7 +165,7 @@ <goalId>1</goalId> <revenue>0</revenue> <goalPageId /> - <serverTimePretty>Mar 6, 2010 4:34:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 16:34:33</serverTimePretty> <url>http://example.org/home</url> <icon>plugins/Morpheus/images/goal.png</icon> <timestamp>1267893273</timestamp> @@ -174,7 +174,7 @@ <type>ecommerceAbandonedCart</type> <revenue>10000000000</revenue> <items>1</items> - <serverTimePretty>Mar 6, 2010 4:40:33 PM</serverTimePretty> + <serverTimePretty>Mar 6, 2010 16:40:33</serverTimePretty> <itemDetails> <row> <itemSKU>sku-007-PRISM</itemSKU> @@ -201,7 +201,7 @@ <url>http://example.org/index.htm</url> <pageTitle>Page view by email@example.com</pageTitle> <pageIdAction>2</pageIdAction> - <serverTimePretty>Mar 14, 2010 11:22:33 AM</serverTimePretty> + <serverTimePretty>Mar 14, 2010 11:22:33</serverTimePretty> <pageId>11</pageId> <icon /> <timestamp>1268565753</timestamp> @@ -220,7 +220,7 @@ <url>http://example.org/index.htm</url> <pageTitle>A page view by new-user-id@one-weeklater</pageTitle> <pageIdAction>2</pageIdAction> - <serverTimePretty>Mar 14, 2010 11:46:33 AM</serverTimePretty> + <serverTimePretty>Mar 14, 2010 11:46:33</serverTimePretty> <pageId>12</pageId> <icon /> <timestamp>1268567193</timestamp> diff --git a/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml b/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml index ded012ba51ad738855e0bd47bcaeab4399795011..1a9ff120e6dfa161edabdd654dde4fc08b7240a7 100644 --- a/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml +++ b/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml @@ -66,6 +66,13 @@ <acceptedValues>13.54.122.1. </code>Select IP ranges with notation: <code>visitIp>13.54.122.0;visitIp<13.54.122.255</acceptedValues> <permission>1</permission> </row> + <row> + <type>metric</type> + <category>Actions</category> + <name>Action Type</name> + <segment>actionType</segment> + <acceptedValues>A type of action, such as: pageviews, contents, sitesearches, events, outlinks, downloads</acceptedValues> + </row> <row> <type>dimension</type> <category>Visit Location</category> @@ -306,6 +313,13 @@ <category>Custom Variables</category> <name>Custom Variable name (scope visit)</name> <segment>customVariableName</segment> + <unionOfSegments> + <row>customVariableName1</row> + <row>customVariableName2</row> + <row>customVariableName3</row> + <row>customVariableName4</row> + <row>customVariableName5</row> + </unionOfSegments> </row> <row> <type>dimension</type> @@ -342,6 +356,13 @@ <category>Custom Variables</category> <name>Custom Variable name (scope page)</name> <segment>customVariablePageName</segment> + <unionOfSegments> + <row>customVariablePageName1</row> + <row>customVariablePageName2</row> + <row>customVariablePageName3</row> + <row>customVariablePageName4</row> + <row>customVariablePageName5</row> + </unionOfSegments> </row> <row> <type>dimension</type> @@ -378,6 +399,13 @@ <category>Custom Variables</category> <name>Custom Variable value (scope page)</name> <segment>customVariablePageValue</segment> + <unionOfSegments> + <row>customVariablePageValue1</row> + <row>customVariablePageValue2</row> + <row>customVariablePageValue3</row> + <row>customVariablePageValue4</row> + <row>customVariablePageValue5</row> + </unionOfSegments> </row> <row> <type>dimension</type> @@ -414,6 +442,13 @@ <category>Custom Variables</category> <name>Custom Variable value (scope visit)</name> <segment>customVariableValue</segment> + <unionOfSegments> + <row>customVariableValue1</row> + <row>customVariableValue2</row> + <row>customVariableValue3</row> + <row>customVariableValue4</row> + <row>customVariableValue5</row> + </unionOfSegments> </row> <row> <type>dimension</type> @@ -445,6 +480,17 @@ <name>Custom Variable value 5 (scope visit)</name> <segment>customVariableValue5</segment> </row> + <row> + <type>dimension</type> + <category>Actions</category> + <name>Action URL</name> + <segment>actionUrl</segment> + <unionOfSegments> + <row>pageUrl</row> + <row>downloadUrl</row> + <row>outlinkUrl</row> + </unionOfSegments> + </row> <row> <type>dimension</type> <category>Actions</category> diff --git a/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems__CustomVariables.getCustomVariables_day.xml index 1d0ee64c8d067080b684d866ef7bee640c4e3340..caf12153e577fa9fdc50ceebda6fc834620f7f63 100755 --- a/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems__CustomVariables.getCustomVariables_day.xml @@ -33,6 +33,12 @@ </goals> <nb_conversions>3</nb_conversions> <revenue>3121.11</revenue> + <slots> + <row> + <scope>visit</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==ValueIsZero</segment> <subtable> <row> @@ -104,6 +110,12 @@ </goals> <nb_conversions>3</nb_conversions> <revenue>3121.11</revenue> + <slots> + <row> + <scope>visit</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -146,6 +158,12 @@ <label>_pkc</label> <nb_visits>7</nb_visits> <nb_actions>12</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==_pkc</segment> <subtable> <row> @@ -191,6 +209,12 @@ <label>_pkn</label> <nb_visits>6</nb_visits> <nb_actions>11</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==_pkn</segment> <subtable> <row> @@ -216,6 +240,12 @@ <label>_pks</label> <nb_visits>6</nb_visits> <nb_actions>11</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==_pks</segment> <subtable> <row> @@ -265,6 +295,12 @@ </goals> <nb_conversions>2</nb_conversions> <revenue>3111.11</revenue> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==VisitorName</segment> <subtable> <row> @@ -302,6 +338,12 @@ <label>_pkp</label> <nb_visits>8</nb_visits> <nb_actions>8</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==_pkp</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html b/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html index b81c8a37d0cc87bd202b9ecfa7289286e6729110..b2825b88eef819e3bd3937427c7ca8444b8045d7 100644 --- a/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html +++ b/tests/PHPUnit/System/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html @@ -5,7 +5,7 @@ </head> <body style="font-family: dejavusans; color: rgb(13,13,13);line-height: 1.33;"> -<a id="reportTop" rel="noreferrer" target="_blank" href="http://localhost/tests/PHPUnit/proxy/"><img title="Go to Piwik" border="0" alt="Piwik" src='http://localhost/tests/PHPUnit/proxy/plugins/Morpheus/images/logo-header.png'/></a> +<a id="reportTop" rel="noreferrer" target="_blank" href="http://example.com/piwik/tests/PHPUnit/proxy/"><img title="Go to Piwik" border="0" alt="Piwik" src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/Morpheus/images/logo-header.png'/></a> <h1 style="font-weight:normal; color: rgb(13,13,13); font-size: 24pt;"> Piwik test @@ -696,7 +696,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicesDetection/images/screens/normal.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/screens/normal.gif'> Desktop </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -818,7 +818,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicesDetection/images/brand/Unknown.ico'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/brand/Unknown.ico'> Unknown </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -940,7 +940,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/WIN.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/WIN.gif'> Windows XP </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1002,7 +1002,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/FF.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/FF.gif'> Firefox </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1064,7 +1064,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/FF.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/browsers/FF.gif'> Firefox 3.6 </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1186,7 +1186,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/WIN.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicesDetection/images/os/WIN.gif'> Windows </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1296,7 +1296,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/cookie.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/cookie.gif'> Cookie </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1309,7 +1309,7 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/flash.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/flash.gif'> Flash </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1322,7 +1322,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/java.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/java.gif'> Java </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1335,7 +1335,7 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/director.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/director.gif'> Director </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1348,7 +1348,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/gears.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/gears.gif'> Gears </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1361,7 +1361,7 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/pdf.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/pdf.gif'> Pdf </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1374,7 +1374,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/quicktime.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/quicktime.gif'> Quicktime </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1387,7 +1387,7 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/realplayer.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/realplayer.gif'> Realplayer </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1400,7 +1400,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/silverlight.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/silverlight.gif'> Silverlight </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1413,7 +1413,7 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/windowsmedia.gif'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/DevicePlugins/images/plugins/windowsmedia.gif'> Windowsmedia </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1463,7 +1463,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/pl.png'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/pl.png'> Poland </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1488,7 +1488,7 @@ <tr style=";line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/fr.png'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/fr.png'> France </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1610,7 +1610,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/xx.png'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/xx.png'> Unknown </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> @@ -1755,7 +1755,7 @@ <tr style="background-color: rgb(242,242,242);line-height: 22px;"> <td style="font-size: 13px; border-right: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> - <img src='http://localhost/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/xx.png'> + <img src='http://example.com/piwik/tests/PHPUnit/proxy/plugins/UserCountry/images/flags/xx.png'> Unknown </td> <td style="font-size: 13px; border-left: 1px solid rgb(217,217,217); padding: 5px 0 5px 5px;"> diff --git a/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getAvailableExtractionDimensions.xml b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getAvailableExtractionDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..7a397597a0aacfd97d7cf23e0878b632d2c9a36b --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getAvailableExtractionDimensions.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>url</value> + <name>Page URL</name> + </row> + <row> + <value>urlparam</value> + <name>Page URL Parameter</name> + </row> + <row> + <value>action_name</value> + <name>Page Title</name> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getAvailableScopes.xml b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getAvailableScopes.xml new file mode 100644 index 0000000000000000000000000000000000000000..149cf8b31c946ff2733882ccf47b8e409437df9d --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getAvailableScopes.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>visit</value> + <name>Visit</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>0</supportsExtractions> + </row> + <row> + <value>action</value> + <name>Action</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>1</supportsExtractions> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getConfiguredCustomDimensions.xml b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getConfiguredCustomDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomDimensions.getConfiguredCustomDimensions.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result /> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomVariables.getUsagesOfSlots.xml b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomVariables.getUsagesOfSlots.xml new file mode 100644 index 0000000000000000000000000000000000000000..81163427e5931b802fd0011c70cc3706ce2dd5b9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit_PeriodIsLast__CustomVariables.getUsagesOfSlots.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <scope>visit</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>5</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>5</index> + <usages> + </usages> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getAvailableExtractionDimensions.xml b/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getAvailableExtractionDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..7a397597a0aacfd97d7cf23e0878b632d2c9a36b --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getAvailableExtractionDimensions.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>url</value> + <name>Page URL</name> + </row> + <row> + <value>urlparam</value> + <name>Page URL Parameter</name> + </row> + <row> + <value>action_name</value> + <name>Page Title</name> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getAvailableScopes.xml b/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getAvailableScopes.xml new file mode 100644 index 0000000000000000000000000000000000000000..149cf8b31c946ff2733882ccf47b8e409437df9d --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getAvailableScopes.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <value>visit</value> + <name>Visit</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>0</supportsExtractions> + </row> + <row> + <value>action</value> + <name>Action</name> + <numSlotsAvailable>5</numSlotsAvailable> + <numSlotsUsed>0</numSlotsUsed> + <numSlotsLeft>5</numSlotsLeft> + <supportsExtractions>1</supportsExtractions> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getConfiguredCustomDimensions.xml b/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getConfiguredCustomDimensions.xml new file mode 100644 index 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit__CustomDimensions.getConfiguredCustomDimensions.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result /> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_noVisit__CustomVariables.getUsagesOfSlots.xml b/tests/PHPUnit/System/expected/test_noVisit__CustomVariables.getUsagesOfSlots.xml new file mode 100644 index 0000000000000000000000000000000000000000..81163427e5931b802fd0011c70cc3706ce2dd5b9 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_noVisit__CustomVariables.getUsagesOfSlots.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <scope>visit</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>visit</scope> + <index>5</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>1</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>2</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>3</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>4</index> + <usages> + </usages> + </row> + <row> + <scope>page</scope> + <index>5</index> + <usages> + </usages> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__CustomVariables.getCustomVariables_range.xml b/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__CustomVariables.getCustomVariables_range.xml index 595575819f453ed3a354311fcd71882044118909..ed926db9f7683273f65dc31a00ae706cdae50f0f 100644 --- a/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__CustomVariables.getCustomVariables_range.xml +++ b/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__CustomVariables.getCustomVariables_range.xml @@ -23,6 +23,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -88,6 +94,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -129,6 +141,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -155,6 +173,16 @@ <row> <label>Status user</label> <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==Status+user</segment> <subtable> <row> @@ -189,6 +217,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Othercustom+value+which+should+be+truncated+abcdefghijklmnopqrstuvwxyz</segment> <subtable> <row> @@ -215,6 +249,12 @@ <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -228,6 +268,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI_pagesegment__CustomVariables.getCustomVariables_range.xml b/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI_pagesegment__CustomVariables.getCustomVariables_range.xml index 595575819f453ed3a354311fcd71882044118909..ed926db9f7683273f65dc31a00ae706cdae50f0f 100644 --- a/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI_pagesegment__CustomVariables.getCustomVariables_range.xml +++ b/tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI_pagesegment__CustomVariables.getCustomVariables_range.xml @@ -23,6 +23,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -88,6 +94,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -129,6 +141,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -155,6 +173,16 @@ <row> <label>Status user</label> <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==Status+user</segment> <subtable> <row> @@ -189,6 +217,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Othercustom+value+which+should+be+truncated+abcdefghijklmnopqrstuvwxyz</segment> <subtable> <row> @@ -215,6 +249,12 @@ <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -228,6 +268,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_reportLimiting__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_reportLimiting__CustomVariables.getCustomVariables_day.xml index d436493f49906c5c7e8645024cc4f523ebdbf2ec..6ee02592b75d96381959ebe371299dcd61942fc9 100644 --- a/tests/PHPUnit/System/expected/test_reportLimiting__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_reportLimiting__CustomVariables.getCustomVariables_day.xml @@ -3,6 +3,12 @@ <row> <label>liked</label> <nb_actions>20</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==liked</segment> <subtable> <row> @@ -20,6 +26,12 @@ <row> <label>name</label> <nb_actions>20</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==name</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_reportLimiting_rankingQuery__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_reportLimiting_rankingQuery__CustomVariables.getCustomVariables_day.xml index d436493f49906c5c7e8645024cc4f523ebdbf2ec..6ee02592b75d96381959ebe371299dcd61942fc9 100644 --- a/tests/PHPUnit/System/expected/test_reportLimiting_rankingQuery__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_reportLimiting_rankingQuery__CustomVariables.getCustomVariables_day.xml @@ -3,6 +3,12 @@ <row> <label>liked</label> <nb_actions>20</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==liked</segment> <subtable> <row> @@ -20,6 +26,12 @@ <row> <label>name</label> <nb_actions>20</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==name</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageTitleEndsWith__Actions.getPageTitles_day.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageTitleEndsWith__Actions.getPageTitles_day.xml new file mode 100644 index 0000000000000000000000000000000000000000..38eb716dff158c54f3e2463f9c50e15004f34cfe --- /dev/null +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageTitleEndsWith__Actions.getPageTitles_day.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <label> Homepage</label> + <nb_visits>2</nb_visits> + <nb_uniq_visitors>2</nb_uniq_visitors> + <nb_hits>2</nb_hits> + <sum_time_spent>360</sum_time_spent> + <entry_nb_uniq_visitors>1</entry_nb_uniq_visitors> + <entry_nb_visits>1</entry_nb_visits> + <entry_nb_actions>3</entry_nb_actions> + <entry_sum_visit_length>364</entry_sum_visit_length> + <entry_bounce_count>0</entry_bounce_count> + <exit_nb_uniq_visitors>1</exit_nb_uniq_visitors> + <exit_nb_visits>1</exit_nb_visits> + <avg_time_on_page>180</avg_time_on_page> + <bounce_rate>0%</bounce_rate> + <exit_rate>50%</exit_rate> + </row> + <row> + <label> Profile page</label> + <nb_visits>1</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_hits>1</nb_hits> + <sum_time_spent>0</sum_time_spent> + <avg_time_on_page>0</avg_time_on_page> + <bounce_rate>0%</bounce_rate> + <exit_rate>0%</exit_rate> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageTitleStartsWith__Actions.getPageTitles_day.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageTitleStartsWith__Actions.getPageTitles_day.xml new file mode 100644 index 0000000000000000000000000000000000000000..7cfe228274d9b466791ec37ea0be74cee3eb495f --- /dev/null +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageTitleStartsWith__Actions.getPageTitles_day.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <label> Profile page</label> + <nb_visits>1</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_hits>1</nb_hits> + <sum_time_spent>0</sum_time_spent> + <avg_time_on_page>0</avg_time_on_page> + <bounce_rate>0%</bounce_rate> + <exit_rate>0%</exit_rate> + </row> + <row> + <label> Profile page for user *_)%</label> + <nb_visits>1</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_hits>1</nb_hits> + <sum_time_spent>0</sum_time_spent> + <exit_nb_uniq_visitors>1</exit_nb_uniq_visitors> + <exit_nb_visits>1</exit_nb_visits> + <avg_time_on_page>0</avg_time_on_page> + <bounce_rate>0%</bounce_rate> + <exit_rate>100%</exit_rate> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageUrlEndsWith__Actions.getPageUrls_day.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageUrlEndsWith__Actions.getPageUrls_day.xml new file mode 100644 index 0000000000000000000000000000000000000000..c64e18155a59d96b3a2088966d2c20258dd88cd7 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageUrlEndsWith__Actions.getPageUrls_day.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <label>user</label> + <nb_visits>1</nb_visits> + <nb_hits>2</nb_hits> + <sum_time_spent>0</sum_time_spent> + <exit_nb_visits>1</exit_nb_visits> + <avg_time_on_page>0</avg_time_on_page> + <bounce_rate>0%</bounce_rate> + <exit_rate>100%</exit_rate> + <subtable> + <row> + <label>/profile</label> + <nb_visits>1</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_hits>2</nb_hits> + <sum_time_spent>0</sum_time_spent> + <exit_nb_uniq_visitors>1</exit_nb_uniq_visitors> + <exit_nb_visits>1</exit_nb_visits> + <avg_time_on_page>0</avg_time_on_page> + <bounce_rate>0%</bounce_rate> + <exit_rate>100%</exit_rate> + <url>http://example.org/user/profile</url> + </row> + </subtable> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageUrlStartsWith__Actions.getPageUrls_day.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageUrlStartsWith__Actions.getPageUrls_day.xml new file mode 100644 index 0000000000000000000000000000000000000000..21450c0dd487c6eec8641f8e137b8eb78e2b3689 --- /dev/null +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_SegmentPageUrlStartsWith__Actions.getPageUrls_day.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <label>/homepage</label> + <nb_visits>2</nb_visits> + <nb_uniq_visitors>2</nb_uniq_visitors> + <nb_hits>2</nb_hits> + <sum_time_spent>0</sum_time_spent> + <entry_nb_uniq_visitors>1</entry_nb_uniq_visitors> + <entry_nb_visits>1</entry_nb_visits> + <entry_nb_actions>3</entry_nb_actions> + <entry_sum_visit_length>364</entry_sum_visit_length> + <entry_bounce_count>0</entry_bounce_count> + <exit_nb_uniq_visitors>1</exit_nb_uniq_visitors> + <exit_nb_visits>1</exit_nb_visits> + <avg_time_on_page>0</avg_time_on_page> + <bounce_rate>0%</bounce_rate> + <exit_rate>50%</exit_rate> + <url>http://example.org/homepage</url> + <segment>pageUrl==http%3A%2F%2Fexample.org%2Fhomepage</segment> + </row> +</result> \ No newline at end of file diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml index 7de013ab81cef36fb196df7ec71b1d402d154fcd..893b862eda391e251e46807ecf669bd8eb089a6e 100644 --- a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml @@ -24,6 +24,12 @@ </goals> <nb_conversions>3</nb_conversions> <revenue>1000</revenue> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -86,6 +92,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -125,6 +137,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -150,6 +168,16 @@ <row> <label>Status user</label> <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==Status+user</segment> <subtable> <row> @@ -181,6 +209,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>1000</revenue> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Othercustom+value+which+should+be+truncated+abcdefghijklmnopqrstuvwxyz</segment> <subtable> <row> @@ -206,6 +240,12 @@ <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -218,6 +258,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> @@ -230,6 +276,12 @@ <row> <label>var1</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==var1</segment> <subtable> <row> @@ -242,6 +294,12 @@ <row> <label>var2</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==var2</segment> <subtable> <row> @@ -254,6 +312,12 @@ <row> <label>var3</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==var3</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml index 5ad33104c98dd13d6cff2ae6599fd95bac77eae1..ed85668d5caabf851f2a81f21bf2430280d9765a 100644 --- a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml @@ -25,6 +25,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -90,6 +96,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -131,6 +143,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -157,6 +175,16 @@ <row> <label>Status user</label> <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> <segment>customVariableName==Status+user</segment> <subtable> <row> @@ -191,6 +219,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Othercustom+value+which+should+be+truncated+abcdefghijklmnopqrstuvwxyz</segment> <subtable> <row> @@ -217,6 +251,12 @@ <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -230,6 +270,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> @@ -243,6 +289,12 @@ <row> <label>var1</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==var1</segment> <subtable> <row> @@ -256,6 +308,12 @@ <row> <label>var2</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==var2</segment> <subtable> <row> @@ -269,6 +327,12 @@ <row> <label>var3</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + </slots> <segment>customVariableName==var3</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_day.xml index eec12ff4429eea0169f909a3e84155454da76a20..1bfb23612e9594dafc49f017558ec5c4030a364c 100644 --- a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_day.xml @@ -24,6 +24,12 @@ </goals> <nb_conversions>3</nb_conversions> <revenue>1000</revenue> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -86,6 +92,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -108,6 +120,33 @@ </row> </subtable> </row> + <row> + <label>Status user</label> + <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> + <segment>customVariableName==Status+user</segment> + <subtable> + <row> + <label>looking at "profile page"</label> + <nb_visits>2</nb_visits> + <nb_actions>2</nb_actions> + </row> + <row> + <label>Loggedin</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> <row> <label>Value will be VERY long and truncated</label> <nb_visits>1</nb_visits> @@ -125,6 +164,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -147,23 +192,6 @@ </row> </subtable> </row> - <row> - <label>Status user</label> - <nb_actions>3</nb_actions> - <segment>customVariableName==Status+user</segment> - <subtable> - <row> - <label>looking at "profile page"</label> - <nb_visits>2</nb_visits> - <nb_actions>2</nb_actions> - </row> - <row> - <label>Loggedin</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> <row> <label>Othercustom value which should be truncated abcdefghijklmnopqrstuvwxyz</label> <nb_visits>2</nb_visits> @@ -181,6 +209,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>1000</revenue> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Othercustom+value+which+should+be+truncated+abcdefghijklmnopqrstuvwxyz</segment> <subtable> <row> @@ -206,6 +240,12 @@ <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -218,6 +258,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_week.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_week.xml index fe4627f8e5f97d795b86170998f871b93298ecd7..4041ca8eacd4b73c9b1e8e9cacebd100487a23f0 100644 --- a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_week.xml +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_week.xml @@ -25,6 +25,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -90,6 +96,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -113,6 +125,35 @@ </row> </subtable> </row> + <row> + <label>Status user</label> + <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> + <segment>customVariableName==Status+user</segment> + <subtable> + <row> + <label>looking at "profile page"</label> + <nb_visits>2</nb_visits> + <nb_actions>2</nb_actions> + <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> + </row> + <row> + <label>Loggedin</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> + </row> + </subtable> + </row> <row> <label>Value will be VERY long and truncated</label> <nb_visits>1</nb_visits> @@ -131,6 +172,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -154,25 +201,6 @@ </row> </subtable> </row> - <row> - <label>Status user</label> - <nb_actions>3</nb_actions> - <segment>customVariableName==Status+user</segment> - <subtable> - <row> - <label>looking at "profile page"</label> - <nb_visits>2</nb_visits> - <nb_actions>2</nb_actions> - <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> - </row> - <row> - <label>Loggedin</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> - </row> - </subtable> - </row> <row> <label>Othercustom value which should be truncated abcdefghijklmnopqrstuvwxyz</label> <nb_visits>2</nb_visits> @@ -191,6 +219,12 @@ <revenue>1000</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==Othercustom+value+which+should+be+truncated+abcdefghijklmnopqrstuvwxyz</segment> <subtable> <row> @@ -217,6 +251,12 @@ <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -230,6 +270,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_day.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_day.xml index 38cbd40db825195fe0083c18018c0b3c4bc6e630..428f0180aec1cf6c1f87349df337deba0144ad0a 100644 --- a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_day.xml +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_day.xml @@ -19,6 +19,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -41,6 +47,33 @@ </row> </subtable> </row> + <row> + <label>Status user</label> + <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> + <segment>customVariableName==Status+user</segment> + <subtable> + <row> + <label>looking at "profile page"</label> + <nb_visits>2</nb_visits> + <nb_actions>2</nb_actions> + </row> + <row> + <label>Loggedin</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + </row> + </subtable> + </row> <row> <label>Value will be VERY long and truncated</label> <nb_visits>1</nb_visits> @@ -58,6 +91,12 @@ </goals> <nb_conversions>1</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -102,6 +141,12 @@ </goals> <nb_conversions>2</nb_conversions> <revenue>0</revenue> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -137,26 +182,15 @@ </row> </subtable> </row> - <row> - <label>Status user</label> - <nb_actions>3</nb_actions> - <segment>customVariableName==Status+user</segment> - <subtable> - <row> - <label>looking at "profile page"</label> - <nb_visits>2</nb_visits> - <nb_actions>2</nb_actions> - </row> - <row> - <label>Loggedin</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - </row> - </subtable> - </row> <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -169,6 +203,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> diff --git a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_week.xml b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_week.xml index 7557e0aa02aa46f04d22451160eac1baa40eb699..4c0da8f95e92c1f64835f450d0d56691aa95e27d 100644 --- a/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_week.xml +++ b/tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_week.xml @@ -20,6 +20,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE</segment> <subtable> <row> @@ -43,6 +49,35 @@ </row> </subtable> </row> + <row> + <label>Status user</label> + <nb_actions>3</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>4</index> + </row> + <row> + <scope>page</scope> + <index>5</index> + </row> + </slots> + <segment>customVariableName==Status+user</segment> + <subtable> + <row> + <label>looking at "profile page"</label> + <nb_visits>2</nb_visits> + <nb_actions>2</nb_actions> + <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> + </row> + <row> + <label>Loggedin</label> + <nb_visits>1</nb_visits> + <nb_actions>1</nb_actions> + <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> + </row> + </subtable> + </row> <row> <label>Value will be VERY long and truncated</label> <nb_visits>1</nb_visits> @@ -61,6 +96,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>3</index> + </row> + </slots> <segment>customVariableName==Value+will+be+VERY+long+and+truncated</segment> <subtable> <row> @@ -107,6 +148,12 @@ <revenue>0</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> + <slots> + <row> + <scope>visit</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==VisitorType</segment> <subtable> <row> @@ -143,28 +190,15 @@ </row> </subtable> </row> - <row> - <label>Status user</label> - <nb_actions>3</nb_actions> - <segment>customVariableName==Status+user</segment> - <subtable> - <row> - <label>looking at "profile page"</label> - <nb_visits>2</nb_visits> - <nb_actions>2</nb_actions> - <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> - </row> - <row> - <label>Loggedin</label> - <nb_visits>1</nb_visits> - <nb_actions>1</nb_actions> - <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> - </row> - </subtable> - </row> <row> <label>Language</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>1</index> + </row> + </slots> <segment>customVariableName==Language</segment> <subtable> <row> @@ -178,6 +212,12 @@ <row> <label>SET WITH EMPTY VALUE PAGE SCOPE</label> <nb_actions>1</nb_actions> + <slots> + <row> + <scope>page</scope> + <index>2</index> + </row> + </slots> <segment>customVariableName==SET+WITH+EMPTY+VALUE+PAGE+SCOPE</segment> <subtable> <row> diff --git a/tests/PHPUnit/Unit/CommonTest.php b/tests/PHPUnit/Unit/CommonTest.php index 8aa85ed550a581e14004ff74fe3f9cd70de6cebb..08931b6bfe2aba7570a472939aed9d7f15c46f9d 100644 --- a/tests/PHPUnit/Unit/CommonTest.php +++ b/tests/PHPUnit/Unit/CommonTest.php @@ -102,14 +102,6 @@ class CommonTest extends PHPUnit_Framework_TestCase */ public function testSanitizeInputValues($input, $output) { - if (version_compare(PHP_VERSION, '5.4') < 0) { - $this->assertTrue(@set_magic_quotes_runtime(1)); - $this->assertEquals(1, @get_magic_quotes_runtime()); - $this->assertEquals($output, Common::sanitizeInputValues($input)); - - $this->assertTrue(@set_magic_quotes_runtime(0)); - $this->assertEquals(0, @get_magic_quotes_runtime()); - } $this->assertEquals($output, Common::sanitizeInputValues($input)); } @@ -465,39 +457,4 @@ class CommonTest extends PHPUnit_Framework_TestCase { $this->assertEquals($expected, Common::extractLanguageCodeFromBrowserLanguage($browserLanguage, $validLanguages), "test with {$browserLanguage} failed, expected {$expected}"); } - - public function testSearchEnginesDefinedCorrectly() - { - include "DataFiles/SearchEngines.php"; - - $searchEngines = array(); - foreach ($GLOBALS['Piwik_SearchEngines'] as $host => $info) { - if (isset($info[2]) && $info[2] !== false) { - $this->assertTrue(strrpos($info[2], "{k}") !== false, $host . " search URL is not defined correctly, must contain the macro {k}"); - } - - if (!array_key_exists($info[0], $searchEngines)) { - $searchEngines[$info[0]] = true; - - $this->assertTrue(strpos($host, '{}') === false, $host . " search URL is the master record and should not contain {}"); - } - - if (isset($info[3]) && $info[3] !== false) { - $this->assertTrue(is_array($info[3]) || is_string($info[3]), $host . ' encoding must be either a string or an array'); - - if (is_string($info[3])) { - $this->assertTrue(trim($info[3]) !== '', $host . ' encoding cannot be an empty string'); - $this->assertTrue(strpos($info[3], ' ') === false, $host . ' encoding cannot contain spaces'); - - } - - if (is_array($info[3])) { - $this->assertTrue(count($info[3]) > 0, $host . ' encodings cannot be an empty array'); - $this->assertTrue(strpos(serialize($info[3]), '""') === false, $host . ' encodings in array cannot be empty stringss'); - $this->assertTrue(strpos(serialize($info[3]), ' ') === false, $host . ' encodings in array cannot contain spaces'); - } - } - } - } - } diff --git a/tests/PHPUnit/Unit/DataTable/Renderer/CSVTest.php b/tests/PHPUnit/Unit/DataTable/Renderer/CSVTest.php index c6fd94e40667f052d03a3e25698a13b8ea6b7770..057f500d189f7f21a388eefa2defafd2edf800fc 100644 --- a/tests/PHPUnit/Unit/DataTable/Renderer/CSVTest.php +++ b/tests/PHPUnit/Unit/DataTable/Renderer/CSVTest.php @@ -96,6 +96,22 @@ class DataTable_Renderer_CSVTest extends \PHPUnit_Framework_TestCase return $table; } + protected function _getDataTableHavingAnArrayInRowMetadata() + { + $array = array( + array(Row::COLUMNS => array('label' => 'sub1', 'count' => 1)), + array(Row::COLUMNS => array('label' => 'sub2', 'count' => 2), Row::METADATA => array('test' => 'render')), + array(Row::COLUMNS => array('label' => 'sub3', 'count' => 2), Row::METADATA => array('test' => 'renderMe', 'testArray' => 'ignore')), + array(Row::COLUMNS => array('label' => 'sub4', 'count' => 6), Row::METADATA => array('testArray' => array('do not render'))), + array(Row::COLUMNS => array('label' => 'sub5', 'count' => 2), Row::METADATA => array('testArray' => 'do ignore', 'mymeta' => 'should be rendered')), + array(Row::COLUMNS => array('label' => 'sub6', 'count' => 3), Row::METADATA => array('mymeta' => 'renderrrrrr')), + ); + + $table = new DataTable(); + $table->addRowsFromArray($array); + + return $table; + } public function testCSVTest1() { @@ -186,6 +202,25 @@ class DataTable_Renderer_CSVTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expected, $actual); } + public function testCSVTest7_shouldNotRenderMetadataThatContainsAnArray() + { + $dataTable = $this->_getDataTableHavingAnArrayInRowMetadata(); + $render = new Csv(); + $render->setTable($dataTable); + $render->convertToUnicode = false; + + // the column "testArray" should be ignored and not rendered, all other columns should be assigned correctly + $expected = "label,count,metadata_test,metadata_mymeta +sub1,1,, +sub2,2,render, +sub3,2,renderMe, +sub4,6,, +sub5,2,,should be rendered +sub6,3,,renderrrrrr"; + $rendered = $render->render(); + $this->assertEquals($expected, $rendered); + } + /** * DATA OF DATATABLE_ARRAY * ------------------------- diff --git a/tests/PHPUnit/Unit/DataTable/RowTest.php b/tests/PHPUnit/Unit/DataTable/RowTest.php index e18806d2d55069e75db48f1acd37100fdcaf0fee..bc9c49bb845174b39cab97f634ebe69c44a7f468 100644 --- a/tests/PHPUnit/Unit/DataTable/RowTest.php +++ b/tests/PHPUnit/Unit/DataTable/RowTest.php @@ -362,6 +362,65 @@ class RowTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->row->hasColumn('test')); } + public function test_sumRowMetadata_shouldSumMetadataAccordingToAggregationOperations() + { + $this->row->setColumn('nb_visits', 10); + $this->row->setMetadata('my_sum', 5); + $this->row->setMetadata('my_max', 4); + $this->row->setMetadata('my_array', array(array('test' => 1, 'value' => 1), array('test' => 2, 'value' => 2))); + + + $row = $this->getTestRowWithNoSubDataTable(); + $row->setColumn('nb_visits', 15); + $row->setMetadata('my_sum', 7); + $row->setMetadata('my_max', 2); + $row->setMetadata('my_array', array(array('test' => 3, 'value' => 3), array('test' => 2, 'value' => 2))); + + + $aggregations = array( + 'nosuchcolumn' => 'max', // this metadata name does not exist and should be ignored + 'my_sum' => 'sum', + 'my_max' => 'max', + 'my_array' => 'uniquearraymerge' + ); + $this->row->sumRowMetadata($row, $aggregations); + + $metadata = $this->row->getMetadata(); + $expected = array( + 'my_sum' => 12, + 'my_max' => 4, + 'my_array' => array(array('test' => 1, 'value' => 1), array('test' => 2, 'value' => 2), array('test' => 3, 'value' => 3)) + ); + $this->assertSame($expected, $metadata); + } + + public function test_sumRowMetadata_uniquearraymergeShouldUseArrayFromOtherRow_IfNoMetadataForThisRowSpecified() + { + $row = $this->getTestRowWithNoSubDataTable(); + $arrayValue = array(array('test' => 3, 'value' => 3), array('test' => 2, 'value' => 2)); + $row->setMetadata('my_array', $arrayValue); + + $aggregations = array('my_array' => 'uniquearraymerge'); + + $this->row->sumRowMetadata($row, $aggregations); + + $this->assertSame(array('my_array' => $arrayValue), $this->row->getMetadata()); + } + + public function test_sumRowMetadata_uniquearraymergeShouldUseArrayFromThisRow_IfNoMetadataForOtherRowSpecified() + { + $row = $this->getTestRowWithNoSubDataTable(); + + $arrayValue = array(array('test' => 3, 'value' => 3), array('test' => 2, 'value' => 2)); + $this->row->setMetadata('my_array', $arrayValue); + + $aggregations = array('my_array' => 'uniquearraymerge'); + + $this->row->sumRowMetadata($row, $aggregations); + + $this->assertSame(array('my_array' => $arrayValue), $this->row->getMetadata()); + } + private function assertColumnSavesValue($expectedValue, $columnName, $valueToSet) { $this->row->setColumn($columnName, $valueToSet); diff --git a/tests/PHPUnit/Unit/DateTest.php b/tests/PHPUnit/Unit/DateTest.php index ba18ce1e709ede70b455a21f63ad885a0b283456..ee37aba1eb71a29e1ebddcf6b45da686bb32ab3c 100644 --- a/tests/PHPUnit/Unit/DateTest.php +++ b/tests/PHPUnit/Unit/DateTest.php @@ -9,8 +9,10 @@ namespace Piwik\Tests\Unit; use Exception; +use Piwik\Container\StaticContainer; use Piwik\Date; use Piwik\SettingsServer; +use Piwik\Translate; /** */ @@ -331,4 +333,34 @@ class DateTest extends \PHPUnit_Framework_TestCase $this->assertTrue($date->isLeapYear()); } } + + + public function getLocalizedLongStrings() + { + return array( + array('en', false, '2000-01-01 16:05:52', '16:05:52'), + array('de', false, '2000-01-01 16:05:52', '16:05:52'), + array('en', true, '2000-01-01 16:05:52', '4:05:52 PM'), + array('de', true, '2000-01-01 04:05:52', '4:05:52 vorm.'), + array('zh-tw', true, '2000-01-01 04:05:52', '上åˆ4:05:52'), + array('lt', true, '2000-01-01 16:05:52', '04:05:52 popiet'), + array('ar', true, '2000-01-01 04:05:52', '4:05:52 ص'), + ); + } + + /** + * @group Core + * @dataProvider getLocalizedLongStrings + */ + public function testGetLocalizedTimeFormats($language, $use12HourClock, $time, $shouldBe) + { + Translate::loadAllTranslations(); + StaticContainer::get('Piwik\Translation\Translator')->setCurrentLanguage($language); + StaticContainer::get('Piwik\Intl\Data\Provider\DateTimeFormatProvider')->forceTimeFormat($use12HourClock); + + $date = Date::factory($time); + + $this->assertEquals($shouldBe, $date->getLocalized(Date::TIME_FORMAT)); + Translate::reset(); + } } diff --git a/tests/PHPUnit/Unit/IPTest.php b/tests/PHPUnit/Unit/IPTest.php index 222514455772f9622e00939017d480cd2c7f29fb..139687f619c200554cf29169757f248cd815cc29 100644 --- a/tests/PHPUnit/Unit/IPTest.php +++ b/tests/PHPUnit/Unit/IPTest.php @@ -10,11 +10,12 @@ namespace Piwik\Tests\Unit; -use Piwik\Common; use Piwik\Config; use Piwik\IP; -use Piwik\Tests\Framework\Mock\TestConfig; +/** + * @group Core + */ class IPTest extends \PHPUnit_Framework_TestCase { /** @@ -83,7 +84,6 @@ class IPTest extends \PHPUnit_Framework_TestCase /** * @dataProvider getIpFromHeaderTestData - * @group Core */ public function testGetIpFromHeader($description, $test) { @@ -111,8 +111,6 @@ class IPTest extends \PHPUnit_Framework_TestCase } /** - * @group Core - * * @dataProvider getIpTestData */ public function testGetNonProxyIpFromHeader($ip) @@ -121,8 +119,6 @@ class IPTest extends \PHPUnit_Framework_TestCase } /** - * @group Core - * * @dataProvider getIpTestData */ public function testGetNonProxyIpFromHeader2($ip) @@ -134,8 +130,6 @@ class IPTest extends \PHPUnit_Framework_TestCase } /** - * @group Core - * * @dataProvider getIpTestData */ public function testGetNonProxyIpFromHeader3($ip) @@ -154,6 +148,20 @@ class IPTest extends \PHPUnit_Framework_TestCase $this->assertEquals($ip, IP::getNonProxyIpFromHeader('1.1.1.1', array('HTTP_X_FORWARDED_FOR'))); } + /** + * See https://github.com/piwik/piwik/issues/8721 + */ + public function testGetNonProxyIpFromHeader4_ShouldReturnDefaultIp_IfDefaultIpIsGivenMultipleTimes() + { + // 1.1.1.1 is a trusted proxy + $_SERVER['REMOTE_ADDR'] = '1.1.1.1'; + $_SERVER['HTTP_X_FORWARDED_FOR'] = $_SERVER['REMOTE_ADDR']; + $_SERVER['HTTP_CF_CONNECTING_IP'] = $_SERVER['REMOTE_ADDR']; + + $this->assertEquals('1.1.1.1', IP::getNonProxyIpFromHeader('1.1.1.1', array('HTTP_X_FORWARDED_FOR', 'HTTP_CF_CONNECTING_IP'))); + unset($_SERVER['HTTP_CF_CONNECTING_IP']); + } + /** * Dataprovider for testGetLastIpFromList */ @@ -170,8 +178,6 @@ class IPTest extends \PHPUnit_Framework_TestCase } /** - * @group Core - * * @dataProvider getLastIpFromListTestData */ public function testGetLastIpFromList($csv, $expected) @@ -182,4 +188,10 @@ class IPTest extends \PHPUnit_Framework_TestCase // with excluded Ips $this->assertEquals($expected, IP::getLastIpFromList($csv . ', 10.10.10.10', array('10.10.10.10'))); } + + public function testGetLastIpFromList_shouldReturnAnEmptyString_IfMultipleIpsAreGivenButAllAreExcluded() + { + // with excluded Ips + $this->assertEquals('', IP::getLastIpFromList('10.10.10.10, 10.10.10.10', array('10.10.10.10'))); + } } diff --git a/tests/PHPUnit/Unit/Metrics/FormatterTest.php b/tests/PHPUnit/Unit/Metrics/FormatterTest.php index 0bcef84c5faecf05c295de6e3401623ffda24a3f..d9ccc18c6dae62e25712dcd1275cb5c7746b7dba 100644 --- a/tests/PHPUnit/Unit/Metrics/FormatterTest.php +++ b/tests/PHPUnit/Unit/Metrics/FormatterTest.php @@ -190,9 +190,9 @@ class FormatterTest extends \PHPUnit_Framework_TestCase array(100, array('1 min 40s', '00:01:40')), array(3600, array('1 hours 0 min', '01:00:00')), array(3700, array('1 hours 1 min', '01:01:40')), - array(86400 + 3600 * 10, array('1 days 10 hours', '34:00:00')), - array(86400 * 365, array('365 days 0 hours', '8760:00:00')), - array((86400 * (365.25 + 10)), array('1 years 10 days', '9006:00:00')), + array(86400 + 3600 * 10, array('1 days 10 hours', '1 days 10:00:00')), + array(86400 * 365, array('365 days 0 hours', '365 days 00:00:00')), + array((86400 * (365.25 + 10)), array('1 years 10 days', '375 days 06:00:00')), array(1.342, array('1.34s', '00:00:01.34')), array(.342, array('0.34s', '00:00:00.34')), array(.02, array('0.02s', '00:00:00.02')), @@ -202,7 +202,7 @@ class FormatterTest extends \PHPUnit_Framework_TestCase array(1.2, array('1.2s', '00:00:01.20')), array(122.1, array('2 min 2.1s', '00:02:02.10')), array(-122.1, array('-2 min 2.1s', '-00:02:02.10')), - array(86400 * -365, array('-365 days 0 hours', '-8760:00:00')) + array(86400 * -365, array('-365 days 0 hours', '-365 days 00:00:00')) ); } @@ -222,4 +222,4 @@ class FormatterTest extends \PHPUnit_Framework_TestCase SitesManagerAPI::setSingletonInstance($mock); } -} \ No newline at end of file +} diff --git a/tests/PHPUnit/Unit/Segment/SegmentExpressionTest.php b/tests/PHPUnit/Unit/Segment/SegmentExpressionTest.php index 6d9dcc67b11eba5c8133c1d2c46005d8484490dd..71e64863c1c4227672bd602411da1a31497496a4 100644 --- a/tests/PHPUnit/Unit/Segment/SegmentExpressionTest.php +++ b/tests/PHPUnit/Unit/Segment/SegmentExpressionTest.php @@ -72,6 +72,7 @@ class SegmentExpressionTest extends \PHPUnit_Framework_TestCase array('A==B,C==D', array('where' => " (A = ? OR C = ? )", 'bind' => array('B', 'D'))), array('A!=B;C==D', array('where' => " ( A IS NULL OR A <> ? ) AND C = ? ", 'bind' => array('B', 'D'))), array('A!=B;C==D,E!=Hello World!=', array('where' => " ( A IS NULL OR A <> ? ) AND (C = ? OR ( E IS NULL OR E <> ? ) )", 'bind' => array('B', 'D', 'Hello World!='))), + array('A=@B;C=$D', array('where' => " A LIKE ? AND C LIKE ? ", 'bind' => array('%B%', '%D'))), array('A>B', array('where' => " A > ? ", 'bind' => array('B'))), array('A<B', array('where' => " A < ? ", 'bind' => array('B'))), @@ -83,6 +84,8 @@ class SegmentExpressionTest extends \PHPUnit_Framework_TestCase array('A=@B_', array('where' => " A LIKE ? ", 'bind' => array('%B\_%'))), array('A!@B%', array('where' => " ( A IS NULL OR A NOT LIKE ? ) ", 'bind' => array('%B\%%'))), + array('A=$B%', array('where' => " A LIKE ? ", 'bind' => array('%B\%'))), + array('A=^B%', array('where' => " A LIKE ? ", 'bind' => array('B\%%'))), ); } diff --git a/tests/PHPUnit/Unit/Tracker/RequestTest.php b/tests/PHPUnit/Unit/Tracker/RequestTest.php index 3db5c22a4ab9afd049970f8b074c14672647fbee..7eb38059a26b394a7357837d889b83b2fc6407e8 100644 --- a/tests/PHPUnit/Unit/Tracker/RequestTest.php +++ b/tests/PHPUnit/Unit/Tracker/RequestTest.php @@ -470,6 +470,25 @@ class RequestTest extends UnitTestCase $this->assertContains($needle, $cookie . ''); } + public function test_getLocalTime() + { + $request = $this->buildRequest(array('h' => '12', 'm' => '34', 's' => '3')); + $this->assertSame('12:34:03', $request->getLocalTime()); + + + $request = $this->buildRequest(array('h' => '23', 'm' => '59', 's' => '59')); + $this->assertSame('23:59:59', $request->getLocalTime()); + } + + public function test_getLocalTime_shouldReturnValidTime_whenTimeWasInvalid() + { + $request = $this->buildRequest(array('h' => '26', 'm' => '60', 's' => '333')); + $this->assertSame('00:00:00', $request->getLocalTime()); + + $request = $this->buildRequest(array('h' => '-26', 'm' => '-60', 's' => '-333')); + $this->assertSame('00:00:00', $request->getLocalTime()); + } + public function test_getIdSite() { $request = $this->buildRequest(array('idsite' => '14')); diff --git a/tests/PHPUnit/Unit/UrlHelperTest.php b/tests/PHPUnit/Unit/UrlHelperTest.php index c3cd578a6514b34db54ad3dfb848f57ba6431497..bfdf9959aabba4187ba91fc64388045c3e82afd7 100644 --- a/tests/PHPUnit/Unit/UrlHelperTest.php +++ b/tests/PHPUnit/Unit/UrlHelperTest.php @@ -149,32 +149,6 @@ class UrlHelperTest extends \PHPUnit_Framework_TestCase $this->assertEquals(serialize($expected), serialize(UrlHelper::getArrayFromQueryString('a&b=&c=1&d[]&e[]=&f[]=a&g[]=b&g[]=c'))); } - /** - * Dataprovider for testExtractSearchEngineInformationFromUrl - */ - public function getSearchEngineUrls() - { - return Spyc::YAMLLoad(PIWIK_PATH_TEST_TO_ROOT .'/tests/resources/extractSearchEngineInformationFromUrlTests.yml'); - } - - /** - * @dataProvider getSearchEngineUrls - * @group Core - */ - public function testExtractSearchEngineInformationFromUrl($url, $engine, $keywords) - { - $this->includeDataFilesForSearchEngineTest(); - $returnedValue = UrlHelper::extractSearchEngineInformationFromUrl($url); - - $exptectedValue = false; - - if (!empty($engine)) { - $exptectedValue = array('name' => $engine, 'keywords' => $keywords); - } - - $this->assertEquals($exptectedValue, $returnedValue); - } - /** * Dataprovider for testGetLossyUrl */ @@ -203,11 +177,6 @@ class UrlHelperTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expected, UrlHelper::getLossyUrl($input)); } - private function includeDataFilesForSearchEngineTest() - { - include "DataFiles/SearchEngines.php"; - } - /** * @group Core */ diff --git a/tests/PHPUnit/bootstrap.php b/tests/PHPUnit/bootstrap.php index 5eed01f8060e99249c7f62095aaf1e405756e94a..313f8f4b6a5a6975a4ed5a8f22162dc3f231f6f5 100644 --- a/tests/PHPUnit/bootstrap.php +++ b/tests/PHPUnit/bootstrap.php @@ -82,6 +82,7 @@ function prepareServerVariables(Config $config) $_SERVER['HTTP_HOST'] = $testConfig['http_host']; $_SERVER['REQUEST_URI'] = $testConfig['request_uri']; $_SERVER['REMOTE_ADDR'] = $testConfig['remote_addr']; + $_SERVER['SERVER_PORT'] = $testConfig['port']; } function prepareTestDatabaseConfig(Config $config) diff --git a/tests/PHPUnit/config.ini.travis.php b/tests/PHPUnit/config.ini.travis.php index 093aeaca61140aeaf343e81d577c0396e4b98d3f..0261a631e2094b99a97f5a35cd7313a84c65d48f 100644 --- a/tests/PHPUnit/config.ini.travis.php +++ b/tests/PHPUnit/config.ini.travis.php @@ -14,6 +14,7 @@ tables_prefix = [tests] request_uri = "/" +port = 3000 [database_tests] host = 127.0.0.1 diff --git a/tests/README.md b/tests/README.md index aaa18d6d340865c053beb503b66261b02fa0c093..49a4882f013c8a9f784b7a01bd24ca0173ff936c 100644 --- a/tests/README.md +++ b/tests/README.md @@ -31,7 +31,7 @@ To execute the tests: 1. To install PHPUnit, run `php composer.phar install --dev` in the Piwik root directory. -2. Ensure the `[database_tests]` section in `piwik/config/config.php.ini` is set up correctly, +2. Ensure the `[database_tests]` section in `piwik/config/config.ini.php` is set up correctly, i.e. with the correct password to prevent the following error: `SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' (using password: NO)` diff --git a/tests/UI/specs/CoreUpdaterDb_spec.js b/tests/UI/specs/CoreUpdaterDb_spec.js index 98586a7ca506221c86a3987e8b0adcd131046c17..33236fda5bff39560f844b440959b1e7901abdeb 100644 --- a/tests/UI/specs/CoreUpdaterDb_spec.js +++ b/tests/UI/specs/CoreUpdaterDb_spec.js @@ -18,7 +18,7 @@ describe("CoreUpdaterDb", function () { }); function apiUpgradeTest(format) { - it("should start the updater when an old version of Piwik is detected in the DB", function (done) { + it("should start the updater when an old version of Piwik is detected in the DB with format " + format, function (done) { expect.file('CoreUpdater.API.ErrorMessage' + format + '.txt').to.be.pageContents(function (page) { page.load(''); page.downloadUrl('?module=API&method=API.getPiwikVersion&format=' + format); diff --git a/tests/UI/specs/Dashboard_spec.js b/tests/UI/specs/Dashboard_spec.js index 3c6166c6981f061b6ba5893093da6f625aff4f49..9607b126ac99cea5b8f159697637706406123987 100644 --- a/tests/UI/specs/Dashboard_spec.js +++ b/tests/UI/specs/Dashboard_spec.js @@ -38,11 +38,7 @@ describe("Dashboard", function () { var setup = function (done) { // make sure live widget doesn't refresh constantly for UI tests - testEnvironment.configOverride = { - General: { - 'live_widget_refresh_after_seconds': 1000000 - } - }; + testEnvironment.overrideConfig('General', 'live_widget_refresh_after_seconds', 1000000); testEnvironment.save(); // save empty layout for dashboard ID = 5 diff --git a/tests/UI/specs/Installation_spec.js b/tests/UI/specs/Installation_spec.js index 6830091da63d5bad7d61329a48a006d61e490849..6aca4b0b78c25205e53c2b1e0e51d016824f3089 100644 --- a/tests/UI/specs/Installation_spec.js +++ b/tests/UI/specs/Installation_spec.js @@ -121,6 +121,15 @@ describe("Installation", function () { }); page.click('.btn'); page.wait(3000); + + // manually remove port in tracking code, since ui-test.php won't be using the correct INI config file + page.evaluate(function () { + $('pre').each(function () { + var html = $(this).html(); + html = html.replace(/localhost\:[0-9]+/g, 'localhost'); + $(this).html(html); + }); + }); }, done); }); diff --git a/tests/UI/specs/Morpheus_spec.js b/tests/UI/specs/Morpheus_spec.js index e2dd4322e53bbd7b9391d35c83042fb6fa825281..0a57d26540eddcfed106b5dd896793ab19ecef2e 100644 --- a/tests/UI/specs/Morpheus_spec.js +++ b/tests/UI/specs/Morpheus_spec.js @@ -12,11 +12,7 @@ describe("Morpheus", function () { before(function () { // Enable development mode - testEnvironment.configOverride = { - Development: { - enabled: true - } - }; + testEnvironment.overrideConfig('Development', 'enabled', true); testEnvironment.save(); }); diff --git a/tests/UI/specs/Overlay_spec.js b/tests/UI/specs/Overlay_spec.js index 5fb74621f5bfb625efeac16fae6aeea1867b9b72..c0adc30a433c74dc7aabe30c3237690aa310adbf 100644 --- a/tests/UI/specs/Overlay_spec.js +++ b/tests/UI/specs/Overlay_spec.js @@ -12,6 +12,7 @@ describe("Overlay", function () { this.timeout(0); var url = null; + var urlWithSegment; function removeOptOutIframe(page) { page.evaluate(function () { @@ -20,8 +21,12 @@ describe("Overlay", function () { } before(function (done) { - url = "?module=Overlay&period=year&date=today&idSite=3#?l=" + encodeURIComponent(testEnvironment.overlayUrl).replace(/[%]/g, "$"); - + var baseUrl = '?module=Overlay&period=year&date=today&idSite=3'; + var hash = '#?l=' + encodeURIComponent(testEnvironment.overlayUrl).replace(/[%]/g, "$"); + + url = baseUrl + hash; + urlWithSegment = baseUrl + '&segment=' + encodeURIComponent('visitIp==20.56.34.67') + hash; + testEnvironment.callApi("SitesManager.addSiteAliasUrls", {idSite: 3, urls: [config.piwikUrl]}, done); }); @@ -49,6 +54,14 @@ describe("Overlay", function () { }); page.sendMouseEvent('mousemove', pos); + page.evaluate(function () { + $('div#PIS_StatusBar', $('iframe').contents()).each(function () { + var html = $(this).html(); + html = html.replace(/localhost\:[0-9]+/g, 'localhost'); + $(this).html(html); + }); + }); + removeOptOutIframe(page); }, done); }); @@ -114,4 +127,12 @@ describe("Overlay", function () { removeOptOutIframe(page); }, done); }); + + it("should load an overlay with segment", function (done) { + expect.screenshot("loaded_with_segment").to.be.capture(function (page) { + page.load(urlWithSegment); + + removeOptOutIframe(page); + }, done); + }); }); \ No newline at end of file diff --git a/tests/UI/specs/SegmentSelectorEditor_spec.js b/tests/UI/specs/SegmentSelectorEditor_spec.js index 0f53003c10066e425b9ca2bfa7850298492ab18d..2bb57217624e23f73a8ec4df37d8c1d510185528 100644 --- a/tests/UI/specs/SegmentSelectorEditor_spec.js +++ b/tests/UI/specs/SegmentSelectorEditor_spec.js @@ -74,7 +74,7 @@ describe("SegmentSelectorEditorTest", function () { it("should add new segment expression when segment dimension drag dropped", function (done) { expect.screenshot("dimension_drag_drop").to.be.captureSelector(selectorsToCapture, function (page) { page.click('.segmentEditorPanel .metric_category:contains(Actions)'); - page.dragDrop('.segmentEditorPanel li[data-metric=entryPageUrl]', '.segmentEditorPanel .ui-droppable'); + page.dragDrop('.segmentEditorPanel li[data-metric=actionUrl]', '.segmentEditorPanel .ui-droppable'); }, done); }); diff --git a/tests/UI/specs/Theme_spec.js b/tests/UI/specs/Theme_spec.js index 81c162b0c561d10005a8c997d71c7048046e1b46..a7fffd2f3050be0ffbddd6f7c7ede3361e48290d 100644 --- a/tests/UI/specs/Theme_spec.js +++ b/tests/UI/specs/Theme_spec.js @@ -20,18 +20,14 @@ describe("Theme", function () { testEnvironment.pluginsToLoad = ['ExampleTheme']; // Enable development mode to be able to see the UI demo page - testEnvironment.configOverride = { - Development: { - enabled: true - } - }; - + testEnvironment.overrideConfig('Development', 'enabled', true); testEnvironment.save(); clearAssets(); }); after(function () { + clearAssets(); }); diff --git a/tests/UI/specs/UIIntegration_spec.js b/tests/UI/specs/UIIntegration_spec.js index 972e15f23ad8a870f87203794e9bf894ce0702cf..0849e5c8a20794a815f30d7db4863ae555de6aea 100644 --- a/tests/UI/specs/UIIntegration_spec.js +++ b/tests/UI/specs/UIIntegration_spec.js @@ -30,7 +30,9 @@ describe("UIIntegrationTest", function () { // TODO: Rename to Piwik? }); beforeEach(function () { - delete testEnvironment.configOverride; + if (testEnvironment.configOverride.database) { + delete testEnvironment.configOverride.database; + } testEnvironment.testUseMockAuth = 1; testEnvironment.save(); }); @@ -41,6 +43,7 @@ describe("UIIntegrationTest", function () { // TODO: Rename to Piwik? testEnvironment.save(); }); + // dashboard tests it("should load dashboard1 correctly", function (done) { expect.screenshot("dashboard1").to.be.captureSelector('.pageWrap,.expandDataTableFooterDrawer', function (page) { @@ -149,6 +152,15 @@ describe("UIIntegrationTest", function () { // TODO: Rename to Piwik? }, done); }); + // actions pages + it('should load the actions > pages help tooltip, including the "Report generated time"', function (done) { + expect.screenshot('actions_pages_tooltip_help').to.be.captureSelector('.pageWrap,.expandDataTableFooterDrawer', function (page) { + page.load("?" + urlBase + "#" + generalParams + "&module=Actions&action=menuGetPageUrls"); + page.mouseMove('h2[piwik-enriched-headline]'); + page.click(".helpIcon"); + }, done); + }); + it('should load the actions > entry pages page correctly', function (done) { expect.screenshot('actions_entry_pages').to.be.captureSelector('.pageWrap,.expandDataTableFooterDrawer', function (page) { page.load("?" + urlBase + "#?" + generalParams + "&category=General_Actions&subcategory=Actions_SubmenuPagesEntry"); @@ -512,15 +524,14 @@ describe("UIIntegrationTest", function () { // TODO: Rename to Piwik? // DB error message it('should fail correctly when db information in config is incorrect', function (done) { - testEnvironment.configOverride = { - database: { - host: '127.50.50.50', - username: 'slkdfjsdlkfj', - password: 'slkdfjsldkfj', - dbname: 'abcdefg', - tables_prefix: 'gfedcba' - } - }; + + testEnvironment.overrideConfig('database', { + host: config.phpServer.REMOTE_ADDR, + username: 'slkdfjsdlkfj', + password: 'slkdfjsldkfj', + dbname: 'abcdefg', + tables_prefix: 'gfedcba' + }); testEnvironment.save(); expect.screenshot('db_connect_error').to.be.capture(function (page) { @@ -545,8 +556,16 @@ describe("UIIntegrationTest", function () { // TODO: Rename to Piwik? it('should load the widgets listing page correctly', function (done) { expect.screenshot('widgets_listing').to.be.captureSelector('.pageWrap', function (page) { page.load("?" + generalParams + "&module=Widgetize&action=index"); + page.mouseMove('.widgetpreview-categorylist>li:contains(Visitors)'); page.mouseMove('li[uniqueid="widgetVisitsSummarygetEvolutionGraphforceView1viewDataTablegraphEvolution"]'); + page.evaluate(function () { + $('.formEmbedCode').each(function () { + var val = $(this).val(); + val = val.replace(/localhost\:[0-9]+/g, 'localhost'); + $(this).val(val); + }); + }); }, done); }); diff --git a/tests/angularjs/scripts/install-ubuntu.sh b/tests/angularjs/scripts/install-ubuntu.sh index 60a564dae26d336c93f3fb07472db8ebbd852cc2..86953430d502230d0b74679fa73e74a0245e9323 100755 --- a/tests/angularjs/scripts/install-ubuntu.sh +++ b/tests/angularjs/scripts/install-ubuntu.sh @@ -1,11 +1,7 @@ +#!/usr/bin/env bash DIR=`dirname $0` source $DIR/../../travis/travis-helper.sh -cd $DIR -travis_retry sudo apt-get -qq install python-software-properties -travis_retry sudo apt-add-repository -y ppa:chris-lea/node.js > /dev/null -travis_retry sudo apt-get -qq update - cd .. npm config set loglevel error travis_retry npm install . \ No newline at end of file diff --git a/tests/angularjs/scripts/run-once.sh b/tests/angularjs/scripts/run-once.sh index 5f95af3fa546adabf6a380a90bdc3d9c9636c674..4f796b4acb70dfca2db47f2705f860a04bde39d4 100755 --- a/tests/angularjs/scripts/run-once.sh +++ b/tests/angularjs/scripts/run-once.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash DIR=`dirname $0` cd $DIR cd .. diff --git a/tests/angularjs/scripts/travis.sh b/tests/angularjs/scripts/travis.sh index f2002203ad35b4da472caf5c8723ef46678a0eaf..70e083a4f844bb82eab98b4f833edda7a50fdd86 100755 --- a/tests/angularjs/scripts/travis.sh +++ b/tests/angularjs/scripts/travis.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash DIR=`dirname $0` cd $DIR ./install-ubuntu.sh diff --git a/tests/javascript/README.md b/tests/javascript/README.md index 5852407301dbe2069d8ed9c53474cb219fa917a7..9e34fdff0768ba5bc241da8b4c69a5132d5ecf2b 100644 --- a/tests/javascript/README.md +++ b/tests/javascript/README.md @@ -1,10 +1,9 @@ # JavaScript Tests ## Setup -Javascript integration tests require sqlite: - * ensure this PHP extension is enabled to make sure you run all tests apt-get install php5-sqlite - * Then please create an empty file `enable_sqlite` in `tests/javascript/enable_sqlite` - * Re-execute the tests and make sure the "missing sqlite" error message does not display +Javascript integration tests require an installed Piwik and ensure the `[database_tests]` section in `piwik/config/config.ini.php` is set up correctly, i.e. with th correct password to prevent the following error: `SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' (using password: NO)` + +The tests will create a database named `tracker_tests` and store several tracking requests in it. ## Execute diff --git a/tests/javascript/SQLite.php b/tests/javascript/SQLite.php deleted file mode 100644 index 5b4a3b3343ae127ab33da9c4e43a80e5835ffbf7..0000000000000000000000000000000000000000 --- a/tests/javascript/SQLite.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/*! - * Piwik - free/libre analytics platform - * - * SQLite shim - * - * @link http://piwik.org - * @license http://www.opensource.org/licenses/bsd-license.php Simplified BSD - */ -if (class_exists('SQLite3')) -{ - class SQLite extends SQLite3 - { - public function __construct($filename) - { - parent::__construct($filename); - - // for backward compatibility - if (version_compare(PHP_VERSION, '5.3.3') > 0) - { - $this->busyTimeout(60000); - } - } - - public function query_array($sql) - { - $result = parent::query($sql); - - $rows = array(); - while ($res = $result->fetchArray(SQLITE3_ASSOC)) - { - $rows[] = $res; - } - return $rows; - } - } -} -else if (extension_loaded('sqlite')) -{ - class SQLite - { - private $handle; - - public function __construct($filename) - { - $this->handle = sqlite_open($filename); - } - - public function query_array($sql) - { - return sqlite_array_query($this->handle, $sql); - } - - public function exec($sql) - { - return sqlite_exec($this->handle, $sql); - } - - public function changes() - { - return sqlite_changes($this->handle); - } - - public function close() - { - sqlite_close($this->handle); - unset($this->handle); - } - } -} diff --git a/tests/javascript/index.php b/tests/javascript/index.php index 702233d62264c519e3405176b3f0337c526874d3..60d7f11558fa6acb3f0f1c6c2ed6b12e6a04043b 100644 --- a/tests/javascript/index.php +++ b/tests/javascript/index.php @@ -5,7 +5,14 @@ <meta charset="utf-8"> <title>piwik.js: Unit Tests</title> <?php -require_once(dirname(__FILE__).'/SQLite.php'); +$root = dirname(__FILE__) . '/../..'; + +try { + $mysql = include_once $root . "/tests/PHPUnit/bootstrap.php"; +} catch (Exception $e) { + echo 'alert("' . $e->getMessage() . '")'; + $mysql = false; +} if(file_exists("stub.tpl")) { echo file_get_contents("stub.tpl"); @@ -22,17 +29,8 @@ function getHeartbeatToken() { return "<?php $token = md5(uniqid(mt_rand(), true)); echo $token; ?>"; } <?php -$sqlite = false; -if (file_exists("enable_sqlite")) { - if (class_exists('SQLite')) { - $sqlite = true; - } -} -if(!$sqlite) { - echo 'alert("WARNING: Javascript integration tests require sqlite, \n1) ensure this PHP extension is enabled to make sure you run all tests \napt-get install php5-sqlite \n2) Then please create an empty file enable_sqlite in tests/javascript/enable_sqlite \n3) Re-execute this page and make sure this popup does not display ");'; -} -if ($sqlite) { +if ($mysql) { echo ' var _paq = _paq || []; @@ -1930,7 +1928,7 @@ function PiwikTest() { }); test("API methods", function() { - expect(66); + expect(69); equal( typeof Piwik.addPlugin, 'function', 'addPlugin' ); equal( typeof Piwik.getTracker, 'function', 'getTracker' ); @@ -1959,6 +1957,9 @@ function PiwikTest() { equal( typeof tracker.setCustomData, 'function', 'setCustomData' ); equal( typeof tracker.getCustomData, 'function', 'getCustomData' ); equal( typeof tracker.setCustomRequestProcessing, 'function', 'setCustomRequestProcessing' ); + equal( typeof tracker.setCustomDimension, 'function', 'setCustomDimension' ); + equal( typeof tracker.getCustomDimension, 'function', 'getCustomDimension' ); + equal( typeof tracker.deleteCustomDimension, 'function', 'deleteCustomDimension' ); equal( typeof tracker.setCustomVariable, 'function', 'setCustomVariable' ); equal( typeof tracker.getCustomVariable, 'function', 'getCustomVariable' ); equal( typeof tracker.deleteCustomVariable, 'function', 'deleteCustomVariable' ); @@ -2241,12 +2242,48 @@ function PiwikTest() { } }); - test("Tracker setDomains() and isSiteHostName()", function() { - expect(13); + test("Tracker setDomains(), isSiteHostName(), isSiteHostPath(), findConfigCookiePathToUse() and getLinkIfShouldBeProcessed()", function() { + expect(117); var tracker = Piwik.getTracker(); + var initialDomains = tracker.getDomains(); + var domainAlias = initialDomains[0]; equal( typeof tracker.hook.test._isSiteHostName, 'function', "isSiteHostName" ); + equal( typeof tracker.hook.test._isSiteHostPath, 'function', "isSiteHostPath" ); + equal( typeof tracker.hook.test._getLinkIfShouldBeProcessed, 'function', "getLinkIfShouldBeProcessed" ); + equal( typeof tracker.hook.test._findConfigCookiePathToUse, 'function', "findConfigCookiePathToUse" ); + + var isSiteHostName = tracker.hook.test._isSiteHostName; + var isSiteHostPath = tracker.hook.test._isSiteHostPath; + var getLinkIfShouldBeProcessed = tracker.hook.test._getLinkIfShouldBeProcessed; + var findConfigCookiePathToUse = tracker.hook.test._findConfigCookiePathToUse; + + // tracker.setDomain() + + // test wildcards + tracker.setDomains( ['*.Example.com'] ); + propEqual(["*.Example.com", domainAlias], tracker.getDomains()), 'should add domainAlias'; + + tracker.setDomains( '*.Example.org' ); + propEqual(["*.Example.org", domainAlias], tracker.getDomains()), 'should handle a string'; + + tracker.setDomains( ['*.Example.com', '*.example.ORG'] ); + propEqual(["*.Example.com", '*.example.ORG', domainAlias], tracker.getDomains()), 'should be able to set many domains'; + + tracker.setDomains( [] ); + propEqual([domainAlias], tracker.getDomains()), 'setting an empty array should reset the list'; + + tracker.setDomains( ['*.Example.com', domainAlias + '/path', '*.example.ORG'] ); + propEqual(['*.Example.com', domainAlias + '/path', '*.example.ORG'], tracker.getDomains()), 'if domain alias is already given should not add domainAlias'; + + tracker.setDomains( ['.' + domainAlias + '/path'] ); + propEqual(['.' + domainAlias + '/path'], tracker.getDomains()), 'if domain alias with subdomain is already given should not add domainAlias'; + + + /** + * isSiteHostName () + */ // test wildcards tracker.setDomains( ['*.Example.com'] ); @@ -2254,21 +2291,171 @@ function PiwikTest() { // skip test if testing on localhost ok( window.location.hostname != 'localhost' ? !tracker.hook.test._isSiteHostName('localhost') : true, '!isSiteHostName("localhost")' ); - ok( !tracker.hook.test._isSiteHostName('google.com'), '!isSiteHostName("google.com")' ); - ok( tracker.hook.test._isSiteHostName('example.com'), 'isSiteHostName("example.com")' ); - ok( tracker.hook.test._isSiteHostName('www.example.com'), 'isSiteHostName("www.example.com")' ); - ok( tracker.hook.test._isSiteHostName('www.sub.example.com'), 'isSiteHostName("www.sub.example.com")' ); + ok( !isSiteHostName('google.com'), '!isSiteHostName("google.com")' ); + ok( isSiteHostName('example.com'), 'isSiteHostName("example.com")' ); + ok( isSiteHostName('www.example.com'), 'isSiteHostName("www.example.com")' ); + ok( isSiteHostName('www.sub.example.com'), 'isSiteHostName("www.sub.example.com")' ); tracker.setDomains( 'dev.piwik.org' ); - ok( !tracker.hook.test._isSiteHostName('piwik.org'), '!isSiteHostName("piwik.org")' ); - ok( tracker.hook.test._isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' ); - ok( !tracker.hook.test._isSiteHostName('piwik.example.org'), '!isSiteHostName("piwik.example.org")'); - ok( !tracker.hook.test._isSiteHostName('dev.piwik.org.com'), '!isSiteHostName("dev.piwik.org.com")'); + ok( !isSiteHostName('piwik.org'), '!isSiteHostName("piwik.org")' ); + ok( isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' ); + ok( !isSiteHostName('piwik.example.org'), '!isSiteHostName("piwik.example.org")'); + ok( !isSiteHostName('dev.piwik.org.com'), '!isSiteHostName("dev.piwik.org.com")'); tracker.setDomains( '.piwik.org' ); - ok( tracker.hook.test._isSiteHostName('piwik.org'), 'isSiteHostName("piwik.org")' ); - ok( tracker.hook.test._isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' ); - ok( !tracker.hook.test._isSiteHostName('piwik.org.com'), '!isSiteHostName("piwik.org.com")'); + ok( isSiteHostName('piwik.org'), 'isSiteHostName("piwik.org")' ); + ok( isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' ); + ok( !isSiteHostName('piwik.org.com'), '!isSiteHostName("piwik.org.com")'); + + /** + * isSiteHostPath () + */ + + // with path + tracker.setDomains( '.piwik.org/path' ); + ok( isSiteHostPath('piwik.org', '/path'), 'isSiteHostPath("piwik.org", "/path")' ); + ok( isSiteHostPath('piwik.org', '/path/'), 'isSiteHostPath("piwik.org", "/path/")' ); + ok( isSiteHostPath('piwik.org', '/path/test'), 'isSiteHostPath("piwik.org", "/path/test)' ); + ok( isSiteHostPath('dev.piwik.org', '/path'), 'isSiteHostPath("dev.piwik.org", "/path")' ); + ok( !isSiteHostPath('piwik.org', '/pat'), '!isSiteHostPath("piwik.org", "/pat")'); + ok( !isSiteHostPath('piwik.org', '.com'), '!isSiteHostPath("piwik.org", ".com")'); + ok( !isSiteHostPath('piwik.com', '/path'), '!isSiteHostPath("piwik.com", "/path")'); + ok( !isSiteHostPath('piwik.com', '/path/test'), '!isSiteHostPath("piwik.com", "/path/test")'); + ok( !isSiteHostPath('piwik.com', ''), '!isSiteHostPath("piwik.com", "/path/test")'); + + // no path + var domains = ['.piwik.org', 'piwik.org', '*.piwik.org', '.piwik.org/']; + for (var i in domains) { + var domain = domains[i]; + tracker.setDomains( domain ); + ok( isSiteHostPath('piwik.org', '/path'), 'isSiteHostPath("piwik.org", "/path"), domain: ' + domain ); + ok( isSiteHostPath('piwik.org', '/path/'), 'isSiteHostPath("piwik.org", "/path/"), domain: ' + domain ); + ok( isSiteHostPath('piwik.org', '/path/test'), 'isSiteHostPath("piwik.org", "/path/test), domain: ' + domain ); + + if (domain === 'piwik.org') { + ok( !isSiteHostPath('dev.piwik.org', '/path'), 'isSiteHostPath("dev.piwik.org", "/path"), domain: ' + domain ); + } else { + ok( isSiteHostPath('dev.piwik.org', '/path'), 'isSiteHostPath("dev.piwik.org", "/path"), domain: ' + domain ); + } + ok( isSiteHostPath('piwik.org', '/pat'), '!isSiteHostPath("piwik.org", "/pat"), domain: ' + domain ); + ok( isSiteHostPath('piwik.org', '.com'), '!isSiteHostPath("piwik.org", ".com"), domain: ' + domain); + ok( isSiteHostPath('piwik.org', '/foo'), '!isSiteHostPath("piwik.com", "/foo"), domain: ' + domain); + ok( !isSiteHostPath('piwik.com', '/path'), '!isSiteHostPath("piwik.com", "/path"), domain: ' + domain); + ok( !isSiteHostPath('piwik.com', '/path/test'), '!isSiteHostPath("piwik.com", "/path/test"), domain: ' + domain); + ok( !isSiteHostPath('piwik.com', ''), '!isSiteHostPath("piwik.com", "/path/test"), domain: ' + domain); + } + + // multiple paths / domains + tracker.setDomains( ['piwik.org/path', 'piwik.org/foo', 'piwik.org/bar/baz', '.piwik.pro/test'] ); + ok( isSiteHostPath('piwik.pro', '/test/bar'), 'isSiteHostPath("piwik.pro", "/test/bar")' ); + ok( !isSiteHostPath('piwik.org', '/foobar/'), 'isSiteHostPath("piwik.org", "/foobar/")' ); + ok( isSiteHostPath('piwik.org', '/foo/bar'), 'isSiteHostPath("piwik.org", "/foo/bar")' ); + ok( isSiteHostPath('piwik.org', '/bar/baz/foo'), 'isSiteHostPath("piwik.org", "/bar/baz/foo/")' ); + ok( !isSiteHostPath('piwik.org', '/bar/ba'), 'isSiteHostPath("piwik.org", "/bar/ba")' ); + ok( isSiteHostPath('piwik.org', '/path/test'), 'isSiteHostPath("piwik.org", "/path/test)' ); + ok( isSiteHostPath('dev.piwik.pro', '/test'), 'isSiteHostPath("dev.piwik.pro", "/test")' ); + ok( !isSiteHostPath('dev.piwik.pro', '/'), 'isSiteHostPath("dev.piwik.pro", "/")' ); + ok( !isSiteHostPath('piwik.pro', '/'), 'isSiteHostPath("piwik.pro", "/")' ); + ok( !isSiteHostPath('piwik.org', '/'), 'isSiteHostPath("piwik.org", "/")' ); + ok( !isSiteHostPath('piwik.org', '/anythingelse'), 'isSiteHostPath("piwik.org", "/anythingelse")' ); + + // all is compared lower case + tracker.setDomains( '.piwik.oRg/PaTh' ); + ok( isSiteHostPath('piwiK.org', '/pAth'), 'isSiteHostPath("piwik.org", "/path")' ); + ok( isSiteHostPath('piwik.org', '/patH/'), 'isSiteHostPath("piwik.org", "/path/")' ); + ok( isSiteHostPath('Piwik.ORG', '/PATH/TEST'), 'isSiteHostPath("piwik.org", "/path/test)' ); + + /** + * getLinkIfShouldBeProcessed () + */ + var getLinkIfShouldBeProcessed = tracker.hook.test._getLinkIfShouldBeProcessed; + function createLink(url) { + var link = document.createElement('a'); + link.href = url; + return link; + } + + tracker.setDomains( ['.piwik.org/path', '.piwik.org/foo', '.piwik.org/bar/baz', '.piwik.pro/test'] ); + + // they should not be detected as outlink as they match one of the domains + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed http://www.piwik.org/foo/bar matches .piwik.org/foo') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed http://piwik.org/foo/bar matches .piwik.org/foo') + equal(undefined, getLinkIfShouldBeProcessed(createLink('piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed missing protocol only domain given') + equal(undefined, getLinkIfShouldBeProcessed(createLink('//piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed no protcol but url starts with //') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo?x=1')), 'getLinkIfShouldBeProcessed url with query parameter should detect correct path') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo')), 'getLinkIfShouldBeProcessed path is same as allowed path') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo/')), 'getLinkIfShouldBeProcessed path is same as allowed path but with appended slash') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz/')), 'getLinkIfShouldBeProcessed multiple directories with appended slash') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz')), 'getLinkIfShouldBeProcessed multiple directories') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://WWW.PIWIK.ORG/BAR/BAZ')), 'getLinkIfShouldBeProcessed should test everything lowercase') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz/x/y/z')), 'getLinkIfShouldBeProcessed many appended paths') + equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz?test=1&foo=bar')), 'getLinkIfShouldBeProcessed another test with query parameter and multiple directories') + propEqual({ + "href": "http://www.piwik.org/foo/download.apk", + "type": "download" + }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo/download.apk')), 'getLinkIfShouldBeProcessed should detect download even if it is link to same domain') + propEqual({ + "href": "http://www.piwik.org/foobar/download.apk", + "type": "download" + }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foobar/download.apk')), 'getLinkIfShouldBeProcessed should detect download even if it goes to different domain/path') + propEqual({ + "href": "http://www.piwik.com/foobar/download.apk", + "type": "download" + }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.com/foobar/download.apk')), 'getLinkIfShouldBeProcessed should detect download even if it goes to different domain') + propEqual({ + "href": "http://www.piwik.pro/foo/", + "type": "link" + }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.pro/foo/')), 'getLinkIfShouldBeProcessed path matches but domain not so outlink') + propEqual({ + "href": "http://www.piwik.org/bar", + "type": "link" + }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar')), 'getLinkIfShouldBeProcessed domain matches but path not so outlink') + propEqual({ + "href": "http://www.piwik.org/footer", + "type": "link" + }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/footer')), 'getLinkIfShouldBeProcessed http://www.piwik.org/footer and there is domain piwik.org/foo but it should be outlink as path is different') + + + /** + * findConfigCookiePathToUse () + */ + + tracker.setDomains( ['.piwik.org', '.piwik.pro/foo/bar', '.piwik.pro/foo', '.piwik.com/test/foo', 'example.com/foo'] ); + + equal(null, findConfigCookiePathToUse('.piwik.org/test', 'http://piwik.org/test/two'), 'findConfigCookiePathToUse no cookiePath because there is a domain alias given allowing them all'); + equal('/foo', findConfigCookiePathToUse('.piwik.pro/foo', 'http://piwik.pro/foo/bar/test'), 'findConfigCookiePathToUse should find a match'); + equal('/foo', findConfigCookiePathToUse('.piwik.pro/foo/bar/test', 'http://piwik.pro/foo/bar/test'), 'findConfigCookiePathToUse should find a less restrictive path automatically'); + equal('/foo', findConfigCookiePathToUse('.piwik.pro/foo/bar/test', 'http://piwik.pro/foo'), 'findConfigCookiePathToUse should find a less restrictive path automatically, urlPath===domainPath'); + equal('/test/bar/test', findConfigCookiePathToUse('.piwik.com/test/bar/test', 'http://piwik.com/test/bar/test/'), 'findConfigCookiePathToUse should use exactly given path if no less restrictive version is available'); + equal('/test/foo', findConfigCookiePathToUse('.piwik.com/test/foo/test', 'http://piwik.com/test/foo/test'), 'findConfigCookiePathToUse should find a less restrictive path automatically, configAlias === currentUrl'); + equal('/test/foo', findConfigCookiePathToUse('.piwik.com/test/foo', 'http://piwik.com/test/foo/test'), 'findConfigCookiePathToUse should find a less restrictive path automatically'); + equal(null, findConfigCookiePathToUse('.piwik.pro/foo', 'http://piwik.pro/test'), 'findConfigCookiePathToUse should not return a path when user is actually not on that path'); + equal(null, findConfigCookiePathToUse('.piwik.pro/foo', 'http://piwik.pro'), 'findConfigCookiePathToUse when there is no path set we cannot use a configPath'); + + /** + * Test sets a good cookie path automatically + */ + tracker.setCookiePath(null); + tracker.setDomains( ['.' + domainAlias + '/tests'] ); + equal('/tests', tracker.getConfigCookiePath()), 'should set a cookie path automatically'; + + tracker.setCookiePath(null); + tracker.setDomains( ['.' + domainAlias + '/tests/javascript'] ); + equal('/tests/javascript', tracker.getConfigCookiePath()), 'should set a cookie path automatically, multiple directories'; + + tracker.setCookiePath(null); + tracker.setDomains( ['.' + domainAlias + '/tests/javascript', '.' + domainAlias + '/tests'] ); + equal('/tests', tracker.getConfigCookiePath()), 'should find shortest path for possible cookie path'; + + tracker.setCookiePath(null); + tracker.setDomains( ['.' + domainAlias + '/tests/javascript', '.example.com/tests'] ); + equal('/tests/javascript', tracker.getConfigCookiePath()), 'should not find a shorter path when no other domain matches'; + + tracker.setCookiePath(null); + tracker.setDomains( ['.' + domainAlias + '/another/one', '.example.org/tests/javascript', '.example.com/tests'] ); + equal(null, tracker.getConfigCookiePath()), 'should not set a path when no domain and no path matches'; + + tracker.setCookiePath(null); }); test("Tracker getClassesRegExp()", function() { @@ -2710,7 +2897,7 @@ function PiwikTest() { }); <?php -if ($sqlite) { +if ($mysql) { ?> module("request", { @@ -2727,7 +2914,7 @@ if ($sqlite) { }); test("tracking", function() { - expect(102); + expect(114); // Prevent Opera and HtmlUnit from performing the default action (i.e., load the href URL) var stopEvent = function (evt) { @@ -2783,6 +2970,21 @@ if ($sqlite) { deepEqual( tracker.getCustomVariable(5), ["new name", ""], "getting a custom variable with no value" ); tracker.deleteCustomVariable(5); + equal(tracker.getCustomDimension(94), null, "if no custom dimension for this index is specified should return null"); + equal(tracker.getCustomDimension(-1), null, "if custom dimension index is invalid should return null"); + equal(tracker.getCustomDimension('not valid'), null, "if custom dimension index is invalid should return null"); + tracker.setCustomDimension(1, 5); + equal(tracker.getCustomDimension(1), "5", "set custom dimension should convert any value to a string" ); + tracker.setCustomDimension(1, "my custom value"); + equal(tracker.getCustomDimension(1), "my custom value", "should get stored custom dimension value" ); + tracker.setCustomDimension(2, undefined); + equal(tracker.getCustomDimension(2), "", "setCustomDimension should convert undefined to an empty string" ); + + tracker.setCustomDimension(3, 'my third value'); + equal(tracker.getCustomDimension(3), "my third value", "deleteCustomDimension verify a value is set for this dimension" ); + tracker.deleteCustomDimension(3); + equal(tracker.getCustomDimension(3), null, "deleteCustomDimension verify value was removed" ); + tracker.setDocumentTitle("PiwikTest"); var referrerUrl = "http://referrer.example.com/page/sub?query=test&test2=test3"; @@ -2791,7 +2993,10 @@ if ($sqlite) { referrerTimestamp = Math.round(new Date().getTime() / 1000); tracker.trackPageView(); - tracker.trackPageView("CustomTitleTest"); + equal(tracker.getCustomDimension(1), "my custom value", "custom dimensions should not be cleared after a tracked pageview"); + equal(tracker.getCustomDimension(2), "", "custom dimensions should not be cleared after a tracked pageview"); + + tracker.trackPageView("CustomTitleTest", {dimension2: 'my new value', dimension5: 'another dimension'}); var customUrlShouldNotChangeCampaign = "http://localhost.localdomain/?utm_campaign=NONONONONONONO&utm_term=PLEASE NO!"; tracker.setCustomUrl(customUrl); @@ -3056,6 +3261,12 @@ if ($sqlite) { // Test Custom variables ok( /SaveCustomVariableCookie.*&cvar=%7B%222%22%3A%5B%22cookiename2PAGE%22%2C%22cookievalue2PAGE%22%5D%7D.*&_cvar=%7B%221%22%3A%5B%22cookiename%22%2C%22cookievalue%22%5D%2C%222%22%3A%5B%22cookiename2%22%2C%22cookievalue2%22%5D%7D/.test(results), "test custom vars are set"); + // Test CustomDimension (persistent ones across requests) + ok( /dimension1=my%20custom%20value&dimension2=&/.test(results), "test custom dimensions are set"); + + // send along a page view and ony valid for this pageview (dimension 2 overwrites another one) + ok( /dimension2=my%20new%20value&dimension5=another%20dimension&dimension1=my%20custom%20value&data=%7B%22token/.test( results ), "trackPageView(customTitle, customData)" ); + // Test campaign parameters set ok( /&_rcn=YEAH&_rck=RIGHT!/.test( results), "Test campaign parameters found"); ok( /&_ref=http%3A%2F%2Freferrer.example.com%2Fpage%2Fsub%3Fquery%3Dtest%26test2%3Dtest3/.test( results), "Test cookie Ref URL found "); diff --git a/tests/javascript/piwik.php b/tests/javascript/piwik.php index 73fbedb232a5a0ef958710a4b34674075bd0fdeb..0c3831717579e7344fa0d85a8af6d8ca55535b6f 100644 --- a/tests/javascript/piwik.php +++ b/tests/javascript/piwik.php @@ -1,7 +1,31 @@ <?php // piwik.php test harness -require_once(dirname(__FILE__).'/SQLite.php'); +if (!defined('PIWIK_DOCUMENT_ROOT')) { + define('PIWIK_DOCUMENT_ROOT', dirname(__FILE__) . '/../..'); +} + +define('PIWIK_INCLUDE_PATH', PIWIK_DOCUMENT_ROOT); + + +require_once PIWIK_INCLUDE_PATH . '/core/bootstrap.php'; + +$environment = new \Piwik\Application\Environment(null); +$environment->init(); +$dbConfig = Piwik\Config::getInstance()->database_tests; +$dbConfig['dbname'] = 'tracker_tests'; + +try { + Piwik\Db::createDatabaseObject($dbConfig); +} catch (Exception $e) { + $dbInfosConnectOnly = $dbConfig; + $dbInfosConnectOnly['dbname'] = null; + Piwik\Db::createDatabaseObject($dbInfosConnectOnly); + Piwik\DbHelper::createDatabase($dbConfig['dbname']); + Piwik\Db::createDatabaseObject($dbConfig); +} + +$db = Piwik\Db::get(); function sendWebBug() { $trans_gif_64 = "R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="; @@ -14,25 +38,14 @@ function isPost() return $_SERVER['REQUEST_METHOD'] == 'POST'; } -if (!file_exists("enable_sqlite")) { +if (!Piwik\Db::hasDatabaseObject()) { sendWebBug(); exit; } -if (!class_exists('SQLite')) { - sendWebBug(); - exit; -} - -$sqlite = new SQLite( 'unittest2.dbf' ); -if (!$sqlite) { - header("HTTP/1.0 500 Internal Server Error"); - exit; -} - -function getNextRequestId($sqlite, $token) +function getNextRequestId($db, $token) { - $requests = $sqlite->query_array("SELECT uri FROM requests WHERE token = \"$token\""); + $requests = $db->fetchAll("SELECT uri FROM requests WHERE token = \"$token\""); if (empty($requests)) { return 1; @@ -41,17 +54,14 @@ function getNextRequestId($sqlite, $token) return count($requests) + 1; } -if (filesize(dirname(__FILE__).'/unittest2.dbf') == 0) -{ - try { - $query = @$sqlite->exec( 'CREATE TABLE requests (requestid TEXT, token TEXT, ip TEXT, ts TEXT, uri TEXT, referer TEXT, ua TEXT)' ); - } catch (Exception $e) { - header("HTTP/1.0 500 Internal Server Error"); - exit; - } +try { + $db->query( 'CREATE TABLE IF NOT EXISTS `requests` (requestid TEXT, token TEXT, ip TEXT, ts TEXT, uri TEXT, referer TEXT, ua TEXT) DEFAULT CHARSET=utf8' ); +} catch (Exception $e) { + header("HTTP/1.0 500 Internal Server Error"); + exit; } -function logRequest($sqlite, $uri, $data) { +function logRequest($db, $uri, $data) { $ip = $_SERVER['REMOTE_ADDR']; $ts = $_SERVER['REQUEST_TIME']; @@ -62,9 +72,9 @@ function logRequest($sqlite, $uri, $data) { $token = isset($data['token']) ? $data['token'] : ''; - $id = getNextRequestId($sqlite, $token); + $id = getNextRequestId($db, $token); - $query = $sqlite->exec("INSERT INTO requests (requestid, token, ip, ts, uri, referer, ua) VALUES (\"$id\", \"$token\", \"$ip\", \"$ts\", \"$uri\", \"$referrer\", \"$ua\")"); + $query = $db->query("INSERT INTO requests (requestid, token, ip, ts, uri, referer, ua) VALUES (\"$id\", \"$token\", \"$ip\", \"$ts\", \"$uri\", \"$referrer\", \"$ua\")"); return $query; } @@ -75,8 +85,7 @@ if (isset($_GET['requests'])) { echo "<html><head><title>$token</title></head><body>\n"; -// $result = $sqlite->query_array("SELECT uri FROM requests"); - $result = @$sqlite->query_array("SELECT uri FROM requests WHERE token = \"$token\" AND ua = \"$ua\" ORDER BY ts ASC, requestid ASC"); + $result = @$db->fetchAll("SELECT uri FROM requests WHERE token = \"$token\" AND ua = \"$ua\" ORDER BY ts ASC, requestid ASC"); if ($result !== false) { $nofRows = count($result); echo "<span>$nofRows</span>\n"; @@ -107,7 +116,7 @@ if (isset($_GET['requests'])) { $data = array('token' => $matches[1]); } - $query = $query && logRequest($sqlite, $uri . $request, $data); + $query = $query && logRequest($db, $uri . $request, $data); } } else { @@ -115,16 +124,13 @@ if (isset($_GET['requests'])) { $uri .= '?' . file_get_contents('php://input'); } - $query = logRequest($sqlite, $uri, $data); + $query = logRequest($db, $uri, $data); } if (!$query) { header("HTTP/1.0 500 Internal Server Error"); } else { -// echo 'Number of rows modified: ', $sqlite->changes(); sendWebBug(); } } } - -$sqlite->close(); diff --git a/tests/javascript/piwiktest.js b/tests/javascript/piwiktest.js index 415bd57d8a282b1cffdf857533798c0b99b99e02..67157c6d96a3d8573431c9863327af27f4dee42b 100644 --- a/tests/javascript/piwiktest.js +++ b/tests/javascript/piwiktest.js @@ -20,11 +20,14 @@ Piwik.addPlugin('testPlugin', { '_isObject : isObject,' + '_isString : isString,' + '_isSiteHostName : isSiteHostName,' + + '_isSiteHostPath : isSiteHostPath,' + '_getClassesRegExp : getClassesRegExp,' + '_hasCookies : hasCookies,' + '_getCookie : getCookie,' + '_getCookieName : getCookieName,' + '_setCookie : setCookie,' + + '_getLinkIfShouldBeProcessed : getLinkIfShouldBeProcessed,' + + '_findConfigCookiePathToUse : findConfigCookiePathToUse,' + '_encode : encodeWrapper,' + '_decode : decodeWrapper,' + '_urldecode : urldecode,' + diff --git a/tests/javascript/testrunner.js b/tests/javascript/testrunner.js index 7ac70b4a31dad85cff9abff5888bec3149e7c71e..7194540ec8274e2f2f3fe5a273d7c18b7e54c405 100644 --- a/tests/javascript/testrunner.js +++ b/tests/javascript/testrunner.js @@ -22,7 +22,8 @@ // IN THE SOFTWARE var fs = require("fs"); -var url = 'http://localhost/tests/javascript/'; +var system = require("system"); +var url = system.args[1] || 'http://localhost/tests/javascript/'; function printError(message) { console.error(message + "\n"); diff --git a/tests/lib/screenshot-testing/support/app.js b/tests/lib/screenshot-testing/support/app.js index 95995797c2cf2b0067736f70a8d0c5ff9e6e8d96..51ca56ad554b7992bbe01919bbdf8bf950d9eb9d 100644 --- a/tests/lib/screenshot-testing/support/app.js +++ b/tests/lib/screenshot-testing/support/app.js @@ -229,7 +229,7 @@ Application.prototype.doRunTests = function () { this.runner = mocha.run(function () { // remove symlinks if (!options['keep-symlinks']) { - var symlinks = ['libs', 'plugins', 'tests', 'piwik.js']; + var symlinks = ['libs', 'plugins', 'tests', 'misc', 'piwik.js']; symlinks.forEach(function (item) { var file = path.join(uiTestsDir, '..', 'PHPUnit', 'proxy', item); diff --git a/tests/lib/screenshot-testing/support/chai-extras.js b/tests/lib/screenshot-testing/support/chai-extras.js index aeb2d86b1bb38d7964d81742487e3209681727d6..576229946e1b2354a4010bda0ac640ef4b6c0ff4 100644 --- a/tests/lib/screenshot-testing/support/chai-extras.js +++ b/tests/lib/screenshot-testing/support/chai-extras.js @@ -181,6 +181,7 @@ function capture(screenName, compareAgainst, selector, pageSetupFn, comparisonTh child.on("exit", function (code) { if (testFailure) { testFailure = 'Processed screenshot does not match expected for ' + screenshotFileName + ' ' + testFailure; + testFailure += 'TestEnvironment was ' + JSON.stringify(testEnvironment); } if (code == 0 && !testFailure) { diff --git a/tests/lib/screenshot-testing/support/page-renderer.js b/tests/lib/screenshot-testing/support/page-renderer.js index 2bb909f721675e13eb44a38f13e2d69f9829160e..5c92abb276036f9c83e60b41b131ae4718e3cb0f 100644 --- a/tests/lib/screenshot-testing/support/page-renderer.js +++ b/tests/lib/screenshot-testing/support/page-renderer.js @@ -338,7 +338,7 @@ PageRenderer.prototype.capture = function (outputPath, callback, selector) { self.abort(); callback(new Error("Screenshot load timeout. Details:\n" + timeoutDetails)); - }, 120 * 1000); + }, 180 * 1000); if (this.webpage === null) { this._recreateWebPage(); @@ -654,6 +654,7 @@ PageRenderer.prototype._removeUrlFromQueue = function (url) { } }; +var linkObject = document.createElement('a'); PageRenderer.prototype._setupWebpageEvents = function () { var self = this; this.webpage.onError = function (message, trace) { @@ -669,11 +670,31 @@ PageRenderer.prototype._setupWebpageEvents = function () { self._logMessage(msgStack.join('\n')); }; + linkObject.setAttribute('href', config.piwikUrl); + var piwikHost = linkObject.hostname, + piwikPort = linkObject.port; + this.webpage.onResourceRequested = function (requestData, networkRequest) { - self._addUrlToQueue(requestData.url); + var url = requestData.url; + + // replaces the requested URL to the piwik URL w/ a port, if it does not have one. This allows us to run UI + // tests when Piwik is on a port, w/o having to have different UI screenshots. (This is one half of the + // solution, the other half is in config/environment/ui-test.php, where we remove all ports from Piwik URLs.) + if (piwikPort && piwikPort != 0) { + linkObject.setAttribute('href', url); + + if (linkObject.hostname == piwikHost && (!linkObject.port || linkObject.port == 0 || linkObject.port == 80)) { + linkObject.port = piwikPort; + url = linkObject.href; + + networkRequest.changeUrl(url); + } + } + + self._addUrlToQueue(url); if (VERBOSE) { - self._logMessage('Requesting resource (#' + requestData.id + 'URL:' + requestData.url + ')'); + self._logMessage('Requesting resource (#' + requestData.id + 'URL:' + url + ')'); } }; diff --git a/tests/lib/screenshot-testing/support/test-environment.js b/tests/lib/screenshot-testing/support/test-environment.js index 700493f9330978a579b3f788c3eaf443651028e9..01914c8c242d5637f1c445c45b51a9417d9c00d9 100644 --- a/tests/lib/screenshot-testing/support/test-environment.js +++ b/tests/lib/screenshot-testing/support/test-environment.js @@ -25,6 +25,7 @@ TestingEnvironment.prototype.reload = function () { this['useOverrideJs'] = true; this['loadRealTranslations'] = true; // UI tests should test w/ real translations, not translation keys this['testUseMockAuth'] = true; + this['configOverride'] = {}; if (fs.exists(testingEnvironmentOverridePath)) { var data = JSON.parse(fs.read(testingEnvironmentOverridePath)); @@ -34,6 +35,33 @@ TestingEnvironment.prototype.reload = function () { } }; +/** + * Overrides a config entry. + * + * You can use this method either to set one specific config value `overrideConfig(group, name, value)` + * or you can set a whole group of values `overrideConfig(group, valueObject)`. + */ +TestingEnvironment.prototype.overrideConfig = function (group, name, value) { + if (!name) { + return; + } + + if (!this['configOverride']) { + this['configOverride'] = {}; + } + + if ((typeof value) === 'undefined') { + this['configOverride'][group] = name; + return; + } + + if (!this['configOverride'][group]) { + this['configOverride'][group] = {}; + } + + this['configOverride'][group][name] = value; +}; + TestingEnvironment.prototype.save = function () { var copy = {}; for (var key in this) { diff --git a/tests/travis b/tests/travis index 2a41a93a776f5f053c8dd34c029061e1cd4d6a6c..73a4b16ebb9a5db23bca53115195e8317ce6917a 160000 --- a/tests/travis +++ b/tests/travis @@ -1 +1 @@ -Subproject commit 2a41a93a776f5f053c8dd34c029061e1cd4d6a6c +Subproject commit 73a4b16ebb9a5db23bca53115195e8317ce6917a