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

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Steur <thomas.steur@gmail.com>2015-12-10 00:50:07 +0300
committerThomas Steur <thomas.steur@gmail.com>2015-12-10 00:50:07 +0300
commitebced800c0184f5ce93663afab6b0337c3755cbb (patch)
treefb26c2506d37586ff0d38fb902d63d17701bd883 /plugins/SitesManager
parent3d26af780d8fe0e4f7c5824a88b95c4a0d0d25d7 (diff)
parentdb36ca384809ea36457a465a3b6d1ecf951b0e26 (diff)
Merge master into "3.0"
Conflicts: .travis.yml CHANGELOG.md core/Plugin/ControllerAdmin.php core/Version.php core/testMinimumPhpVersion.php plugins/API/API.php plugins/Actions/Reports/GetPageUrls.php plugins/AnonymousPiwikUsageMeasurement plugins/CoreHome/CoreHome.php plugins/CoreHome/templates/_menu.twig plugins/CoreVisualizations/javascripts/jqplotEvolutionGraph.js plugins/CustomVariables/tests/System/expected/test_CustomVariablesSystemTest__CustomVariables.getCustomVariables_day.xml plugins/Goals/Controller.php tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php tests/PHPUnit/Integration/Plugin/ManagerTest.php tests/PHPUnit/System/expected/test_FlattenReports__CustomVariables.getCustomVariables_day.xml tests/PHPUnit/System/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml tests/PHPUnit/System/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__CustomVariables.getCustomVariables_range.xml tests/PHPUnit/System/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI_pagesegment__CustomVariables.getCustomVariables_range.xml tests/PHPUnit/System/expected/test_reportLimiting__CustomVariables.getCustomVariables_day.xml tests/PHPUnit/System/expected/test_reportLimiting_rankingQuery__CustomVariables.getCustomVariables_day.xml tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_day.xml tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__CustomVariables.getCustomVariables_week.xml tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_day.xml tests/PHPUnit/System/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__CustomVariables.getCustomVariables_week.xml tests/UI/expected-ui-screenshots tests/UI/specs/Overlay_spec.js tests/UI/specs/UIIntegration_spec.js
Diffstat (limited to 'plugins/SitesManager')
-rw-r--r--plugins/SitesManager/API.php9
-rw-r--r--plugins/SitesManager/Model.php16
-rw-r--r--plugins/SitesManager/SiteUrls.php169
-rw-r--r--plugins/SitesManager/SitesManager.php8
-rw-r--r--plugins/SitesManager/config/config.php9
-rw-r--r--plugins/SitesManager/lang/cs.json4
-rw-r--r--plugins/SitesManager/lang/fr.json4
-rw-r--r--plugins/SitesManager/lang/ja.json6
-rw-r--r--plugins/SitesManager/tests/Integration/ModelTest.php52
-rw-r--r--plugins/SitesManager/tests/Integration/SiteUrlsTest.php170
10 files changed, 417 insertions, 30 deletions
diff --git a/plugins/SitesManager/API.php b/plugins/SitesManager/API.php
index 4a67c45c2c..739af7d5e9 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 93ddb01d8f..96062b608a 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 a1fac67a89..33e2e4844a 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 4b686e2bde..ca3f2757b9 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 0855c39329..0000000000
--- 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 014c9f88f2..6854eadf75 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 283f77c0f3..2372187f6c 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 56cc2b4697..b1d3a73a83 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 45ebce2be8..7291ac346f 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 f9362ae2f4..3db34199fb 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();