diff options
Diffstat (limited to 'plugins/UserCountry/UserCountry.php')
-rw-r--r-- | plugins/UserCountry/UserCountry.php | 1012 |
1 files changed, 496 insertions, 516 deletions
diff --git a/plugins/UserCountry/UserCountry.php b/plugins/UserCountry/UserCountry.php index 31bda64852..20d2935248 100644 --- a/plugins/UserCountry/UserCountry.php +++ b/plugins/UserCountry/UserCountry.php @@ -20,525 +20,505 @@ require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/GeoIPAutoUpdater.php'; */ class Piwik_UserCountry extends Piwik_Plugin { - const VISITS_BY_COUNTRY_RECORD_NAME = 'UserCountry_country'; - const VISITS_BY_REGION_RECORD_NAME = 'UserCountry_region'; - const VISITS_BY_CITY_RECORD_NAME = 'UserCountry_city'; - - const DISTINCT_COUNTRIES_METRIC = 'UserCountry_distinctCountries'; - - // separate region, city & country info in stored report labels - const LOCATION_SEPARATOR = '|'; - - public function getInformation() - { - $info = array( - 'description' => Piwik_Translate('UserCountry_PluginDescription'), - 'author' => 'Piwik', - 'author_homepage' => 'http://piwik.org/', - 'version' => Piwik_Version::VERSION, - 'TrackerPlugin' => true, - ); - return $info; - } - - function getListHooksRegistered() - { - $hooks = array( - 'ArchiveProcessing_Day.compute' => 'archiveDay', - 'ArchiveProcessing_Period.compute' => 'archivePeriod', - 'WidgetsList.add' => 'addWidgets', - 'Menu.add' => 'addMenu', - 'AdminMenu.add' => 'addAdminMenu', - 'Goals.getReportsWithGoalMetrics' => 'getReportsWithGoalMetrics', - 'API.getReportMetadata' => 'getReportMetadata', - 'API.getSegmentsMetadata' => 'getSegmentsMetadata', - 'AssetManager.getCssFiles' => 'getCssFiles', - 'AssetManager.getJsFiles' => 'getJsFiles', - 'Tracker.getVisitorLocation' => 'getVisitorLocation', - 'TaskScheduler.getScheduledTasks' => 'getScheduledTasks', - ); - return $hooks; - } - - /** - * @param Piwik_Event_Notification $notification notification object - */ - function getScheduledTasks($notification) - { - $tasks = &$notification->getNotificationObject(); - - // add the auto updater task - $tasks[] = Piwik_UserCountry_GeoIPAutoUpdater::makeScheduledTask(); - } - - /** - * @param Piwik_Event_Notification $notification notification object - */ - function getCssFiles( $notification ) - { - $cssFiles = &$notification->getNotificationObject(); - - $cssFiles[] = "plugins/UserCountry/templates/styles.css"; - } - - /** - * @param Piwik_Event_Notification $notification notification object - */ - public function getJsFiles( $notification ) + const VISITS_BY_COUNTRY_RECORD_NAME = 'UserCountry_country'; + const VISITS_BY_REGION_RECORD_NAME = 'UserCountry_region'; + const VISITS_BY_CITY_RECORD_NAME = 'UserCountry_city'; + + const DISTINCT_COUNTRIES_METRIC = 'UserCountry_distinctCountries'; + + // separate region, city & country info in stored report labels + const LOCATION_SEPARATOR = '|'; + + public function getInformation() + { + $info = array( + 'description' => Piwik_Translate('UserCountry_PluginDescription'), + 'author' => 'Piwik', + 'author_homepage' => 'http://piwik.org/', + 'version' => Piwik_Version::VERSION, + 'TrackerPlugin' => true, + ); + return $info; + } + + function getListHooksRegistered() + { + $hooks = array( + 'ArchiveProcessing_Day.compute' => 'archiveDay', + 'ArchiveProcessing_Period.compute' => 'archivePeriod', + 'WidgetsList.add' => 'addWidgets', + 'Menu.add' => 'addMenu', + 'AdminMenu.add' => 'addAdminMenu', + 'Goals.getReportsWithGoalMetrics' => 'getReportsWithGoalMetrics', + 'API.getReportMetadata' => 'getReportMetadata', + 'API.getSegmentsMetadata' => 'getSegmentsMetadata', + 'AssetManager.getCssFiles' => 'getCssFiles', + 'AssetManager.getJsFiles' => 'getJsFiles', + 'Tracker.getVisitorLocation' => 'getVisitorLocation', + 'TaskScheduler.getScheduledTasks' => 'getScheduledTasks', + ); + return $hooks; + } + + /** + * @param Piwik_Event_Notification $notification notification object + */ + function getScheduledTasks($notification) + { + $tasks = & $notification->getNotificationObject(); + + // add the auto updater task + $tasks[] = Piwik_UserCountry_GeoIPAutoUpdater::makeScheduledTask(); + } + + /** + * @param Piwik_Event_Notification $notification notification object + */ + function getCssFiles($notification) { - $jsFiles = &$notification->getNotificationObject(); + $cssFiles = & $notification->getNotificationObject(); + + $cssFiles[] = "plugins/UserCountry/templates/styles.css"; + } + + /** + * @param Piwik_Event_Notification $notification notification object + */ + public function getJsFiles($notification) + { + $jsFiles = & $notification->getNotificationObject(); $jsFiles[] = "plugins/UserCountry/templates/admin.js"; } - - /** - * @param Piwik_Event_Notification $notification notification object - */ - public function getVisitorLocation( $notification ) - { - require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php"; - $location = &$notification->getNotificationObject(); - $visitorInfo = $notification->getNotificationInfo(); - - $id = Piwik_Common::getCurrentLocationProviderId(); - $provider = Piwik_UserCountry_LocationProvider::getProviderById($id); - if ($provider === false) - { - $id = Piwik_UserCountry_LocationProvider_Default::ID; - $provider = Piwik_UserCountry_LocationProvider::getProviderById($id); - printDebug("GEO: no current location provider sent, falling back to default '$id' one."); - } - - $location = $provider->getLocation($visitorInfo); - - // if we can't find a location, use default provider - if ($location === false) - { - $defaultId = Piwik_UserCountry_LocationProvider_Default::ID; - $provider = Piwik_UserCountry_LocationProvider::getProviderById($defaultId); - $location = $provider->getLocation($visitorInfo); - printDebug("GEO: couldn't find a location with Geo Module '$id', using Default '$defaultId' provider as fallback..."); - $id = $defaultId; - } - printDebug("GEO: Found IP location (provider '". $id . "'): ". var_export($location, true)); - } - - function addWidgets() - { - $widgetContinentLabel = Piwik_Translate('UserCountry_WidgetLocation') - . ' ('.Piwik_Translate('UserCountry_Continent').')'; - $widgetCountryLabel = Piwik_Translate('UserCountry_WidgetLocation') - . ' ('.Piwik_Translate('UserCountry_Country').')'; - $widgetRegionLabel = Piwik_Translate('UserCountry_WidgetLocation') - . ' ('.Piwik_Translate('UserCountry_Region').')'; - $widgetCityLabel = Piwik_Translate('UserCountry_WidgetLocation') - . ' ('.Piwik_Translate('UserCountry_City').')'; - - Piwik_AddWidget( 'General_Visitors', $widgetContinentLabel, 'UserCountry', 'getContinent'); - Piwik_AddWidget( 'General_Visitors', $widgetCountryLabel, 'UserCountry', 'getCountry'); - Piwik_AddWidget( 'General_Visitors', $widgetRegionLabel, 'UserCountry', 'getRegion'); - Piwik_AddWidget( 'General_Visitors', $widgetCityLabel, 'UserCountry', 'getCity'); - } - - function addMenu() - { - Piwik_AddMenu('General_Visitors', 'UserCountry_SubmenuLocations', array('module' => 'UserCountry', 'action' => 'index')); - } - - /** - * Event handler. Adds menu items to the Admin menu. - */ - function addAdminMenu() - { - Piwik_AddAdminSubMenu('General_Settings', 'UserCountry_Geolocation', - array('module' => 'UserCountry', 'action' => 'adminIndex'), - Piwik::isUserIsSuperUser(), - $order = 8); - } - - /** - * @param Piwik_Event_Notification $notification notification object - */ - public function getSegmentsMetadata($notification) - { - $segments =& $notification->getNotificationObject(); - $segments[] = array( - 'type' => 'dimension', - 'category' => 'Visit Location', - 'name' => Piwik_Translate('UserCountry_Country'), - 'segment' => 'country', - 'sqlSegment' => 'log_visit.location_country', - 'acceptedValues' => 'de, us, fr, in, es, etc.', - ); - $segments[] = array( - 'type' => 'dimension', - 'category' => 'Visit Location', - 'name' => Piwik_Translate('UserCountry_Continent'), - 'segment' => 'continent', - 'sqlSegment' => 'log_visit.location_country', - 'acceptedValues' => 'eur, asi, amc, amn, ams, afr, ant, oce', - 'sqlFilter' => array('Piwik_UserCountry', 'getCountriesForContinent'), - ); - $segments[] = array( - 'type' => 'dimension', - 'category' => 'Visit Location', - 'name' => Piwik_Translate('UserCountry_Region'), - 'segment' => 'region', - 'sqlSegment' => 'log_visit.location_region', - 'acceptedValues' => '01 02, OR, P8, etc.<br/>eg. region=A1;country=fr', - ); - $segments[] = array( - 'type' => 'dimension', - 'category' => 'Visit Location', - 'name' => Piwik_Translate('UserCountry_City'), - 'segment' => 'city', - 'sqlSegment' => 'log_visit.location_city', - 'acceptedValues' => 'Sydney, Sao Paolo, Rome, etc.', - ); - $segments[] = array( - 'type' => 'dimension', - 'category' => 'Visit Location', - 'name' => Piwik_Translate('UserCountry_Latitude'), - 'segment' => 'lat', - 'sqlSegment' => 'log_visit.location_latitude', - 'acceptedValues' => '-33.578, 40.830, etc.<br/>You can select visitors within a lat/long range using &segment=lat>X;lat<Y;long>M;long<N.', - ); - $segments[] = array( - 'type' => 'dimension', - 'category' => 'Visit Location', - 'name' => Piwik_Translate('UserCountry_Longitude'), - 'segment' => 'long', - 'sqlSegment' => 'log_visit.location_longitude', - 'acceptedValues' => '-70.664, 14.326, etc.', - ); - } - - /** - * @param Piwik_Event_Notification $notification notification object - */ - public function getReportMetadata($notification) - { - $metrics = array( - 'nb_visits' => Piwik_Translate('General_ColumnNbVisits'), - 'nb_uniq_visitors' => Piwik_Translate('General_ColumnNbUniqVisitors'), - 'nb_actions' => Piwik_Translate('General_ColumnNbActions'), - ); - - $reports = &$notification->getNotificationObject(); - - $reports[] = array( - 'category' => Piwik_Translate('General_Visitors'), - 'name' => Piwik_Translate('UserCountry_Country'), - 'module' => 'UserCountry', - 'action' => 'getCountry', - 'dimension' => Piwik_Translate('UserCountry_Country'), - 'metrics' => $metrics, - 'order' => 5, - ); - - $reports[] = array( - 'category' => Piwik_Translate('General_Visitors'), - 'name' => Piwik_Translate('UserCountry_Continent'), - 'module' => 'UserCountry', - 'action' => 'getContinent', - 'dimension' => Piwik_Translate('UserCountry_Continent'), - 'metrics' => $metrics, - 'order' => 6, - ); - - $reports[] = array( - 'category' => Piwik_Translate('General_Visitors'), - 'name' => Piwik_Translate('UserCountry_Region'), - 'module' => 'UserCountry', - 'action' => 'getRegion', - 'dimension' => Piwik_Translate('UserCountry_Region'), - 'metrics' => $metrics, - 'order' => 7, - ); - - $reports[] = array( - 'category' => Piwik_Translate('General_Visitors'), - 'name' => Piwik_Translate('UserCountry_City'), - 'module' => 'UserCountry', - 'action' => 'getCity', - 'dimension' => Piwik_Translate('UserCountry_City'), - 'metrics' => $metrics, - 'order' => 8, - ); - } - - /** - * @param Piwik_Event_Notification $notification notification object - */ - function getReportsWithGoalMetrics( $notification ) - { - $dimensions =& $notification->getNotificationObject(); - $dimensions = array_merge($dimensions, array( - array( 'category' => Piwik_Translate('General_Visit'), - 'name' => Piwik_Translate('UserCountry_Country'), - 'module' => 'UserCountry', - 'action' => 'getCountry', - ), - array( 'category' => Piwik_Translate('General_Visit'), - 'name' => Piwik_Translate('UserCountry_Continent'), - 'module' => 'UserCountry', - 'action' => 'getContinent', - ), - array('category' => Piwik_Translate('General_Visit'), - 'name' => Piwik_Translate('UserCountry_Region'), - 'module' => 'UserCountry', - 'action' => 'getRegion'), - array('category' => Piwik_Translate('General_Visit'), - 'name' => Piwik_Translate('UserCountry_City'), - 'module' => 'UserCountry', - 'action' => 'getCity'), - )); - } - - /** - * @param Piwik_Event_Notification $notification notification object - * @return mixed - */ - function archivePeriod( $notification ) - { - /** - * @param Piwik_ArchiveProcessing_Period $archiveProcessing - */ - $archiveProcessing = $notification->getNotificationObject(); - - if(!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return; - - $dataTableToSum = array( - self::VISITS_BY_COUNTRY_RECORD_NAME, - self::VISITS_BY_REGION_RECORD_NAME, - self::VISITS_BY_CITY_RECORD_NAME, - ); - - $nameToCount = $archiveProcessing->archiveDataTable($dataTableToSum); - $archiveProcessing->insertNumericRecord(self::DISTINCT_COUNTRIES_METRIC, - $nameToCount[self::VISITS_BY_COUNTRY_RECORD_NAME]['level0']); - } - - private $interestTables = null; - private $latLongForCities = null; - - /** - * @param Piwik_Event_Notification $notification notification object - * @return mixed - */ - function archiveDay($notification) - { - /** - * @var Piwik_ArchiveProcessing - */ - $archiveProcessing = $notification->getNotificationObject(); - - if(!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return; - - $this->interestTables = array('location_country' => array(), - 'location_region' => array(), - 'location_city' => array()); - $this->latLongForCities = array(); - - $this->archiveDayAggregateVisits($archiveProcessing); - $this->archiveDayAggregateGoals($archiveProcessing); - $this->archiveDayRecordInDatabase($archiveProcessing); - - unset($this->interestTables); - unset($this->latLongForCities); - } - - /** - * @param Piwik_ArchiveProcessing_Day $archiveProcessing - */ - protected function archiveDayAggregateVisits($archiveProcessing) - { - $dimensions = array_keys($this->interestTables); - $query = $archiveProcessing->queryVisitsByDimension( - $dimensions, - $where = '', - $metrics = false, - $orderBy = false, - $rankingQuery = null, - $addSelect = 'MAX(log_visit.location_latitude) as location_latitude, + + /** + * @param Piwik_Event_Notification $notification notification object + */ + public function getVisitorLocation($notification) + { + require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php"; + $location = & $notification->getNotificationObject(); + $visitorInfo = $notification->getNotificationInfo(); + + $id = Piwik_Common::getCurrentLocationProviderId(); + $provider = Piwik_UserCountry_LocationProvider::getProviderById($id); + if ($provider === false) { + $id = Piwik_UserCountry_LocationProvider_Default::ID; + $provider = Piwik_UserCountry_LocationProvider::getProviderById($id); + printDebug("GEO: no current location provider sent, falling back to default '$id' one."); + } + + $location = $provider->getLocation($visitorInfo); + + // if we can't find a location, use default provider + if ($location === false) { + $defaultId = Piwik_UserCountry_LocationProvider_Default::ID; + $provider = Piwik_UserCountry_LocationProvider::getProviderById($defaultId); + $location = $provider->getLocation($visitorInfo); + printDebug("GEO: couldn't find a location with Geo Module '$id', using Default '$defaultId' provider as fallback..."); + $id = $defaultId; + } + printDebug("GEO: Found IP location (provider '" . $id . "'): " . var_export($location, true)); + } + + function addWidgets() + { + $widgetContinentLabel = Piwik_Translate('UserCountry_WidgetLocation') + . ' (' . Piwik_Translate('UserCountry_Continent') . ')'; + $widgetCountryLabel = Piwik_Translate('UserCountry_WidgetLocation') + . ' (' . Piwik_Translate('UserCountry_Country') . ')'; + $widgetRegionLabel = Piwik_Translate('UserCountry_WidgetLocation') + . ' (' . Piwik_Translate('UserCountry_Region') . ')'; + $widgetCityLabel = Piwik_Translate('UserCountry_WidgetLocation') + . ' (' . Piwik_Translate('UserCountry_City') . ')'; + + Piwik_AddWidget('General_Visitors', $widgetContinentLabel, 'UserCountry', 'getContinent'); + Piwik_AddWidget('General_Visitors', $widgetCountryLabel, 'UserCountry', 'getCountry'); + Piwik_AddWidget('General_Visitors', $widgetRegionLabel, 'UserCountry', 'getRegion'); + Piwik_AddWidget('General_Visitors', $widgetCityLabel, 'UserCountry', 'getCity'); + } + + function addMenu() + { + Piwik_AddMenu('General_Visitors', 'UserCountry_SubmenuLocations', array('module' => 'UserCountry', 'action' => 'index')); + } + + /** + * Event handler. Adds menu items to the Admin menu. + */ + function addAdminMenu() + { + Piwik_AddAdminSubMenu('General_Settings', 'UserCountry_Geolocation', + array('module' => 'UserCountry', 'action' => 'adminIndex'), + Piwik::isUserIsSuperUser(), + $order = 8); + } + + /** + * @param Piwik_Event_Notification $notification notification object + */ + public function getSegmentsMetadata($notification) + { + $segments =& $notification->getNotificationObject(); + $segments[] = array( + 'type' => 'dimension', + 'category' => 'Visit Location', + 'name' => Piwik_Translate('UserCountry_Country'), + 'segment' => 'country', + 'sqlSegment' => 'log_visit.location_country', + 'acceptedValues' => 'de, us, fr, in, es, etc.', + ); + $segments[] = array( + 'type' => 'dimension', + 'category' => 'Visit Location', + 'name' => Piwik_Translate('UserCountry_Continent'), + 'segment' => 'continent', + 'sqlSegment' => 'log_visit.location_country', + 'acceptedValues' => 'eur, asi, amc, amn, ams, afr, ant, oce', + 'sqlFilter' => array('Piwik_UserCountry', 'getCountriesForContinent'), + ); + $segments[] = array( + 'type' => 'dimension', + 'category' => 'Visit Location', + 'name' => Piwik_Translate('UserCountry_Region'), + 'segment' => 'region', + 'sqlSegment' => 'log_visit.location_region', + 'acceptedValues' => '01 02, OR, P8, etc.<br/>eg. region=A1;country=fr', + ); + $segments[] = array( + 'type' => 'dimension', + 'category' => 'Visit Location', + 'name' => Piwik_Translate('UserCountry_City'), + 'segment' => 'city', + 'sqlSegment' => 'log_visit.location_city', + 'acceptedValues' => 'Sydney, Sao Paolo, Rome, etc.', + ); + $segments[] = array( + 'type' => 'dimension', + 'category' => 'Visit Location', + 'name' => Piwik_Translate('UserCountry_Latitude'), + 'segment' => 'lat', + 'sqlSegment' => 'log_visit.location_latitude', + 'acceptedValues' => '-33.578, 40.830, etc.<br/>You can select visitors within a lat/long range using &segment=lat>X;lat<Y;long>M;long<N.', + ); + $segments[] = array( + 'type' => 'dimension', + 'category' => 'Visit Location', + 'name' => Piwik_Translate('UserCountry_Longitude'), + 'segment' => 'long', + 'sqlSegment' => 'log_visit.location_longitude', + 'acceptedValues' => '-70.664, 14.326, etc.', + ); + } + + /** + * @param Piwik_Event_Notification $notification notification object + */ + public function getReportMetadata($notification) + { + $metrics = array( + 'nb_visits' => Piwik_Translate('General_ColumnNbVisits'), + 'nb_uniq_visitors' => Piwik_Translate('General_ColumnNbUniqVisitors'), + 'nb_actions' => Piwik_Translate('General_ColumnNbActions'), + ); + + $reports = & $notification->getNotificationObject(); + + $reports[] = array( + 'category' => Piwik_Translate('General_Visitors'), + 'name' => Piwik_Translate('UserCountry_Country'), + 'module' => 'UserCountry', + 'action' => 'getCountry', + 'dimension' => Piwik_Translate('UserCountry_Country'), + 'metrics' => $metrics, + 'order' => 5, + ); + + $reports[] = array( + 'category' => Piwik_Translate('General_Visitors'), + 'name' => Piwik_Translate('UserCountry_Continent'), + 'module' => 'UserCountry', + 'action' => 'getContinent', + 'dimension' => Piwik_Translate('UserCountry_Continent'), + 'metrics' => $metrics, + 'order' => 6, + ); + + $reports[] = array( + 'category' => Piwik_Translate('General_Visitors'), + 'name' => Piwik_Translate('UserCountry_Region'), + 'module' => 'UserCountry', + 'action' => 'getRegion', + 'dimension' => Piwik_Translate('UserCountry_Region'), + 'metrics' => $metrics, + 'order' => 7, + ); + + $reports[] = array( + 'category' => Piwik_Translate('General_Visitors'), + 'name' => Piwik_Translate('UserCountry_City'), + 'module' => 'UserCountry', + 'action' => 'getCity', + 'dimension' => Piwik_Translate('UserCountry_City'), + 'metrics' => $metrics, + 'order' => 8, + ); + } + + /** + * @param Piwik_Event_Notification $notification notification object + */ + function getReportsWithGoalMetrics($notification) + { + $dimensions =& $notification->getNotificationObject(); + $dimensions = array_merge($dimensions, array( + array('category' => Piwik_Translate('General_Visit'), + 'name' => Piwik_Translate('UserCountry_Country'), + 'module' => 'UserCountry', + 'action' => 'getCountry', + ), + array('category' => Piwik_Translate('General_Visit'), + 'name' => Piwik_Translate('UserCountry_Continent'), + 'module' => 'UserCountry', + 'action' => 'getContinent', + ), + array('category' => Piwik_Translate('General_Visit'), + 'name' => Piwik_Translate('UserCountry_Region'), + 'module' => 'UserCountry', + 'action' => 'getRegion'), + array('category' => Piwik_Translate('General_Visit'), + 'name' => Piwik_Translate('UserCountry_City'), + 'module' => 'UserCountry', + 'action' => 'getCity'), + )); + } + + /** + * @param Piwik_Event_Notification $notification notification object + * @return mixed + */ + function archivePeriod($notification) + { + /** + * @param Piwik_ArchiveProcessing_Period $archiveProcessing + */ + $archiveProcessing = $notification->getNotificationObject(); + + if (!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return; + + $dataTableToSum = array( + self::VISITS_BY_COUNTRY_RECORD_NAME, + self::VISITS_BY_REGION_RECORD_NAME, + self::VISITS_BY_CITY_RECORD_NAME, + ); + + $nameToCount = $archiveProcessing->archiveDataTable($dataTableToSum); + $archiveProcessing->insertNumericRecord(self::DISTINCT_COUNTRIES_METRIC, + $nameToCount[self::VISITS_BY_COUNTRY_RECORD_NAME]['level0']); + } + + private $interestTables = null; + private $latLongForCities = null; + + /** + * @param Piwik_Event_Notification $notification notification object + * @return mixed + */ + function archiveDay($notification) + { + /** + * @var Piwik_ArchiveProcessing + */ + $archiveProcessing = $notification->getNotificationObject(); + + if (!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) return; + + $this->interestTables = array('location_country' => array(), + 'location_region' => array(), + 'location_city' => array()); + $this->latLongForCities = array(); + + $this->archiveDayAggregateVisits($archiveProcessing); + $this->archiveDayAggregateGoals($archiveProcessing); + $this->archiveDayRecordInDatabase($archiveProcessing); + + unset($this->interestTables); + unset($this->latLongForCities); + } + + /** + * @param Piwik_ArchiveProcessing_Day $archiveProcessing + */ + protected function archiveDayAggregateVisits($archiveProcessing) + { + $dimensions = array_keys($this->interestTables); + $query = $archiveProcessing->queryVisitsByDimension( + $dimensions, + $where = '', + $metrics = false, + $orderBy = false, + $rankingQuery = null, + $addSelect = 'MAX(log_visit.location_latitude) as location_latitude, MAX(log_visit.location_longitude) as location_longitude' - ); - - if ($query === false) - { - return; - } - - while ($row = $query->fetch()) - { - // get latitude/longitude if there's a city - $lat = $long = false; - if (!empty($row['location_city'])) - { - if (!empty($row['location_latitude'])) - { - $lat = $row['location_latitude']; - } - if (!empty($row['location_longitude'])) - { - $long = $row['location_longitude']; - } - } - - // make sure regions & cities w/ the same name don't get merged - $this->setLongCityRegionId($row); - - // store latitude/longitude, if we should - if ($lat !== false && $long !== false) - { - $this->latLongForCities[$row['location_city']] = array($lat, $long); - } - - // add the stats to each dimension's table - foreach ($this->interestTables as $dimension => &$table) - { - $label = (string)$row[$dimension]; - - if (!isset($table[$label])) - { - $table[$label] = $archiveProcessing->getNewInterestRow(); - } - $archiveProcessing->updateInterestStats($row, $table[$label]); - } - } - } - - /** - * @param Piwik_ArchiveProcessing_Day $archiveProcessing - */ - protected function archiveDayAggregateGoals($archiveProcessing) - { - $dimensions = array_keys($this->interestTables); - $query = $archiveProcessing->queryConversionsByDimension($dimensions); - - if ($query === false) - { - return; - } - - while ($row = $query->fetch()) - { - // make sure regions & cities w/ the same name don't get merged - $this->setLongCityRegionId($row); - - $idGoal = $row['idgoal']; - foreach ($this->interestTables as $dimension => &$table) - { - $label = (string)$row[$dimension]; - - if (!isset($table[$label][Piwik_Archive::INDEX_GOALS][$idGoal])) - { - $table[$label][Piwik_Archive::INDEX_GOALS][$idGoal] = $archiveProcessing->getNewGoalRow($idGoal); - } - - $archiveProcessing->updateGoalStats($row, $table[$label][Piwik_Archive::INDEX_GOALS][$idGoal]); - } - } - - foreach ($this->interestTables as &$table) - { - $archiveProcessing->enrichConversionsByLabelArray($table); - } - } - - /** - * @param Piwik_ArchiveProcessing_Day $archiveProcessing - */ - protected function archiveDayRecordInDatabase($archiveProcessing) - { - $maximumRows = Piwik_Config::getInstance()->General['datatable_archiving_maximum_rows_standard']; - - $tableCountry = Piwik_ArchiveProcessing_Day::getDataTableFromArray($this->interestTables['location_country']); - $archiveProcessing->insertBlobRecord(self::VISITS_BY_COUNTRY_RECORD_NAME, $tableCountry->getSerialized()); - $archiveProcessing->insertNumericRecord(self::DISTINCT_COUNTRIES_METRIC, $tableCountry->getRowsCount()); - destroy($tableCountry); - - $tableRegion = Piwik_ArchiveProcessing_Day::getDataTableFromArray($this->interestTables['location_region']); - $serialized = $tableRegion->getSerialized($maximumRows, $maximumRows, Piwik_Archive::INDEX_NB_VISITS); - $archiveProcessing->insertBlobRecord(self::VISITS_BY_REGION_RECORD_NAME, $serialized); - destroy($tableRegion); - - $tableCity = Piwik_ArchiveProcessing_Day::getDataTableFromArray($this->interestTables['location_city']); - $this->setLatitudeLongitude($tableCity); - $serialized = $tableCity->getSerialized($maximumRows, $maximumRows, Piwik_Archive::INDEX_NB_VISITS); - $archiveProcessing->insertBlobRecord(self::VISITS_BY_CITY_RECORD_NAME, $serialized); - destroy($tableCity); - } - - /** - * Makes sure the region and city of a query row are unique. - * - * @param array $row - */ - private function setLongCityRegionId( &$row ) - { - static $locationColumns = array('location_region', 'location_country', 'location_city'); - - // to be on the safe side, remove the location separator from the region/city/country we - // get from the query - foreach ($locationColumns as $column) - { - $row[$column] = str_replace(self::LOCATION_SEPARATOR, '', $row[$column]); - } - - if (!empty($row['location_region'])) // do not differentiate between unknown regions - { - $row['location_region'] = $row['location_region'].self::LOCATION_SEPARATOR.$row['location_country']; - } - - if (!empty($row['location_city'])) // do not differentiate between unknown cities - { - $row['location_city'] = $row['location_city'].self::LOCATION_SEPARATOR.$row['location_region']; - } - } - - /** - * Returns a list of country codes for a given continent code. - * - * @param string $continent The continent code. - * @return array - */ - public static function getCountriesForContinent( $continent ) - { - $continent = strtolower($continent); - - $result = array(); - foreach (Piwik_Common::getCountriesList() as $countryCode => $continentCode) - { - if ($continent == $continentCode) - { - $result[] = $countryCode; - } - } - return array('SQL' => "'".implode("', '", $result)."', ?", - 'bind' => '-'); // HACK: SegmentExpression requires a $bind, even if there's nothing to bind - } - - /** - * Utility method, appends latitude/longitude pairs to city table labels, if that data - * exists for the city. - */ - private function setLatitudeLongitude( $tableCity ) - { - foreach ($tableCity->getRows() as $row) - { - $label = $row->getColumn('label'); - if (isset($this->latLongForCities[$label])) - { - // get lat/long for city - list($lat, $long) = $this->latLongForCities[$label]; - $lat = round($lat, Piwik_UserCountry_LocationProvider::GEOGRAPHIC_COORD_PRECISION); - $long = round($long, Piwik_UserCountry_LocationProvider::GEOGRAPHIC_COORD_PRECISION); - - // set latitude + longitude metadata - $row->setMetadata('lat', $lat); - $row->setMetadata('long', $long); - } - } - } + ); + + if ($query === false) { + return; + } + + while ($row = $query->fetch()) { + // get latitude/longitude if there's a city + $lat = $long = false; + if (!empty($row['location_city'])) { + if (!empty($row['location_latitude'])) { + $lat = $row['location_latitude']; + } + if (!empty($row['location_longitude'])) { + $long = $row['location_longitude']; + } + } + + // make sure regions & cities w/ the same name don't get merged + $this->setLongCityRegionId($row); + + // store latitude/longitude, if we should + if ($lat !== false && $long !== false) { + $this->latLongForCities[$row['location_city']] = array($lat, $long); + } + + // add the stats to each dimension's table + foreach ($this->interestTables as $dimension => &$table) { + $label = (string)$row[$dimension]; + + if (!isset($table[$label])) { + $table[$label] = $archiveProcessing->getNewInterestRow(); + } + $archiveProcessing->updateInterestStats($row, $table[$label]); + } + } + } + + /** + * @param Piwik_ArchiveProcessing_Day $archiveProcessing + */ + protected function archiveDayAggregateGoals($archiveProcessing) + { + $dimensions = array_keys($this->interestTables); + $query = $archiveProcessing->queryConversionsByDimension($dimensions); + + if ($query === false) { + return; + } + + while ($row = $query->fetch()) { + // make sure regions & cities w/ the same name don't get merged + $this->setLongCityRegionId($row); + + $idGoal = $row['idgoal']; + foreach ($this->interestTables as $dimension => &$table) { + $label = (string)$row[$dimension]; + + if (!isset($table[$label][Piwik_Archive::INDEX_GOALS][$idGoal])) { + $table[$label][Piwik_Archive::INDEX_GOALS][$idGoal] = $archiveProcessing->getNewGoalRow($idGoal); + } + + $archiveProcessing->updateGoalStats($row, $table[$label][Piwik_Archive::INDEX_GOALS][$idGoal]); + } + } + + foreach ($this->interestTables as &$table) { + $archiveProcessing->enrichConversionsByLabelArray($table); + } + } + + /** + * @param Piwik_ArchiveProcessing_Day $archiveProcessing + */ + protected function archiveDayRecordInDatabase($archiveProcessing) + { + $maximumRows = Piwik_Config::getInstance()->General['datatable_archiving_maximum_rows_standard']; + + $tableCountry = Piwik_ArchiveProcessing_Day::getDataTableFromArray($this->interestTables['location_country']); + $archiveProcessing->insertBlobRecord(self::VISITS_BY_COUNTRY_RECORD_NAME, $tableCountry->getSerialized()); + $archiveProcessing->insertNumericRecord(self::DISTINCT_COUNTRIES_METRIC, $tableCountry->getRowsCount()); + destroy($tableCountry); + + $tableRegion = Piwik_ArchiveProcessing_Day::getDataTableFromArray($this->interestTables['location_region']); + $serialized = $tableRegion->getSerialized($maximumRows, $maximumRows, Piwik_Archive::INDEX_NB_VISITS); + $archiveProcessing->insertBlobRecord(self::VISITS_BY_REGION_RECORD_NAME, $serialized); + destroy($tableRegion); + + $tableCity = Piwik_ArchiveProcessing_Day::getDataTableFromArray($this->interestTables['location_city']); + $this->setLatitudeLongitude($tableCity); + $serialized = $tableCity->getSerialized($maximumRows, $maximumRows, Piwik_Archive::INDEX_NB_VISITS); + $archiveProcessing->insertBlobRecord(self::VISITS_BY_CITY_RECORD_NAME, $serialized); + destroy($tableCity); + } + + /** + * Makes sure the region and city of a query row are unique. + * + * @param array $row + */ + private function setLongCityRegionId(&$row) + { + static $locationColumns = array('location_region', 'location_country', 'location_city'); + + // to be on the safe side, remove the location separator from the region/city/country we + // get from the query + foreach ($locationColumns as $column) { + $row[$column] = str_replace(self::LOCATION_SEPARATOR, '', $row[$column]); + } + + if (!empty($row['location_region'])) // do not differentiate between unknown regions + { + $row['location_region'] = $row['location_region'] . self::LOCATION_SEPARATOR . $row['location_country']; + } + + if (!empty($row['location_city'])) // do not differentiate between unknown cities + { + $row['location_city'] = $row['location_city'] . self::LOCATION_SEPARATOR . $row['location_region']; + } + } + + /** + * Returns a list of country codes for a given continent code. + * + * @param string $continent The continent code. + * @return array + */ + public static function getCountriesForContinent($continent) + { + $continent = strtolower($continent); + + $result = array(); + foreach (Piwik_Common::getCountriesList() as $countryCode => $continentCode) { + if ($continent == $continentCode) { + $result[] = $countryCode; + } + } + return array('SQL' => "'" . implode("', '", $result) . "', ?", + 'bind' => '-'); // HACK: SegmentExpression requires a $bind, even if there's nothing to bind + } + + /** + * Utility method, appends latitude/longitude pairs to city table labels, if that data + * exists for the city. + */ + private function setLatitudeLongitude($tableCity) + { + foreach ($tableCity->getRows() as $row) { + $label = $row->getColumn('label'); + if (isset($this->latLongForCities[$label])) { + // get lat/long for city + list($lat, $long) = $this->latLongForCities[$label]; + $lat = round($lat, Piwik_UserCountry_LocationProvider::GEOGRAPHIC_COORD_PRECISION); + $long = round($long, Piwik_UserCountry_LocationProvider::GEOGRAPHIC_COORD_PRECISION); + + // set latitude + longitude metadata + $row->setMetadata('lat', $lat); + $row->setMetadata('long', $long); + } + } + } } |