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:
-rw-r--r--.travis.yml1
-rw-r--r--config/global.ini.php17
-rw-r--r--core/AssetManager.php2
-rw-r--r--core/AssetManager/UIAssetCatalog.php17
-rw-r--r--core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php2
-rw-r--r--core/Cache/LanguageAwareStaticCache.php26
-rw-r--r--core/Cache/PersistentCache.php116
-rw-r--r--core/Cache/PluginAwareStaticCache.php31
-rw-r--r--core/Cache/StaticCache.php64
-rw-r--r--core/CacheFile.php16
-rw-r--r--core/Columns/Dimension.php97
-rw-r--r--core/Columns/Updater.php330
-rw-r--r--core/Config.php1
-rw-r--r--core/Console.php31
-rw-r--r--core/Db/Schema.php12
-rw-r--r--core/Db/Schema/Mysql.php92
-rw-r--r--core/Db/SchemaInterface.php9
-rw-r--r--core/DbHelper.php12
-rw-r--r--core/Development.php96
-rw-r--r--core/FrontController.php81
-rw-r--r--core/Loader.php4
-rw-r--r--core/Log.php1
-rw-r--r--core/Menu/MenuAbstract.php48
-rw-r--r--core/Menu/MenuReporting.php8
-rw-r--r--core/Metrics.php54
-rw-r--r--core/Plugin.php101
-rw-r--r--core/Plugin/Controller.php31
-rw-r--r--core/Plugin/Dimension/ActionDimension.php137
-rw-r--r--core/Plugin/Dimension/ConversionDimension.php158
-rw-r--r--core/Plugin/Dimension/VisitDimension.php204
-rw-r--r--core/Plugin/Manager.php64
-rw-r--r--core/Plugin/Menu.php1
-rw-r--r--core/Plugin/Report.php357
-rw-r--r--core/Plugin/Segment.php156
-rw-r--r--core/Plugin/Tasks.php8
-rw-r--r--core/Plugin/ViewDataTable.php32
-rw-r--r--core/Plugin/Widgets.php145
-rw-r--r--core/Settings/SystemSetting.php1
-rw-r--r--core/Tracker.php7
-rw-r--r--core/Tracker/Action.php143
-rw-r--r--core/Tracker/ActionPageview.php12
-rw-r--r--core/Tracker/GoalManager.php243
-rw-r--r--core/Tracker/Request.php30
-rw-r--r--core/Tracker/Settings.php55
-rw-r--r--core/Tracker/Visit.php307
-rw-r--r--core/Tracker/Visitor.php95
-rw-r--r--core/Translate.php26
-rw-r--r--core/Updater.php115
-rw-r--r--core/Updates/1.2-rc1.php26
-rw-r--r--core/Updates/1.5-b1.php3
-rwxr-xr-xcore/Updates/1.9-b9.php13
-rw-r--r--core/Updates/2.5.0-b1.php37
-rw-r--r--core/Version.php2
-rw-r--r--core/ViewDataTable/Factory.php27
-rw-r--r--core/ViewDataTable/Manager.php9
-rw-r--r--core/WidgetsList.php64
-rw-r--r--lang/en.json4
-rw-r--r--piwik.php4
-rw-r--r--plugins/API/API.php127
-rw-r--r--plugins/API/ProcessedReport.php149
-rw-r--r--plugins/Actions/API.php2
-rw-r--r--plugins/Actions/Actions.php817
-rw-r--r--plugins/Actions/Actions/ActionClickUrl.php (renamed from core/Tracker/ActionClickUrl.php)36
-rw-r--r--plugins/Actions/Actions/ActionDownloadUrl.php41
-rw-r--r--plugins/Actions/Actions/ActionSiteSearch.php (renamed from core/Tracker/ActionSiteSearch.php)28
-rw-r--r--plugins/Actions/Archiver.php2
-rw-r--r--plugins/Actions/Columns/ClickedUrl.php21
-rw-r--r--plugins/Actions/Columns/DestinationPage.php20
-rw-r--r--plugins/Actions/Columns/DownloadUrl.php21
-rw-r--r--plugins/Actions/Columns/EntryPageTitle.php52
-rw-r--r--plugins/Actions/Columns/EntryPageUrl.php53
-rw-r--r--plugins/Actions/Columns/ExitPageTitle.php67
-rw-r--r--plugins/Actions/Columns/ExitPageUrl.php73
-rw-r--r--plugins/Actions/Columns/Keyword.php20
-rw-r--r--plugins/Actions/Columns/KeywordwithNoSearchResult.php20
-rw-r--r--plugins/Actions/Columns/PageTitle.php33
-rw-r--r--plugins/Actions/Columns/PageUrl.php33
-rw-r--r--plugins/Actions/Columns/SearchCategory.php20
-rw-r--r--plugins/Actions/Columns/SearchDestinationPage.php20
-rw-r--r--plugins/Actions/Columns/SearchKeyword.php30
-rw-r--r--plugins/Actions/Columns/SearchNoResultKeyword.php20
-rw-r--r--plugins/Actions/Columns/ServerTime.php43
-rw-r--r--plugins/Actions/Columns/TimeSpentRefAction.php36
-rw-r--r--plugins/Actions/Columns/VisitTotalActions.php95
-rw-r--r--plugins/Actions/Columns/VisitTotalSearches.php77
-rw-r--r--plugins/Actions/Controller.php131
-rw-r--r--plugins/Actions/Menu.php13
-rw-r--r--plugins/Actions/Reports/Base.php119
-rw-r--r--plugins/Actions/Reports/Get.php34
-rw-r--r--plugins/Actions/Reports/GetDownloads.php58
-rw-r--r--plugins/Actions/Reports/GetEntryPageTitles.php61
-rw-r--r--plugins/Actions/Reports/GetEntryPageUrls.php72
-rw-r--r--plugins/Actions/Reports/GetExitPageTitles.php68
-rw-r--r--plugins/Actions/Reports/GetExitPageUrls.php84
-rw-r--r--plugins/Actions/Reports/GetOutlinks.php65
-rw-r--r--plugins/Actions/Reports/GetPageTitles.php82
-rw-r--r--plugins/Actions/Reports/GetPageTitlesFollowingSiteSearch.php71
-rw-r--r--plugins/Actions/Reports/GetPageUrls.php62
-rw-r--r--plugins/Actions/Reports/GetPageUrlsFollowingSiteSearch.php40
-rw-r--r--plugins/Actions/Reports/GetSiteSearchCategories.php65
-rw-r--r--plugins/Actions/Reports/GetSiteSearchKeywords.php54
-rw-r--r--plugins/Actions/Reports/GetSiteSearchNoResultKeywords.php51
-rw-r--r--plugins/Actions/Reports/SiteSearchBase.php40
-rw-r--r--plugins/Actions/Segment.php22
-rw-r--r--plugins/Actions/Widgets.php51
-rw-r--r--plugins/CoreConsole/Commands/DevelopmentEnable.php63
-rw-r--r--plugins/CoreConsole/Commands/DevelopmentManageTestFiles.php (renamed from plugins/CoreConsole/Commands/ManageTestFiles.php)2
-rw-r--r--plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php (renamed from plugins/CoreConsole/Commands/SyncUITestScreenshots.php)2
-rw-r--r--plugins/CoreConsole/Commands/GenerateDimension.php245
-rw-r--r--plugins/CoreConsole/Commands/GenerateReport.php280
-rw-r--r--plugins/CoreConsole/Commands/GenerateWidget.php53
-rw-r--r--plugins/CoreConsole/Commands/TestsRun.php (renamed from plugins/CoreConsole/Commands/RunTests.php)2
-rw-r--r--plugins/CoreConsole/Commands/TestsRunUI.php (renamed from plugins/CoreConsole/Commands/RunUITests.php)2
-rw-r--r--plugins/CoreConsole/Commands/TestsSetupFixture.php (renamed from plugins/CoreConsole/Commands/SetupFixture.php)4
-rw-r--r--plugins/CoreHome/Columns/IdSite.php52
-rw-r--r--plugins/CoreHome/Columns/VisitFirstActionTime.php37
-rw-r--r--plugins/CoreHome/Columns/VisitGoalBuyer.php136
-rw-r--r--plugins/CoreHome/Columns/VisitGoalConverted.php57
-rw-r--r--plugins/CoreHome/Columns/VisitLastActionTime.php52
-rw-r--r--plugins/CoreHome/Columns/VisitTotalTime.php116
-rw-r--r--plugins/CoreHome/Columns/VisitorDaysSinceFirst.php57
-rw-r--r--plugins/CoreHome/Columns/VisitorDaysSinceOrder.php64
-rw-r--r--plugins/CoreHome/Columns/VisitorReturning.php84
-rw-r--r--plugins/CoreHome/Columns/VisitsCount.php57
-rw-r--r--plugins/CoreHome/Controller.php85
-rw-r--r--plugins/CoreHome/Segment.php21
-rw-r--r--plugins/CoreHome/Widgets.php40
-rw-r--r--plugins/CoreHome/javascripts/menu.js6
-rw-r--r--plugins/CorePluginsAdmin/PluginInstaller.php4
-rw-r--r--plugins/CoreUpdater/Controller.php4
-rw-r--r--plugins/CoreUpdater/CoreUpdater.php21
-rw-r--r--plugins/CoreUpdater/templates/runUpdaterAndExit_welcome.twig10
-rw-r--r--plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig7
-rw-r--r--plugins/CoreVisualizations/CoreVisualizations.php3
-rw-r--r--plugins/CustomVariables/API.php2
-rw-r--r--plugins/CustomVariables/Columns/CustomVariableName.php20
-rw-r--r--plugins/CustomVariables/Columns/CustomVariableValue.php20
-rw-r--r--plugins/CustomVariables/Controller.php21
-rw-r--r--plugins/CustomVariables/CustomVariables.php82
-rw-r--r--plugins/CustomVariables/Menu.php24
-rw-r--r--plugins/CustomVariables/Reports/Base.php18
-rw-r--r--plugins/CustomVariables/Reports/GetCustomVariables.php39
-rw-r--r--plugins/CustomVariables/Reports/GetCustomVariablesValuesFromNameId.php39
-rw-r--r--plugins/CustomVariables/Widgets.php20
-rw-r--r--plugins/DBStats/Controller.php134
-rw-r--r--plugins/DBStats/DBStats.php320
-rw-r--r--plugins/DBStats/Reports/Base.php158
-rw-r--r--plugins/DBStats/Reports/GetAdminDataSummary.php33
-rw-r--r--plugins/DBStats/Reports/GetDatabaseUsageSummary.php56
-rw-r--r--plugins/DBStats/Reports/GetIndividualMetricsSummary.php36
-rw-r--r--plugins/DBStats/Reports/GetIndividualReportsSummary.php41
-rw-r--r--plugins/DBStats/Reports/GetMetricDataSummary.php39
-rw-r--r--plugins/DBStats/Reports/GetMetricDataSummaryByYear.php40
-rw-r--r--plugins/DBStats/Reports/GetReportDataSummary.php39
-rw-r--r--plugins/DBStats/Reports/GetReportDataSummaryByYear.php40
-rw-r--r--plugins/DBStats/Reports/GetTrackerDataSummary.php30
-rw-r--r--plugins/Dashboard/Dashboard.php5
-rw-r--r--plugins/DevicesDetection/Columns/Base.php20
-rw-r--r--plugins/DevicesDetection/Columns/BrowserName.php45
-rw-r--r--plugins/DevicesDetection/Columns/BrowserVersion.php45
-rw-r--r--plugins/DevicesDetection/Columns/DeviceBrand.php39
-rw-r--r--plugins/DevicesDetection/Columns/DeviceModel.php39
-rw-r--r--plugins/DevicesDetection/Columns/DeviceType.php64
-rw-r--r--plugins/DevicesDetection/Columns/Os.php46
-rw-r--r--plugins/DevicesDetection/Columns/OsVersion.php39
-rw-r--r--plugins/DevicesDetection/Controller.php50
-rw-r--r--plugins/DevicesDetection/DevicesDetection.php290
-rw-r--r--plugins/DevicesDetection/Reports/Base.php19
-rw-r--r--plugins/DevicesDetection/Reports/GetBrand.php34
-rw-r--r--plugins/DevicesDetection/Reports/GetBrowserFamilies.php41
-rw-r--r--plugins/DevicesDetection/Reports/GetBrowserVersions.php40
-rw-r--r--plugins/DevicesDetection/Reports/GetModel.php34
-rw-r--r--plugins/DevicesDetection/Reports/GetOsFamilies.php42
-rw-r--r--plugins/DevicesDetection/Reports/GetOsVersions.php41
-rw-r--r--plugins/DevicesDetection/Reports/GetType.php34
-rw-r--r--plugins/DevicesDetection/Widgets.php27
-rw-r--r--plugins/Events/Actions/ActionEvent.php (renamed from core/Tracker/ActionEvent.php)43
-rw-r--r--plugins/Events/Columns/EventAction.php56
-rw-r--r--plugins/Events/Columns/EventCategory.php56
-rw-r--r--plugins/Events/Columns/EventName.php55
-rw-r--r--plugins/Events/Columns/TotalEvents.php77
-rw-r--r--plugins/Events/Controller.php24
-rw-r--r--plugins/Events/Events.php151
-rw-r--r--plugins/Events/Reports/Base.php117
-rw-r--r--plugins/Events/Reports/GetAction.php27
-rw-r--r--plugins/Events/Reports/GetCategory.php28
-rw-r--r--plugins/Events/Reports/GetName.php28
-rw-r--r--plugins/Events/Segment.php22
-rw-r--r--plugins/Events/Widgets.php25
-rw-r--r--plugins/ExamplePlugin/API.php16
-rw-r--r--plugins/ExamplePlugin/Columns/ExampleActionDimension.php134
-rw-r--r--plugins/ExamplePlugin/Columns/ExampleConversionDimension.php131
-rw-r--r--plugins/ExamplePlugin/Columns/ExampleVisitDimension.php155
-rw-r--r--plugins/ExamplePlugin/Reports/Base.php19
-rw-r--r--plugins/ExamplePlugin/Reports/GetExampleReport.php111
-rw-r--r--plugins/ExamplePlugin/Widgets.php41
-rw-r--r--plugins/ExamplePlugin/javascripts/plugin.js2
-rw-r--r--plugins/ExamplePlugin/lang/en.json5
-rw-r--r--plugins/ExampleRssWidget/Controller.php53
-rw-r--r--plugins/ExampleRssWidget/Widgets.php51
-rw-r--r--plugins/ExampleVisualization/ExampleVisualization.php14
-rw-r--r--plugins/ExampleVisualization/Visualizations/SimpleTable.php (renamed from plugins/ExampleVisualization/SimpleTable.php)2
-rw-r--r--plugins/Feedback/API.php16
-rw-r--r--plugins/Goals/Archiver.php2
-rw-r--r--plugins/Goals/Columns/BaseConversion.php34
-rw-r--r--plugins/Goals/Columns/DaysToConversion.php20
-rw-r--r--plugins/Goals/Columns/IdGoal.php33
-rw-r--r--plugins/Goals/Columns/ProductCategory.php20
-rw-r--r--plugins/Goals/Columns/ProductName.php20
-rw-r--r--plugins/Goals/Columns/ProductSku.php20
-rw-r--r--plugins/Goals/Columns/Revenue.php70
-rw-r--r--plugins/Goals/Columns/RevenueDiscount.php38
-rw-r--r--plugins/Goals/Columns/RevenueShipping.php38
-rw-r--r--plugins/Goals/Columns/RevenueSubtotal.php38
-rw-r--r--plugins/Goals/Columns/RevenueTax.php38
-rw-r--r--plugins/Goals/Columns/VisitsUntilConversion.php20
-rw-r--r--plugins/Goals/Controller.php29
-rw-r--r--plugins/Goals/Goals.php453
-rw-r--r--plugins/Goals/Reports/BaseEcommerce.php73
-rw-r--r--plugins/Goals/Reports/BaseEcommerceItem.php103
-rw-r--r--plugins/Goals/Reports/BaseGoal.php63
-rw-r--r--plugins/Goals/Reports/Get.php40
-rw-r--r--plugins/Goals/Reports/GetDaysToConversion.php66
-rw-r--r--plugins/Goals/Reports/GetDaysToConversionAbandonedCart.php32
-rw-r--r--plugins/Goals/Reports/GetDaysToConversionEcommerceOrder.php32
-rw-r--r--plugins/Goals/Reports/GetEcommerceAbandonedCart.php36
-rw-r--r--plugins/Goals/Reports/GetEcommerceOrder.php46
-rw-r--r--plugins/Goals/Reports/GetItemsCategory.php25
-rw-r--r--plugins/Goals/Reports/GetItemsName.php25
-rw-r--r--plugins/Goals/Reports/GetItemsSku.php26
-rw-r--r--plugins/Goals/Reports/GetVisitsUntilConversion.php66
-rw-r--r--plugins/Goals/Reports/GetVisitsUntilConversionAbandonedCart.php32
-rw-r--r--plugins/Goals/Reports/GetVisitsUntilConversionEcommerceOrder.php32
-rw-r--r--plugins/Goals/Widgets.php43
-rw-r--r--plugins/Insights/Insights.php8
-rw-r--r--plugins/Insights/Widgets.php14
-rw-r--r--plugins/Live/Controller.php35
-rw-r--r--plugins/Live/Live.php8
-rw-r--r--plugins/Live/Menu.php19
-rw-r--r--plugins/Live/Reports/Base.php21
-rw-r--r--plugins/Live/Reports/GetLastVisitsDetails.php42
-rw-r--r--plugins/Live/Reports/GetSimpleLastVisitCount.php55
-rw-r--r--plugins/Live/Visitor.php9
-rw-r--r--plugins/Live/Widgets.php15
-rw-r--r--plugins/MultiSites/Columns/Website.php20
-rw-r--r--plugins/MultiSites/MultiSites.php57
-rw-r--r--plugins/MultiSites/Reports/Base.php31
-rw-r--r--plugins/MultiSites/Reports/GetAll.php26
-rw-r--r--plugins/MultiSites/Reports/GetOne.php27
-rw-r--r--plugins/PrivacyManager/Config.php1
-rw-r--r--plugins/PrivacyManager/IPAnonymizer.php1
-rw-r--r--plugins/Provider/Columns/Provider.php94
-rw-r--r--plugins/Provider/Controller.php8
-rw-r--r--plugins/Provider/Provider.php126
-rw-r--r--plugins/Provider/Reports/GetProvider.php33
-rw-r--r--plugins/Provider/Widgets.php20
-rw-r--r--plugins/Referrers/Columns/Base.php (renamed from core/Tracker/Referrer.php)122
-rw-r--r--plugins/Referrers/Columns/Campaign.php20
-rw-r--r--plugins/Referrers/Columns/Keyword.php66
-rw-r--r--plugins/Referrers/Columns/Referrer.php20
-rw-r--r--plugins/Referrers/Columns/ReferrerName.php66
-rw-r--r--plugins/Referrers/Columns/ReferrerType.php63
-rw-r--r--plugins/Referrers/Columns/ReferrerUrl.php50
-rw-r--r--plugins/Referrers/Columns/ReferrerVisitServerDate.php35
-rw-r--r--plugins/Referrers/Columns/SearchEngine.php20
-rw-r--r--plugins/Referrers/Columns/SocialNetwork.php20
-rw-r--r--plugins/Referrers/Columns/Website.php20
-rw-r--r--plugins/Referrers/Columns/WebsitePage.php20
-rw-r--r--plugins/Referrers/Controller.php88
-rw-r--r--plugins/Referrers/Menu.php1
-rw-r--r--plugins/Referrers/Referrers.php429
-rw-r--r--plugins/Referrers/Reports/Base.php18
-rw-r--r--plugins/Referrers/Reports/GetAll.php47
-rw-r--r--plugins/Referrers/Reports/GetCampaigns.php40
-rw-r--r--plugins/Referrers/Reports/GetKeywords.php43
-rw-r--r--plugins/Referrers/Reports/GetKeywordsFromCampaignId.php35
-rw-r--r--plugins/Referrers/Reports/GetKeywordsFromSearchEngineId.php34
-rw-r--r--plugins/Referrers/Reports/GetReferrerType.php77
-rw-r--r--plugins/Referrers/Reports/GetSearchEngines.php44
-rw-r--r--plugins/Referrers/Reports/GetSearchEnginesFromKeywordId.php34
-rw-r--r--plugins/Referrers/Reports/GetSocials.php54
-rw-r--r--plugins/Referrers/Reports/GetUrlsForSocial.php36
-rw-r--r--plugins/Referrers/Reports/GetUrlsFromWebsiteId.php35
-rw-r--r--plugins/Referrers/Reports/GetWebsites.php43
-rw-r--r--plugins/Referrers/Segment.php21
-rw-r--r--plugins/Referrers/Widgets.php18
-rw-r--r--plugins/SEO/Controller.php47
-rw-r--r--plugins/SEO/Widgets.php40
-rw-r--r--plugins/UserCountry/Columns/Base.php165
-rw-r--r--plugins/UserCountry/Columns/City.php77
-rw-r--r--plugins/UserCountry/Columns/Continent.php20
-rw-r--r--plugins/UserCountry/Columns/Country.php141
-rw-r--r--plugins/UserCountry/Columns/Latitude.php77
-rw-r--r--plugins/UserCountry/Columns/Longitude.php77
-rw-r--r--plugins/UserCountry/Columns/Provider.php61
-rw-r--r--plugins/UserCountry/Columns/Region.php77
-rw-r--r--plugins/UserCountry/Controller.php42
-rwxr-xr-xplugins/UserCountry/LocationProvider.php11
-rw-r--r--plugins/UserCountry/Reports/Base.php64
-rw-r--r--plugins/UserCountry/Reports/GetCity.php42
-rw-r--r--plugins/UserCountry/Reports/GetContinent.php42
-rw-r--r--plugins/UserCountry/Reports/GetCountry.php50
-rw-r--r--plugins/UserCountry/Reports/GetRegion.php42
-rw-r--r--plugins/UserCountry/Segment.php21
-rw-r--r--plugins/UserCountry/UserCountry.php345
-rw-r--r--plugins/UserCountry/Widgets.php36
-rw-r--r--plugins/UserSettings/Columns/Browser.php33
-rw-r--r--plugins/UserSettings/Columns/BrowserFamily.php20
-rw-r--r--plugins/UserSettings/Columns/BrowserVersion.php32
-rw-r--r--plugins/UserSettings/Columns/Configuration.php20
-rw-r--r--plugins/UserSettings/Columns/Language.php37
-rw-r--r--plugins/UserSettings/Columns/MobilevsDesktop.php20
-rw-r--r--plugins/UserSettings/Columns/Operatingsystem.php33
-rw-r--r--plugins/UserSettings/Columns/OperatingsystemFamily.php20
-rw-r--r--plugins/UserSettings/Columns/Plugin.php20
-rw-r--r--plugins/UserSettings/Columns/PluginCookie.php37
-rw-r--r--plugins/UserSettings/Columns/PluginDirector.php37
-rw-r--r--plugins/UserSettings/Columns/PluginFlash.php37
-rw-r--r--plugins/UserSettings/Columns/PluginGears.php37
-rw-r--r--plugins/UserSettings/Columns/PluginJava.php37
-rw-r--r--plugins/UserSettings/Columns/PluginPdf.php37
-rw-r--r--plugins/UserSettings/Columns/PluginQuickTime.php37
-rw-r--r--plugins/UserSettings/Columns/PluginRealPlayer.php37
-rw-r--r--plugins/UserSettings/Columns/PluginSilverlight.php37
-rw-r--r--plugins/UserSettings/Columns/PluginWindowsMedia.php37
-rw-r--r--plugins/UserSettings/Columns/Resolution.php53
-rw-r--r--plugins/UserSettings/Columns/TypeOfScreen.php20
-rw-r--r--plugins/UserSettings/Controller.php79
-rw-r--r--plugins/UserSettings/Reports/Base.php32
-rw-r--r--plugins/UserSettings/Reports/GetBrowser.php46
-rw-r--r--plugins/UserSettings/Reports/GetBrowserType.php43
-rw-r--r--plugins/UserSettings/Reports/GetBrowserVersion.php47
-rw-r--r--plugins/UserSettings/Reports/GetConfiguration.php36
-rw-r--r--plugins/UserSettings/Reports/GetLanguage.php38
-rw-r--r--plugins/UserSettings/Reports/GetMobileVsDesktop.php43
-rw-r--r--plugins/UserSettings/Reports/GetOS.php41
-rw-r--r--plugins/UserSettings/Reports/GetOSFamily.php42
-rw-r--r--plugins/UserSettings/Reports/GetPlugin.php53
-rw-r--r--plugins/UserSettings/Reports/GetResolution.php34
-rw-r--r--plugins/UserSettings/Reports/GetWideScreen.php44
-rw-r--r--plugins/UserSettings/Segment.php21
-rw-r--r--plugins/UserSettings/UserSettings.php407
-rw-r--r--plugins/UserSettings/Widgets.php30
-rw-r--r--plugins/VisitFrequency/Reports/Get.php25
-rw-r--r--plugins/VisitFrequency/VisitFrequency.php42
-rw-r--r--plugins/VisitFrequency/Widgets.php14
-rw-r--r--plugins/VisitTime/Columns/DayOfTheWeek.php20
-rw-r--r--plugins/VisitTime/Columns/LocalTime.php48
-rw-r--r--plugins/VisitTime/Columns/ServerTime.php33
-rw-r--r--plugins/VisitTime/Controller.php21
-rw-r--r--plugins/VisitTime/Reports/Base.php41
-rw-r--r--plugins/VisitTime/Reports/GetByDayOfWeek.php72
-rw-r--r--plugins/VisitTime/Reports/GetVisitInformationPerLocalTime.php48
-rw-r--r--plugins/VisitTime/Reports/GetVisitInformationPerServerTime.php44
-rw-r--r--plugins/VisitTime/Segment.php21
-rw-r--r--plugins/VisitTime/VisitTime.php204
-rw-r--r--plugins/VisitTime/Widgets.php25
-rw-r--r--plugins/VisitorInterest/Columns/PagesPerVisit.php20
-rw-r--r--plugins/VisitorInterest/Columns/VisitDuration.php20
-rw-r--r--plugins/VisitorInterest/Columns/VisitsByDaysSinceLastVisit.php49
-rw-r--r--plugins/VisitorInterest/Columns/VisitsbyVisitNumber.php20
-rw-r--r--plugins/VisitorInterest/Controller.php46
-rw-r--r--plugins/VisitorInterest/Reports/Base.php18
-rw-r--r--plugins/VisitorInterest/Reports/GetNumberOfVisitsByDaysSinceLast.php47
-rw-r--r--plugins/VisitorInterest/Reports/GetNumberOfVisitsByVisitCount.php55
-rw-r--r--plugins/VisitorInterest/Reports/GetNumberOfVisitsPerPage.php60
-rw-r--r--plugins/VisitorInterest/Reports/GetNumberOfVisitsPerVisitDuration.php60
-rw-r--r--plugins/VisitorInterest/VisitorInterest.php182
-rw-r--r--plugins/VisitorInterest/Widgets.php26
-rw-r--r--plugins/VisitsSummary/Reports/Get.php46
-rw-r--r--plugins/VisitsSummary/VisitsSummary.php29
-rw-r--r--plugins/VisitsSummary/Widgets.php15
-rw-r--r--plugins/Widgetize/Controller.php9
-rw-r--r--plugins/Widgetize/Widgetize.php5
-rw-r--r--tests/PHPUnit/Core/AssetManager/configs/merged-assets-disabled.ini.php2
-rw-r--r--tests/PHPUnit/Core/AssetManager/configs/merged-assets-enabled.ini.php2
-rw-r--r--tests/PHPUnit/Fixture.php17
-rw-r--r--tests/PHPUnit/Fixtures/OmniFixture.php2
-rw-r--r--tests/PHPUnit/Fixtures/UITestFixture.php3
-rw-r--r--tests/PHPUnit/Integration/AutoSuggestAPITest.php6
-rw-r--r--tests/PHPUnit/Integration/Core/JsProxyTest.php (renamed from tests/PHPUnit/Core/JsProxyTest.php)0
-rwxr-xr-xtests/PHPUnit/Integration/PurgeDataTest.php11
-rw-r--r--tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_achievementPoints__API.getSuggestedValuesForSegment.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_keywords__API.getSuggestedValuesForSegment.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_myConversionSegmentName__API.getSuggestedValuesForSegment.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_ImportLogs__ExamplePlugin.getExampleReport.xml6
-rw-r--r--tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric_constantRowsCountShouldKeepEmptyRows__API.getProcessedReport_day.xml19
-rw-r--r--tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__ExamplePlugin.getExampleReport.xml6
-rw-r--r--tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__subtable__API.getProcessedReport_week.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumnsWithProcessedMetrics___API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_RowEvolution_entryPageTitles__API.getRowEvolution_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_month.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_month.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_month.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_month.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_month.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml19
-rw-r--r--tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml19
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml2
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml9
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referrers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml19
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml12
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml13
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml8
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_csv__ScheduledReports.generateReport_month.original.csv4
-rw-r--r--tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html73
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getDefaultMetricTranslations.xml36
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getMetadata_day.xml18
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getProcessedReport_day.xml18
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml834
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml23
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_phpRenderer__API.getDefaultMetricTranslations.php2
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_showRawMetrics__API.getProcessedReport_day.xml18
-rw-r--r--tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_year__API.getProcessedReport_year.xml18
-rw-r--r--tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_AbandonedCart__API.getProcessedReport_day.xml3
-rw-r--r--tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_NormalGoal__API.getProcessedReport_day.xml3
-rw-r--r--tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_Order__API.getProcessedReport_day.xml3
-rw-r--r--tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_VisitTime.getVisitInformationPerServerTime__API.getProcessedReport_day.xml19
-rw-r--r--tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml18
-rw-r--r--tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_csv__ScheduledReports.generateReport_week.original.csv4
-rw-r--r--tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html73
-rw-r--r--tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__ExamplePlugin.getExampleReport.xml6
-rw-r--r--tests/PHPUnit/Integration/expected/test_noVisit__ExamplePlugin.getExampleReport.xml6
-rw-r--r--tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__API.getProcessedReport_range.xml18
-rw-r--r--tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__subtable__API.getProcessedReport_day.xml17
m---------tests/PHPUnit/UI0
-rw-r--r--tests/PHPUnit/proxy/includes.php8
-rwxr-xr-xtests/PHPUnit/travis.sh2
-rwxr-xr-xtests/travis/initiate_ui_tests.sh16
444 files changed, 15435 insertions, 6744 deletions
diff --git a/.travis.yml b/.travis.yml
index 02e066c1a9..25286e1e14 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -84,6 +84,7 @@ before_script:
# Uncomment to enable sql_mode STRICT_TRANS_TABLES (new default in Mysql 5.6)
#- mysql -e "SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'"
- mysql -e "SELECT @@sql_mode;"
+ - mysql -e "SHOW GLOBAL VARIABLES;"
# Setup Piwik stack
- ./tests/travis/initiate_ui_tests.sh
- travis_retry composer self-update
diff --git a/config/global.ini.php b/config/global.ini.php
index 234b4c669d..19fbef68bc 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -77,10 +77,6 @@ enable_sql_profiler = 0
; this is useful for Piwik developers as an easy way to create data in their local Piwik
enable_measure_piwik_usage_in_idsite = 0
-; if set to 1, javascript files will be included individually and neither merged nor minified.
-; this option must be set to 1 when adding, removing or modifying javascript files
-disable_merged_assets = 0
-
; If set to 1, all requests to piwik.php will be forced to be 'new visitors'
tracker_always_new_visitor = 0
@@ -92,7 +88,20 @@ allow_upgrades_to_beta = 0
; will be loaded when executing tests.
enable_load_standalone_plugins_during_tests = 0
+[Development]
+
+; Enables the development mode where we avoid most caching to make sure code changes will be directly applied as
+; some caches are only invalidated after an update otherwise. When enabled it'll also performs some validation checks.
+; For instance if you register a method in a widget we will verify whether the method actually exists and is public.
+; If not, we will show you a helpful warning to make it easy to find simple typos etc.
+enabled = 0
+
+; if set to 1, javascript files will be included individually and neither merged nor minified.
+; this option must be set to 1 when adding, removing or modifying javascript files
+disable_merged_assets = 0
+
[General]
+
; the following settings control whether Unique Visitors will be processed for different period types.
; year and range periods are disabled by default, to ensure optimal performance for high traffic Piwik instances
; if you set it to 1 and want the Unique Visitors to be re-processed for reports in the past, drop all piwik_archive_* tables
diff --git a/core/AssetManager.php b/core/AssetManager.php
index 4bf29afef0..1badba4d9e 100644
--- a/core/AssetManager.php
+++ b/core/AssetManager.php
@@ -273,7 +273,7 @@ class AssetManager extends Singleton
*/
public function isMergedAssetsDisabled()
{
- return Config::getInstance()->Debug['disable_merged_assets'];
+ return Config::getInstance()->Development['disable_merged_assets'];
}
/**
diff --git a/core/AssetManager/UIAssetCatalog.php b/core/AssetManager/UIAssetCatalog.php
index 8c7ba10e3b..d8a45f8964 100644
--- a/core/AssetManager/UIAssetCatalog.php
+++ b/core/AssetManager/UIAssetCatalog.php
@@ -21,6 +21,11 @@ class UIAssetCatalog
private $catalogSorter;
/**
+ * @var string[] Absolute file locations
+ */
+ private $existingAssetLocations = array();
+
+ /**
* @param UIAssetCatalogSorter $catalogSorter
*/
function __construct($catalogSorter)
@@ -33,8 +38,10 @@ class UIAssetCatalog
*/
public function addUIAsset($uiAsset)
{
- if(!$this->assetAlreadyInCatalog($uiAsset)) {
+ $location = $uiAsset->getAbsoluteLocation();
+ if(!$this->assetAlreadyInCatalog($location)) {
+ $this->existingAssetLocations[] = $location;
$this->uiAssets[] = $uiAsset;
}
}
@@ -59,12 +66,8 @@ class UIAssetCatalog
* @param UIAsset $uiAsset
* @return boolean
*/
- private function assetAlreadyInCatalog($uiAsset)
+ private function assetAlreadyInCatalog($location)
{
- foreach($this->uiAssets as $existingAsset)
- if($uiAsset->getAbsoluteLocation() == $existingAsset->getAbsoluteLocation())
- return true;
-
- return false;
+ return in_array($location, $this->existingAssetLocations);
}
}
diff --git a/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php b/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php
index d63134c08f..a5ab3d096d 100644
--- a/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php
+++ b/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php
@@ -31,7 +31,7 @@ class JScriptUIAssetFetcher extends UIAssetFetcher
* plugin's root directory.
*
* _Note: While you are developing your plugin you should enable the config setting
- * `[Debug] disable_merged_assets` so JavaScript files will be reloaded immediately
+ * `[Development] disable_merged_assets` so JavaScript files will be reloaded immediately
* after every change._
*
* **Example**
diff --git a/core/Cache/LanguageAwareStaticCache.php b/core/Cache/LanguageAwareStaticCache.php
new file mode 100644
index 0000000000..95c324dcb0
--- /dev/null
+++ b/core/Cache/LanguageAwareStaticCache.php
@@ -0,0 +1,26 @@
+<?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\Cache;
+
+use Piwik\Translate;
+
+/**
+ * Caching class used for static caching which is language aware. It'll cache the given content depending on the
+ * current loaded language. This prevents you from having to invalidate the cache during tests in case the loaded
+ * language changes etc.
+ *
+ * TODO convert this to a decorator...
+ */
+class LanguageAwareStaticCache extends StaticCache
+{
+ protected function completeKey($cacheKey)
+ {
+ return $cacheKey . Translate::getLanguageLoaded();
+ }
+}
diff --git a/core/Cache/PersistentCache.php b/core/Cache/PersistentCache.php
new file mode 100644
index 0000000000..2596b950a5
--- /dev/null
+++ b/core/Cache/PersistentCache.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\Cache;
+
+use Piwik\CacheFile;
+use Piwik\Development;
+use Piwik\Piwik;
+use Piwik\SettingsServer;
+
+/**
+ * Caching class used for static caching.
+ */
+class PersistentCache
+{
+ /**
+ * @var CacheFile
+ */
+ private static $storage = null;
+ private static $content = null;
+ private static $isDirty = false;
+
+ private $cacheKey;
+
+ public function __construct($cacheKey)
+ {
+ $this->cacheKey = $cacheKey;
+
+ if (is_null(self::$content)) {
+ self::$content = array();
+ self::populateCache();
+ }
+ }
+
+ public function setCacheKey($cacheKey)
+ {
+ $this->cacheKey = $cacheKey;
+ }
+
+ public function get()
+ {
+ return self::$content[$this->cacheKey];
+ }
+
+ public function has()
+ {
+ return array_key_exists($this->cacheKey, self::$content);
+ }
+
+ public function set($content)
+ {
+ self::$content[$this->cacheKey] = $content;
+ self::$isDirty = true;
+ }
+
+ private static function populateCache()
+ {
+ if (Development::isEnabled()) {
+ return;
+ }
+
+ if (SettingsServer::isTrackerApiRequest()) {
+ $eventToPersist = 'Tracker.end';
+ $mode = 'tracker';
+ } else {
+ $eventToPersist = 'Request.dispatch.end';
+ $mode = 'ui';
+ }
+
+ $cache = self::getStorage()->get('StaticCache-' . $mode);
+
+ if (is_array($cache)) {
+ self::$content = $cache;
+ }
+
+ Piwik::addAction($eventToPersist, array(__CLASS__, 'persistCache'));
+ }
+
+ public static function persistCache()
+ {
+ if (self::$isDirty) {
+ if (SettingsServer::isTrackerApiRequest()) {
+ $mode = 'tracker';
+ } else {
+ $mode = 'ui';
+ }
+
+ self::getStorage()->set('StaticCache-' . $mode, self::$content);
+ }
+ }
+
+ public static function _reset()
+ {
+ self::$content = array();
+ }
+
+ /**
+ * @return CacheFile
+ */
+ private static function getStorage()
+ {
+ if (is_null(self::$storage)) {
+ self::$storage = new CacheFile('tracker', 43200);
+ self::$storage->addOnDeleteCallback(function () {
+ PersistentCache::_reset();
+ });
+ }
+
+ return self::$storage;
+ }
+}
diff --git a/core/Cache/PluginAwareStaticCache.php b/core/Cache/PluginAwareStaticCache.php
new file mode 100644
index 0000000000..5d4208ede7
--- /dev/null
+++ b/core/Cache/PluginAwareStaticCache.php
@@ -0,0 +1,31 @@
+<?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\Cache;
+
+use Piwik\Plugin\Manager as PluginManager;
+use Piwik\Translate;
+
+/**
+ * Caching class used for static caching which is plugin aware. It'll cache the given content depending on the plugins
+ * that are installed. This prevents you from having to invalidate the cache during tests in case the loaded plugins
+ * changes etc. The key is language aware as well.
+ *
+ * TODO convert this to a decorator...
+ */
+class PluginAwareStaticCache extends StaticCache
+{
+ protected function completeKey($cacheKey)
+ {
+ $pluginManager = PluginManager::getInstance();
+ $pluginNames = $pluginManager->getLoadedPluginsName();
+ $cacheKey = $cacheKey . md5(implode('', $pluginNames)) . Translate::getLanguageLoaded();
+
+ return $cacheKey;
+ }
+}
diff --git a/core/Cache/StaticCache.php b/core/Cache/StaticCache.php
new file mode 100644
index 0000000000..a63c8fd796
--- /dev/null
+++ b/core/Cache/StaticCache.php
@@ -0,0 +1,64 @@
+<?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\Cache;
+
+/**
+ * Caching class used for static caching.
+ *
+ * TODO the default static cache should actually not be language aware. Especially since we would end up in classes like
+ * LanguageAwareStaticCache, PluginAwareStaticCache, PluginAwareLanguageAwareStaticCache, PluginAwareXYZStaticCache,...
+ * once we have dependency injection we should "build" all the caches we need removing duplicated code and extend the
+ * static cache by using decorators which "enrich" the cache key depending on their awareness.
+ */
+class StaticCache
+{
+ protected static $staticCache = array();
+
+ private $cacheKey;
+
+ public function __construct($cacheKey)
+ {
+ $this->setCacheKey($cacheKey);
+ }
+
+ public function setCacheKey($cacheKey)
+ {
+ $this->cacheKey = $this->completeKey($cacheKey);
+ }
+
+ public function getCacheKey()
+ {
+ return $this->cacheKey;
+ }
+
+ public function get()
+ {
+ return self::$staticCache[$this->cacheKey];
+ }
+
+ public function has()
+ {
+ return array_key_exists($this->cacheKey, self::$staticCache);
+ }
+
+ public function clear()
+ {
+ unset(self::$staticCache[$this->cacheKey]);
+ }
+
+ public function set($content)
+ {
+ self::$staticCache[$this->cacheKey] = $content;
+ }
+
+ protected function completeKey($cacheKey)
+ {
+ return $cacheKey;
+ }
+} \ No newline at end of file
diff --git a/core/CacheFile.php b/core/CacheFile.php
index 94ad253020..7a1c824ff8 100644
--- a/core/CacheFile.php
+++ b/core/CacheFile.php
@@ -37,6 +37,11 @@ class CacheFile
const MINIMUM_TTL = 60;
/**
+ * @var \Callable[]
+ */
+ private static $onDeleteCallback = array();
+
+ /**
* @param string $directory directory to use
* @param int $timeToLiveInSeconds TTL
*/
@@ -182,6 +187,11 @@ class CacheFile
return false;
}
+ public function addOnDeleteCallback($onDeleteCallback)
+ {
+ self::$onDeleteCallback[] = $onDeleteCallback;
+ }
+
/**
* A function to delete all cache entries in the directory
*/
@@ -193,6 +203,12 @@ class CacheFile
};
Filesystem::unlinkRecursive($this->cachePath, $deleteRootToo = false, $beforeUnlink);
+
+ if (!empty(self::$onDeleteCallback)) {
+ foreach (self::$onDeleteCallback as $callback) {
+ $callback();
+ }
+ }
}
public function opCacheInvalidate($filepath)
diff --git a/core/Columns/Dimension.php b/core/Columns/Dimension.php
new file mode 100644
index 0000000000..4455480cdf
--- /dev/null
+++ b/core/Columns/Dimension.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\Columns;
+
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugin\Dimension\ConversionDimension;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugin\Segment;
+use Piwik\Translate;
+
+/**
+ * @api
+ * @since 2.5.0
+ */
+abstract class Dimension
+{
+ protected $name;
+ protected $columnName = '';
+ protected $columnType = '';
+ protected $segments = array();
+
+ protected function configureSegments()
+ {
+
+ }
+
+ public function hasImplementedEvent($method)
+ {
+ $method = new \ReflectionMethod($this, $method);
+ $declaringClass = $method->getDeclaringClass();
+
+ return 0 === strpos($declaringClass->name, 'Piwik\Plugins');
+ }
+
+ protected function addSegment(Segment $segment)
+ {
+ $type = $segment->getType();
+
+ if (empty($type)) {
+ $segment->setType(Segment::TYPE_DIMENSION);
+ }
+
+ $this->segments[] = $segment;
+ }
+
+ /**
+ * @return Segment[]
+ */
+ public function getSegments()
+ {
+ if (empty($this->segments)) {
+ $this->configureSegments();
+ }
+
+ return $this->segments;
+ }
+
+ public function getColumnName()
+ {
+ return $this->columnName;
+ }
+
+ public function hasColumnType()
+ {
+ return !empty($this->columnType);
+ }
+
+ abstract public function getName();
+
+ /**
+ * @return Dimension[]
+ */
+ public static function getAllDimensions()
+ {
+ $dimensions = array();
+
+ foreach (VisitDimension::getAllDimensions() as $dimension) {
+ $dimensions[] = $dimension;
+ }
+
+ foreach (ActionDimension::getAllDimensions() as $dimension) {
+ $dimensions[] = $dimension;
+ }
+
+ foreach (ConversionDimension::getAllDimensions() as $dimension) {
+ $dimensions[] = $dimension;
+ }
+
+ return $dimensions;
+ }
+}
diff --git a/core/Columns/Updater.php b/core/Columns/Updater.php
new file mode 100644
index 0000000000..e9f6dfd9c7
--- /dev/null
+++ b/core/Columns/Updater.php
@@ -0,0 +1,330 @@
+<?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\Columns;
+use Piwik\Common;
+use Piwik\DbHelper;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugin\Dimension\ConversionDimension;
+use Piwik\Db;
+use Piwik\Updater as PiwikUpdater;
+use Piwik\Cache\PersistentCache;
+use Piwik\Filesystem;
+
+/**
+ * Class that handles dimension updates
+ */
+class Updater extends \Piwik\Updates
+{
+ /**
+ * @var Updater
+ */
+ private static $updater;
+
+ /**
+ * Return SQL to be executed in this update
+ *
+ * @return array(
+ * 'ALTER .... ' => '1234', // if the query fails, it will be ignored if the error code is 1234
+ * 'ALTER .... ' => false, // if an error occurs, the update will stop and fail
+ * // and user will have to manually run the query
+ * )
+ */
+ public static function getSql()
+ {
+ $sqls = array();
+
+ $changingColumns = self::getUpdates();
+
+ foreach ($changingColumns as $table => $columns) {
+ if (empty($columns) || !is_array($columns)) {
+ continue;
+ }
+
+ $sqls["ALTER TABLE `" . Common::prefixTable($table) . "` " . implode(', ', $columns)] = false;
+ }
+
+ return $sqls;
+ }
+
+ /**
+ * Incremental version update
+ */
+ public static function update()
+ {
+ foreach (self::getSql() as $sql => $errorCode) {
+ try {
+ Db::exec($sql);
+ } catch (\Exception $e) {
+ if (!Db::get()->isErrNo($e, '1091') && !Db::get()->isErrNo($e, '1060')) {
+ PiwikUpdater::handleQueryError($e, $sql, false, __FILE__);
+ }
+ }
+ }
+ }
+
+ public static function setUpdater($updater)
+ {
+ self::$updater = $updater;
+ }
+
+ private static function hasComponentNewVersion($component)
+ {
+ return empty(self::$updater) || self::$updater->hasNewVersion($component);
+ }
+
+ private static function getUpdates()
+ {
+ $visitColumns = DbHelper::getTableColumns(Common::prefixTable('log_visit'));
+ $actionColumns = DbHelper::getTableColumns(Common::prefixTable('log_link_visit_action'));
+ $conversionColumns = DbHelper::getTableColumns(Common::prefixTable('log_conversion'));
+
+ $changingColumns = array();
+
+ foreach (VisitDimension::getAllDimensions() as $dimension) {
+ $updates = self::getUpdatesForDimension($dimension, 'log_visit.', $visitColumns, $conversionColumns);
+ $changingColumns = self::mixinUpdates($changingColumns, $updates);
+ }
+
+ foreach (ActionDimension::getAllDimensions() as $dimension) {
+ $updates = self::getUpdatesForDimension($dimension, 'log_link_visit_action.', $actionColumns);
+ $changingColumns = self::mixinUpdates($changingColumns, $updates);
+ }
+
+ foreach (ConversionDimension::getAllDimensions() as $dimension) {
+ $updates = self::getUpdatesForDimension($dimension, 'log_conversion.', $conversionColumns);
+ $changingColumns = self::mixinUpdates($changingColumns, $updates);
+ }
+
+ return $changingColumns;
+ }
+
+ /**
+ * @param ActionDimension|ConversionDimension|VisitDimension $dimension
+ * @param string $componentPrefix
+ * @param array $existingColumnsInDb
+ * @param array $conversionColumns
+ * @return array
+ */
+ private static function getUpdatesForDimension($dimension, $componentPrefix, $existingColumnsInDb, $conversionColumns = array())
+ {
+ $column = $dimension->getColumnName();
+ $componentName = $componentPrefix . $column;
+
+ if (!self::hasComponentNewVersion($componentName)) {
+ return array();
+ }
+
+ if (array_key_exists($column, $existingColumnsInDb)) {
+ if ($dimension instanceof VisitDimension) {
+ $sqlUpdates = $dimension->update($conversionColumns);
+ } else {
+ $sqlUpdates = $dimension->update();
+ }
+ } else {
+ $sqlUpdates = $dimension->install();
+ }
+
+ return $sqlUpdates;
+ }
+
+ private static function mixinUpdates($changingColumns, $updatesFromDimension)
+ {
+ if (!empty($updatesFromDimension)) {
+ foreach ($updatesFromDimension as $table => $col) {
+ if (empty($changingColumns[$table])) {
+ $changingColumns[$table] = $col;
+ } else {
+ $changingColumns[$table] = array_merge($changingColumns[$table], $col);
+ }
+ }
+ }
+
+ return $changingColumns;
+ }
+
+ public static function getAllVersions()
+ {
+ // to avoid having to load all dimensions on each request we check if there were any changes on the file system
+ // can easily save > 100ms for each request
+ $cachedTimes = self::getCachedDimensionFileChanges();
+ $currentTimes = self::getCurrentDimensionFileChanges();
+ $diff = array_diff_assoc($currentTimes, $cachedTimes);
+
+ if (empty($diff)) {
+ return array();
+ }
+
+ $versions = array();
+
+ $visitColumns = DbHelper::getTableColumns(Common::prefixTable('log_visit'));
+ $actionColumns = DbHelper::getTableColumns(Common::prefixTable('log_link_visit_action'));
+ $conversionColumns = DbHelper::getTableColumns(Common::prefixTable('log_conversion'));
+
+ foreach (VisitDimension::getAllDimensions() as $dimension) {
+ $versions = self::mixinVersions($dimension, 'log_visit.', $visitColumns, $versions);
+ }
+
+ foreach (ActionDimension::getAllDimensions() as $dimension) {
+ $versions = self::mixinVersions($dimension, 'log_link_visit_action.', $actionColumns, $versions);
+ }
+
+ foreach (ConversionDimension::getAllDimensions() as $dimension) {
+ $versions = self::mixinVersions($dimension, 'log_conversion.', $conversionColumns, $versions);
+ }
+
+ return $versions;
+ }
+
+ /**
+ * @param ActionDimension|ConversionDimension|VisitDimension $dimension
+ * @param string $componentPrefix
+ * @param array $columns
+ * @param array $versions
+ * @return array The modified versions array
+ */
+ private static function mixinVersions($dimension, $componentPrefix, $columns, $versions)
+ {
+ $columnName = $dimension->getColumnName();
+
+ if (!$columnName || !$dimension->hasColumnType()) {
+ return $versions;
+ }
+
+ $component = $componentPrefix . $columnName;
+ $version = $dimension->getVersion();
+
+ if (array_key_exists($columnName, $columns)
+ && false === PiwikUpdater::getCurrentRecordedComponentVersion($component)
+ && self::wasDimensionMovedFromCoreToPlugin($component, $version)) {
+ PiwikUpdater::recordComponentSuccessfullyUpdated($component, $version);
+ return $versions;
+ }
+
+ $versions[$component] = $version;
+
+ return $versions;
+ }
+
+ public static function isDimensionComponent($name)
+ {
+ return 0 === strpos($name, 'log_visit.')
+ || 0 === strpos($name, 'log_conversion.')
+ || 0 === strpos($name, 'log_conversion_item.')
+ || 0 === strpos($name, 'log_link_visit_action.');
+ }
+
+ public static function wasDimensionMovedFromCoreToPlugin($name, $version)
+ {
+ $dimensions = array (
+ 'log_visit.config_resolution' => 'VARCHAR(9) NOT NULL',
+ 'log_visit.config_device_brand' => 'VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL',
+ 'log_visit.config_device_model' => 'VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL',
+ 'log_visit.config_windowsmedia' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_silverlight' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_java' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_gears' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_pdf' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_quicktime' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_realplayer' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_device_type' => 'TINYINT( 100 ) NULL DEFAULT NULL',
+ 'log_visit.visitor_localtime' => 'TIME NOT NULL',
+ 'log_visit.location_region' => 'char(2) DEFAULT NULL1',
+ 'log_visit.visitor_days_since_last' => 'SMALLINT(5) UNSIGNED NOT NULL',
+ 'log_visit.location_longitude' => 'float(10, 6) DEFAULT NULL1',
+ 'log_visit.visit_total_events' => 'SMALLINT(5) UNSIGNED NOT NULL',
+ 'log_visit.config_os_version' => 'VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL',
+ 'log_visit.location_city' => 'varchar(255) DEFAULT NULL1',
+ 'log_visit.location_country' => 'CHAR(3) NOT NULL1',
+ 'log_visit.location_latitude' => 'float(10, 6) DEFAULT NULL1',
+ 'log_visit.config_flash' => 'TINYINT(1) NOT NULL',
+ 'log_visit.config_director' => 'TINYINT(1) NOT NULL',
+ 'log_visit.visit_total_time' => 'SMALLINT(5) UNSIGNED NOT NULL',
+ 'log_visit.visitor_count_visits' => 'SMALLINT(5) UNSIGNED NOT NULL1',
+ 'log_visit.visit_entry_idaction_name' => 'INTEGER(11) UNSIGNED NOT NULL',
+ 'log_visit.visit_entry_idaction_url' => 'INTEGER(11) UNSIGNED NOT NULL',
+ 'log_visit.visitor_returning' => 'TINYINT(1) NOT NULL1',
+ 'log_visit.visitor_days_since_order' => 'SMALLINT(5) UNSIGNED NOT NULL1',
+ 'log_visit.visit_goal_buyer' => 'TINYINT(1) NOT NULL',
+ 'log_visit.visit_first_action_time' => 'DATETIME NOT NULL',
+ 'log_visit.visit_goal_converted' => 'TINYINT(1) NOT NULL',
+ 'log_visit.visitor_days_since_first' => 'SMALLINT(5) UNSIGNED NOT NULL1',
+ 'log_visit.visit_exit_idaction_name' => 'INTEGER(11) UNSIGNED NOT NULL',
+ 'log_visit.visit_exit_idaction_url' => 'INTEGER(11) UNSIGNED NULL DEFAULT 0',
+ 'log_visit.config_browser_version' => 'VARCHAR(20) NOT NULL',
+ 'log_visit.config_browser_name' => 'VARCHAR(10) NOT NULL',
+ 'log_visit.location_browser_lang' => 'VARCHAR(20) NOT NULL',
+ 'log_visit.config_os' => 'CHAR(3) NOT NULL',
+ 'log_visit.config_cookie' => 'TINYINT(1) NOT NULL',
+ 'log_visit.referer_visit_server_date' => 'date default NULL1',
+ 'log_visit.referer_url' => 'TEXT NOT NULL',
+ 'log_visit.visit_total_searches' => 'SMALLINT(5) UNSIGNED NOT NULL',
+ 'log_visit.visit_total_actions' => 'SMALLINT(5) UNSIGNED NOT NULL',
+ 'log_visit.referer_keyword' => 'VARCHAR(255) NULL1',
+ 'log_visit.referer_name' => 'VARCHAR(70) NULL1',
+ 'log_visit.referer_type' => 'TINYINT(1) UNSIGNED NULL1',
+ 'log_link_visit_action.idaction_name' => 'INTEGER(10) UNSIGNED',
+ 'log_link_visit_action.idaction_url' => 'INTEGER(10) UNSIGNED DEFAULT NULL',
+ 'log_link_visit_action.server_time' => 'DATETIME NOT NULL',
+ 'log_link_visit_action.time_spent_ref_action' => 'INTEGER(10) UNSIGNED NOT NULL',
+ 'log_link_visit_action.idaction_event_action' => 'INTEGER(10) UNSIGNED DEFAULT NULL',
+ 'log_link_visit_action.idaction_event_category' => 'INTEGER(10) UNSIGNED DEFAULT NULL',
+ 'log_conversion.revenue_discount' => 'float default NULL',
+ 'log_conversion.revenue' => 'float default NULL',
+ 'log_conversion.revenue_shipping' => 'float default NULL',
+ 'log_conversion.revenue_subtotal' => 'float default NULL',
+ 'log_conversion.revenue_tax' => 'float default NULL',
+ );
+
+ if (!array_key_exists($name, $dimensions)) {
+ return false;
+ }
+
+ return strtolower($dimensions[$name]) === strtolower($version);
+ }
+
+ public static function onNoUpdateAvailable($versionsThatWereChecked)
+ {
+ if (!empty($versionsThatWereChecked)) {
+ // invalidate cache only if there were actually file changes before, otherwise we write the cache on each
+ // request. There were versions checked only if there was a file change but no update, meaning we can
+ // set the cache and declare this state as "no update available".
+ self::cacheCurrentDimensionFileChanges();
+ }
+ }
+
+ private static function getCurrentDimensionFileChanges()
+ {
+ $files = Filesystem::globr(PIWIK_INCLUDE_PATH . '/plugins/*/Columns', '*.php');
+
+ $times = array();
+ foreach ($files as $file) {
+ $times[$file] = filemtime($file);
+ }
+
+ return $times;
+ }
+
+ private static function cacheCurrentDimensionFileChanges()
+ {
+ $changes = self::getCurrentDimensionFileChanges();
+ $persistentCache = new PersistentCache('AllDimensionModifyTime');
+ $persistentCache->set($changes);
+ }
+
+ private static function getCachedDimensionFileChanges()
+ {
+ $persistentCache = new PersistentCache('AllDimensionModifyTime');
+ if ($persistentCache->has()) {
+ return $persistentCache->get();
+ }
+
+ return array();
+ }
+}
diff --git a/core/Config.php b/core/Config.php
index c2ee88b119..0c56f95b0c 100644
--- a/core/Config.php
+++ b/core/Config.php
@@ -143,6 +143,7 @@ class Config extends Singleton
$this->configCache['Tracker'] = $this->configGlobal['Tracker'];
$this->configCache['Deletelogs'] = $this->configGlobal['Deletelogs'];
$this->configCache['Deletereports'] = $this->configGlobal['Deletereports'];
+ $this->configCache['Development'] = $this->configGlobal['Development'];
}
// for unit tests, we set that no plugin is installed. This will force
diff --git a/core/Console.php b/core/Console.php
index a33a72d3b9..d03fe0501f 100644
--- a/core/Console.php
+++ b/core/Console.php
@@ -72,11 +72,9 @@ class Console extends Application
private function getAvailableCommands()
{
$commands = $this->getDefaultPiwikCommands();
+ $detected = PluginManager::getInstance()->findMultipleComponents('Commands', 'Piwik\\Plugin\\ConsoleCommand');
- $pluginNames = PluginManager::getInstance()->getLoadedPluginsName();
- foreach ($pluginNames as $pluginName) {
- $commands = array_merge($commands, $this->findCommandsInPlugin($pluginName));
- }
+ $commands = array_merge($commands, $detected);
/**
* Triggered to filter / restrict console commands. Plugins that want to restrict commands
@@ -101,31 +99,6 @@ class Console extends Application
return $commands;
}
- private function findCommandsInPlugin($pluginName)
- {
- $commands = array();
-
- $files = Filesystem::globr(PIWIK_INCLUDE_PATH . '/plugins/' . $pluginName .'/Commands', '*.php');
-
- foreach ($files as $file) {
- $klassName = sprintf('Piwik\\Plugins\\%s\\Commands\\%s', $pluginName, basename($file, '.php'));
-
- if (!class_exists($klassName) || !is_subclass_of($klassName, 'Piwik\\Plugin\\ConsoleCommand')) {
- continue;
- }
-
- $klass = new \ReflectionClass($klassName);
-
- if ($klass->isAbstract()) {
- continue;
- }
-
- $commands[] = $klassName;
- }
-
- return $commands;
- }
-
private function checkCompatibility()
{
if (Common::isPhpCgiType()) {
diff --git a/core/Db/Schema.php b/core/Db/Schema.php
index 4568724ede..c54389fd75 100644
--- a/core/Db/Schema.php
+++ b/core/Db/Schema.php
@@ -235,6 +235,18 @@ class Schema extends Singleton
}
/**
+ * Get list of installed columns in a table
+ *
+ * @param string $tableName The name of a table.
+ *
+ * @return array Installed columns indexed by the column name.
+ */
+ public function getTableColumns($tableName)
+ {
+ return $this->getSchema()->getTableColumns($tableName);
+ }
+
+ /**
* Returns true if Piwik tables exist
*
* @return bool True if tables exist; false otherwise
diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php
index ea51164215..76c7f17ce7 100644
--- a/core/Db/Schema/Mysql.php
+++ b/core/Db/Schema/Mysql.php
@@ -148,50 +148,9 @@ class Mysql implements SchemaInterface
idvisit INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
idsite INTEGER(10) UNSIGNED NOT NULL,
idvisitor BINARY(8) NOT NULL,
- visitor_localtime TIME NOT NULL,
- visitor_returning TINYINT(1) NOT NULL,
- visitor_count_visits SMALLINT(5) UNSIGNED NOT NULL,
- visitor_days_since_last SMALLINT(5) UNSIGNED NOT NULL,
- visitor_days_since_order SMALLINT(5) UNSIGNED NOT NULL,
- visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL,
- visit_first_action_time DATETIME NOT NULL,
visit_last_action_time DATETIME NOT NULL,
- visit_exit_idaction_url INTEGER(11) UNSIGNED NULL DEFAULT 0,
- visit_exit_idaction_name INTEGER(11) UNSIGNED NOT NULL,
- visit_entry_idaction_url INTEGER(11) UNSIGNED NOT NULL,
- visit_entry_idaction_name INTEGER(11) UNSIGNED NOT NULL,
- visit_total_actions SMALLINT(5) UNSIGNED NOT NULL,
- visit_total_searches SMALLINT(5) UNSIGNED NOT NULL,
- visit_total_events SMALLINT(5) UNSIGNED NOT NULL,
- visit_total_time SMALLINT(5) UNSIGNED NOT NULL,
- visit_goal_converted TINYINT(1) NOT NULL,
- visit_goal_buyer TINYINT(1) NOT NULL,
- referer_type TINYINT(1) UNSIGNED NULL,
- referer_name VARCHAR(70) NULL,
- referer_url TEXT NOT NULL,
- referer_keyword VARCHAR(255) NULL,
config_id BINARY(8) NOT NULL,
- config_os CHAR(3) NOT NULL,
- config_browser_name VARCHAR(10) NOT NULL,
- config_browser_version VARCHAR(20) NOT NULL,
- config_resolution VARCHAR(9) NOT NULL,
- config_pdf TINYINT(1) NOT NULL,
- config_flash TINYINT(1) NOT NULL,
- config_java TINYINT(1) NOT NULL,
- config_director TINYINT(1) NOT NULL,
- config_quicktime TINYINT(1) NOT NULL,
- config_realplayer TINYINT(1) NOT NULL,
- config_windowsmedia TINYINT(1) NOT NULL,
- config_gears TINYINT(1) NOT NULL,
- config_silverlight TINYINT(1) NOT NULL,
- config_cookie TINYINT(1) NOT NULL,
location_ip VARBINARY(16) NOT NULL,
- location_browser_lang VARCHAR(20) NOT NULL,
- location_country CHAR(3) NOT NULL,
- location_region char(2) DEFAULT NULL,
- location_city varchar(255) DEFAULT NULL,
- location_latitude float(10, 6) DEFAULT NULL,
- location_longitude float(10, 6) DEFAULT NULL,
PRIMARY KEY(idvisit),
INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time),
INDEX index_idsite_datetime (idsite, visit_last_action_time),
@@ -229,30 +188,11 @@ class Mysql implements SchemaInterface
server_time datetime NOT NULL,
idaction_url int(11) default NULL,
idlink_va int(11) default NULL,
- referer_visit_server_date date default NULL,
- referer_type int(10) unsigned default NULL,
- referer_name varchar(70) default NULL,
- referer_keyword varchar(255) default NULL,
- visitor_returning tinyint(1) NOT NULL,
- visitor_count_visits SMALLINT(5) UNSIGNED NOT NULL,
- visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL,
- visitor_days_since_order SMALLINT(5) UNSIGNED NOT NULL,
- location_country char(3) NOT NULL,
- location_region char(2) DEFAULT NULL,
- location_city varchar(255) DEFAULT NULL,
- location_latitude float(10, 6) DEFAULT NULL,
- location_longitude float(10, 6) DEFAULT NULL,
- url text NOT NULL,
idgoal int(10) NOT NULL,
buster int unsigned NOT NULL,
-
idorder varchar(100) default NULL,
items SMALLINT UNSIGNED DEFAULT NULL,
- revenue float default NULL,
- revenue_subtotal float default NULL,
- revenue_tax float default NULL,
- revenue_shipping float default NULL,
- revenue_discount float default NULL,
+ url text NOT NULL,
PRIMARY KEY (idvisit, idgoal, buster),
UNIQUE KEY unique_idsite_idorder (idsite, idorder),
@@ -264,20 +204,13 @@ class Mysql implements SchemaInterface
idlink_va INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT,
idsite int(10) UNSIGNED NOT NULL,
idvisitor BINARY(8) NOT NULL,
- server_time DATETIME NOT NULL,
idvisit INTEGER(10) UNSIGNED NOT NULL,
- idaction_url INTEGER(10) UNSIGNED DEFAULT NULL,
idaction_url_ref INTEGER(10) UNSIGNED NULL DEFAULT 0,
- idaction_name INTEGER(10) UNSIGNED,
idaction_name_ref INTEGER(10) UNSIGNED NOT NULL,
- idaction_event_category INTEGER(10) UNSIGNED DEFAULT NULL,
- idaction_event_action INTEGER(10) UNSIGNED DEFAULT NULL,
- time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL,
custom_float FLOAT NULL DEFAULT NULL,
PRIMARY KEY(idlink_va),
- INDEX index_idvisit(idvisit),
- INDEX index_idsite_servertime ( idsite, server_time )
+ INDEX index_idvisit(idvisit)
) ENGINE=$engine DEFAULT CHARSET=utf8
",
@@ -377,6 +310,27 @@ class Mysql implements SchemaInterface
private $tablesInstalled = null;
/**
+ * Get list of installed columns in a table
+ *
+ * @param string $tableName The name of a table.
+ *
+ * @return array Installed columns indexed by the column name.
+ */
+ public function getTableColumns($tableName)
+ {
+ $db = Db::get();
+
+ $allColumns = $db->fetchAll("SHOW COLUMNS FROM . $tableName");
+
+ $fields = array();
+ foreach ($allColumns as $column) {
+ $fields[$column['Field']] = $column;
+ }
+
+ return $fields;
+ }
+
+ /**
* Get list of tables installed
*
* @param bool $forceReload Invalidate cache
diff --git a/core/Db/SchemaInterface.php b/core/Db/SchemaInterface.php
index a8a3771ac5..8cb79f6a73 100644
--- a/core/Db/SchemaInterface.php
+++ b/core/Db/SchemaInterface.php
@@ -88,6 +88,15 @@ interface SchemaInterface
public function getTablesInstalled($forceReload = true);
/**
+ * Get list of installed columns in a table
+ *
+ * @param string $tableName The name of a table.
+ *
+ * @return array Installed columns indexed by the column name.
+ */
+ public function getTableColumns($tableName);
+
+ /**
* Checks whether any table exists
*
* @return bool True if tables exist; false otherwise
diff --git a/core/DbHelper.php b/core/DbHelper.php
index df616b2cd6..8dbf7d0a9e 100644
--- a/core/DbHelper.php
+++ b/core/DbHelper.php
@@ -29,6 +29,18 @@ class DbHelper
}
/**
+ * Get list of installed columns in a table
+ *
+ * @param string $tableName The name of a table.
+ *
+ * @return array Installed columns indexed by the column name.
+ */
+ public static function getTableColumns($tableName)
+ {
+ return Schema::getInstance()->getTableColumns($tableName);
+ }
+
+ /**
* Creates a new table in the database.
*
* Example:
diff --git a/core/Development.php b/core/Development.php
new file mode 100644
index 0000000000..c0d34f11e9
--- /dev/null
+++ b/core/Development.php
@@ -0,0 +1,96 @@
+<?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;
+
+use \Exception;
+
+/**
+ * Development related checks and tools
+ */
+class Development
+{
+ private static $isEnabled = null;
+
+ /**
+ * Returns `true` if segmentation is allowed for this user, `false` if otherwise.
+ *
+ * @return bool
+ * @api
+ */
+ public static function isEnabled()
+ {
+ if (is_null(self::$isEnabled)) {
+ self::$isEnabled = (bool) Config::getInstance()->Development['enabled'];
+ }
+
+ return self::$isEnabled;
+ }
+
+ public static function methodExists($classOrInstance, $method)
+ {
+ if (is_string($classOrInstance)) {
+ return class_exists($classOrInstance) && method_exists($classOrInstance, $method);
+ }
+
+ return method_exists($classOrInstance, $method);
+ }
+
+ public static function formatMethodCall($classOrInstance, $method)
+ {
+ if (is_object($classOrInstance)) {
+ $classOrInstance = get_class($classOrInstance);
+ }
+
+ return $classOrInstance . '::' . $method . '()';
+ }
+
+ public static function checkMethodIsCallable($classOrInstance, $method, $prefixMessageIfError)
+ {
+ if (!self::isEnabled()) {
+ return;
+ }
+
+ if (!self::methodExists($classOrInstance, $method)) {
+ self::error($prefixMessageIfError . ' "' . self::formatMethodCall($classOrInstance, $method) . '" does not exist. Please make sure to define such a method.');
+ }
+
+ if (!self::isCallableMethod($classOrInstance, $method)) {
+ self::error($prefixMessageIfError . ' "' . self::formatMethodCall($classOrInstance, $method) . '" is not callable. Please make sure to method is public');
+
+ }
+ }
+
+ public static function isCallableMethod($classOrInstance, $method)
+ {
+ if (!self::methodExists($classOrInstance, $method)) {
+ return false;
+ }
+
+ $reflection = new \ReflectionMethod($classOrInstance, $method);
+ return $reflection->isPublic();
+ }
+
+ public static function error($message)
+ {
+ if (!self::isEnabled()) {
+ return;
+ }
+
+ $message .= ' (This error is only shown in development mode)';
+
+ if (SettingsServer::isTrackerApiRequest()
+ || Common::isPhpCliMode()) {
+ Log::error($message);
+ } else {
+ throw new Exception($message);
+ }
+
+ }
+}
diff --git a/core/FrontController.php b/core/FrontController.php
index a59e425ba7..a06a08db9f 100644
--- a/core/FrontController.php
+++ b/core/FrontController.php
@@ -13,8 +13,10 @@ use Exception;
use Piwik\API\Request;
use Piwik\API\ResponseBuilder;
use Piwik\Plugin\Controller;
+use Piwik\Plugin\Report;
+use Piwik\Plugin\Widgets;
use Piwik\Session;
-use Piwik\Log;
+use \Piwik\Plugins\CoreHome\Controller as CoreHomeController;
/**
* This singleton dispatches requests to the appropriate plugin Controller.
@@ -102,30 +104,73 @@ class FrontController extends Singleton
}
}
- protected function makeController($module, $action)
+ protected function makeController($module, $action, &$parameters)
{
$controllerClassName = $this->getClassNameController($module);
- // FrontController's autoloader
- if (!class_exists($controllerClassName, false)) {
- $moduleController = PIWIK_INCLUDE_PATH . '/plugins/' . $module . '/Controller.php';
- if (!is_readable($moduleController)) {
- throw new Exception("Module controller $moduleController not found!");
+ // TRY TO FIND ACTION IN CONTROLLER
+ if (class_exists($controllerClassName)) {
+
+ $class = $this->getClassNameController($module);
+ /** @var $controller Controller */
+ $controller = new $class;
+
+ $controllerAction = $action;
+ if ($controllerAction === false) {
+ $controllerAction = $controller->getDefaultAction();
+ }
+
+ if (is_callable(array($controller, $controllerAction))) {
+
+ return array($controller, $controllerAction);
+ }
+
+ if ($action === false) {
+ $this->triggerControllerActionNotFoundError($controller, $controllerAction);
}
- require_once $moduleController; // prefixed by PIWIK_INCLUDE_PATH
+
}
- $class = $this->getClassNameController($module);
- /** @var $controller Controller */
- $controller = new $class;
- if ($action === false) {
- $action = $controller->getDefaultAction();
+ // TRY TO FIND ACTION IN WIDGET
+ $widget = Widgets::factory($module, $action);
+
+ if (!empty($widget)) {
+
+ $parameters['widgetModule'] = $module;
+ $parameters['widgetMethod'] = $action;
+
+ return array(new CoreHomeController(), 'renderWidget');
}
- if (!is_callable(array($controller, $action))) {
- throw new Exception("Action '$action' not found in the controller '$controllerClassName'.");
+ // TRY TO FIND ACTION IN REPORT
+ $report = Report::factory($module, $action);
+
+ if (!empty($report)) {
+
+ $parameters['reportModule'] = $module;
+ $parameters['reportAction'] = $action;
+
+ return array(new CoreHomeController(), 'renderReportWidget');
}
- return array($controller, $action);
+
+ if (!empty($action) && 'menu' === substr($action, 0, 4)) {
+ $reportAction = lcfirst(substr($action, 4)); // menuGetPageUrls => getPageUrls
+ $report = Report::factory($module, $reportAction);
+
+ if (!empty($report)) {
+ $parameters['reportModule'] = $module;
+ $parameters['reportAction'] = $reportAction;
+
+ return array(new CoreHomeController(), 'renderReportMenu');
+ }
+ }
+
+ $this->triggerControllerActionNotFoundError($module, $action);
+ }
+
+ protected function triggerControllerActionNotFoundError($module, $action)
+ {
+ throw new Exception("Action '$action' not found in the module '$module'.");
}
protected function getClassNameController($module)
@@ -513,7 +558,7 @@ class FrontController extends Singleton
*/
Piwik::postEvent('Request.dispatch', array(&$module, &$action, &$parameters));
- list($controller, $action) = $this->makeController($module, $action);
+ list($controller, $actionToCall) = $this->makeController($module, $action, $parameters);
/**
* Triggered directly before controller actions are dispatched.
@@ -528,7 +573,7 @@ class FrontController extends Singleton
*/
Piwik::postEvent(sprintf('Controller.%s.%s', $module, $action), array(&$parameters));
- $result = call_user_func_array(array($controller, $action), $parameters);
+ $result = call_user_func_array(array($controller, $actionToCall), $parameters);
/**
* Triggered after a controller action is successfully called.
diff --git a/core/Loader.php b/core/Loader.php
index 9cdf282fcb..6e33987f19 100644
--- a/core/Loader.php
+++ b/core/Loader.php
@@ -27,7 +27,7 @@ class Loader
* @return string Class file name
* @throws Exception if class name is invalid
*/
- protected static function getClassFileName($class)
+ protected static function getClassFileName($class)
{
if (!preg_match('/^[A-Za-z0-9_\\\\]+$/D', $class)) {
throw new Exception("Invalid class name \"$class\".");
@@ -82,7 +82,7 @@ class Loader
if (static::isPluginClass($class)) {
static::tryToLoadClass($class, '/plugins/', $classPath);
- } else if (static::usesPiwikNamespace($class)) {
+ } elseif (static::usesPiwikNamespace($class)) {
static::tryToLoadClass($class, '/core/', $classPath);
} else {
// non-Piwik classes (e.g., Zend Framework) are in libs/
diff --git a/core/Log.php b/core/Log.php
index df1ce57c98..a28032be9b 100644
--- a/core/Log.php
+++ b/core/Log.php
@@ -373,6 +373,7 @@ class Log extends Singleton
$this->currentLogLevel = $logLevel;
}
+
public function getLogLevel()
{
return $this->currentLogLevel;
diff --git a/core/Menu/MenuAbstract.php b/core/Menu/MenuAbstract.php
index 3f624b117f..69b48f76b1 100644
--- a/core/Menu/MenuAbstract.php
+++ b/core/Menu/MenuAbstract.php
@@ -126,13 +126,17 @@ abstract class MenuAbstract extends Singleton
*/
private function buildMenuItem($menuName, $subMenuName, $url, $order = 50, $tooltip = false)
{
- if (!isset($this->menu[$menuName]) || empty($subMenuName)) {
- $this->menu[$menuName]['_url'] = $url;
- if (empty($subMenuName)) {
- $this->menu[$menuName]['_order'] = $order;
- }
- $this->menu[$menuName]['_name'] = $menuName;
- $this->menu[$menuName]['_hasSubmenu'] = false;
+ if (!isset($this->menu[$menuName])) {
+ $this->menu[$menuName] = array(
+ '_hasSubmenu' => false,
+ '_order' => $order
+ );
+ }
+
+ if (empty($subMenuName)) {
+ $this->menu[$menuName]['_url'] = $url;
+ $this->menu[$menuName]['_order'] = $order;
+ $this->menu[$menuName]['_name'] = $menuName;
$this->menu[$menuName]['_tooltip'] = $tooltip;
}
if (!empty($subMenuName)) {
@@ -141,7 +145,10 @@ abstract class MenuAbstract extends Singleton
$this->menu[$menuName][$subMenuName]['_name'] = $subMenuName;
$this->menu[$menuName][$subMenuName]['_tooltip'] = $tooltip;
$this->menu[$menuName]['_hasSubmenu'] = true;
- $this->menu[$menuName]['_tooltip'] = $tooltip;
+
+ if (!array_key_exists('_tooltip', $this->menu[$menuName])) {
+ $this->menu[$menuName]['_tooltip'] = $tooltip;
+ }
}
}
@@ -284,15 +291,34 @@ abstract class MenuAbstract extends Singleton
*/
protected function menuCompare($itemOne, $itemTwo)
{
- if (!is_array($itemOne) || !is_array($itemTwo)
- || !isset($itemOne['_order']) || !isset($itemTwo['_order'])
- ) {
+ if (!is_array($itemOne) && !is_array($itemTwo)) {
return 0;
}
+ if (!is_array($itemOne) && is_array($itemTwo)) {
+ return -1;
+ }
+
+ if (is_array($itemOne) && !is_array($itemTwo)) {
+ return 1;
+ }
+
+ if (!isset($itemOne['_order']) && !isset($itemTwo['_order'])) {
+ return 0;
+ }
+
+ if (!isset($itemOne['_order']) && isset($itemTwo['_order'])) {
+ return -1;
+ }
+
+ if (isset($itemOne['_order']) && !isset($itemTwo['_order'])) {
+ return 1;
+ }
+
if ($itemOne['_order'] == $itemTwo['_order']) {
return strcmp($itemOne['_name'], $itemTwo['_name']);
}
+
return ($itemOne['_order'] < $itemTwo['_order']) ? -1 : 1;
}
}
diff --git a/core/Menu/MenuReporting.php b/core/Menu/MenuReporting.php
index 146c6d08f1..c085e7b41d 100644
--- a/core/Menu/MenuReporting.php
+++ b/core/Menu/MenuReporting.php
@@ -8,6 +8,7 @@
*/
namespace Piwik\Menu;
use Piwik\Piwik;
+use Piwik\Plugin\Report;
/**
* Contains menu entries for the Reporting menu (the menu displayed under the Piwik logo).
@@ -67,9 +68,16 @@ class MenuReporting extends MenuAbstract
*/
Piwik::postEvent('Menu.Reporting.addItems', array());
+ foreach (Report::getAllReports() as $report) {
+ if ($report->isEnabled()) {
+ $report->configureReportingMenu($this);
+ }
+ }
+
foreach ($this->getAvailableMenus() as $menu) {
$menu->configureReportingMenu($this);
}
+
}
return parent::getMenu();
diff --git a/core/Metrics.php b/core/Metrics.php
index 4f12a8e3ab..0d9bc2c16e 100644
--- a/core/Metrics.php
+++ b/core/Metrics.php
@@ -9,6 +9,9 @@
namespace Piwik;
+use Piwik\Cache\LanguageAwareStaticCache;
+use Piwik\Cache\PluginAwareStaticCache;
+
require_once PIWIK_INCLUDE_PATH . "/core/Piwik.php";
/**
@@ -219,6 +222,12 @@ class Metrics
static public function getDefaultMetricTranslations()
{
+ $cache = new PluginAwareStaticCache('DefaultMetricTranslations');
+
+ if ($cache->has()) {
+ return $cache->get();
+ }
+
$translations = array(
'label' => 'General_ColumnLabel',
'date' => 'General_Date',
@@ -264,22 +273,39 @@ class Metrics
$translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
+ $cache->set($translations);
+
return $translations;
}
static public function getDefaultMetrics()
{
+ $cache = new LanguageAwareStaticCache('DefaultMetrics');
+
+ if ($cache->has()) {
+ return $cache->get();
+ }
+
$translations = array(
'nb_visits' => 'General_ColumnNbVisits',
'nb_uniq_visitors' => 'General_ColumnNbUniqVisitors',
'nb_actions' => 'General_ColumnNbActions',
);
$translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
+
+ $cache->set($translations);
+
return $translations;
}
static public function getDefaultProcessedMetrics()
{
+ $cache = new LanguageAwareStaticCache('DefaultProcessedMetrics');
+
+ if ($cache->has()) {
+ return $cache->get();
+ }
+
$translations = array(
// Processed in AddColumnsProcessedMetrics
'nb_actions_per_visit' => 'General_ColumnActionsPerVisit',
@@ -287,7 +313,11 @@ class Metrics
'bounce_rate' => 'General_ColumnBounceRate',
'conversion_rate' => 'General_ColumnConversionRate',
);
- return array_map(array('\\Piwik\\Piwik','translate'), $translations);
+ $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
+
+ $cache->set($translations);
+
+ return $translations;
}
static public function getReadableColumnName($columnIdRaw)
@@ -323,7 +353,13 @@ class Metrics
static public function getDefaultMetricsDocumentation()
{
- $documentation = array(
+ $cache = new PluginAwareStaticCache('DefaultMetricsDocumentation');
+
+ if ($cache->has()) {
+ return $cache->get();
+ }
+
+ $translations = array(
'nb_visits' => 'General_ColumnNbVisitsDocumentation',
'nb_uniq_visitors' => 'General_ColumnNbUniqVisitorsDocumentation',
'nb_actions' => 'General_ColumnNbActionsDocumentation',
@@ -335,7 +371,19 @@ class Metrics
'nb_hits' => 'General_ColumnPageviewsDocumentation',
'exit_rate' => 'General_ColumnExitRateDocumentation'
);
- return array_map(array('\\Piwik\\Piwik','translate'), $documentation);
+
+ /**
+ * Use this event to register translations for metrics documentation processed by your plugin.
+ *
+ * @param string[] $translations The array mapping of column_name => Plugin_TranslationForColumnDocumentation
+ */
+ Piwik::postEvent('Metrics.getDefaultMetricDocumentationTranslations', array(&$translations));
+
+ $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
+
+ $cache->set($translations);
+
+ return $translations;
}
public static function getPercentVisitColumn()
diff --git a/core/Plugin.php b/core/Plugin.php
index 2ddd07aa26..d646b26866 100644
--- a/core/Plugin.php
+++ b/core/Plugin.php
@@ -8,6 +8,7 @@
*/
namespace Piwik;
+use Piwik\Cache\PersistentCache;
use Piwik\Plugin\Dependency;
use Piwik\Plugin\MetadataLoader;
@@ -106,6 +107,15 @@ class Plugin
private $pluginInformation;
/**
+ * As the cache is used quite often we avoid having to create instances all the time. We reuse it which is not
+ * perfect but efficient. If the cache is used we need to make sure to call setCacheKey() before usage as there
+ * is maybe a different key set since last usage.
+ *
+ * @var PersistentCache
+ */
+ private $cache;
+
+ /**
* Constructor.
*
* @param string|bool $pluginName A plugin name to force. If not supplied, it is set
@@ -127,6 +137,8 @@ class Plugin
if ($this->hasDefinedPluginInformationInPluginClass() && $metadataLoader->hasPluginJson()) {
throw new \Exception('Plugin ' . $pluginName . ' has defined the method getInformation() and as well as having a plugin.json file. Please delete the getInformation() method from the plugin class. Alternatively, you may delete the plugin directory from plugins/' . $pluginName);
}
+
+ $this->cache = new PersistentCache('Plugin' . $pluginName);
}
private function hasDefinedPluginInformationInPluginClass()
@@ -206,7 +218,7 @@ class Plugin
* - update existing tables
* - etc.
*
- * @throws Exception if installation of fails for some reason.
+ * @throws \Exception if installation of fails for some reason.
*/
public function install()
{
@@ -293,25 +305,90 @@ class Plugin
*/
public function findComponent($componentName, $expectedSubclass)
{
+ $this->cache->setCacheKey('Plugin' . $this->pluginName . $componentName . $expectedSubclass);
+
$componentFile = sprintf('%s/plugins/%s/%s.php', PIWIK_INCLUDE_PATH, $this->pluginName, $componentName);
- if (!file_exists($componentFile)) {
- return;
+ if ($this->cache->has()) {
+ $klassName = $this->cache->get();
+
+ if (empty($klassName)) {
+ return; // might by "false" in case has no menu, widget, ...
+ }
+
+ include_once $componentFile;
+
+ } else {
+ $this->cache->set(false); // prevent from trying to load over and over again for instance if there is no Menu for a plugin
+
+ if (!file_exists($componentFile)) {
+ return;
+ }
+
+ require_once $componentFile;
+
+ $klassName = sprintf('Piwik\\Plugins\\%s\\%s', $this->pluginName, $componentName);
+
+ if (!class_exists($klassName)) {
+ return;
+ }
+
+ if (!empty($expectedSubclass) && !is_subclass_of($klassName, $expectedSubclass)) {
+ Log::warning(sprintf('Cannot use component %s for plugin %s, class %s does not extend %s',
+ $componentName, $this->pluginName, $klassName, $expectedSubclass));
+ return;
+ }
+
+ $this->cache->set($klassName);
}
- $klassName = sprintf('Piwik\\Plugins\\%s\\%s', $this->pluginName, $componentName);
+ return new $klassName;
+ }
+
+ public function findMultipleComponents($directoryWithinPlugin, $expectedSubclass)
+ {
+ $this->cache->setCacheKey('Plugin' . $this->pluginName . $directoryWithinPlugin . $expectedSubclass);
+
+ if ($this->cache->has()) {
+ $components = $this->cache->get();
- if (!class_exists($klassName)) {
- return;
+ foreach ($components as $file => $klass) {
+ include_once $file;
+ }
+
+ return $components;
}
- if (!empty($expectedSubclass) && !is_subclass_of($klassName, $expectedSubclass)) {
- Log::warning(sprintf('Cannot use component %s for plugin %s, class %s does not extend %s',
- $componentName, $this->pluginName, $klassName, $expectedSubclass));
- return;
+ $components = array();
+
+ $files = Filesystem::globr(PIWIK_INCLUDE_PATH . '/plugins/' . $this->pluginName .'/' . $directoryWithinPlugin, '*.php');
+
+ foreach ($files as $file) {
+ require_once $file;
+
+ $fileName = basename($file, '.php');
+ $klassName = sprintf('Piwik\\Plugins\\%s\\%s\\%s', $this->pluginName, $directoryWithinPlugin, $fileName);
+
+ if (!class_exists($klassName)) {
+ continue;
+ }
+
+ if (!empty($expectedSubclass) && !is_subclass_of($klassName, $expectedSubclass)) {
+ continue;
+ }
+
+ $klass = new \ReflectionClass($klassName);
+
+ if ($klass->isAbstract()) {
+ continue;
+ }
+
+ $components[$file] = $klassName;
}
- return new $klassName;
+ $this->cache->set($components);
+
+ return $components;
}
/**
@@ -378,4 +455,4 @@ class Plugin
return false;
}
}
-} \ No newline at end of file
+}
diff --git a/core/Plugin/Controller.php b/core/Plugin/Controller.php
index 9ce914a90e..b8b636c6d4 100644
--- a/core/Plugin/Controller.php
+++ b/core/Plugin/Controller.php
@@ -251,7 +251,8 @@ abstract class Controller
/**
* Convenience method that creates and renders a ViewDataTable for a API method.
*
- * @param string $apiAction The name of the API action (eg, `'getResolution'`).
+ * @param string|\Piwik\Plugin\Report $apiAction The name of the API action (eg, `'getResolution'`) or
+ * an instance of an report.
* @param bool $controllerAction The name of the Controller action name that is rendering the report. Defaults
* to the `$apiAction`.
* @param bool $fetch If `true`, the rendered string is returned, if `false` it is `echo`'d.
@@ -262,6 +263,21 @@ abstract class Controller
*/
protected function renderReport($apiAction, $controllerAction = false)
{
+ if (empty($controllerAction) && is_string($apiAction)) {
+ $report = Report::factory($this->pluginName, $apiAction);
+
+ if (!empty($report)) {
+ $apiAction = $report;
+ }
+ }
+
+ if ($apiAction instanceof Report) {
+ $this->checkSitePermission();
+ $apiAction->checkIsEnabled();
+
+ return $apiAction->render();
+ }
+
$pluginName = $this->pluginName;
/** @var Proxy $apiProxy */
@@ -518,10 +534,7 @@ abstract class Controller
try {
$view->idSite = $this->idSite;
- if (empty($this->site) || empty($this->idSite)) {
- throw new Exception("The requested website idSite is not found in the request, or is invalid.
- Please check that you are logged in Piwik and have permission to access the specified website.");
- }
+ $this->checkSitePermission();
$this->setPeriodVariablesView($view);
$rawDate = Common::getRequestVar('date');
@@ -926,4 +939,12 @@ abstract class Controller
return $result;
}
+
+ protected function checkSitePermission()
+ {
+ if (empty($this->site) || empty($this->idSite)) {
+ throw new Exception("The requested website idSite is not found in the request, or is invalid.
+ Please check that you are logged in Piwik and have permission to access the specified website.");
+ }
+ }
}
diff --git a/core/Plugin/Dimension/ActionDimension.php b/core/Plugin/Dimension/ActionDimension.php
new file mode 100644
index 0000000000..ec552e6d8e
--- /dev/null
+++ b/core/Plugin/Dimension/ActionDimension.php
@@ -0,0 +1,137 @@
+<?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\Dimension;
+
+use Piwik\Cache\PluginAwareStaticCache;
+use Piwik\Columns\Dimension;
+use Piwik\Plugin\Manager as PluginManager;
+use Piwik\Plugin\Segment;
+use Piwik\Common;
+use Piwik\Db;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Translate;
+
+/**
+ * @api
+ * @since 2.5.0
+ */
+abstract class ActionDimension extends Dimension
+{
+ private $tableName = 'log_link_visit_action';
+
+ public function install()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return array();
+ }
+
+ return array(
+ $this->tableName => array("ADD COLUMN `$this->columnName` $this->columnType")
+ );
+ }
+
+ public function update()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return array();
+ }
+
+ return array(
+ $this->tableName => array("MODIFY COLUMN `$this->columnName` $this->columnType")
+ );
+ }
+
+ public function uninstall()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return;
+ }
+
+ try {
+ $sql = "ALTER TABLE `" . Common::prefixTable($this->tableName) . "` DROP COLUMN `$this->columnName`";
+ Db::exec($sql);
+ } catch (\Exception $e) {
+ if (!Db::get()->isErrNo($e, '1091')) {
+ throw $e;
+ }
+ }
+ }
+
+ public function getVersion()
+ {
+ return $this->columnType;
+ }
+
+ public function onLookupAction(Request $request, Action $action)
+ {
+ return false;
+ }
+
+ /**
+ * @return string|int
+ * @throws \Exception in case not implemented
+ */
+ public function getActionId()
+ {
+ throw new \Exception('You need to overwrite the getActionId method in case you implement the onLookupAction method in class: ' . get_class($this));
+ }
+
+ protected function addSegment(Segment $segment)
+ {
+ $sqlSegment = $segment->getSqlSegment();
+ if (!empty($this->columnName) && empty($sqlSegment)) {
+ $segment->setSqlSegment($this->tableName . '.' . $this->columnName);
+ }
+
+ parent::addSegment($segment);
+ }
+
+ /** @return \Piwik\Plugin\Dimension\ActionDimension[] */
+ public static function getAllDimensions()
+ {
+ $cache = new PluginAwareStaticCache('ActionDimensions');
+
+ if (!$cache->has()) {
+
+ $plugins = PluginManager::getInstance()->getLoadedPlugins();
+ $instances = array();
+
+ foreach ($plugins as $plugin) {
+ foreach (self::getDimensions($plugin) as $instance) {
+ $instances[] = $instance;
+ }
+ }
+
+ $cache->set($instances);
+ }
+
+ return $cache->get();
+ }
+
+ /** @return \Piwik\Plugin\Dimension\ActionDimension[] */
+ public static function getDimensions(\Piwik\Plugin $plugin)
+ {
+ $dimensions = $plugin->findMultipleComponents('Columns', '\\Piwik\\Plugin\\Dimension\\ActionDimension');
+ $instances = array();
+
+ foreach ($dimensions as $dimension) {
+ $instances[] = new $dimension();
+ }
+
+ return $instances;
+ }
+
+ public function onNewAction(Request $request, Visitor $visitor, Action $action)
+ {
+ return false;
+ }
+
+}
diff --git a/core/Plugin/Dimension/ConversionDimension.php b/core/Plugin/Dimension/ConversionDimension.php
new file mode 100644
index 0000000000..0df0a02718
--- /dev/null
+++ b/core/Plugin/Dimension/ConversionDimension.php
@@ -0,0 +1,158 @@
+<?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\Dimension;
+
+use Piwik\Cache\PluginAwareStaticCache;
+use Piwik\Columns\Dimension;
+use Piwik\Plugin\Manager as PluginManager;
+use Piwik\Common;
+use Piwik\Db;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Translate;
+use Piwik\Plugin\Segment;
+
+/**
+ * @api
+ * @since 2.5.0
+ */
+abstract class ConversionDimension extends Dimension
+{
+ private $tableName = 'log_conversion';
+
+ public function install()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return array();
+ }
+
+ return array(
+ $this->tableName => array("ADD COLUMN `$this->columnName` $this->columnType")
+ );
+ }
+
+ public function update()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return array();
+ }
+
+ return array(
+ $this->tableName => array("MODIFY COLUMN `$this->columnName` $this->columnType")
+ );
+ }
+
+ public function uninstall()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return;
+ }
+
+ try {
+ $sql = "ALTER TABLE `" . Common::prefixTable($this->tableName) . "` DROP COLUMN `$this->columnName`";
+ Db::exec($sql);
+ } catch (\Exception $e) {
+ if (!Db::get()->isErrNo($e, '1091')) {
+ throw $e;
+ }
+ }
+ }
+
+ public function getVersion()
+ {
+ return $this->columnType;
+ }
+
+ protected function addSegment(Segment $segment)
+ {
+ $sqlSegment = $segment->getSqlSegment();
+ if (!empty($this->columnName) && empty($sqlSegment)) {
+ $segment->setSqlSegment($this->tableName . '.' . $this->columnName);
+ }
+
+ parent::addSegment($segment);
+ }
+
+ /** @return \Piwik\Plugin\Dimension\ConversionDimension[] */
+ public static function getAllDimensions()
+ {
+ $cache = new PluginAwareStaticCache('ConversionDimensions');
+
+ if (!$cache->has()) {
+
+ $plugins = PluginManager::getInstance()->getLoadedPlugins();
+ $instances = array();
+
+ foreach ($plugins as $plugin) {
+ foreach (self::getDimensions($plugin) as $instance) {
+ $instances[] = $instance;
+ }
+ }
+
+ $cache->set($instances);
+ }
+
+ return $cache->get();
+ }
+
+ /** @return \Piwik\Plugin\Dimension\ConversionDimension[] */
+ public static function getDimensions(\Piwik\Plugin $plugin)
+ {
+ $dimensions = $plugin->findMultipleComponents('Columns', '\\Piwik\\Plugin\\Dimension\\ConversionDimension');
+ $instances = array();
+
+ foreach ($dimensions as $dimension) {
+ $instances[] = new $dimension();
+ }
+
+ return $instances;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceOrderConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return false;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceCartUpdateConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return false;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onGoalConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return false;
+ }
+
+}
diff --git a/core/Plugin/Dimension/VisitDimension.php b/core/Plugin/Dimension/VisitDimension.php
new file mode 100644
index 0000000000..cf7204bdd5
--- /dev/null
+++ b/core/Plugin/Dimension/VisitDimension.php
@@ -0,0 +1,204 @@
+<?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\Dimension;
+
+use Piwik\Cache\PluginAwareStaticCache;
+use Piwik\Columns\Dimension;
+use Piwik\Common;
+use Piwik\Db;
+use Piwik\Plugin\Manager as PluginManager;
+use Piwik\Plugin\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+use Piwik\Tracker;
+use Piwik\Translate;
+
+/**
+ * @api
+ * @since 2.5.0
+ */
+abstract class VisitDimension extends Dimension
+{
+ private $tableName = 'log_visit';
+
+ public function install()
+ {
+ if (!$this->columnType) {
+ return array();
+ }
+
+ $changes = array(
+ $this->tableName => array("ADD COLUMN `$this->columnName` $this->columnType")
+ );
+
+ if ($this->isHandlingLogConversion()) {
+ $changes['log_conversion'] = array("ADD COLUMN `$this->columnName` $this->columnType");
+ }
+
+ return $changes;
+ }
+
+ public function update($conversionColumns)
+ {
+ if (!$this->columnType) {
+ return array();
+ }
+
+ $changes = array();
+
+ $changes[$this->tableName] = array("MODIFY COLUMN `$this->columnName` $this->columnType");
+
+ $handlingConversion = $this->isHandlingLogConversion();
+ $hasConversionColumn = array_key_exists($this->columnName, $conversionColumns);
+
+ if ($hasConversionColumn && $handlingConversion) {
+ $changes['log_conversion'] = array("MODIFY COLUMN `$this->columnName` $this->columnType");
+ } elseif (!$hasConversionColumn && $handlingConversion) {
+ $changes['log_conversion'] = array("ADD COLUMN `$this->columnName` $this->columnType");
+ } elseif ($hasConversionColumn && !$handlingConversion) {
+ $changes['log_conversion'] = array("DROP COLUMN `$this->columnName`");
+ }
+
+ return $changes;
+ }
+
+ public function getVersion()
+ {
+ return $this->columnType . $this->isHandlingLogConversion();
+ }
+
+ private function isHandlingLogConversion()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return false;
+ }
+
+ return $this->hasImplementedEvent('onAnyGoalConversion');
+ }
+
+ public function uninstall()
+ {
+ if (empty($this->columnName) || empty($this->columnType)) {
+ return;
+ }
+
+ try {
+ $sql = "ALTER TABLE `" . Common::prefixTable($this->tableName) . "` DROP COLUMN `$this->columnName`";
+ Db::exec($sql);
+ } catch (\Exception $e) {
+ if (!Db::get()->isErrNo($e, '1091')) {
+ throw $e;
+ }
+ }
+
+ try {
+ $sql = "ALTER TABLE `" . Common::prefixTable('log_conversion') . "` DROP COLUMN `$this->columnName`";
+ Db::exec($sql);
+ } catch (\Exception $e) {
+ if (!Db::get()->isErrNo($e, '1091')) {
+ throw $e;
+ }
+ }
+ }
+
+ protected function addSegment(Segment $segment)
+ {
+ $sqlSegment = $segment->getSqlSegment();
+ if (!empty($this->columnName) && empty($sqlSegment)) {
+ $segment->setSqlSegment('log_visit.' . $this->columnName);
+ }
+
+ parent::addSegment($segment);
+ }
+
+ public function getRequiredVisitFields()
+ {
+ return array();
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return false;
+ }
+
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ return false;
+ }
+
+ public function onConvertedVisit(Request $request, Visitor $visitor, $action)
+ {
+ return false;
+ }
+
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return false;
+ }
+
+ /** @return \Piwik\Plugin\Dimension\VisitDimension[] */
+ public static function getAllDimensions()
+ {
+ $cache = new PluginAwareStaticCache('VisitDimensions');
+
+ if (!$cache->has()) {
+
+ $plugins = PluginManager::getInstance()->getLoadedPlugins();
+ $instances = array();
+
+ foreach ($plugins as $plugin) {
+ foreach (self::getDimensions($plugin) as $instance) {
+ $instances[] = $instance;
+ }
+ }
+
+ usort($instances, array('self', 'sortByRequiredFields'));
+
+ $cache->set($instances);
+ }
+
+ return $cache->get();
+ }
+
+ public static function sortByRequiredFields($a, $b)
+ {
+ $fields = $a->getRequiredVisitFields();
+
+ if (empty($fields)) {
+ return -1;
+ }
+
+ if (in_array($b->columnName, $fields)) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /** @return \Piwik\Plugin\Dimension\VisitDimension[] */
+ public static function getDimensions(\Piwik\Plugin $plugin)
+ {
+ $dimensions = $plugin->findMultipleComponents('Columns', '\\Piwik\\Plugin\\Dimension\\VisitDimension');
+ $instances = array();
+
+ foreach ($dimensions as $dimension) {
+ $instances[] = new $dimension();
+ }
+
+ return $instances;
+ }
+
+}
diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php
index ada7dd6e70..67f3355ce8 100644
--- a/core/Plugin/Manager.php
+++ b/core/Plugin/Manager.php
@@ -12,6 +12,7 @@ namespace Piwik\Plugin;
use Piwik\Common;
use Piwik\Config as PiwikConfig;
use Piwik\Config;
+use Piwik\Db;
use Piwik\EventDispatcher;
use Piwik\Filesystem;
use Piwik\Option;
@@ -21,6 +22,9 @@ use Piwik\Theme;
use Piwik\Tracker;
use Piwik\Translate;
use Piwik\Updater;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugin\Dimension\ConversionDimension;
+use Piwik\Plugin\Dimension\VisitDimension;
require_once PIWIK_INCLUDE_PATH . '/core/EventDispatcher.php';
@@ -301,6 +305,22 @@ class Manager extends Singleton
return $components;
}
+ public function findMultipleComponents($directoryWithinPlugin, $expectedSubclass)
+ {
+ $plugins = $this->getLoadedPlugins();
+ $found = array();
+
+ foreach ($plugins as $plugin) {
+ $components = $plugin->findMultipleComponents($directoryWithinPlugin, $expectedSubclass);
+
+ if (!empty($components)) {
+ $found = array_merge($found, $components);
+ }
+ }
+
+ return $found;
+ }
+
/**
* Uninstalls a Plugin (deletes plugin files from the disk)
* Only deactivated plugins can be uninstalled
@@ -365,6 +385,7 @@ class Manager extends Singleton
$messages[] = $e->getMessage();
}
}
+
return $messages;
}
@@ -402,7 +423,6 @@ class Manager extends Singleton
PiwikConfig::getInstance()->forceSave();
$this->clearCache($pluginName);
-
}
protected function isPluginInFilesystem($pluginName)
@@ -837,7 +857,6 @@ class Manager extends Singleton
$path = self::getPluginsDirectory() . $pluginFileName;
-
if (!file_exists($path)) {
// Create the smallest minimal Piwik Plugin
// Eg. Used for Morpheus default theme which does not have a Morpheus.php file
@@ -1052,6 +1071,16 @@ class Manager extends Singleton
public function isTrackerPlugin(Plugin $plugin)
{
+ $dimensions = VisitDimension::getDimensions($plugin);
+ if (!empty($dimensions)) {
+ return true;
+ }
+
+ $dimensions = ActionDimension::getDimensions($plugin);
+ if (!empty($dimensions)) {
+ return true;
+ }
+
$hooks = $plugin->getListHooksRegistered();
$hookNames = array_keys($hooks);
foreach ($hookNames as $name) {
@@ -1062,6 +1091,12 @@ class Manager extends Singleton
return true;
}
}
+
+ $dimensions = ConversionDimension::getDimensions($plugin);
+ if (!empty($dimensions)) {
+ return true;
+ }
+
return false;
}
@@ -1205,6 +1240,31 @@ class Manager extends Singleton
$plugin->uninstall();
} catch (\Exception $e) {
}
+
+ if (empty($plugin)) {
+ return;
+ }
+
+ try {
+ foreach (VisitDimension::getDimensions($plugin) as $dimension) {
+ $dimension->uninstall();
+ }
+ } catch (\Exception $e) {
+ }
+
+ try {
+ foreach (ActionDimension::getDimensions($plugin) as $dimension) {
+ $dimension->uninstall();
+ }
+ } catch (\Exception $e) {
+ }
+
+ try {
+ foreach (ConversionDimension::getDimensions($plugin) as $dimension) {
+ $dimension->uninstall();
+ }
+ } catch (\Exception $e) {
+ }
}
/**
diff --git a/core/Plugin/Menu.php b/core/Plugin/Menu.php
index 5217bd2560..9f7240b1f3 100644
--- a/core/Plugin/Menu.php
+++ b/core/Plugin/Menu.php
@@ -23,6 +23,7 @@ use Piwik\Menu\MenuUser;
* For an example, see the {@link https://github.com/piwik/piwik/blob/master/plugins/ExampleUI/Menu.php} plugin.
*
* @api
+ * @since 2.4.0
*/
class Menu
{
diff --git a/core/Plugin/Report.php b/core/Plugin/Report.php
new file mode 100644
index 0000000000..ffc88157bc
--- /dev/null
+++ b/core/Plugin/Report.php
@@ -0,0 +1,357 @@
+<?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\API\Proxy;
+use Piwik\Cache\LanguageAwareStaticCache;
+use Piwik\Menu\MenuReporting;
+use Piwik\Metrics;
+use Piwik\Piwik;
+use Piwik\Plugin\Manager as PluginManager;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Translate;
+use Piwik\WidgetsList;
+use Piwik\ViewDataTable\Factory as ViewDataTableFactory;
+
+/**
+ * @api
+ * @since 2.5.0
+ */
+class Report
+{
+ protected $module;
+ protected $action;
+ protected $name;
+ protected $category;
+ protected $widgetTitle;
+ protected $widgetParams = array();
+ protected $menuTitle;
+ protected $processedMetrics = array();
+ protected $hasGoalMetrics = false;
+ protected $metrics = array();
+ protected $constantRowsCount = null;
+ protected $isSubtableReport = null;
+ protected $parameters = null;
+
+ public static $orderOfReports = array(
+ 'General_MultiSitesSummary',
+ 'VisitsSummary_VisitsSummary',
+ 'Goals_Ecommerce',
+ 'General_Actions',
+ 'Events_Events',
+ 'Actions_SubmenuSitesearch',
+ 'Referrers_Referrers',
+ 'Goals_Goals',
+ 'General_Visitors',
+ 'DevicesDetection_DevicesDetection',
+ 'UserSettings_VisitorSettings',
+ );
+
+ /**
+ * @var \Piwik\Plugin\Dimension\VisitDimension|\Piwik\Plugin\Dimension\ActionDimension
+ */
+ protected $dimension;
+ protected $documentation;
+
+ /**
+ * @var null|Report
+ */
+ protected $actionToLoadSubTables;
+ protected $order = 1;
+
+ public function __construct()
+ {
+ $classname = get_class($this);
+ $parts = explode('\\', $classname);
+ $this->module = $parts[2];
+ $this->action = lcfirst($parts[4]);
+ $this->processedMetrics = Metrics::getDefaultProcessedMetrics();
+ $this->metrics = array_keys(Metrics::getDefaultMetrics());
+
+ $this->init();
+ }
+
+ protected function init()
+ {
+ }
+
+ public function isEnabled()
+ {
+ return true;
+ }
+
+ public function checkIsEnabled()
+ {
+ if (!$this->isEnabled()) {
+ throw new \Exception(Piwik::translate('General_ExceptionReportNotEnabled'));
+ }
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return HtmlTable::ID;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+
+ }
+
+ /**
+ * @return string
+ * @throws \Exception
+ */
+ public function render()
+ {
+ $apiProxy = Proxy::getInstance();
+
+ if (!$apiProxy->isExistingApiAction($this->module, $this->action)) {
+ throw new \Exception("Invalid action name '$this->action' for '$this->module' plugin.");
+ }
+
+ $apiAction = $apiProxy->buildApiActionName($this->module, $this->action);
+
+ $view = ViewDataTableFactory::build(null, $apiAction, $this->module . '.' . $this->action);
+ $rendered = $view->render();
+
+ return $rendered;
+ }
+
+ public function configureWidget(WidgetsList $widget)
+ {
+ if ($this->widgetTitle) {
+ $params = array();
+ if (!empty($this->widgetParams) && is_array($this->widgetParams)) {
+ $params = $this->widgetParams;
+ }
+ $widget->add($this->category, $this->widgetTitle, $this->module, $this->action, $params);
+ }
+ }
+
+ public function configureReportingMenu(MenuReporting $menu)
+ {
+ if ($this->menuTitle) {
+ $action = 'menu' . ucfirst($this->action);
+ $menu->add($this->category,
+ $this->menuTitle,
+ array('module' => $this->module, 'action' => $action),
+ $this->isEnabled(),
+ $this->order);
+ }
+ }
+
+ public function getMetrics()
+ {
+ return $this->getMetricTranslations($this->metrics);
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ $translations = Metrics::getDefaultMetricsDocumentation();
+ $documentation = array();
+
+ foreach ($this->metrics as $metric) {
+ if (!empty($translations[$metric])) {
+ $documentation[$metric] = $translations[$metric];
+ }
+ }
+
+ return $documentation;
+ }
+
+ public function hasGoalMetrics()
+ {
+ return $this->hasGoalMetrics;
+ }
+
+ public function configureReportMetadata(&$availableReports, $infos)
+ {
+ if (!$this->isEnabled()) {
+ return;
+ }
+
+ $report = $this->buildReportMetadata();
+
+ if (!empty($report)) {
+ $availableReports[] = $report;
+ }
+ }
+
+ protected function buildReportMetadata()
+ {
+ $report = array(
+ 'category' => $this->getCategory(),
+ 'name' => $this->getName(),
+ 'module' => $this->getModule(),
+ 'action' => $this->getAction()
+ );
+
+ if (null !== $this->parameters) {
+ $report['parameters'] = $this->parameters;
+ }
+
+ if (!empty($this->dimension)) {
+ $report['dimension'] = $this->dimension->getName();
+ }
+
+ if (!empty($this->documentation)) {
+ $report['documentation'] = $this->documentation;
+ }
+
+ if (null !== $this->isSubtableReport) {
+ $report['isSubtableReport'] = $this->isSubtableReport;
+ }
+
+ $report['metrics'] = $this->getMetrics();
+ $report['metricsDocumentation'] = $this->getMetricsDocumentation();
+
+ $report['processedMetrics'] = $this->processedMetrics;
+
+ if (!empty($this->actionToLoadSubTables)) {
+ $report['actionToLoadSubTables'] = $this->actionToLoadSubTables;
+ }
+
+ if (null !== $this->constantRowsCount) {
+ $report['constantRowsCount'] = $this->constantRowsCount;
+ }
+
+ $report['order'] = $this->order;
+
+ return $report;
+ }
+
+ /**
+ * @return Report[]
+ */
+ public function getRelatedReports()
+ {
+ return array();
+ }
+
+ public function getWidgetTitle()
+ {
+ if ($this->widgetTitle) {
+ return Piwik::translate($this->widgetTitle);
+ }
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getAction()
+ {
+ return $this->action;
+ }
+
+ public function getCategory()
+ {
+ return Piwik::translate($this->category);
+ }
+
+ public function getDimension()
+ {
+ return $this->dimension;
+ }
+
+ public function getOrder()
+ {
+ return $this->order;
+ }
+
+ public function getModule()
+ {
+ return $this->module;
+ }
+
+ public function getMenuTitle()
+ {
+ return $this->menuTitle;
+ }
+
+ public function getActionToLoadSubTables()
+ {
+ return $this->actionToLoadSubTables;
+ }
+
+ public static function factory($module, $action)
+ {
+ if (empty($module) || empty($action)) {
+ return;
+ }
+
+ try {
+ $plugin = PluginManager::getInstance()->getLoadedPlugin($module);
+ } catch (\Exception $e) {
+ return;
+ }
+
+ $reports = $plugin->findMultipleComponents('Reports', '\\Piwik\\Plugin\\Report');
+ $action = ucfirst($action);
+
+ foreach ($reports as $reportClass) {
+ if ($reportClass == 'Piwik\\Plugins\\' . $module . '\\Reports\\' . $action) {
+ return new $reportClass();
+ }
+ }
+ }
+
+ /** @return \Piwik\Plugin\Report[] */
+ public static function getAllReports()
+ {
+ $reports = PluginManager::getInstance()->findMultipleComponents('Reports', '\\Piwik\\Plugin\\Report');
+ $cache = new LanguageAwareStaticCache('Reports' . implode('', $reports));
+
+ if (!$cache->has()) {
+ $instances = array();
+
+ foreach ($reports as $report) {
+ $instances[] = new $report();
+ }
+
+ usort($instances, array('self', 'sort'));
+
+ $cache->set($instances);
+ }
+
+ return $cache->get();
+ }
+
+ /**
+ * API metadata are sorted by category/name,
+ * with a little tweak to replicate the standard Piwik category ordering
+ *
+ * @param Report $a
+ * @param Report $b
+ * @return int
+ */
+ private static function sort($a, $b)
+ {
+ return ($category = strcmp(array_search($a->category, self::$orderOfReports), array_search($b->category, self::$orderOfReports))) == 0
+ ? ($a->order < $b->order ? -1 : 1)
+ : $category;
+ }
+
+ private function getMetricTranslations($metricsToTranslate)
+ {
+ $translations = Metrics::getDefaultMetricTranslations();
+ $metrics = array();
+
+ foreach ($metricsToTranslate as $metric) {
+ if (!empty($translations[$metric])) {
+ $metrics[$metric] = $translations[$metric];
+ } else {
+ $metrics[$metric] = $metric;
+ }
+ }
+
+ return $metrics;
+ }
+}
diff --git a/core/Plugin/Segment.php b/core/Plugin/Segment.php
new file mode 100644
index 0000000000..4169d1453c
--- /dev/null
+++ b/core/Plugin/Segment.php
@@ -0,0 +1,156 @@
+<?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;
+
+/**
+ * @api
+ * @since 2.5.0
+ */
+class Segment
+{
+ const TYPE_DIMENSION = 'dimension';
+ const TYPE_METRIC = 'metric';
+
+ private $type;
+ private $category;
+ private $name;
+ private $segment;
+ private $sqlSegment;
+ private $sqlFilter;
+ private $sqlFilterValue;
+ private $acceptValues;
+ private $permission;
+
+ public function __construct()
+ {
+ $this->init();
+ }
+
+ protected function init()
+ {
+
+ }
+
+ /**
+ * @param string $acceptValues
+ */
+ public function setAcceptedValues($acceptValues)
+ {
+ $this->acceptValues = $acceptValues;
+ }
+
+ /**
+ * @param string $category
+ */
+ public function setCategory($category)
+ {
+ $this->category = $category;
+ }
+
+ /**
+ * @param string $name
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * @param string $segment
+ */
+ public function setSegment($segment)
+ {
+ $this->segment = $segment;
+ }
+
+ /**
+ * @param string|\Closure $sqlFilter
+ */
+ public function setSqlFilter($sqlFilter)
+ {
+ $this->sqlFilter = $sqlFilter;
+ }
+
+ /**
+ * @param string|array $sqlFilterValue
+ */
+ public function setSqlFilterValue($sqlFilterValue)
+ {
+ $this->sqlFilterValue = $sqlFilterValue;
+ }
+
+ /**
+ * @param string $sqlSegment
+ */
+ public function setSqlSegment($sqlSegment)
+ {
+ $this->sqlSegment = $sqlSegment;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSqlSegment()
+ {
+ return $this->sqlSegment;
+ }
+
+ /**
+ * @param string $type See constansts TYPE_*
+ */
+ public function setType($type)
+ {
+ $this->type = $type;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * @param bool $permission
+ */
+ public function setPermission($permission)
+ {
+ $this->permission = $permission;
+ }
+
+ public function toArray()
+ {
+ $segment = array(
+ 'type' => $this->type,
+ 'category' => $this->category,
+ 'name' => $this->name,
+ 'segment' => $this->segment,
+ 'sqlSegment' => $this->sqlSegment,
+ );
+
+ if (!empty($this->sqlFilter)) {
+ $segment['sqlFilter'] = $this->sqlFilter;
+ }
+
+ if (!empty($this->sqlFilterValue)) {
+ $segment['sqlFilterValue'] = $this->sqlFilterValue;
+ }
+
+ if (!empty($this->acceptValues)) {
+ $segment['acceptedValues'] = $this->acceptValues;
+ }
+
+ if (isset($this->permission)) {
+ $segment['permission'] = $this->permission;
+ }
+
+ return $segment;
+ }
+}
diff --git a/core/Plugin/Tasks.php b/core/Plugin/Tasks.php
index 1e357575a7..87b2c34d41 100644
--- a/core/Plugin/Tasks.php
+++ b/core/Plugin/Tasks.php
@@ -8,6 +8,7 @@
*/
namespace Piwik\Plugin;
+use Piwik\Development;
use Piwik\ScheduledTask;
use Piwik\ScheduledTime;
@@ -120,6 +121,8 @@ class Tasks
*/
protected function custom($objectOrClassName, $methodName, $methodParameter, $time, $priority = self::NORMAL_PRIORITY)
{
+ $this->checkIsValidTask($objectOrClassName, $methodName);
+
if (is_string($time)) {
$time = ScheduledTime::factory($time);
}
@@ -143,4 +146,9 @@ class Tasks
{
$this->tasks[] = $task;
}
+
+ private function checkIsValidTask($objectOrClassName, $methodName)
+ {
+ Development::checkMethodIsCallable($objectOrClassName, $methodName, 'The registered task is not valid as the method');
+ }
} \ No newline at end of file
diff --git a/core/Plugin/ViewDataTable.php b/core/Plugin/ViewDataTable.php
index 37dfce506a..6d1aa8e7f2 100644
--- a/core/Plugin/ViewDataTable.php
+++ b/core/Plugin/ViewDataTable.php
@@ -191,6 +191,38 @@ abstract class ViewDataTable implements ViewInterface
$this->requestConfig->apiMethodToRequestDataTable = $apiMethodToRequestDataTable;
+ $report = Report::factory($this->requestConfig->getApiModuleToRequest(), $this->requestConfig->getApiMethodToRequest());
+
+ if (!empty($report)) {
+ $subtable = $report->getActionToLoadSubTables();
+ if (!empty($subtable)) {
+ $this->config->subtable_controller_action = $subtable;
+ }
+
+ $relatedReports = $report->getRelatedReports();
+ if (!empty($relatedReports)) {
+ foreach ($relatedReports as $relatedReport) {
+ $widgetTitle = $relatedReport->getWidgetTitle();
+
+ if ($widgetTitle && Common::getRequestVar('widget', 0, 'int')) {
+ $relatedReportName = $widgetTitle;
+ } else {
+ $relatedReportName = $relatedReport->getName();
+ }
+
+ $this->config->addRelatedReport($relatedReport->getModule() . '.' . $relatedReport->getAction(),
+ $relatedReportName);
+ }
+ }
+
+ $metrics = $report->getMetrics();
+ if (!empty($metrics)) {
+ $this->config->addTranslations($metrics);
+ }
+
+ $report->configureView($this);
+ }
+
/**
* Triggered during {@link ViewDataTable} construction. Subscribers should customize
* the view based on the report that is being displayed.
diff --git a/core/Plugin/Widgets.php b/core/Plugin/Widgets.php
index 201fe743f6..0895b9ca01 100644
--- a/core/Plugin/Widgets.php
+++ b/core/Plugin/Widgets.php
@@ -8,6 +8,8 @@
*/
namespace Piwik\Plugin;
+use Piwik\Development;
+use Piwik\Plugin\Manager as PluginManager;
use Piwik\WidgetsList;
/**
@@ -20,10 +22,149 @@ use Piwik\WidgetsList;
*/
class Widgets
{
+ protected $category = '';
+ protected $widgets = array();
+
+ private $module = '';
+
+ public function __construct()
+ {
+ $this->module = $this->getModule();
+ }
+
+ public function getCategory()
+ {
+ return $this->category;
+ }
+
+ private function getModule()
+ {
+ $className = get_class($this);
+ $className = explode('\\', $className);
+
+ return $className[2];
+ }
+
/**
- * Configures the widgets. Here you can for instance add or remove widgets.
+ * @api
*/
- public function configure(WidgetsList $widgetsList)
+ protected function addWidget($name, $method, $parameters = array())
+ {
+ // to be developer friendly we could check whether such a method exists (in controller or widget) and if
+ // not throw an exception so the developer does not have to handle with typos etc. I do not want to do this
+ // right now because of performance but if we add a development setting in config we could do such check
+ $this->addWidgetWithCustomCategory($this->category, $name, $method, $parameters);
+ }
+
+ protected function addWidgetWithCustomCategory($category, $name, $method, $parameters = array())
{
+ $this->checkIsValidWidget($name, $method);
+
+ $this->widgets[] = array('category' => $category,
+ 'name' => $name,
+ 'params' => $parameters,
+ 'method' => $method,
+ 'module' => $this->module);
+ }
+
+ /**
+ * @api
+ */
+ protected function init()
+ {
+ }
+
+ public function getWidgets()
+ {
+ $this->widgets = array();
+
+ $this->init();
+
+ return $this->widgets;
+ }
+
+ /**
+ * Configures the widgets. Here you can for instance remove widgets.
+ */
+ public function configureWidgetsList(WidgetsList $widgetsList)
+ {
+
+ }
+
+ /**
+ * @return \Piwik\Plugin\Widgets[]
+ */
+ public static function getAllWidgets()
+ {
+ return PluginManager::getInstance()->findComponents('Widgets', 'Piwik\\Plugin\\Widgets');
+ }
+
+ public static function factory($module, $action)
+ {
+ if (empty($module) || empty($action)) {
+ return;
+ }
+
+ try {
+ $plugin = PluginManager::getInstance()->getLoadedPlugin($module);
+ } catch (\Exception $e) {
+ // we are not allowed to use possible widgets, plugin is not active
+ return;
+ }
+
+ /** @var Widgets $widgetContainer */
+ $widgetContainer = $plugin->findComponent('Widgets', 'Piwik\\Plugin\\Widgets');
+
+ if (empty($widgetContainer)) {
+ // plugin does not define any widgets, we cannot do anything
+ return;
+ }
+
+ if (!is_callable(array($widgetContainer, $action))) {
+ // widget does not implement such a method, we cannot do anything
+ return;
+ }
+
+ // the widget class implements such an action, but we have to check whether it is actually exposed and whether
+ // it was maybe disabled by another plugin, this is only possible by checking the widgetslist, unfortunately
+ if (!WidgetsList::isDefined($module, $action)) {
+ return;
+ }
+
+ return $widgetContainer;
+ }
+
+ private function checkIsValidWidget($name, $method)
+ {
+ if (!Development::isEnabled()) {
+ return;
+ }
+
+ if (empty($name)) {
+ Development::error('No name is defined for added widget having method "' . $method . '" in ' . get_class($this));
+ }
+
+ if (Development::isCallableMethod($this, $method)) {
+ return;
+ }
+
+ $controllerClass = '\\Piwik\\Plugins\\' . $this->module . '\\Controller';
+
+ if (!Development::methodExists($this, $method) &&
+ !Development::methodExists($controllerClass, $method)) {
+ Development::error('The added method "' . $method . '" neither exists in "' . get_class($this) . '" nor "' . $controllerClass . '". Make sure to define such a method.');
+ }
+
+ $definedInClass = get_class($this);
+
+ if (Development::methodExists($controllerClass, $method)) {
+ if (Development::isCallableMethod($controllerClass, $method)) {
+ return;
+ }
+
+ $definedInClass = $controllerClass;
+ }
+
+ Development::error('The method "' . $method . '" is not callable on "' . $definedInClass . '". Make sure the method is public.');
}
}
diff --git a/core/Settings/SystemSetting.php b/core/Settings/SystemSetting.php
index c7e1c93ad1..f26c979ae1 100644
--- a/core/Settings/SystemSetting.php
+++ b/core/Settings/SystemSetting.php
@@ -27,6 +27,7 @@ class SystemSetting extends Setting
* readable by everyone.
*
* @var bool
+ * @since 2.4.0
*/
public $readableByCurrentUser = false;
diff --git a/core/Tracker.php b/core/Tracker.php
index 16507a8d40..90ca70ff53 100644
--- a/core/Tracker.php
+++ b/core/Tracker.php
@@ -226,6 +226,7 @@ class Tracker
*/
public function main($args = null)
{
+
try {
$tokenAuth = $this->initRequests($args);
} catch (Exception $ex) {
@@ -252,6 +253,8 @@ class Tracker
$this->handleEmptyRequest(new Request($_GET + $_POST));
}
+ Piwik::postEvent('Tracker.end');
+
$this->end();
$this->flushOutputBuffer();
@@ -636,7 +639,7 @@ class Tracker
* Triggered before a new **visit tracking object** is created. Subscribers to this
* event can force the use of a custom visit tracking object that extends from
* {@link Piwik\Tracker\VisitInterface}.
- *
+ *
* @param \Piwik\Tracker\VisitInterface &$visit Initialized to null, but can be set to
* a new visit object. If it isn't modified
* Piwik uses the default class.
@@ -863,11 +866,11 @@ class Tracker
try {
if ($this->isVisitValid()) {
- $visit = $this->getNewVisitObject();
$request->setForcedVisitorId(self::$forcedVisitorId);
$request->setForceDateTime(self::$forcedDateTime);
$request->setForceIp(self::$forcedIpString);
+ $visit = $this->getNewVisitObject();
$visit->setRequest($request);
$visit->handle();
} else {
diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php
index b8949c0955..22c0107aec 100644
--- a/core/Tracker/Action.php
+++ b/core/Tracker/Action.php
@@ -12,6 +12,8 @@ namespace Piwik\Tracker;
use Exception;
use Piwik\Common;
use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugin\Manager;
use Piwik\Tracker;
/**
@@ -36,37 +38,71 @@ abstract class Action
const DB_COLUMN_CUSTOM_FLOAT = 'custom_float';
+ private static $factoryPriority = array(
+ self::TYPE_PAGE_URL, self::TYPE_SITE_SEARCH, self::TYPE_EVENT, self::TYPE_OUTLINK, self::TYPE_DOWNLOAD
+ );
+
/**
* Makes the correct Action object based on the request.
*
* @param Request $request
- * @return ActionClickUrl|ActionPageview|ActionSiteSearch
+ * @return Action
*/
static public function factory(Request $request)
{
- $downloadUrl = $request->getParam('download');
- if (!empty($downloadUrl)) {
- return new ActionClickUrl(self::TYPE_DOWNLOAD, $downloadUrl, $request);
+ /** @var Action[] $actions */
+ $actions = self::getAllActions($request);
+
+ foreach ($actions as $actionType) {
+ if (empty($action)) {
+ $action = $actionType;
+ continue;
+ }
+
+ $posPrevious = self::getPriority($action);
+ $posCurrent = self::getPriority($actionType);
+
+ if ($posCurrent > $posPrevious) {
+ $action = $actionType;
+ }
}
- $outlinkUrl = $request->getParam('link');
- if (!empty($outlinkUrl)) {
- return new ActionClickUrl(self::TYPE_OUTLINK, $outlinkUrl, $request);
+ if (!empty($action)) {
+ return $action;
}
- $url = $request->getParam('url');
+ return new ActionPageview($request);
+ }
+
+ private static function getPriority(Action $actionType)
+ {
+ $key = array_search($actionType->getActionType(), self::$factoryPriority);
- $eventCategory = $request->getParam('e_c');
- $eventAction = $request->getParam('e_a');
- if(strlen($eventCategory) > 0 && strlen($eventAction) > 0 ) {
- return new ActionEvent($eventCategory, $eventAction, $url, $request);
+ if (false === $key) {
+ return -1;
}
- $action = new ActionSiteSearch($url, $request);
- if ($action->isSearchDetected()) {
- return $action;
+ return $key;
+ }
+
+ public static function shouldHandle(Request $request)
+ {
+ return false;
+ }
+
+ static private function getAllActions(Request $request)
+ {
+ $actions = Manager::getInstance()->findMultipleComponents('Actions', '\\Piwik\\Tracker\\Action');
+ $instances = array();
+
+ foreach ($actions as $action) {
+ /** @var \Piwik\Tracker\Action $instance */
+ if ($action::shouldHandle($request)) {
+ $instances[] = new $action($request);
+ }
}
- return new ActionPageview($url, $request);
+
+ return $instances;
}
/**
@@ -85,7 +121,7 @@ abstract class Action
public function __construct($type, Request $request)
{
$this->actionType = $type;
- $this->request = $request;
+ $this->request = $request;
}
/**
@@ -120,7 +156,6 @@ abstract class Action
return false;
}
-
protected function setActionName($name)
{
$name = PageUrl::cleanupString((string)$name);
@@ -149,7 +184,7 @@ abstract class Action
if (!empty($url)) {
// normalize urls by stripping protocol and www
$url = PageUrl::normalizeUrl($url);
- return array($url['url'], Tracker\Action::TYPE_PAGE_URL, $url['prefixId']);
+ return array($url['url'], self::TYPE_PAGE_URL, $url['prefixId']);
}
return false;
}
@@ -161,7 +196,6 @@ abstract class Action
return (int)$idUrl;
}
-
public function getIdActionUrlForEntryAndExitIds()
{
return $this->getIdActionUrl();
@@ -225,10 +259,28 @@ abstract class Action
if(!empty($this->actionIdsCached)) {
return;
}
- $actions = $this->getActionsToLookup();
+
+ $actions = $this->getActionsToLookup();
+ $dimensions = ActionDimension::getAllDimensions();
+
+ foreach ($dimensions as $dimension) {
+ $value = $dimension->onLookupAction($this->request, $this);
+
+ if ($value !== false) {
+ $field = $dimension->getColumnName();
+
+ if (empty($field)) {
+ throw new Exception('Dimension ' . get_class($dimension) . ' does not define a field name');
+ }
+
+ $actions[$field] = array($value, $dimension->getActionId());
+ Common::printDebug("$field = $value");
+ }
+ }
+
$actions = array_filter($actions, 'count');
- if(empty($actions)) {
+ if (empty($actions)) {
return;
}
@@ -241,34 +293,39 @@ abstract class Action
/**
* Records in the DB the association between the visit and this action.
*
- * @param int $idVisit is the ID of the current visit in the DB table log_visit
- * @param $visitorIdCookie
* @param int $idReferrerActionUrl is the ID of the last action done by the current visit.
* @param $idReferrerActionName
- * @param int $timeSpentReferrerAction is the number of seconds since the last action was done.
- * It is directly related to idReferrerActionUrl.
+ * @param Visitor $visitor
*/
- public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idReferrerActionName, $timeSpentReferrerAction)
+ public function record(Visitor $visitor, $idReferrerActionUrl, $idReferrerActionName)
{
$this->loadIdsFromLogActionTable();
$visitAction = array(
- 'idvisit' => $idVisit,
- 'idsite' => $this->request->getIdSite(),
- 'idvisitor' => $visitorIdCookie,
- 'server_time' => Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()),
- 'idaction_url' => $this->getIdActionUrl(),
- 'idaction_url_ref' => $idReferrerActionUrl,
- 'idaction_name_ref' => $idReferrerActionName,
- 'time_spent_ref_action' => $timeSpentReferrerAction
+ 'idvisit' => $visitor->getVisitorColumn('idvisit'),
+ 'idsite' => $this->request->getIdSite(),
+ 'idvisitor' => $visitor->getVisitorColumn('idvisitor'),
+ 'idaction_url' => $this->getIdActionUrl(),
+ 'idaction_url_ref' => $idReferrerActionUrl,
+ 'idaction_name_ref' => $idReferrerActionName
);
+ $dimensions = ActionDimension::getAllDimensions();
+
+ foreach ($dimensions as $dimension) {
+ $value = $dimension->onNewAction($this->request, $visitor, $this);
+
+ if ($value !== false) {
+ $visitAction[$dimension->getColumnName()] = $value;
+ }
+ }
+
// idaction_name is NULLable. we only set it when applicable
- if($this->isActionHasActionName()) {
+ if ($this->isActionHasActionName()) {
$visitAction['idaction_name'] = (int)$this->getIdActionName();
}
- foreach($this->actionIdsCached as $field => $idAction) {
+ foreach ($this->actionIdsCached as $field => $idAction) {
$visitAction[$field] = ($idAction === false) ? 0 : $idAction;
}
@@ -284,9 +341,9 @@ abstract class Action
}
$visitAction = array_merge($visitAction, $customVariables);
- $fields = implode(", ", array_keys($visitAction));
- $bind = array_values($visitAction);
- $values = Common::getSqlStringFieldsArray($visitAction);
+ $fields = implode(", ", array_keys($visitAction));
+ $bind = array_values($visitAction);
+ $values = Common::getSqlStringFieldsArray($visitAction);
$sql = "INSERT INTO " . Common::prefixTable('log_link_visit_action') . " ($fields) VALUES ($values)";
Tracker::getDatabase()->query($sql, $bind);
@@ -312,8 +369,8 @@ abstract class Action
*/
protected function isActionHasActionName()
{
- return in_array($this->getActionType(), array(Tracker\Action::TYPE_PAGE_TITLE,
- Tracker\Action::TYPE_PAGE_URL,
- Tracker\Action::TYPE_SITE_SEARCH));
+ return in_array($this->getActionType(), array(self::TYPE_PAGE_TITLE,
+ self::TYPE_PAGE_URL,
+ self::TYPE_SITE_SEARCH));
}
}
diff --git a/core/Tracker/ActionPageview.php b/core/Tracker/ActionPageview.php
index 3dc5ab93fb..fa3d0146dc 100644
--- a/core/Tracker/ActionPageview.php
+++ b/core/Tracker/ActionPageview.php
@@ -20,10 +20,11 @@ class ActionPageview extends Action
{
protected $timeGeneration = false;
- function __construct($url, Request $request)
+ function __construct(Request $request)
{
parent::__construct(Action::TYPE_PAGE_URL, $request);
+ $url = $request->getParam('url');
$this->setActionUrl($url);
$actionName = $request->getParam('action_name');
@@ -41,12 +42,17 @@ class ActionPageview extends Action
);
}
- function getCustomFloatValue()
+ public function getCustomFloatValue()
{
return $this->request->getPageGenerationTime();
}
- protected function cleanupActionName($actionName)
+ public static function shouldHandle(Request $request)
+ {
+ return true;
+ }
+
+ private function cleanupActionName($actionName)
{
// get the delimiter, by default '/'; BC, we read the old action_category_delimiter first (see #1067)
$actionCategoryDelimiter = isset(Config::getInstance()->General['action_category_delimiter'])
diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php
index b2b0c03ba8..7f974619f3 100644
--- a/core/Tracker/GoalManager.php
+++ b/core/Tracker/GoalManager.php
@@ -10,8 +10,9 @@ namespace Piwik\Tracker;
use Exception;
use Piwik\Common;
-use Piwik\Config;
use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ConversionDimension;
+use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\CustomVariables\CustomVariables;
use Piwik\Tracker;
@@ -20,8 +21,6 @@ use Piwik\Tracker;
class GoalManager
{
// log_visit.visit_goal_buyer
- const TYPE_BUYER_NONE = 0;
- const TYPE_BUYER_ORDERED = 1;
const TYPE_BUYER_OPEN_CART = 2;
const TYPE_BUYER_ORDERED_AND_OPEN_CART = 3;
@@ -37,20 +36,24 @@ class GoalManager
const MAXIMUM_PRODUCT_CATEGORIES = 5;
public $idGoal;
public $requestIsEcommerce;
- public $isGoalAnOrder;
+ private $isGoalAnOrder;
/**
* @var Action
*/
protected $action = null;
protected $convertedGoals = array();
- protected $isThereExistingCartInVisit = false;
+
+ private $currentGoal = array();
+
/**
* @var Request
*/
protected $request;
protected $orderId;
+ protected $isThereExistingCartInVisit = false;
+
/**
* Constructor
* @param Request $request
@@ -58,37 +61,27 @@ class GoalManager
public function __construct(Request $request)
{
$this->request = $request;
- $this->init();
- }
+ $this->orderId = $request->getParam('ec_id');
+ $this->idGoal = $request->getParam('idgoal');
- function init()
- {
- $this->orderId = $this->request->getParam('ec_id');
$this->isGoalAnOrder = !empty($this->orderId);
- $this->idGoal = $this->request->getParam('idgoal');
$this->requestIsEcommerce = ($this->idGoal == 0);
}
- function getBuyerType($existingType = GoalManager::TYPE_BUYER_NONE)
+ public function isGoalAnOrder()
{
- // Was there a Cart for this visit prior to the order?
- $this->isThereExistingCartInVisit = in_array($existingType,
- array(GoalManager::TYPE_BUYER_OPEN_CART,
- GoalManager::TYPE_BUYER_ORDERED_AND_OPEN_CART));
+ return $this->isGoalAnOrder;
+ }
- if (!$this->requestIsEcommerce) {
- return $existingType;
- }
- if ($this->isGoalAnOrder) {
- return self::TYPE_BUYER_ORDERED;
- }
- // request is Add to Cart
- if ($existingType == self::TYPE_BUYER_ORDERED
- || $existingType == self::TYPE_BUYER_ORDERED_AND_OPEN_CART
- ) {
- return self::TYPE_BUYER_ORDERED_AND_OPEN_CART;
+ public function detectIsThereExistingCartInVisit($visitInformation)
+ {
+ if (!empty($visitInformation['visit_goal_buyer'])) {
+ $goalBuyer = $visitInformation['visit_goal_buyer'];
+ $types = array(GoalManager::TYPE_BUYER_OPEN_CART, GoalManager::TYPE_BUYER_ORDERED_AND_OPEN_CART);
+
+ // Was there a Cart for this visit prior to the order?
+ $this->isThereExistingCartInVisit = in_array($goalBuyer, $types);
}
- return self::TYPE_BUYER_OPEN_CART;
}
static public function getGoalDefinitions($idSite)
@@ -129,7 +122,7 @@ class GoalManager
* @throws Exception
* @return int Number of goals matched
*/
- function detectGoalsMatchingUrl($idSite, $action)
+ public function detectGoalsMatchingUrl($idSite, $action)
{
if (!Common::isGoalPluginEnabled()) {
return false;
@@ -165,7 +158,7 @@ class GoalManager
return count($this->convertedGoals) > 0;
}
- function detectGoalId($idSite)
+ public function detectGoalId($idSite)
{
if (!Common::isGoalPluginEnabled()) {
return false;
@@ -178,7 +171,6 @@ class GoalManager
$url = $this->request->getParam('url');
$goal['url'] = PageUrl::excludeQueryParametersFromUrl($url, $idSite);
- $goal['revenue'] = $this->getRevenue($this->request->getGoalRevenue($goal['revenue']));
$this->convertedGoals[] = $goal;
return true;
}
@@ -186,43 +178,23 @@ class GoalManager
/**
* Records one or several goals matched in this request.
*
- * @param int $idSite
+ * @param Visitor $visitor
* @param array $visitorInformation
* @param array $visitCustomVariables
* @param Action $action
*/
- public function recordGoals($idSite, $visitorInformation, $visitCustomVariables, $action)
+ public function recordGoals(Visitor $visitor, $visitorInformation, $visitCustomVariables, $action)
{
- $referrerTimestamp = $this->request->getParam('_refts');
- $referrerUrl = $this->request->getParam('_ref');
- $referrerCampaignName = trim(urldecode($this->request->getParam('_rcn')));
- $referrerCampaignKeyword = trim(urldecode($this->request->getParam('_rck')));
- $browserLanguage = $this->request->getBrowserLanguage();
-
- $location_country = isset($visitorInformation['location_country'])
- ? $visitorInformation['location_country']
- : Common::getCountry(
- $browserLanguage,
- $enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess'],
- $visitorInformation['location_ip']
- );
-
$goal = array(
- 'idvisit' => $visitorInformation['idvisit'],
- 'idsite' => $idSite,
- 'idvisitor' => $visitorInformation['idvisitor'],
- 'server_time' => Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']),
- 'location_country' => $location_country,
- 'visitor_returning' => $visitorInformation['visitor_returning'],
- 'visitor_days_since_first' => $visitorInformation['visitor_days_since_first'],
- 'visitor_days_since_order' => $visitorInformation['visitor_days_since_order'],
- 'visitor_count_visits' => $visitorInformation['visitor_count_visits'],
+ 'idvisit' => $visitorInformation['idvisit'],
+ 'idvisitor' => $visitorInformation['idvisitor'],
+ 'server_time' => Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time'])
);
- $extraLocationCols = array('location_region', 'location_city', 'location_latitude', 'location_longitude');
- foreach ($extraLocationCols as $col) {
- if (isset($visitorInformation[$col])) {
- $goal[$col] = $visitorInformation[$col];
+ foreach (VisitDimension::getAllDimensions() as $dimension) {
+ $value = $dimension->onAnyGoalConversion($this->request, $visitor, $action);
+ if (false !== $value) {
+ $goal[$dimension->getColumnName()] = $value;
}
}
@@ -244,60 +216,11 @@ class GoalManager
}
}
- // Attributing the correct Referrer to this conversion.
- // Priority order is as follows:
- // 0) In some cases, the campaign is not passed from the JS so we look it up from the current visit
- // 1) Campaign name/kwd parsed in the JS
- // 2) Referrer URL stored in the _ref cookie
- // 3) If no info from the cookie, attribute to the current visit referrer
-
- // 3) Default values: current referrer
- $type = $visitorInformation['referer_type'];
- $name = $visitorInformation['referer_name'];
- $keyword = $visitorInformation['referer_keyword'];
- $time = $visitorInformation['visit_first_action_time'];
-
- // 0) In some (unknown!?) cases the campaign is not found in the attribution cookie, but the URL ref was found.
- // In this case we look up if the current visit is credited to a campaign and will credit this campaign rather than the URL ref (since campaigns have higher priority)
- if (empty($referrerCampaignName)
- && $type == Common::REFERRER_TYPE_CAMPAIGN
- && !empty($name)
- ) {
- // Use default values per above
- } // 1) Campaigns from 1st party cookie
- elseif (!empty($referrerCampaignName)) {
- $type = Common::REFERRER_TYPE_CAMPAIGN;
- $name = $referrerCampaignName;
- $keyword = $referrerCampaignKeyword;
- $time = $referrerTimestamp;
- } // 2) Referrer URL parsing
- elseif (!empty($referrerUrl)) {
- $referrer = new Referrer();
- $referrer = $referrer->getReferrerInformation($referrerUrl, $currentUrl = '', $idSite);
-
- // if the parsed referrer is interesting enough, ie. website or search engine
- if (in_array($referrer['referer_type'], array(Common::REFERRER_TYPE_SEARCH_ENGINE, Common::REFERRER_TYPE_WEBSITE))) {
- $type = $referrer['referer_type'];
- $name = $referrer['referer_name'];
- $keyword = $referrer['referer_keyword'];
- $time = $referrerTimestamp;
- }
- }
- $this->setCampaignValuesToLowercase($type, $name, $keyword);
-
- $goal += array(
- 'referer_type' => $type,
- 'referer_name' => $name,
- 'referer_keyword' => $keyword,
- // this field is currently unused
- 'referer_visit_server_date' => date("Y-m-d", $time),
- );
-
// some goals are converted, so must be ecommerce Order or Cart Update
if ($this->requestIsEcommerce) {
- $this->recordEcommerceGoal($goal, $visitorInformation);
+ $this->recordEcommerceGoal($goal, $visitor, $action, $visitorInformation);
} else {
- $this->recordStandardGoals($goal, $action, $visitorInformation);
+ $this->recordStandardGoals($goal, $visitor, $action, $visitorInformation);
}
}
@@ -320,30 +243,35 @@ class GoalManager
* Will deal with 2 types of conversions: Ecommerce Order and Ecommerce Cart update (Add to cart, Update Cart etc).
*
* @param array $conversion
+ * @param Visitor $visitor
+ * @param Action $action
* @param array $visitInformation
*/
- protected function recordEcommerceGoal($conversion, $visitInformation)
+ protected function recordEcommerceGoal($conversion, Visitor $visitor, $action, $visitInformation)
{
if ($this->isThereExistingCartInVisit) {
Common::printDebug("There is an existing cart for this visit");
}
+
if ($this->isGoalAnOrder) {
- $conversion['idgoal'] = self::IDGOAL_ORDER;
+ $debugMessage = 'The conversion is an Ecommerce order';
+
$conversion['idorder'] = $this->orderId;
- $conversion['buster'] = Common::hashStringToInt($this->orderId);
- $conversion['revenue_subtotal'] = $this->getRevenue($this->request->getParam('ec_st'));
- $conversion['revenue_tax'] = $this->getRevenue($this->request->getParam('ec_tx'));
- $conversion['revenue_shipping'] = $this->getRevenue($this->request->getParam('ec_sh'));
- $conversion['revenue_discount'] = $this->getRevenue($this->request->getParam('ec_dt'));
+ $conversion['idgoal'] = self::IDGOAL_ORDER;
+ $conversion['buster'] = Common::hashStringToInt($this->orderId);
- $debugMessage = 'The conversion is an Ecommerce order';
+ $conversionDimensions = ConversionDimension::getAllDimensions();
+ $conversion = $this->triggerHookOnDimensions($conversionDimensions, 'onEcommerceOrderConversion', $visitor, $action, $conversion);
} // If Cart update, select current items in the previous Cart
else {
+ $debugMessage = 'The conversion is an Ecommerce Cart Update';
+
$conversion['buster'] = 0;
$conversion['idgoal'] = self::IDGOAL_CART;
- $debugMessage = 'The conversion is an Ecommerce Cart Update';
+
+ $conversionDimensions = ConversionDimension::getAllDimensions();
+ $conversion = $this->triggerHookOnDimensions($conversionDimensions, 'onEcommerceCartUpdateConversion', $visitor, $action, $conversion);
}
- $conversion['revenue'] = $this->getRevenue($this->request->getGoalRevenue($defaultRevenue = 0));
Common::printDebug($debugMessage . ':' . var_export($conversion, true));
@@ -355,11 +283,12 @@ class GoalManager
$itemsCount = 0;
foreach ($items as $item) {
- $itemsCount += $item[self::INTERNAL_ITEM_QUANTITY];
+ $itemsCount += $item[GoalManager::INTERNAL_ITEM_QUANTITY];
}
+
$conversion['items'] = $itemsCount;
- if($this->isThereExistingCartInVisit) {
+ if ($this->isThereExistingCartInVisit) {
$updateWhere = array(
'idvisit' => $visitInformation['idvisit'],
'idgoal' => self::IDGOAL_CART,
@@ -376,10 +305,10 @@ class GoalManager
/**
* Triggered after successfully persisting an ecommerce conversion.
- *
+ *
* _Note: Subscribers should be wary of doing any expensive computation here as it may slow
* the tracker down._
- *
+ *
* @param array $conversion The conversion entity that was just persisted. See what information
* it contains [here](/guides/persistence-and-the-mysql-backend#conversions).
* @param array $visitInformation The visit entity that we are tracking a conversion for. See what
@@ -392,7 +321,7 @@ class GoalManager
* Returns Items read from the request string
* @return array|bool
*/
- protected function getEcommerceItemsFromRequest()
+ private function getEcommerceItemsFromRequest()
{
$items = Common::unsanitizeInputValue($this->request->getParam('ec_items'));
if (empty($items)) {
@@ -520,7 +449,7 @@ class GoalManager
* @param array $items
* @return array $cleanedItems
*/
- protected function getCleanedEcommerceItems($items)
+ private function getCleanedEcommerceItems($items)
{
// Clean up the items array
$cleanedItems = array();
@@ -718,21 +647,31 @@ class GoalManager
return $newRow;
}
+ public function getGoalColumn($column)
+ {
+ if (array_key_exists($column, $this->currentGoal)) {
+ return $this->currentGoal[$column];
+ }
+
+ return false;
+ }
+
/**
* Records a standard non-Ecommerce goal in the DB (URL/Title matching),
* linking the conversion to the action that triggered it
* @param $goal
+ * @param Visitor $visitor
* @param Action $action
* @param $visitorInformation
*/
- protected function recordStandardGoals($goal, $action, $visitorInformation)
+ protected function recordStandardGoals($goal, Visitor $visitor, $action, $visitorInformation)
{
foreach ($this->convertedGoals as $convertedGoal) {
+ $this->currentGoal = $convertedGoal;
Common::printDebug("- Goal " . $convertedGoal['idgoal'] . " matched. Recording...");
$conversion = $goal;
$conversion['idgoal'] = $convertedGoal['idgoal'];
$conversion['url'] = $convertedGoal['url'];
- $conversion['revenue'] = $this->getRevenue($convertedGoal['revenue']);
if (!is_null($action)) {
$conversion['idaction_url'] = $action->getIdActionUrl();
@@ -744,6 +683,9 @@ class GoalManager
? '0'
: $visitorInformation['visit_last_action_time'];
+ $conversionDimensions = ConversionDimension::getAllDimensions();
+ $conversion = $this->triggerHookOnDimensions($conversionDimensions, 'onGoalConversion', $visitor, $action, $conversion);
+
$this->insertNewConversion($conversion, $visitorInformation);
/**
@@ -841,23 +783,6 @@ class GoalManager
}
/**
- * @param $type
- * @param $name
- * @param $keyword
- */
- protected function setCampaignValuesToLowercase($type, &$name, &$keyword)
- {
- if ($type === Common::REFERRER_TYPE_CAMPAIGN) {
- if (!empty($name)) {
- $name = Common::mb_strtolower($name);
- }
- if (!empty($keyword)) {
- $keyword = Common::mb_strtolower($keyword);
- }
- }
- }
-
- /**
* @param $goal
* @param $pattern_type
* @param $url
@@ -902,4 +827,30 @@ class GoalManager
}
return $match;
}
+
+
+ /**
+ * @param ConversionDimension[] $dimensions
+ * @param string $hook
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param array|null $valuesToUpdate If null, $this->visitorInfo will be updated
+ *
+ * @return array|null The updated $valuesToUpdate or null if no $valuesToUpdate given
+ */
+ private function triggerHookOnDimensions($dimensions, $hook, $visitor, $action, $valuesToUpdate)
+ {
+ foreach ($dimensions as $dimension) {
+ $value = $dimension->$hook($this->request, $visitor, $action, $this);
+
+ if ($value !== false) {
+ $fieldName = $dimension->getColumnName();
+ $visitor->setVisitorColumn($fieldName, $value);
+
+ $valuesToUpdate[$fieldName] = $value;
+ }
+ }
+
+ return $valuesToUpdate;
+ }
}
diff --git a/core/Tracker/Request.php b/core/Tracker/Request.php
index fe54533e06..ccd044320d 100644
--- a/core/Tracker/Request.php
+++ b/core/Tracker/Request.php
@@ -300,6 +300,11 @@ class Request
return $value;
}
+ public function getParams()
+ {
+ return $this->params;
+ }
+
public function getCurrentTimestamp()
{
return $this->timestamp;
@@ -518,31 +523,6 @@ class Request
return $this->forcedVisitorId;
}
- public function overrideLocation(&$visitorInfo)
- {
- if (!$this->isAuthenticated()) {
- return;
- }
-
- // check for location override query parameters (ie, lat, long, country, region, city)
- static $locationOverrideParams = array(
- 'country' => array('string', 'location_country'),
- 'region' => array('string', 'location_region'),
- 'city' => array('string', 'location_city'),
- 'lat' => array('float', 'location_latitude'),
- 'long' => array('float', 'location_longitude'),
- );
- foreach ($locationOverrideParams as $queryParamName => $info) {
- list($type, $visitorInfoKey) = $info;
-
- $value = Common::getRequestVar($queryParamName, false, $type, $this->params);
- if (!empty($value)) {
- $visitorInfo[$visitorInfoKey] = $value;
- }
- }
- return;
- }
-
public function getPlugins()
{
static $pluginsInOrder = array('fla', 'java', 'dir', 'qt', 'realp', 'pdf', 'wma', 'gears', 'ag', 'cookie');
diff --git a/core/Tracker/Settings.php b/core/Tracker/Settings.php
index e524f623a3..2d8299581d 100644
--- a/core/Tracker/Settings.php
+++ b/core/Tracker/Settings.php
@@ -8,11 +8,9 @@
*/
namespace Piwik\Tracker;
-use Piwik\DeviceDetectorCache;
+use Piwik\Tracker;
use Piwik\DeviceDetectorFactory;
use Piwik\SettingsPiwik;
-use Piwik\Tracker;
-use DeviceDetector\DeviceDetector;
class Settings
{
@@ -20,17 +18,18 @@ class Settings
function __construct(Request $request, $ip)
{
- $this->request = $request;
+ $this->request = $request;
$this->ipAddress = $ip;
- $this->params = array();
+ $this->configId = null;
}
- function getInfo()
+ function getConfigId()
{
- if(empty($this->params)) {
+ if (empty($this->configId)) {
$this->loadInfo();
}
- return $this->params;
+
+ return $this->configId;
}
protected function loadInfo()
@@ -38,18 +37,17 @@ class Settings
list($plugin_Flash, $plugin_Java, $plugin_Director, $plugin_Quicktime, $plugin_RealPlayer, $plugin_PDF,
$plugin_WindowsMedia, $plugin_Gears, $plugin_Silverlight, $plugin_Cookie) = $this->request->getPlugins();
- $resolution = $this->request->getParam('res');
$userAgent = $this->request->getUserAgent();
$deviceDetector = DeviceDetectorFactory::getInstance($userAgent);
+ $aBrowserInfo = $deviceDetector->getClient();
- $aBrowserInfo = $deviceDetector->getClient();
if ($aBrowserInfo['type'] != 'browser') {
// for now only track browsers
unset($aBrowserInfo);
}
- $browserName = !empty($aBrowserInfo['short_name']) ? $aBrowserInfo['short_name'] : 'UNK';
+ $browserName = !empty($aBrowserInfo['short_name']) ? $aBrowserInfo['short_name'] : 'UNK';
$browserVersion = !empty($aBrowserInfo['version']) ? $aBrowserInfo['version'] : '';
if ($deviceDetector->isBot()) {
@@ -60,7 +58,8 @@ class Settings
}
$browserLang = substr($this->request->getBrowserLanguage(), 0, 20); // limit the length of this string to match db
- $configurationHash = $this->getConfigHash(
+
+ $this->configId = $this->getConfigHash(
$os,
$browserName,
$browserVersion,
@@ -76,32 +75,8 @@ class Settings
$plugin_Cookie,
$this->ipAddress,
$browserLang);
-
- $this->params = array(
- 'config_id' => $configurationHash,
- 'config_os' => $os,
- 'config_os_version' => $deviceDetector->getOs('version'),
- 'config_browser_name' => $browserName,
- 'config_browser_version' => $browserVersion,
- 'config_device_type' => $deviceDetector->getDevice(),
- 'config_device_model' => $deviceDetector->getModel(),
- 'config_device_brand' => $deviceDetector->getBrand(),
- 'config_resolution' => $resolution,
- 'config_pdf' => $plugin_PDF,
- 'config_flash' => $plugin_Flash,
- 'config_java' => $plugin_Java,
- 'config_director' => $plugin_Director,
- 'config_quicktime' => $plugin_Quicktime,
- 'config_realplayer' => $plugin_RealPlayer,
- 'config_windowsmedia' => $plugin_WindowsMedia,
- 'config_gears' => $plugin_Gears,
- 'config_silverlight' => $plugin_Silverlight,
- 'config_cookie' => $plugin_Cookie,
- 'location_browser_lang' => $browserLang,
- );
}
-
/**
* Returns a 64-bit hash of all the configuration settings
* @param $os
@@ -126,7 +101,7 @@ class Settings
// prevent the config hash from being the same, across different Piwik instances
// (limits ability of different Piwik instances to cross-match users)
$salt = SettingsPiwik::getSalt();
-
+
$configString =
$os
. $browserName . $browserVersion
@@ -134,9 +109,9 @@ class Settings
. $ip
. $browserLang
. $salt;
-
+
$hash = md5($configString, $raw_output = true);
-
+
return substr($hash, 0, Tracker::LENGTH_BINARY_ID);
}
-}
+} \ No newline at end of file
diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php
index 3ed13ce7ca..bada2f794a 100644
--- a/core/Tracker/Visit.php
+++ b/core/Tracker/Visit.php
@@ -13,7 +13,7 @@ use Piwik\Common;
use Piwik\Config;
use Piwik\IP;
use Piwik\Piwik;
-use Piwik\Plugins\CustomVariables\CustomVariables;
+use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Tracker;
/**
@@ -49,7 +49,6 @@ class Visit implements VisitInterface
*/
protected $userSettings;
protected $visitorCustomVariables = array();
- protected $visitorKnown;
/**
* @param Request $request
@@ -82,10 +81,9 @@ class Visit implements VisitInterface
public function handle()
{
// the IP is needed by isExcluded() and GoalManager->recordGoals()
- $ip = $this->request->getIp();
- $this->visitorInfo['location_ip'] = $ip;
+ $this->visitorInfo['location_ip'] = $this->request->getIp();
- $excluded = new VisitExcluded($this->request, $ip);
+ $excluded = new VisitExcluded($this->request, $this->visitorInfo['location_ip']);
if ($excluded->isExcluded()) {
return;
}
@@ -93,9 +91,9 @@ class Visit implements VisitInterface
/**
* Triggered after visits are tested for exclusion so plugins can modify the IP address
* persisted with a visit.
- *
+ *
* This event is primarily used by the **PrivacyManager** plugin to anonymize IP addresses.
- *
+ *
* @param string &$ip The visitor's IP address.
*/
Piwik::postEvent('Tracker.setVisitorIp', array(&$this->visitorInfo['location_ip']));
@@ -117,7 +115,7 @@ class Visit implements VisitInterface
$someGoalsConverted = true;
// Mark the visit as Converted only if it is an order (not for a Cart update)
- if ($this->goalManager->isGoalAnOrder) {
+ if ($this->goalManager->isGoalAnOrder()) {
$visitIsConverted = true;
}
} // this request is from the JS call to piwikTracker.trackGoal()
@@ -143,13 +141,13 @@ class Visit implements VisitInterface
/***
* Visitor recognition
*/
- $visitor = new Visitor($this->request, $this->getSettingsObject(), $this->visitorInfo, $this->visitorCustomVariables);
+ $visitorId = $this->getSettingsObject()->getConfigId();
+ $visitor = new Visitor($this->request, $visitorId, $this->visitorInfo, $this->visitorCustomVariables);
$visitor->recognize();
- $this->visitorKnown = $visitor->isVisitorKnown();
$this->visitorInfo = $visitor->getVisitorInfo();
- $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit();
+ $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit($visitor);
if (!$isLastActionInTheSameVisit) {
Common::printDebug("Visitor detected, but last action was more than 30 minutes ago...");
@@ -161,20 +159,16 @@ class Visit implements VisitInterface
// )
// AND
// - the last page view for this visitor was less than 30 minutes ago @see isLastActionInTheSameVisit()
- if ($this->isVisitorKnown()
+ if ($visitor->isVisitorKnown()
&& $isLastActionInTheSameVisit
) {
- $idReferrerActionUrl = $this->visitorInfo['visit_exit_idaction_url'];
+ $idReferrerActionUrl = $this->visitorInfo['visit_exit_idaction_url'];
$idReferrerActionName = $this->visitorInfo['visit_exit_idaction_name'];
try {
- $this->handleExistingVisit($action, $visitIsConverted);
+ $this->goalManager->detectIsThereExistingCartInVisit($this->visitorInfo);
+ $this->handleExistingVisit($visitor, $action, $visitIsConverted);
if (!is_null($action)) {
- $action->record($this->visitorInfo['idvisit'],
- $this->visitorInfo['idvisitor'],
- $idReferrerActionUrl,
- $idReferrerActionName,
- $this->visitorInfo['time_spent_ref_action']
- );
+ $action->record($visitor, $idReferrerActionUrl, $idReferrerActionName);
}
} catch (VisitorNotFoundInDb $e) {
@@ -191,7 +185,7 @@ class Visit implements VisitInterface
} // When the row wasn't found in the logs, and this is a pageview or
// goal matching URL, we force a new visitor
else {
- $this->visitorKnown = false;
+ $visitor->setIsVisitorKnown(false);
}
}
}
@@ -200,12 +194,12 @@ class Visit implements VisitInterface
// - the visitor has the Piwik cookie but the last action was performed more than 30 min ago @see isLastActionInTheSameVisit()
// - the visitor doesn't have the Piwik cookie, and couldn't be matched in @see recognizeTheVisitor()
// - the visitor does have the Piwik cookie but the idcookie and idvisit found in the cookie didn't match to any existing visit in the DB
- if (!$this->isVisitorKnown()
+ if (!$visitor->isVisitorKnown()
|| !$isLastActionInTheSameVisit
) {
- $this->handleNewVisit($action, $visitIsConverted);
+ $this->handleNewVisit($visitor, $action, $visitIsConverted);
if (!is_null($action)) {
- $action->record($this->visitorInfo['idvisit'], $this->visitorInfo['idvisitor'], 0, 0, 0);
+ $action->record($visitor, 0, 0);
}
}
@@ -215,7 +209,7 @@ class Visit implements VisitInterface
// record the goals if applicable
if ($someGoalsConverted) {
$this->goalManager->recordGoals(
- $this->request->getIdSite(),
+ $visitor,
$this->visitorInfo,
$this->visitorCustomVariables,
$action
@@ -231,19 +225,21 @@ class Visit implements VisitInterface
* 1) Insert the new action
* 2) Update the visit information
*
+ * @param Visitor $visitor
* @param Action $action
* @param $visitIsConverted
* @throws VisitorNotFoundInDb
*/
- protected function handleExistingVisit($action, $visitIsConverted)
+ protected function handleExistingVisit($visitor, $action, $visitIsConverted)
{
Common::printDebug("Visit is known (IP = " . IP::N2P($this->getVisitorIp()) . ")");
- $valuesToUpdate = $this->getExistingVisitFieldsToUpdate($action, $visitIsConverted);
+ $valuesToUpdate = $this->getExistingVisitFieldsToUpdate($visitor, $action, $visitIsConverted);
+ // TODO we should not have to sync this->visitorInfo and $visitor columns.
+ // TODO it should be its own dimension
$this->visitorInfo['time_spent_ref_action'] = $this->getTimeSpentReferrerAction();
-
- $this->request->overrideLocation($valuesToUpdate);
+ $visitor->setVisitorColumn('time_spent_ref_action', $this->visitorInfo['time_spent_ref_action']);
// update visitorInfo
foreach ($valuesToUpdate AS $name => $value) {
@@ -253,10 +249,10 @@ class Visit implements VisitInterface
/**
* Triggered before a [visit entity](/guides/persistence-and-the-mysql-backend#visits) is updated when
* tracking an action for an existing visit.
- *
+ *
* This event can be used to modify the visit properties that will be updated before the changes
* are persisted.
- *
+ *
* @param array &$valuesToUpdate Visit entity properties that will be updated.
* @param array $visit The entire visit entity. Read [this](/guides/persistence-and-the-mysql-backend#visits)
* to see what it contains.
@@ -264,6 +260,9 @@ class Visit implements VisitInterface
Piwik::postEvent('Tracker.existingVisitInformation', array(&$valuesToUpdate, $this->visitorInfo));
$this->updateExistingVisit($valuesToUpdate);
+
+ $this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp();
+ $visitor->setVisitorColumn('visit_last_action_time', $this->visitorInfo['visit_last_action_time']);
}
/**
@@ -289,27 +288,35 @@ class Visit implements VisitInterface
*
* 2) Insert the visit information
*
+ * @param Visitor $visitor
* @param Action $action
* @param bool $visitIsConverted
*/
- protected function handleNewVisit($action, $visitIsConverted)
+ protected function handleNewVisit($visitor, $action, $visitIsConverted)
{
Common::printDebug("New Visit (IP = " . IP::N2P($this->getVisitorIp()) . ")");
- $this->visitorInfo = $this->getNewVisitorInformation($action);
+ $this->visitorInfo = $this->getNewVisitorInformation($visitor);
// Add Custom variable key,value to the visitor array
$this->visitorInfo = array_merge($this->visitorInfo, $this->visitorCustomVariables);
- $this->visitorInfo['visit_goal_converted'] = $visitIsConverted ? 1 : 0;
+ $visitor->clearVisitorInfo();
+ foreach ($this->visitorInfo as $key => $value) {
+ $visitor->setVisitorColumn($key, $value);
+ }
+
+ $dimensions = VisitDimension::getAllDimensions();
+
+ $this->triggerHookOnDimensions($dimensions, 'onNewVisit', $visitor, $action);
- $this->visitorInfo['referer_name'] = substr($this->visitorInfo['referer_name'], 0, 70);
- $this->visitorInfo['referer_keyword'] = substr($this->visitorInfo['referer_keyword'], 0, 255);
- $this->visitorInfo['config_resolution'] = substr($this->visitorInfo['config_resolution'], 0, 9);
+ if ($visitIsConverted) {
+ $this->triggerHookOnDimensions($dimensions, 'onConvertedVisit', $visitor, $action);
+ }
/**
* Triggered before a new [visit entity](/guides/persistence-and-the-mysql-backend#visits) is persisted.
- *
+ *
* This event can be used to modify the visit entity or add new information to it before it is persisted.
* The UserCountry plugin, for example, uses this event to add location information for each visit.
*
@@ -319,7 +326,6 @@ class Visit implements VisitInterface
*/
Piwik::postEvent('Tracker.newVisitorInformation', array(&$this->visitorInfo, $this->request));
- $this->request->overrideLocation($this->visitorInfo);
$this->printVisitorInformation();
$idVisit = $this->insertNewVisit( $this->visitorInfo );
@@ -328,19 +334,9 @@ class Visit implements VisitInterface
$this->visitorInfo['visit_first_action_time'] = $this->request->getCurrentTimestamp();
$this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp();
- }
-
- static private function cleanupVisitTotalTime($t)
- {
- $t = (int)$t;
- if ($t < 0) {
- $t = 0;
- }
- $smallintMysqlLimit = 65534;
- if ($t > $smallintMysqlLimit) {
- $t = $smallintMysqlLimit;
- }
- return $t;
+ $visitor->setVisitorColumn('idvisit', $this->visitorInfo['idvisit']);
+ $visitor->setVisitorColumn('visit_first_action_time', $this->visitorInfo['visit_first_action_time']);
+ $visitor->setVisitorColumn('visit_last_action_time', $this->visitorInfo['visit_last_action_time']);
}
/**
@@ -348,17 +344,19 @@ class Visit implements VisitInterface
*
* @return string binary
*/
- protected function getVisitorIdcookie()
+ protected function getVisitorIdcookie(Visitor $visitor)
{
- if ($this->isVisitorKnown()) {
+ if ($visitor->isVisitorKnown()) {
return $this->visitorInfo['idvisitor'];
}
+
// If the visitor had a first party ID cookie, then we use this value
if (!empty($this->visitorInfo['idvisitor'])
&& strlen($this->visitorInfo['idvisitor']) == Tracker::LENGTH_BINARY_ID
) {
return $this->visitorInfo['idvisitor'];
}
+
return Common::hex2bin($this->generateUniqueVisitorId());
}
@@ -398,20 +396,13 @@ class Visit implements VisitInterface
* Returns true if the last action was done during the last 30 minutes
* @return bool
*/
- protected function isLastActionInTheSameVisit()
+ protected function isLastActionInTheSameVisit(Visitor $visitor)
{
- return isset($this->visitorInfo['visit_last_action_time'])
- && ($this->visitorInfo['visit_last_action_time']
- > ($this->request->getCurrentTimestamp() - Config::getInstance()->Tracker['visit_standard_length']));
- }
+ $lastActionTime = $visitor->getVisitorColumn('visit_last_action_time');
- /**
- * Returns true if the recognizeTheVisitor() method did recognize the visitor
- * @return bool
- */
- protected function isVisitorKnown()
- {
- return $this->visitorKnown === true;
+ return isset($lastActionTime)
+ && false !== $lastActionTime
+ && ($lastActionTime > ($this->request->getCurrentTimestamp() - Config::getInstance()->Tracker['visit_standard_length']));
}
// is the referrer host any of the registered URLs for this website?
@@ -475,8 +466,6 @@ class Visit implements VisitInterface
$result = Tracker::getDatabase()->query($sqlQuery, $sqlBind);
- $this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp();
-
// Debug output
if (isset($valuesToUpdate['idvisitor'])) {
$valuesToUpdate['idvisitor'] = bin2hex($valuesToUpdate['idvisitor']);
@@ -501,171 +490,71 @@ class Visit implements VisitInterface
Common::printDebug($debugVisitInfo);
}
- protected function getNewVisitorInformation($action)
+ protected function getNewVisitorInformation($visitor)
{
- $actionType = $idActionName = $idActionUrl = false;
- if($action) {
- $idActionUrl = $action->getIdActionUrlForEntryAndExitIds();
- $idActionName = $action->getIdActionNameForEntryAndExitIds();
- $actionType = $action->getActionType();
- }
-
- $daysSinceFirstVisit = $this->request->getDaysSinceFirstVisit();
- $visitCount = $this->request->getVisitCount();
- $daysSinceLastVisit = $this->request->getDaysSinceLastVisit();
-
- $daysSinceLastOrder = $this->request->getDaysSinceLastOrder();
- $isReturningCustomer = ($daysSinceLastOrder !== false);
-
- if ($daysSinceLastOrder === false) {
- $daysSinceLastOrder = 0;
- }
-
- // User settings
- $userInfo = $this->getSettingsObject();
- $userInfo = $userInfo->getInfo();
-
- // Referrer data
- $referrer = new Referrer();
- $referrerUrl = $this->request->getParam('urlref');
- $currentUrl = $this->request->getParam('url');
- $referrerInfo = $referrer->getReferrerInformation($referrerUrl, $currentUrl, $this->request->getIdSite());
-
- $visitorReturning = $isReturningCustomer
- ? 2 /* Returning customer */
- : ($visitCount > 1 || $this->isVisitorKnown() || $daysSinceLastVisit > 0
- ? 1 /* Returning */
- : 0 /* New */);
- $defaultTimeOnePageVisit = Config::getInstance()->Tracker['default_time_one_page_visit'];
-
return array(
- 'idsite' => $this->request->getIdSite(),
- 'visitor_localtime' => $this->request->getLocalTime(),
- 'idvisitor' => $this->getVisitorIdcookie(),
- 'visitor_returning' => $visitorReturning,
- 'visitor_count_visits' => $visitCount,
- 'visitor_days_since_last' => $daysSinceLastVisit,
- 'visitor_days_since_order' => $daysSinceLastOrder,
- 'visitor_days_since_first' => $daysSinceFirstVisit,
- 'visit_first_action_time' => Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()),
- 'visit_last_action_time' => Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()),
- 'visit_entry_idaction_url' => (int)$idActionUrl,
- 'visit_entry_idaction_name' => (int)$idActionName,
- 'visit_exit_idaction_url' => (int)$idActionUrl,
- 'visit_exit_idaction_name' => (int)$idActionName,
- 'visit_total_actions' => in_array($actionType,
- array(Action::TYPE_PAGE_URL,
- Action::TYPE_DOWNLOAD,
- Action::TYPE_OUTLINK,
- Action::TYPE_SITE_SEARCH,
- Action::TYPE_EVENT))
- ? 1 : 0, // if visit starts with something else (e.g. ecommerce order), don't record as an action
- 'visit_total_searches' => $actionType == Action::TYPE_SITE_SEARCH ? 1 : 0,
- 'visit_total_events' => $actionType == Action::TYPE_EVENT ? 1 : 0,
- 'visit_total_time' => self::cleanupVisitTotalTime($defaultTimeOnePageVisit),
- 'visit_goal_buyer' => $this->goalManager->getBuyerType(),
- 'referer_type' => $referrerInfo['referer_type'],
- 'referer_name' => $referrerInfo['referer_name'],
- 'referer_url' => $referrerInfo['referer_url'],
- 'referer_keyword' => $referrerInfo['referer_keyword'],
- 'config_id' => $userInfo['config_id'],
- 'config_os' => $userInfo['config_os'],
- 'config_os_version' => $userInfo['config_os_version'],
- 'config_browser_name' => $userInfo['config_browser_name'],
- 'config_browser_version' => $userInfo['config_browser_version'],
- 'config_resolution' => $userInfo['config_resolution'],
- 'config_device_type' => $userInfo['config_device_type'],
- 'config_device_model' => $userInfo['config_device_model'],
- 'config_device_brand' => $userInfo['config_device_brand'],
- 'config_pdf' => $userInfo['config_pdf'],
- 'config_flash' => $userInfo['config_flash'],
- 'config_java' => $userInfo['config_java'],
- 'config_director' => $userInfo['config_director'],
- 'config_quicktime' => $userInfo['config_quicktime'],
- 'config_realplayer' => $userInfo['config_realplayer'],
- 'config_windowsmedia' => $userInfo['config_windowsmedia'],
- 'config_gears' => $userInfo['config_gears'],
- 'config_silverlight' => $userInfo['config_silverlight'],
- 'config_cookie' => $userInfo['config_cookie'],
- 'location_ip' => $this->getVisitorIp(),
- 'location_browser_lang' => $userInfo['location_browser_lang'],
+ 'idvisitor' => $this->getVisitorIdcookie($visitor),
+ 'config_id' => $this->getSettingsObject()->getConfigId(),
+ 'location_ip' => $this->getVisitorIp(),
);
}
/**
* Gather fields=>values that needs to be updated for the existing visit in log_visit
*
- * @param $action
+ * @param Visitor $visitor
+ * @param Action|null $action
* @param $visitIsConverted
* @return array
*/
- protected function getExistingVisitFieldsToUpdate($action, $visitIsConverted)
+ protected function getExistingVisitFieldsToUpdate($visitor, $action, $visitIsConverted)
{
$valuesToUpdate = array();
- if ($action) {
- $idActionUrl = $action->getIdActionUrlForEntryAndExitIds();
- $idActionName = $action->getIdActionNameForEntryAndExitIds();
- $actionType = $action->getActionType();
-
- if ($idActionName !== false) {
- $valuesToUpdate['visit_exit_idaction_name'] = $idActionName;
- }
-
- $incrementActions = false;
- if ($idActionUrl !== false) {
- $valuesToUpdate['visit_exit_idaction_url'] = $idActionUrl;
- $incrementActions = true;
- }
- if ($actionType == Action::TYPE_SITE_SEARCH) {
- $valuesToUpdate['visit_total_searches'] = 'visit_total_searches + 1';
- $incrementActions = true;
- } else if ($actionType == Action::TYPE_EVENT) {
- $valuesToUpdate['visit_total_events'] = 'visit_total_events + 1';
- $incrementActions = true;
- }
-
- if ($incrementActions) {
- $valuesToUpdate['visit_total_actions'] = 'visit_total_actions + 1';
- }
- }
-
- $datetimeServer = Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp());
- $valuesToUpdate['visit_last_action_time'] = $datetimeServer;
-
- // Add 1 so it's always > 0
- $visitTotalTime = 1 + $this->request->getCurrentTimestamp() - $this->visitorInfo['visit_first_action_time'];
- $valuesToUpdate['visit_total_time'] = self::cleanupVisitTotalTime($visitTotalTime);
-
- // Goal conversion
- if ($visitIsConverted) {
- $valuesToUpdate['visit_goal_converted'] = 1;
- // If a pageview and goal conversion in the same second, with previously a goal conversion recorded
- // the request would not "update" the row since all values are the same as previous
- // therefore the request below throws exception, instead we make sure the UPDATE will affect the row
- $valuesToUpdate['visit_total_time'] = self::cleanupVisitTotalTime(
- $valuesToUpdate['visit_total_time']
- + $this->goalManager->idGoal
- // +2 to offset idgoal=-1 and idgoal=0
- + 2);
- }
-
// Might update the idvisitor when it was forced or overwritten for this visit
if (strlen($this->visitorInfo['idvisitor']) == Tracker::LENGTH_BINARY_ID) {
$valuesToUpdate['idvisitor'] = $this->visitorInfo['idvisitor'];
+ $visitor->setVisitorColumn('idvisitor', $this->visitorInfo['idvisitor']);
}
- // Ecommerce buyer status
- $visitEcommerceStatus = $this->goalManager->getBuyerType($this->visitorInfo['visit_goal_buyer']);
+ $dimensions = VisitDimension::getAllDimensions();
+ $valuesToUpdate = $this->triggerHookOnDimensions($dimensions, 'onExistingVisit', $visitor, $action, $valuesToUpdate);
- if($visitEcommerceStatus != GoalManager::TYPE_BUYER_NONE
- // only update if the value has changed (prevents overwriting the value in case a request has updated it in the meantime)
- && $visitEcommerceStatus != $this->visitorInfo['visit_goal_buyer']) {
- $valuesToUpdate['visit_goal_buyer'] = $visitEcommerceStatus;
+ if ($visitIsConverted) {
+ $valuesToUpdate = $this->triggerHookOnDimensions($dimensions, 'onConvertedVisit', $visitor, $action, $valuesToUpdate);
}
// Custom Variables overwrite previous values on each page view
$valuesToUpdate = array_merge($valuesToUpdate, $this->visitorCustomVariables);
return $valuesToUpdate;
}
+
+ /**
+ * @param VisitDimension[] $dimensions
+ * @param string $hook
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param array|null $valuesToUpdate If null, $this->visitorInfo will be updated
+ *
+ * @return array|null The updated $valuesToUpdate or null if no $valuesToUpdate given
+ */
+ private function triggerHookOnDimensions($dimensions, $hook, $visitor, $action, $valuesToUpdate = null)
+ {
+ foreach ($dimensions as $dimension) {
+ $value = $dimension->$hook($this->request, $visitor, $action);
+
+ if ($value !== false) {
+ $fieldName = $dimension->getColumnName();
+ $visitor->setVisitorColumn($fieldName, $value);
+
+ if ($valuesToUpdate !== null) {
+ $valuesToUpdate[$fieldName] = $value;
+ } else {
+ $this->visitorInfo[$fieldName] = $value;
+ }
+ }
+ }
+
+ return $valuesToUpdate;
+ }
}
diff --git a/core/Tracker/Visitor.php b/core/Tracker/Visitor.php
index 758839abdf..cb74248da6 100644
--- a/core/Tracker/Visitor.php
+++ b/core/Tracker/Visitor.php
@@ -10,18 +10,24 @@ namespace Piwik\Tracker;
use Piwik\Common;
use Piwik\Config;
+use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\CustomVariables\CustomVariables;
use Piwik\Piwik;
use Piwik\Tracker;
class Visitor
{
- function __construct(Request $request, Tracker\Settings $settings, $visitorInfo = array(), $customVariables = null)
+ private $visitorKnown = false;
+ private $request;
+ private $visitorInfo;
+ private $configId;
+
+ public function __construct(Request $request, $configId, $visitorInfo = array(), $customVariables = null)
{
$this->request = $request;
$this->visitorInfo = $visitorInfo;
$this->customVariables = $customVariables;
- $this->userInfo = $settings->getInfo();
+ $this->configId = $configId;
}
/**
@@ -31,11 +37,11 @@ class Visitor
* - Known visitor
* - New visitor
*/
- function recognize()
+ public function recognize()
{
- $this->visitorKnown = false;
+ $this->setIsVisitorKnown(false);
- $configId = $this->userInfo['config_id'];
+ $configId = $this->configId;
$idVisitor = $this->request->getVisitorId();
$isVisitorIdToLookup = !empty($idVisitor);
@@ -58,12 +64,13 @@ class Visitor
}
$persistedVisitAttributes = self::getVisitFieldsPersist();
+ array_unshift($persistedVisitAttributes, 'visit_first_action_time');
+ array_unshift($persistedVisitAttributes, 'visit_last_action_time');
+ $persistedVisitAttributes = array_unique($persistedVisitAttributes);
$selectFields = implode(", ", $persistedVisitAttributes);
$select = "SELECT
- visit_last_action_time,
- visit_first_action_time,
$selectFields
$selectCustomVariables
";
@@ -155,14 +162,15 @@ class Visitor
&& $visitRow
&& count($visitRow) > 0
) {
- // These values will be used throughout the request
- $this->visitorInfo['visit_last_action_time'] = strtotime($visitRow['visit_last_action_time']);
- $this->visitorInfo['visit_first_action_time'] = strtotime($visitRow['visit_first_action_time']);
+ // These values will be used throughout the request
foreach($persistedVisitAttributes as $field) {
$this->visitorInfo[$field] = $visitRow[$field];
}
+ $this->visitorInfo['visit_last_action_time'] = strtotime($visitRow['visit_last_action_time']);
+ $this->visitorInfo['visit_first_action_time'] = strtotime($visitRow['visit_first_action_time']);
+
// Custom Variables copied from Visit in potential later conversion
if (!empty($selectCustomVariables)) {
$maxCustomVariables = CustomVariables::getMaxCustomVariables();
@@ -180,7 +188,7 @@ class Visitor
}
}
- $this->visitorKnown = true;
+ $this->setIsVisitorKnown(true);
Common::printDebug("The visitor is known (idvisitor = " . bin2hex($this->visitorInfo['idvisitor']) . ",
config_id = " . bin2hex($configId) . ",
idvisit = {$this->visitorInfo['idvisit']},
@@ -248,7 +256,6 @@ class Visitor
'visitor_days_since_first',
'visitor_days_since_order',
'visitor_count_visits',
- 'visit_goal_buyer',
'location_country',
'location_region',
@@ -261,36 +268,64 @@ class Visitor
'referer_type',
);
+ $dimensions = VisitDimension::getAllDimensions();
+
+ foreach ($dimensions as $dimension) {
+ if ($dimension->hasImplementedEvent('onExistingVisit')) {
+ $fields[] = $dimension->getColumnName();
+ }
+
+ /**
+ * This event collects a list of [visit entity]() properties that should be loaded when reading
+ * the existing visit. Properties that appear in this list will be available in other tracking
+ * events such as 'onExistingVisit'.
+ *
+ * Plugins can use this event to load additional visit entity properties for later use during tracking.
+ */
+ foreach ($dimension->getRequiredVisitFields() as $field) {
+ $fields[] = $field;
+ }
+ }
+
/**
- * Triggered when checking if the current action being tracked belongs to an existing visit.
- *
- * This event collects a list of [visit entity]() properties that should be loaded when reading
- * the existing visit. Properties that appear in this list will be available in other tracking
- * events such as {@hook Tracker.newConversionInformation} and {@hook Tracker.newVisitorInformation}.
- *
- * Plugins can use this event to load additional visit entity properties for later use during tracking.
- * When you add fields to this $fields array, they will be later available in Tracker.newConversionInformation
- *
- * **Example**
- *
- * Piwik::addAction('Tracker.getVisitFieldsToPersist', function (&$fields) {
- * $fields[] = 'custom_visit_property';
- * });
- *
- * @param array &$fields The list of visit properties to load.
+ * @ignore
*/
Piwik::postEvent('Tracker.getVisitFieldsToPersist', array(&$fields));
return $fields;
}
- function getVisitorInfo()
+ public function getVisitorInfo()
{
return $this->visitorInfo;
}
- function isVisitorKnown()
+ public function clearVisitorInfo()
+ {
+ $this->visitorInfo = array();
+ }
+
+ public function setVisitorColumn($column, $value)
+ {
+ $this->visitorInfo[$column] = $value;
+ }
+
+ public function getVisitorColumn($column)
+ {
+ if (array_key_exists($column, $this->visitorInfo)) {
+ return $this->visitorInfo[$column];
+ }
+
+ return false;
+ }
+
+ public function isVisitorKnown()
{
return $this->visitorKnown === true;
}
+
+ public function setIsVisitorKnown($isVisitorKnown)
+ {
+ return $this->visitorKnown = $isVisitorKnown;
+ }
}
diff --git a/core/Translate.php b/core/Translate.php
index e2fb58ee02..c128fd672a 100644
--- a/core/Translate.php
+++ b/core/Translate.php
@@ -138,8 +138,20 @@ class Translate
self::$languageToLoad = null;
}
+ private static function isALanguageLoaded() {
+ return !empty($GLOBALS['Piwik_translations']);
+ }
+
+ /**
+ * Either the name of the currently loaded language such as 'en' or 'de' or null if no language is loaded at all.
+ * @return bool|string
+ */
public static function getLanguageLoaded()
{
+ if (!self::isALanguageLoaded()) {
+ return null;
+ }
+
return self::$loadedLanguage;
}
@@ -212,4 +224,18 @@ class Translate
setlocale(LC_ALL, $locale, $locale_variant);
setlocale(LC_CTYPE, '');
}
+
+ public static function findTranslationKeyForTranslation($translation)
+ {
+ if (empty($GLOBALS['Piwik_translations'])) {
+ return;
+ }
+
+ foreach ($GLOBALS['Piwik_translations'] as $key => $translations) {
+ $possibleKey = array_search($translation, $translations);
+ if (!empty($possibleKey)) {
+ return $key . '_' . $possibleKey;
+ }
+ }
+ }
}
diff --git a/core/Updater.php b/core/Updater.php
index 8b272cde66..e10c6bf33c 100644
--- a/core/Updater.php
+++ b/core/Updater.php
@@ -7,6 +7,7 @@
*
*/
namespace Piwik;
+use Piwik\Columns\Updater as ColumnUpdater;
/**
* Load and execute all relevant, incremental update scripts for Piwik core and plugins, and bump the component version numbers for completed updates.
@@ -21,6 +22,7 @@ class Updater
public $pathUpdateFilePlugins;
private $componentsToCheck = array();
private $hasMajorDbUpdate = false;
+ private $updatedClasses = array();
/**
* Constructor
@@ -29,6 +31,8 @@ class Updater
{
$this->pathUpdateFileCore = PIWIK_INCLUDE_PATH . '/core/Updates/';
$this->pathUpdateFilePlugins = PIWIK_INCLUDE_PATH . '/plugins/%s/Updates/';
+
+ ColumnUpdater::setUpdater($this);
}
/**
@@ -58,6 +62,30 @@ class Updater
}
/**
+ * Retrieve the current version of a recorded component
+ * @param string $name
+ * @return false|string
+ * @throws \Exception
+ */
+ public static function getCurrentRecordedComponentVersion($name)
+ {
+ try {
+ $currentVersion = Option::get(self::getNameInOptionTable($name));
+ } catch (\Exception $e) {
+ // mysql error 1146: table doesn't exist
+ if (Db::get()->isErrNo($e, '1146')) {
+ // case when the option table is not yet created (before 0.2.10)
+ $currentVersion = false;
+ } else {
+ // failed for some other reason
+ throw $e;
+ }
+ }
+
+ return $currentVersion;
+ }
+
+ /**
* Returns the flag name to use in the option table to record current schema version
* @param string $name
* @return string
@@ -111,6 +139,8 @@ class Updater
public function getSqlQueriesToExecute()
{
$queries = array();
+ $classNames = array();
+
foreach ($this->componentsWithUpdateFile as $componentName => $componentUpdateInfo) {
foreach ($componentUpdateInfo as $file => $fileVersion) {
require_once $file; // prefixed by PIWIK_INCLUDE_PATH
@@ -119,6 +149,13 @@ class Updater
if (!class_exists($className, false)) {
throw new \Exception("The class $className was not found in $file");
}
+
+ if (in_array($className, $classNames)) {
+ continue; // prevent from getting updates from Piwik\Columns\Updater multiple times
+ }
+
+ $classNames[] = $className;
+
$queriesForComponent = call_user_func(array($className, 'getSql'));
foreach ($queriesForComponent as $query => $error) {
$queries[] = $query . ';';
@@ -141,6 +178,11 @@ class Updater
if ($componentName == 'core') {
return '\\Piwik\\Updates\\' . $className;
}
+
+ if (ColumnUpdater::isDimensionComponent($componentName)) {
+ return '\\Piwik\\Columns\\Updater';
+ }
+
return '\\Piwik\\Plugins\\' . $componentName . '\\' . $className;
}
@@ -154,14 +196,18 @@ class Updater
public function update($componentName)
{
$warningMessages = array();
+
foreach ($this->componentsWithUpdateFile[$componentName] as $file => $fileVersion) {
try {
require_once $file; // prefixed by PIWIK_INCLUDE_PATH
$className = $this->getUpdateClassName($componentName, $fileVersion);
- if (class_exists($className, false)) {
+ if (!in_array($className, $this->updatedClasses) && class_exists($className, false)) {
// update()
call_user_func(array($className, 'update'));
+ // makes sure to call Piwik\Columns\Updater only once as one call updates all dimensions at the same
+ // time for better performance
+ $this->updatedClasses[] = $className;
}
self::recordComponentSuccessfullyUpdated($componentName, $fileVersion);
@@ -185,29 +231,35 @@ class Updater
private function loadComponentsWithUpdateFile()
{
$componentsWithUpdateFile = array();
+ $hasDimensionUpdate = null;
+
foreach ($this->componentsWithNewVersion as $name => $versions) {
$currentVersion = $versions[self::INDEX_CURRENT_VERSION];
$newVersion = $versions[self::INDEX_NEW_VERSION];
if ($name == 'core') {
$pathToUpdates = $this->pathUpdateFileCore . '*.php';
+ } elseif (ColumnUpdater::isDimensionComponent($name)) {
+ $componentsWithUpdateFile[$name][PIWIK_INCLUDE_PATH . '/core/Columns/Updater.php'] = $newVersion;
} else {
$pathToUpdates = sprintf($this->pathUpdateFilePlugins, $name) . '*.php';
}
- $files = _glob($pathToUpdates);
- if ($files == false) {
- $files = array();
- }
+ if (!empty($pathToUpdates)) {
+ $files = _glob($pathToUpdates);
+ if ($files == false) {
+ $files = array();
+ }
- foreach ($files as $file) {
- $fileVersion = basename($file, '.php');
- if ( // if the update is from a newer version
- version_compare($currentVersion, $fileVersion) == -1
- // but we don't execute updates from non existing future releases
- && version_compare($fileVersion, $newVersion) <= 0
- ) {
- $componentsWithUpdateFile[$name][$file] = $fileVersion;
+ foreach ($files as $file) {
+ $fileVersion = basename($file, '.php');
+ if ( // if the update is from a newer version
+ version_compare($currentVersion, $fileVersion) == -1
+ // but we don't execute updates from non existing future releases
+ && version_compare($fileVersion, $newVersion) <= 0
+ ) {
+ $componentsWithUpdateFile[$name][$file] = $fileVersion;
+ }
}
}
@@ -219,6 +271,7 @@ class Updater
self::recordComponentSuccessfullyUpdated($name, $newVersion);
}
}
+
return $componentsWithUpdateFile;
}
@@ -239,30 +292,24 @@ class Updater
$this->componentsToCheck = array_merge(array('core' => $coreVersions), $this->componentsToCheck);
}
+ $recordedCoreVersion = self::getCurrentRecordedComponentVersion('core');
+ if ($recordedCoreVersion === false) {
+ // This should not happen
+ $recordedCoreVersion = Version::VERSION;
+ self::recordComponentSuccessfullyUpdated('core', $recordedCoreVersion);
+ }
+
foreach ($this->componentsToCheck as $name => $version) {
- try {
- $currentVersion = Option::get(self::getNameInOptionTable($name));
- } catch (\Exception $e) {
- // mysql error 1146: table doesn't exist
- if (Db::get()->isErrNo($e, '1146')) {
- // case when the option table is not yet created (before 0.2.10)
- $currentVersion = false;
- } else {
- // failed for some other reason
- throw $e;
- }
- }
+ $currentVersion = self::getCurrentRecordedComponentVersion($name);
- if ($name === 'core' && $currentVersion === false) {
- // This should not happen
- $currentVersion = Version::VERSION;
- self::recordComponentSuccessfullyUpdated($name, $currentVersion);
+ if (ColumnUpdater::isDimensionComponent($name)) {
+ $isComponentOutdated = $currentVersion !== $version;
+ } else {
+ // note: when versionCompare == 1, the version in the DB is newer, we choose to ignore
+ $isComponentOutdated = version_compare($currentVersion, $version) == -1;
}
- // note: when versionCompare == 1, the version in the DB is newer, we choose to ignore
- $currentVersionIsOutdated = version_compare($currentVersion, $version) == -1;
- $isComponentOutdated = $currentVersion === false || $currentVersionIsOutdated;
- if ($isComponentOutdated) {
+ if ($isComponentOutdated || $currentVersion === false) {
$componentsToUpdate[$name] = array(
self::INDEX_CURRENT_VERSION => $currentVersion,
self::INDEX_NEW_VERSION => $version
@@ -344,4 +391,4 @@ class Updater
*/
class UpdaterErrorException extends \Exception
{
-} \ No newline at end of file
+}
diff --git a/core/Updates/1.2-rc1.php b/core/Updates/1.2-rc1.php
index c037e17fcd..31d8ba58bc 100644
--- a/core/Updates/1.2-rc1.php
+++ b/core/Updates/1.2-rc1.php
@@ -25,17 +25,19 @@ class Updates_1_2_rc1 extends Updates
DROP `visit_server_date`,
DROP INDEX `index_idsite_date_config`,
DROP INDEX `index_idsite_datetime_config`,
+ ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`,
+ ADD `config_id` BINARY(8) NOT NULL AFTER `config_md5config`
+ ' => array(1054, 1091),
+ 'ALTER TABLE `' . Common::prefixTable('log_visit') . '`
ADD `visit_entry_idaction_name` INT UNSIGNED NOT NULL AFTER `visit_entry_idaction_url`,
ADD `visit_exit_idaction_name` INT UNSIGNED NOT NULL AFTER `visit_exit_idaction_url`,
- CHANGE `visit_exit_idaction_url` `visit_exit_idaction_url` INT UNSIGNED NOT NULL,
+ CHANGE `visit_exit_idaction_url` `visit_exit_idaction_url` INT UNSIGNED NOT NULL,
CHANGE `visit_entry_idaction_url` `visit_entry_idaction_url` INT UNSIGNED NOT NULL,
CHANGE `referer_type` `referer_type` TINYINT UNSIGNED NULL DEFAULT NULL,
- ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`,
ADD visitor_count_visits SMALLINT(5) UNSIGNED NOT NULL AFTER `visitor_returning`,
ADD visitor_days_since_last SMALLINT(5) UNSIGNED NOT NULL,
- ADD visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL,
- ADD `config_id` BINARY(8) NOT NULL AFTER `config_md5config`
- ' => array(1054, 1091),
+ ADD visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL
+ ' => 1060,
'ALTER TABLE `' . Common::prefixTable('log_visit') . '`
ADD custom_var_k1 VARCHAR(100) DEFAULT NULL,
ADD custom_var_v1 VARCHAR(100) DEFAULT NULL,
@@ -49,19 +51,23 @@ class Updates_1_2_rc1 extends Updates
ADD custom_var_v5 VARCHAR(100) DEFAULT NULL
' => 1060,
'ALTER TABLE `' . Common::prefixTable('log_link_visit_action') . '`
- ADD `idsite` INT( 10 ) UNSIGNED NOT NULL AFTER `idlink_va` ,
- ADD `server_time` DATETIME AFTER `idsite`,
+ ADD `idsite` INT( 10 ) UNSIGNED NOT NULL AFTER `idlink_va` ,
ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`,
- ADD `idaction_name_ref` INT UNSIGNED NOT NULL AFTER `idaction_name`,
+ ADD `idaction_name_ref` INT UNSIGNED NOT NULL AFTER `idaction_name`
+ ' => 1060,
+ 'ALTER TABLE `' . Common::prefixTable('log_link_visit_action') . '`
+ ADD `server_time` DATETIME AFTER `idsite`,
ADD INDEX `index_idsite_servertime` ( `idsite` , `server_time` )
' => 1060,
'ALTER TABLE `' . Common::prefixTable('log_conversion') . '`
DROP `referer_idvisit`,
- ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`,
+ ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`
+ ' => array(1060, 1091),
+ 'ALTER TABLE `' . Common::prefixTable('log_conversion') . '`
ADD visitor_count_visits SMALLINT(5) UNSIGNED NOT NULL,
ADD visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL
- ' => array(1060, 1091),
+ ' => 1060,
'ALTER TABLE `' . Common::prefixTable('log_conversion') . '`
ADD custom_var_k1 VARCHAR(100) DEFAULT NULL,
ADD custom_var_v1 VARCHAR(100) DEFAULT NULL,
diff --git a/core/Updates/1.5-b1.php b/core/Updates/1.5-b1.php
index 176d2f6059..9a8ed9653d 100644
--- a/core/Updates/1.5-b1.php
+++ b/core/Updates/1.5-b1.php
@@ -44,7 +44,8 @@ class Updates_1_5_b1 extends Updates
ADD visit_goal_buyer TINYINT(1) NOT NULL AFTER visit_goal_converted' => 1060,
'ALTER IGNORE TABLE `' . Common::prefixTable('log_conversion') . '`
- ADD visitor_days_since_order SMALLINT(5) UNSIGNED NOT NULL AFTER visitor_days_since_first,
+ ADD visitor_days_since_order SMALLINT(5) UNSIGNED NOT NULL AFTER visitor_days_since_first' => 1060,
+ 'ALTER IGNORE TABLE `' . Common::prefixTable('log_conversion') . '`
ADD idorder varchar(100) default NULL AFTER buster,
ADD items SMALLINT UNSIGNED DEFAULT NULL,
ADD revenue_subtotal float default NULL,
diff --git a/core/Updates/1.9-b9.php b/core/Updates/1.9-b9.php
index 76a87da8af..5274232cd8 100755
--- a/core/Updates/1.9-b9.php
+++ b/core/Updates/1.9-b9.php
@@ -27,18 +27,21 @@ class Updates_1_9_b9 extends Updates
$logVisit = Common::prefixTable('log_visit');
$logConversion = Common::prefixTable('log_conversion');
- $addColumns = "DROP `location_continent`,
- ADD `location_region` CHAR(2) NULL AFTER `location_country`,
+ $addColumns = "ADD `location_region` CHAR(2) NULL AFTER `location_country`,
ADD `location_city` VARCHAR(255) NULL AFTER `location_region`,
ADD `location_latitude` FLOAT(10, 6) NULL AFTER `location_city`,
ADD `location_longitude` FLOAT(10, 6) NULL AFTER `location_latitude`";
+ $dropColumns = "DROP `location_continent`";
return array(
- // add geoip columns to log_visit
- "ALTER TABLE `$logVisit` $addColumns" => array(1091, 1060),
+ "ALTER TABLE `$logVisit` $dropColumns" => 1091,
+ "ALTER TABLE `$logConversion` $dropColumns" => 1091,
+
+ // add geoip columns to log_visit
+ "ALTER TABLE `$logVisit` $addColumns" => 1060,
// add geoip columns to log_conversion
- "ALTER TABLE `$logConversion` $addColumns" => array(1091, 1060),
+ "ALTER TABLE `$logConversion` $addColumns" => 1060,
);
}
diff --git a/core/Updates/2.5.0-b1.php b/core/Updates/2.5.0-b1.php
new file mode 100644
index 0000000000..54c0e6e026
--- /dev/null
+++ b/core/Updates/2.5.0-b1.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Updates;
+
+use Piwik\Config;
+use Piwik\Updates;
+
+class Updates_2_5_0_b1 extends Updates
+{
+ public static function update()
+ {
+ self::updateConfig();
+ }
+
+ private static function updateConfig()
+ {
+ $config = Config::getInstance();
+ $debug = $config->Debug;
+
+ if (array_key_exists('disable_merged_assets', $debug)) {
+ $development = $config->Development;
+ $development['disable_merged_assets'] = $debug['disable_merged_assets'];
+ unset($debug['disable_merged_assets']);
+
+ $config->Debug = $debug;
+ $config->Development = $development;
+ $config->forceSave();
+ }
+ }
+
+}
diff --git a/core/Version.php b/core/Version.php
index 260f290e97..b11fa037d4 100644
--- a/core/Version.php
+++ b/core/Version.php
@@ -21,5 +21,5 @@ final class Version
* The current Piwik version.
* @var string
*/
- const VERSION = '2.4.1';
+ const VERSION = '2.4.0';
}
diff --git a/core/ViewDataTable/Factory.php b/core/ViewDataTable/Factory.php
index 7f4f32be0a..52c74933d1 100644
--- a/core/ViewDataTable/Factory.php
+++ b/core/ViewDataTable/Factory.php
@@ -10,6 +10,7 @@ namespace Piwik\ViewDataTable;
use Piwik\Common;
use Piwik\Piwik;
+use Piwik\Plugin\Report;
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
/**
@@ -148,6 +149,13 @@ class Factory
*/
private static function getDefaultViewTypeForReport($apiAction)
{
+ list($module, $action) = explode('.', $apiAction);
+ $report = Report::factory($module, $action);
+
+ if (!empty($report) && $report->isEnabled()) {
+ return $report->getDefaultTypeViewDataTable();
+ }
+
$defaultViewTypes = self::getDefaultTypeViewDataTable();
return isset($defaultViewTypes[$apiAction]) ? $defaultViewTypes[$apiAction] : false;
}
@@ -161,24 +169,7 @@ class Factory
if (null === self::$defaultViewTypes) {
self::$defaultViewTypes = array();
/**
- * Triggered when gathering the default view types for all available reports.
- *
- * If you define your own report, you may want to subscribe to this event to
- * make sure the correct default Visualization is used (for example, a pie graph,
- * bar graph, or something else).
- *
- * If there is no default type associated with a report, the **table** visualization
- * used.
- *
- * **Example**
- *
- * public function getDefaultTypeViewDataTable(&$defaultViewTypes)
- * {
- * $defaultViewTypes['Referrers.getSocials'] = HtmlTable::ID;
- * $defaultViewTypes['Referrers.getUrlsForSocial'] = Pie::ID;
- * }
- *
- * @param array &$defaultViewTypes The array mapping report IDs with visualization IDs.
+ * @ignore
*/
Piwik::postEvent('ViewDataTable.getDefaultType', array(&self::$defaultViewTypes));
}
diff --git a/core/ViewDataTable/Manager.php b/core/ViewDataTable/Manager.php
index b57638f0ed..0559661d44 100644
--- a/core/ViewDataTable/Manager.php
+++ b/core/ViewDataTable/Manager.php
@@ -18,6 +18,7 @@ use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Bar;
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Pie;
use Piwik\Plugins\Goals\Visualizations\Goals;
use Piwik\Plugins\Insights\Visualizations\Insight;
+use Piwik\Plugin\Manager as PluginManager;
/**
* ViewDataTable Manager.
@@ -62,8 +63,10 @@ class Manager
*/
public static function getAvailableViewDataTables()
{
+ $klassToExtend = '\\Piwik\\Plugin\\ViewDataTable';
+
/** @var string[] $visualizations */
- $visualizations = array();
+ $visualizations = PluginManager::getInstance()->findMultipleComponents('Visualizations', $klassToExtend);
/**
* Triggered when gathering all available DataTable visualizations.
@@ -79,6 +82,8 @@ class Manager
* }
*
* @param array &$visualizations The array of all available visualizations.
+ * @ignore
+ * @deprecated since 2.5.0 Place visualization in a "Visualizations" directory instead.
*/
Piwik::postEvent('ViewDataTable.addViewDataTable', array(&$visualizations));
@@ -89,7 +94,7 @@ class Manager
throw new \Exception("Invalid visualization class '$viz' found in Visualization.getAvailableVisualizations.");
}
- if (!is_subclass_of($viz, '\\Piwik\\Plugin\\ViewDataTable')) {
+ if (!is_subclass_of($viz, $klassToExtend)) {
throw new \Exception("ViewDataTable class '$viz' does not extend Plugin/ViewDataTable");
}
diff --git a/core/WidgetsList.php b/core/WidgetsList.php
index b79b94d922..9ac66de81b 100644
--- a/core/WidgetsList.php
+++ b/core/WidgetsList.php
@@ -8,7 +8,9 @@
*/
namespace Piwik;
-use Piwik\Plugin\Manager as PluginManager;
+use Piwik\Cache\PluginAwareStaticCache;
+use Piwik\Plugin\Report;
+use Piwik\Plugin\Widgets;
/**
* Manages the global list of reports that can be displayed as dashboard widgets.
@@ -36,6 +38,13 @@ class WidgetsList extends Singleton
static protected $hookCalled = false;
/**
+ * In get() we won't use a cached result in case this is true. Instead we will sort the widgets again and cache
+ * a new result. To make tests work...
+ * @var bool
+ */
+ static private $listCacheToBeInvalidated = false;
+
+ /**
* Returns all available widgets.
*
* @return array Array Mapping widget categories with an array of widget information, eg,
@@ -54,17 +63,29 @@ class WidgetsList extends Singleton
*/
static public function get()
{
+ $cache = self::getCacheForCompleteList();
+ if (!self::$listCacheToBeInvalidated && $cache->has()) {
+ return $cache->get();
+ }
+
self::addWidgets();
uksort(self::$widgets, array('Piwik\WidgetsList', '_sortWidgetCategories'));
$widgets = array();
foreach (self::$widgets as $key => $v) {
- if (isset($widgets[Piwik::translate($key)])) {
- $v = array_merge($widgets[Piwik::translate($key)], $v);
+ $category = Piwik::translate($key);
+
+ if (isset($widgets[$category])) {
+ $v = array_merge($widgets[$category], $v);
}
- $widgets[Piwik::translate($key)] = $v;
+
+ $widgets[$category] = $v;
}
+
+ $cache->set($widgets);
+ self::$listCacheToBeInvalidated = false;
+
return $widgets;
}
@@ -79,12 +100,25 @@ class WidgetsList extends Singleton
*/
Piwik::postEvent('WidgetsList.addWidgets');
- /** @var \Piwik\Plugin\Widgets[] $widgets */
- $widgets = PluginManager::getInstance()->findComponents('Widgets', 'Piwik\\Plugin\\Widgets');
$widgetsList = self::getInstance();
- foreach ($widgets as $widget) {
- $widget->configure($widgetsList);
+ foreach (Report::getAllReports() as $report) {
+ if ($report->isEnabled()) {
+ $report->configureWidget($widgetsList);
+ }
+ }
+
+ $widgetContainers = Widgets::getAllWidgets();
+ foreach ($widgetContainers as $widgetContainer) {
+ $widgets = $widgetContainer->getWidgets();
+
+ foreach ($widgets as $widget) {
+ $widgetsList->add($widget['category'], $widget['name'], $widget['module'], $widget['method'], $widget['params']);
+ }
+ }
+
+ foreach ($widgetContainers as $widgetContainer) {
+ $widgetContainer->configureWidgetsList($widgetsList);
}
}
}
@@ -136,8 +170,9 @@ class WidgetsList extends Singleton
*/
static public function add($widgetCategory, $widgetName, $controllerName, $controllerAction, $customParameters = array())
{
- $widgetName = Piwik::translate($widgetName);
+ $widgetName = Piwik::translate($widgetName);
$widgetUniqueId = 'widget' . $controllerName . $controllerAction;
+
foreach ($customParameters as $name => $value) {
if (is_array($value)) {
// use 'Array' for backward compatibility;
@@ -151,6 +186,7 @@ class WidgetsList extends Singleton
self::$widgets[$widgetCategory] = array();
}
+ self::$listCacheToBeInvalidated = true;
self::$widgets[$widgetCategory][] = array(
'name' => $widgetName,
'uniqueId' => $widgetUniqueId,
@@ -176,11 +212,13 @@ class WidgetsList extends Singleton
if (empty($widgetName)) {
unset(self::$widgets[$widgetCategory]);
+ self::$listCacheToBeInvalidated = true;
return;
}
foreach (self::$widgets[$widgetCategory] as $id => $widget) {
if ($widget['name'] == $widgetName || $widget['name'] == Piwik::translate($widgetName)) {
unset(self::$widgets[$widgetCategory][$id]);
+ self::$listCacheToBeInvalidated = true;
return;
}
}
@@ -196,7 +234,7 @@ class WidgetsList extends Singleton
static public function isDefined($controllerName, $controllerAction)
{
$widgetsList = self::get();
- foreach ($widgetsList as $widgetCategory => $widgets) {
+ foreach ($widgetsList as $widgets) {
foreach ($widgets as $widget) {
if ($widget['parameters']['module'] == $controllerName
&& $widget['parameters']['action'] == $controllerAction
@@ -217,5 +255,11 @@ class WidgetsList extends Singleton
{
self::$widgets = array();
self::$hookCalled = false;
+ self::getCacheForCompleteList()->clear();
+ }
+
+ private static function getCacheForCompleteList()
+ {
+ return new PluginAwareStaticCache('WidgetsList');
}
}
diff --git a/lang/en.json b/lang/en.json
index b80296d9a2..b9699f9226 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -381,6 +381,7 @@
"PluginDescription": "Piwik updating mechanism",
"ReadyToGo": "Ready to go?",
"TheFollowingPluginsWillBeUpgradedX": "The following plugins will be updated: %s.",
+ "TheFollowingDimensionsWillBeUpgradedX": "The following dimensions will be updated: %s.",
"ThereIsNewPluginVersionAvailableForUpdate": "Some plugins you use have been updated on the Marketplace:",
"ThereIsNewVersionAvailableForUpdate": "There is a new version of Piwik available for update",
"TheUpgradeProcessMayFailExecuteCommand": "If you have a large Piwik database, updates might take too long to run in the browser. In this situation, you can execute the updates from your command line: %s",
@@ -636,6 +637,9 @@
"ExceptionUnableToStartSession": "Unable to start session.",
"ExceptionUndeletableFile": "Unable to delete %s",
"ExceptionUnreadableFileDisabledMethod": "The configuration file {%s} could not be read. Your host may have disabled %s.",
+ "ExceptionReportNotFound": "The requested report does not exist.",
+ "ExceptionWidgetNotFound": "The requested widget does not exist.",
+ "ExceptionReportNotEnabled": "The requested report is not enabled. This means usually either the plugin that defines the report is deactivated or you do not have enough permission to access this report.",
"ExpandDataTableFooter": "Change the visualization or configure the report",
"Export": "Export",
"ExportAsImage": "Export as Image",
diff --git a/piwik.php b/piwik.php
index 8c37403a39..d992ef56a5 100644
--- a/piwik.php
+++ b/piwik.php
@@ -76,12 +76,8 @@ require_once PIWIK_INCLUDE_PATH . '/core/Tracker/GoalManager.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/PageUrl.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/TableLogAction.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Action.php';
-require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionClickUrl.php';
-require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionEvent.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionPageview.php';
-require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionSiteSearch.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Request.php';
-require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Referrer.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/VisitExcluded.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/VisitorNotFoundInDb.php';
require_once PIWIK_INCLUDE_PATH . '/core/CacheFile.php';
diff --git a/plugins/API/API.php b/plugins/API/API.php
index b8635f735e..3253ae5f21 100644
--- a/plugins/API/API.php
+++ b/plugins/API/API.php
@@ -10,19 +10,19 @@ namespace Piwik\Plugins\API;
use Piwik\API\Proxy;
use Piwik\API\Request;
+use Piwik\Columns\Dimension;
use Piwik\Config;
use Piwik\DataTable;
use Piwik\DataTable\Filter\ColumnDelete;
use Piwik\DataTable\Row;
use Piwik\Date;
use Piwik\IP;
-use Piwik\Menu\MenuTop;
use Piwik\Metrics;
use Piwik\Period;
use Piwik\Period\Range;
use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\CoreAdminHome\CustomLogo;
-use Piwik\Tracker\GoalManager;
use Piwik\Translate;
use Piwik\Version;
@@ -95,6 +95,12 @@ class API extends \Piwik\Plugin\API
{
$segments = array();
+ foreach (Dimension::getAllDimensions() as $dimension) {
+ foreach ($dimension->getSegments() as $segment) {
+ $segments[] = $segment->toArray();
+ }
+ }
+
/**
* Triggered when gathering all available segment dimensions.
*
@@ -175,88 +181,6 @@ class API extends \Piwik\Plugin\API
'sqlFilterValue' => array('Piwik\IP', 'P2N'),
'permission' => $isAuthenticatedWithViewAccess,
);
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_NbActions',
- 'segment' => 'actions',
- 'sqlSegment' => 'log_visit.visit_total_actions',
- );
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_NbSearches',
- 'segment' => 'searches',
- 'sqlSegment' => 'log_visit.visit_total_searches',
- 'acceptedValues' => 'To select all visits who used internal Site Search, use: &segment=searches>0',
- );
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_ColumnVisitDuration',
- 'segment' => 'visitDuration',
- 'sqlSegment' => 'log_visit.visit_total_time',
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => Piwik::translate('General_VisitType'),
- 'segment' => 'visitorType',
- 'acceptedValues' => 'new, returning, returningCustomer' . ". " . Piwik::translate('General_VisitTypeExample', '"&segment=visitorType==returning,visitorType==returningCustomer"'),
- 'sqlSegment' => 'log_visit.visitor_returning',
- 'sqlFilterValue' => function ($type) {
- return $type == "new" ? 0 : ($type == "returning" ? 1 : 2);
- }
- );
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_DaysSinceLastVisit',
- 'segment' => 'daysSinceLastVisit',
- 'sqlSegment' => 'log_visit.visitor_days_since_last',
- );
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_DaysSinceFirstVisit',
- 'segment' => 'daysSinceFirstVisit',
- 'sqlSegment' => 'log_visit.visitor_days_since_first',
- );
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_NumberOfVisits',
- 'segment' => 'visitCount',
- 'sqlSegment' => 'log_visit.visitor_count_visits',
- );
-
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_VisitConvertedGoal',
- 'segment' => 'visitConverted',
- 'acceptedValues' => '0, 1',
- 'sqlSegment' => 'log_visit.visit_goal_converted',
- );
-
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => Piwik::translate('General_EcommerceVisitStatusDesc'),
- 'segment' => 'visitEcommerceStatus',
- 'acceptedValues' => implode(", ", self::$visitEcommerceStatus)
- . '. ' . Piwik::translate('General_EcommerceVisitStatusEg', '"&segment=visitEcommerceStatus==ordered,visitEcommerceStatus==orderedThenAbandonedCart"'),
- 'sqlSegment' => 'log_visit.visit_goal_buyer',
- 'sqlFilterValue' => __NAMESPACE__ . '\API::getVisitEcommerceStatus',
- );
-
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_DaysSinceLastEcommerceOrder',
- 'segment' => 'daysSinceLastEcommerceOrder',
- 'sqlSegment' => 'log_visit.visitor_days_since_order',
- );
foreach ($segments as &$segment) {
$segment['name'] = Piwik::translate($segment['name']);
@@ -273,47 +197,20 @@ class API extends \Piwik\Plugin\API
return $segments;
}
- static protected $visitEcommerceStatus = array(
- GoalManager::TYPE_BUYER_NONE => 'none',
- GoalManager::TYPE_BUYER_ORDERED => 'ordered',
- GoalManager::TYPE_BUYER_OPEN_CART => 'abandonedCart',
- GoalManager::TYPE_BUYER_ORDERED_AND_OPEN_CART => 'orderedThenAbandonedCart',
- );
-
- /**
- * @ignore
- */
- static public function getVisitEcommerceStatusFromId($id)
- {
- if (!isset(self::$visitEcommerceStatus[$id])) {
- throw new \Exception("Unexpected ECommerce status value ");
- }
- return self::$visitEcommerceStatus[$id];
- }
-
- /**
- * @ignore
- */
- static public function getVisitEcommerceStatus($status)
- {
- $id = array_search($status, self::$visitEcommerceStatus);
- if ($id === false) {
- throw new \Exception("Invalid 'visitEcommerceStatus' segment value $status");
- }
- return $id;
- }
-
private function sortSegments($row1, $row2)
{
+ $customVarCategory = Piwik::translate('CustomVariables_CustomVariables');
+
$columns = array('type', 'category', 'name', 'segment');
foreach ($columns as $column) {
// Keep segments ordered alphabetically inside categories..
$type = -1;
if ($column == 'name') $type = 1;
+
$compare = $type * strcmp($row1[$column], $row2[$column]);
// hack so that custom variables "page" are grouped together in the doc
- if ($row1['category'] == Piwik::translate('CustomVariables_CustomVariables')
+ if ($row1['category'] == $customVarCategory
&& $row1['category'] == $row2['category']
) {
$compare = strcmp($row1['segment'], $row2['segment']);
diff --git a/plugins/API/ProcessedReport.php b/plugins/API/ProcessedReport.php
index bf8488c410..86a7fd1698 100644
--- a/plugins/API/ProcessedReport.php
+++ b/plugins/API/ProcessedReport.php
@@ -11,6 +11,7 @@ namespace Piwik\Plugins\API;
use Exception;
use Piwik\API\Request;
use Piwik\Archive\DataTableFactory;
+use Piwik\Cache\PluginAwareStaticCache;
use Piwik\Common;
use Piwik\DataTable;
use Piwik\DataTable\Row;
@@ -20,13 +21,13 @@ use Piwik\Metrics;
use Piwik\MetricsFormatter;
use Piwik\Period;
use Piwik\Piwik;
+use Piwik\Plugin\Report;
use Piwik\Site;
use Piwik\Timer;
use Piwik\Url;
class ProcessedReport
{
-
/**
* Loads reports metadata, then return the requested one,
* matching optional API parameters.
@@ -148,10 +149,23 @@ class ProcessedReport
Piwik::checkUserHasViewAccess($idSites);
}
+ // as they cache key contains a lot of information there would be an even better cache result by caching parts of
+ // this huge method separately but that makes it also more complicated. leaving it like this for now.
+ $key = $this->buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports);
+ $cache = new PluginAwareStaticCache($key);
+
+ if ($cache->has()) {
+ return $cache->get();
+ }
+
$parameters = array('idSites' => $idSites, 'period' => $period, 'date' => $date);
$availableReports = array();
+ foreach (Report::getAllReports() as $report) {
+ $report->configureReportMetadata($availableReports, $parameters);
+ }
+
/**
* Triggered when gathering metadata for all available reports.
*
@@ -196,12 +210,18 @@ class ProcessedReport
* `'2013-01-01'` or `'2012-01-01,2013-01-01'`.
*
* TODO: put dimensions section in all about analytics data
+ * @deprecated since 2.5.0 Use Report Classes instead.
+ * @ignore
*/
Piwik::postEvent('API.getReportMetadata', array(&$availableReports, $parameters));
+
+ // TODO we can remove this one once we remove API.getReportMetadata event (except hideMetricsDoc)
foreach ($availableReports as &$availableReport) {
+ // can be removed once we remove hook API.getReportMetadata
if (!isset($availableReport['metrics'])) {
$availableReport['metrics'] = Metrics::getDefaultMetrics();
}
+ // can be removed once we remove hook API.getReportMetadata
if (!isset($availableReport['processedMetrics'])) {
$availableReport['processedMetrics'] = Metrics::getDefaultProcessedMetrics();
}
@@ -211,6 +231,7 @@ class ProcessedReport
unset($availableReport['metricsDocumentation']);
} else if (!isset($availableReport['metricsDocumentation'])) {
// set metric documentation to default if it's not set
+ // can be removed once we remove hook API.getReportMetadata
$availableReport['metricsDocumentation'] = Metrics::getDefaultMetricsDocumentation();
}
}
@@ -238,16 +259,20 @@ class ProcessedReport
Piwik::postEvent('API.getReportMetadata.end', array(&$availableReports, $parameters));
// Sort results to ensure consistent order
- usort($availableReports, array($this, 'sort'));
+ usort($availableReports, array('self', 'sortReports'));
// Add the magic API.get report metadata aggregating all plugins API.get API calls automatically
$this->addApiGetMetdata($availableReports);
$knownMetrics = array_merge(Metrics::getDefaultMetrics(), Metrics::getDefaultProcessedMetrics());
+ $columnsToKeep = $this->getColumnsToKeep();
+ $columnsToRemove = $this->getColumnsToRemove();
+
foreach ($availableReports as &$availableReport) {
// Ensure all metrics have a translation
$metrics = $availableReport['metrics'];
$cleanedMetrics = array();
+ // TODO we can remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility
foreach ($metrics as $metricId => $metricTranslation) {
// When simply the column name was given, ie 'metric' => array( 'nb_visits' )
// $metricTranslation is in this case nb_visits. We look for a known translation.
@@ -262,13 +287,13 @@ class ProcessedReport
$availableReport['metrics'] = $cleanedMetrics;
// if hide/show columns specified, hide/show metrics & docs
- $availableReport['metrics'] = $this->hideShowMetrics($availableReport['metrics']);
+ $availableReport['metrics'] = $this->hideShowMetricsWithParams($availableReport['metrics'], $columnsToRemove, $columnsToKeep);
if (isset($availableReport['processedMetrics'])) {
- $availableReport['processedMetrics'] = $this->hideShowMetrics($availableReport['processedMetrics']);
+ $availableReport['processedMetrics'] = $this->hideShowMetricsWithParams($availableReport['processedMetrics'], $columnsToRemove, $columnsToKeep);
}
if (isset($availableReport['metricsDocumentation'])) {
$availableReport['metricsDocumentation'] =
- $this->hideShowMetrics($availableReport['metricsDocumentation']);
+ $this->hideShowMetricsWithParams($availableReport['metricsDocumentation'], $columnsToRemove, $columnsToKeep);
}
// Remove array elements that are false (to clean up API output)
@@ -278,6 +303,7 @@ class ProcessedReport
}
}
// when there are per goal metrics, don't display conversion_rate since it can differ from per goal sum
+ // TODO we should remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility
if (isset($availableReport['metricsGoal'])) {
unset($availableReport['processedMetrics']['conversion_rate']);
unset($availableReport['metricsGoal']['conversion_rate']);
@@ -306,34 +332,28 @@ class ProcessedReport
}
}
- return array_values($availableReports); // make sure array has contiguous key values
+ $actualReports = array_values($availableReports);
+ $cache->set($actualReports);
+
+ return $actualReports; // make sure array has contiguous key values
}
/**
* API metadata are sorted by category/name,
* with a little tweak to replicate the standard Piwik category ordering
*
- * @param string $a
- * @param string $b
+ * @param array $a
+ * @param array $b
* @return int
*/
- private function sort($a, $b)
+ private static function sortReports($a, $b)
{
static $order = null;
if (is_null($order)) {
- $order = array(
- Piwik::translate('General_MultiSitesSummary'),
- Piwik::translate('VisitsSummary_VisitsSummary'),
- Piwik::translate('Goals_Ecommerce'),
- Piwik::translate('General_Actions'),
- Piwik::translate('Events_Events'),
- Piwik::translate('Actions_SubmenuSitesearch'),
- Piwik::translate('Referrers_Referrers'),
- Piwik::translate('Goals_Goals'),
- Piwik::translate('General_Visitors'),
- Piwik::translate('DevicesDetection_DevicesDetection'),
- Piwik::translate('UserSettings_VisitorSettings'),
- );
+ $order = array();
+ foreach (Report::$orderOfReports as $category) {
+ $order[] = Piwik::translate($category);
+ }
}
return ($category = strcmp(array_search($a['category'], $order), array_search($b['category'], $order))) == 0
? (@$a['order'] < @$b['order'] ? -1 : 1)
@@ -553,14 +573,17 @@ class ProcessedReport
return;
}
- $columns = $this->hideShowMetrics($columns, $emptyColumns);
+ $columnsToRemove = $this->getColumnsToRemove();
+ $columnsToKeep = $this->getColumnsToKeep();
+
+ $columns = $this->hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns);
if (isset($reportMetadata['metrics'])) {
- $reportMetadata['metrics'] = $this->hideShowMetrics($reportMetadata['metrics'], $emptyColumns);
+ $reportMetadata['metrics'] = $this->hideShowMetricsWithParams($reportMetadata['metrics'], $columnsToRemove, $columnsToKeep, $emptyColumns);
}
if (isset($reportMetadata['metricsDocumentation'])) {
- $reportMetadata['metricsDocumentation'] = $this->hideShowMetrics($reportMetadata['metricsDocumentation'], $emptyColumns);
+ $reportMetadata['metricsDocumentation'] = $this->hideShowMetricsWithParams($reportMetadata['metricsDocumentation'], $columnsToRemove, $columnsToKeep, $emptyColumns);
}
}
@@ -580,9 +603,21 @@ class ProcessedReport
}
// remove columns if hideColumns query parameters exist
- $columnsToRemove = Common::getRequestVar('hideColumns', '');
- if ($columnsToRemove != '') {
- $columnsToRemove = explode(',', $columnsToRemove);
+ $columnsToRemove = $this->getColumnsToRemove();
+
+ // remove columns if showColumns query parameters exist
+ $columnsToKeep = $this->getColumnsToKeep();
+
+ return $this->hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns);
+ }
+
+ private function hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns = array())
+ {
+ if (!is_array($columns)) {
+ return $columns;
+ }
+
+ if (null !== $columnsToRemove) {
foreach ($columnsToRemove as $name) {
// if a column to remove is in the column list, remove it
if (isset($columns[$name])) {
@@ -591,12 +626,7 @@ class ProcessedReport
}
}
- // remove columns if showColumns query parameters exist
- $columnsToKeep = Common::getRequestVar('showColumns', '');
- if ($columnsToKeep != '') {
- $columnsToKeep = explode(',', $columnsToKeep);
- $columnsToKeep[] = 'label';
-
+ if (null !== $columnsToKeep) {
foreach ($columns as $name => $ignore) {
// if the current column should not be kept, remove it
$idx = array_search($name, $columnsToKeep);
@@ -732,4 +762,55 @@ class ProcessedReport
return $totals;
}
+
+ private function getColumnsToRemove()
+ {
+ $columnsToRemove = Common::getRequestVar('hideColumns', '');
+
+ if ($columnsToRemove != '') {
+ return explode(',', $columnsToRemove);
+ }
+
+ return null;
+ }
+
+ private function getColumnsToKeep()
+ {
+ $columnsToKeep = Common::getRequestVar('showColumns', '');
+
+ if ($columnsToKeep != '') {
+ $columnsToKeep = explode(',', $columnsToKeep);
+ $columnsToKeep[] = 'label';
+
+ return $columnsToKeep;
+ }
+
+ return null;
+ }
+
+ private function buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports)
+ {
+ if (isset($_GET) && isset($_POST) && is_array($_GET) && is_array($_POST)) {
+ $request = $_GET + $_POST;
+ } elseif (isset($_GET) && is_array($_GET)) {
+ $request = $_GET;
+ } elseif (isset($_POST) && is_array($_POST)) {
+ $request = $_POST;
+ } else {
+ $request = array();
+ }
+
+ $key = '';
+ foreach ($request as $k => $v) {
+ if (is_array($v)) {
+ $key .= $k . implode(',',$v) . ',';
+ } else {
+ $key .= $k . $v . ',';
+ }
+ }
+
+ $key .= implode(',', $idSites) . ($period === false ? 0 : $period) . ($date === false ? 0 : $date);
+ $key .= (int)$hideMetricsDoc . (int)$showSubtableReports . Piwik::getCurrentUserLogin();
+ return 'reportMetadata' . md5($key);
+ }
}
diff --git a/plugins/Actions/API.php b/plugins/Actions/API.php
index 60f774536a..c915060885 100644
--- a/plugins/Actions/API.php
+++ b/plugins/Actions/API.php
@@ -17,8 +17,8 @@ use Piwik\Date;
use Piwik\Metrics;
use Piwik\Piwik;
use Piwik\Plugins\CustomVariables\API as APICustomVariables;
+use Piwik\Plugins\Actions\Actions\ActionSiteSearch;
use Piwik\Tracker\Action;
-use Piwik\Tracker\ActionSiteSearch;
use Piwik\Tracker\PageUrl;
/**
diff --git a/plugins/Actions/Actions.php b/plugins/Actions/Actions.php
index f39e150fd7..91042fce4f 100644
--- a/plugins/Actions/Actions.php
+++ b/plugins/Actions/Actions.php
@@ -8,15 +8,12 @@
*/
namespace Piwik\Plugins\Actions;
-use Piwik\API\Request;
use Piwik\ArchiveProcessor;
use Piwik\Common;
use Piwik\Db;
-use Piwik\MetricsFormatter;
-use Piwik\Piwik;
+use Piwik\Site;
use Piwik\Plugin\ViewDataTable;
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
-use Piwik\Site;
/**
* Actions plugin
@@ -33,15 +30,57 @@ class Actions extends \Piwik\Plugin
*/
public function getListHooksRegistered()
{
- $hooks = array(
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
+ return array(
'ViewDataTable.configure' => 'configureViewDataTable',
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
- 'Insights.addReportToOverview' => 'addReportToInsightsOverview'
+ 'Insights.addReportToOverview' => 'addReportToInsightsOverview',
+ 'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations',
+ 'Metrics.getDefaultMetricDocumentationTranslations' => 'addMetricDocumentationTranslations'
);
- return $hooks;
+ }
+
+ public function addMetricTranslations(&$translations)
+ {
+ $metrics = array(
+ 'nb_pageviews' => 'General_ColumnPageviews',
+ 'nb_uniq_pageviews' => 'General_ColumnUniquePageviews',
+ 'nb_downloads' => 'General_Downloads',
+ 'nb_uniq_downloads' => 'Actions_ColumnUniqueDownloads',
+ 'nb_outlinks' => 'General_Outlinks',
+ 'nb_uniq_outlinks' => 'Actions_ColumnUniqueOutlinks',
+ 'nb_searches' => 'Actions_ColumnSearches',
+ 'nb_keywords' => 'Actions_ColumnSiteSearchKeywords',
+ 'avg_time_generation' => 'General_ColumnAverageGenerationTime',
+ 'exit_rate' => 'General_ColumnExitRate',
+ 'entry_nb_visits' => 'General_ColumnEntrances',
+ 'entry_bounce_count' => 'General_ColumnBounces',
+ 'exit_nb_visits' => 'General_ColumnExits',
+ 'nb_pages_per_search' => 'Actions_ColumnPagesPerSearch',
+ 'nb_hits_following_search' => 'General_ColumnViewedAfterSearch',
+ );
+
+ $translations = array_merge($translations, $metrics);
+ }
+
+ public function addMetricDocumentationTranslations(&$translations)
+ {
+ $metrics = array(
+ 'nb_pageviews' => 'General_ColumnPageviewsDocumentation',
+ 'nb_uniq_pageviews' => 'General_ColumnUniquePageviewsDocumentation',
+ 'nb_downloads' => 'Actions_ColumnClicksDocumentation',
+ 'nb_uniq_downloads' => 'Actions_ColumnUniqueClicksDocumentation',
+ 'nb_outlinks' => 'Actions_ColumnClicksDocumentation',
+ 'nb_uniq_outlinks' => 'Actions_ColumnUniqueClicksDocumentation',
+ 'nb_searches' => 'Actions_ColumnSearchesDocumentation',
+ 'avg_time_generation' => 'General_ColumnAverageGenerationTimeDocumentation',
+ 'entry_nb_visits' => 'General_ColumnEntrancesDocumentation',
+ 'entry_bounce_count' => 'General_ColumnBouncesDocumentation',
+ 'exit_nb_visits' => 'General_ColumnExitsDocumentation',
+ 'exit_rate' => 'General_ColumnExitRateDocumentation'
+ );
+
+ $translations = array_merge($translations, $metrics);
}
public function addReportToInsightsOverview(&$reports)
@@ -61,403 +100,6 @@ class Actions extends \Piwik\Plugin
$jsFiles[] = "plugins/Actions/javascripts/actionsDataTable.js";
}
- public function getSegmentsMetadata(&$segments)
- {
- $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment';
-
- // entry and exit pages of visit
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'General_Actions',
- 'name' => 'Actions_ColumnEntryPageURL',
- 'segment' => 'entryPageUrl',
- 'sqlSegment' => 'log_visit.visit_entry_idaction_url',
- 'sqlFilter' => $sqlFilter,
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'General_Actions',
- 'name' => 'Actions_ColumnEntryPageTitle',
- 'segment' => 'entryPageTitle',
- 'sqlSegment' => 'log_visit.visit_entry_idaction_name',
- 'sqlFilter' => $sqlFilter,
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'General_Actions',
- 'name' => 'Actions_ColumnExitPageURL',
- 'segment' => 'exitPageUrl',
- 'sqlSegment' => 'log_visit.visit_exit_idaction_url',
- 'sqlFilter' => $sqlFilter,
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'General_Actions',
- 'name' => 'Actions_ColumnExitPageTitle',
- 'segment' => 'exitPageTitle',
- 'sqlSegment' => 'log_visit.visit_exit_idaction_name',
- 'sqlFilter' => $sqlFilter,
- );
-
- // single pages
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'General_Actions',
- 'name' => 'Actions_ColumnPageURL',
- 'segment' => 'pageUrl',
- 'sqlSegment' => 'log_link_visit_action.idaction_url',
- 'sqlFilter' => $sqlFilter,
- 'acceptedValues' => "All these segments must be URL encoded, for example: " . urlencode('http://example.com/path/page?query'),
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'General_Actions',
- 'name' => 'Actions_ColumnPageName',
- 'segment' => 'pageTitle',
- 'sqlSegment' => 'log_link_visit_action.idaction_name',
- 'sqlFilter' => $sqlFilter,
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'General_Actions',
- 'name' => 'Actions_SiteSearchKeyword',
- 'segment' => 'siteSearchKeyword',
- 'sqlSegment' => 'log_link_visit_action.idaction_name',
- 'sqlFilter' => $sqlFilter,
- );
- }
-
- public function getReportMetadata(&$reports)
- {
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('General_Actions') . ' - ' . Piwik::translate('General_MainMetrics'),
- 'module' => 'Actions',
- 'action' => 'get',
- 'metrics' => array(
- 'nb_pageviews' => Piwik::translate('General_ColumnPageviews'),
- 'nb_uniq_pageviews' => Piwik::translate('General_ColumnUniquePageviews'),
- 'nb_downloads' => Piwik::translate('General_Downloads'),
- 'nb_uniq_downloads' => Piwik::translate('Actions_ColumnUniqueDownloads'),
- 'nb_outlinks' => Piwik::translate('General_Outlinks'),
- 'nb_uniq_outlinks' => Piwik::translate('Actions_ColumnUniqueOutlinks'),
- 'nb_searches' => Piwik::translate('Actions_ColumnSearches'),
- 'nb_keywords' => Piwik::translate('Actions_ColumnSiteSearchKeywords'),
- 'avg_time_generation' => Piwik::translate('General_ColumnAverageGenerationTime'),
- ),
- 'metricsDocumentation' => array(
- 'nb_pageviews' => Piwik::translate('General_ColumnPageviewsDocumentation'),
- 'nb_uniq_pageviews' => Piwik::translate('General_ColumnUniquePageviewsDocumentation'),
- 'nb_downloads' => Piwik::translate('Actions_ColumnClicksDocumentation'),
- 'nb_uniq_downloads' => Piwik::translate('Actions_ColumnUniqueClicksDocumentation'),
- 'nb_outlinks' => Piwik::translate('Actions_ColumnClicksDocumentation'),
- 'nb_uniq_outlinks' => Piwik::translate('Actions_ColumnUniqueClicksDocumentation'),
- 'nb_searches' => Piwik::translate('Actions_ColumnSearchesDocumentation'),
- 'avg_time_generation' => Piwik::translate('General_ColumnAverageGenerationTimeDocumentation'),
-// 'nb_keywords' => Piwik::translate('Actions_ColumnSiteSearchKeywords'),
- ),
- 'processedMetrics' => false,
- 'order' => 1
- );
-
- $metrics = array(
- 'nb_hits' => Piwik::translate('General_ColumnPageviews'),
- 'nb_visits' => Piwik::translate('General_ColumnUniquePageviews'),
- 'bounce_rate' => Piwik::translate('General_ColumnBounceRate'),
- 'avg_time_on_page' => Piwik::translate('General_ColumnAverageTimeOnPage'),
- 'exit_rate' => Piwik::translate('General_ColumnExitRate'),
- 'avg_time_generation' => Piwik::translate('General_ColumnAverageGenerationTime')
- );
-
- $documentation = array(
- 'nb_hits' => Piwik::translate('General_ColumnPageviewsDocumentation'),
- 'nb_visits' => Piwik::translate('General_ColumnUniquePageviewsDocumentation'),
- 'bounce_rate' => Piwik::translate('General_ColumnPageBounceRateDocumentation'),
- 'avg_time_on_page' => Piwik::translate('General_ColumnAverageTimeOnPageDocumentation'),
- 'exit_rate' => Piwik::translate('General_ColumnExitRateDocumentation'),
- 'avg_time_generation' => Piwik::translate('General_ColumnAverageGenerationTimeDocumentation'),
- );
-
- // pages report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('Actions_PageUrls'),
- 'module' => 'Actions',
- 'action' => 'getPageUrls',
- 'dimension' => Piwik::translate('Actions_ColumnPageURL'),
- 'metrics' => $metrics,
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik::translate('Actions_PagesReportDocumentation', '<br />')
- . '<br />' . Piwik::translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getPageUrls',
- 'order' => 2
- );
-
- // entry pages report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('Actions_SubmenuPagesEntry'),
- 'module' => 'Actions',
- 'action' => 'getEntryPageUrls',
- 'dimension' => Piwik::translate('Actions_ColumnPageURL'),
- 'metrics' => array(
- 'entry_nb_visits' => Piwik::translate('General_ColumnEntrances'),
- 'entry_bounce_count' => Piwik::translate('General_ColumnBounces'),
- 'bounce_rate' => Piwik::translate('General_ColumnBounceRate'),
- ),
- 'metricsDocumentation' => array(
- 'entry_nb_visits' => Piwik::translate('General_ColumnEntrancesDocumentation'),
- 'entry_bounce_count' => Piwik::translate('General_ColumnBouncesDocumentation'),
- 'bounce_rate' => Piwik::translate('General_ColumnBounceRateForPageDocumentation')
- ),
- 'documentation' => Piwik::translate('Actions_EntryPagesReportDocumentation', '<br />')
- . ' ' . Piwik::translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getEntryPageUrls',
- 'order' => 3
- );
-
- // exit pages report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('Actions_SubmenuPagesExit'),
- 'module' => 'Actions',
- 'action' => 'getExitPageUrls',
- 'dimension' => Piwik::translate('Actions_ColumnPageURL'),
- 'metrics' => array(
- 'exit_nb_visits' => Piwik::translate('General_ColumnExits'),
- 'nb_visits' => Piwik::translate('General_ColumnUniquePageviews'),
- 'exit_rate' => Piwik::translate('General_ColumnExitRate')
- ),
- 'metricsDocumentation' => array(
- 'exit_nb_visits' => Piwik::translate('General_ColumnExitsDocumentation'),
- 'nb_visits' => Piwik::translate('General_ColumnUniquePageviewsDocumentation'),
- 'exit_rate' => Piwik::translate('General_ColumnExitRateDocumentation')
- ),
- 'documentation' => Piwik::translate('Actions_ExitPagesReportDocumentation', '<br />')
- . ' ' . Piwik::translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getExitPageUrls',
- 'order' => 4
- );
-
- // page titles report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('Actions_SubmenuPageTitles'),
- 'module' => 'Actions',
- 'action' => 'getPageTitles',
- 'dimension' => Piwik::translate('Actions_ColumnPageName'),
- 'metrics' => $metrics,
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik::translate('Actions_PageTitlesReportDocumentation', array('<br />', htmlentities('<title>'))),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getPageTitles',
- 'order' => 5,
-
- );
-
- // entry page titles report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('Actions_EntryPageTitles'),
- 'module' => 'Actions',
- 'action' => 'getEntryPageTitles',
- 'dimension' => Piwik::translate('Actions_ColumnPageName'),
- 'metrics' => array(
- 'entry_nb_visits' => Piwik::translate('General_ColumnEntrances'),
- 'entry_bounce_count' => Piwik::translate('General_ColumnBounces'),
- 'bounce_rate' => Piwik::translate('General_ColumnBounceRate'),
- ),
- 'metricsDocumentation' => array(
- 'entry_nb_visits' => Piwik::translate('General_ColumnEntrancesDocumentation'),
- 'entry_bounce_count' => Piwik::translate('General_ColumnBouncesDocumentation'),
- 'bounce_rate' => Piwik::translate('General_ColumnBounceRateForPageDocumentation')
- ),
- 'documentation' => Piwik::translate('Actions_ExitPageTitlesReportDocumentation', '<br />')
- . ' ' . Piwik::translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getEntryPageTitles',
- 'order' => 6
- );
-
- // exit page titles report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('Actions_ExitPageTitles'),
- 'module' => 'Actions',
- 'action' => 'getExitPageTitles',
- 'dimension' => Piwik::translate('Actions_ColumnPageName'),
- 'metrics' => array(
- 'exit_nb_visits' => Piwik::translate('General_ColumnExits'),
- 'nb_visits' => Piwik::translate('General_ColumnUniquePageviews'),
- 'exit_rate' => Piwik::translate('General_ColumnExitRate')
- ),
- 'metricsDocumentation' => array(
- 'exit_nb_visits' => Piwik::translate('General_ColumnExitsDocumentation'),
- 'nb_visits' => Piwik::translate('General_ColumnUniquePageviewsDocumentation'),
- 'exit_rate' => Piwik::translate('General_ColumnExitRateDocumentation')
- ),
- 'documentation' => Piwik::translate('Actions_EntryPageTitlesReportDocumentation', '<br />')
- . ' ' . Piwik::translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getExitPageTitles',
- 'order' => 7
- );
-
- $documentation = array(
- 'nb_visits' => Piwik::translate('Actions_ColumnUniqueClicksDocumentation'),
- 'nb_hits' => Piwik::translate('Actions_ColumnClicksDocumentation')
- );
-
- // outlinks report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('General_Outlinks'),
- 'module' => 'Actions',
- 'action' => 'getOutlinks',
- 'dimension' => Piwik::translate('Actions_ColumnClickedURL'),
- 'metrics' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnUniqueClicks'),
- 'nb_hits' => Piwik::translate('Actions_ColumnClicks')
- ),
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik::translate('Actions_OutlinksReportDocumentation') . ' '
- . Piwik::translate('Actions_OutlinkDocumentation') . '<br />'
- . Piwik::translate('General_UsePlusMinusIconsDocumentation'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getOutlinks',
- 'order' => 8,
- );
-
- // downloads report
- $reports[] = array(
- 'category' => Piwik::translate('General_Actions'),
- 'name' => Piwik::translate('General_Downloads'),
- 'module' => 'Actions',
- 'action' => 'getDownloads',
- 'dimension' => Piwik::translate('Actions_ColumnDownloadURL'),
- 'metrics' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnUniqueDownloads'),
- 'nb_hits' => Piwik::translate('General_Downloads')
- ),
- 'metricsDocumentation' => $documentation,
- 'documentation' => Piwik::translate('Actions_DownloadsReportDocumentation', '<br />'),
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => 'getDownloads',
- 'order' => 9,
- );
-
- if ($this->isSiteSearchEnabled()) {
- // Search Keywords
- $reports[] = array(
- 'category' => Piwik::translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik::translate('Actions_WidgetSearchKeywords'),
- 'module' => 'Actions',
- 'action' => 'getSiteSearchKeywords',
- 'dimension' => Piwik::translate('General_ColumnKeyword'),
- 'metrics' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
- 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearch'),
- 'exit_rate' => Piwik::translate('Actions_ColumnSearchExits'),
- ),
- 'metricsDocumentation' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnSearchesDocumentation'),
- 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearchDocumentation'),
- 'exit_rate' => Piwik::translate('Actions_ColumnSearchExitsDocumentation'),
- ),
- 'documentation' => Piwik::translate('Actions_SiteSearchKeywordsDocumentation') . '<br/><br/>' . Piwik::translate('Actions_SiteSearchIntro') . '<br/><br/>'
- . '<a href="http://piwik.org/docs/site-search/" target="_blank">' . Piwik::translate('Actions_LearnMoreAboutSiteSearchLink') . '</a>',
- 'processedMetrics' => false,
- 'order' => 15
- );
- // No Result Search Keywords
- $reports[] = array(
- 'category' => Piwik::translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik::translate('Actions_WidgetSearchNoResultKeywords'),
- 'module' => 'Actions',
- 'action' => 'getSiteSearchNoResultKeywords',
- 'dimension' => Piwik::translate('Actions_ColumnNoResultKeyword'),
- 'metrics' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
- 'exit_rate' => Piwik::translate('Actions_ColumnSearchExits'),
- ),
- 'metricsDocumentation' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnSearchesDocumentation'),
- 'exit_rate' => Piwik::translate('Actions_ColumnSearchExitsDocumentation'),
- ),
- 'documentation' => Piwik::translate('Actions_SiteSearchIntro') . '<br /><br />' . Piwik::translate('Actions_SiteSearchKeywordsNoResultDocumentation'),
- 'processedMetrics' => false,
- 'order' => 16
- );
-
- if (self::isCustomVariablesPluginsEnabled()) {
- // Search Categories
- $reports[] = array(
- 'category' => Piwik::translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik::translate('Actions_WidgetSearchCategories'),
- 'module' => 'Actions',
- 'action' => 'getSiteSearchCategories',
- 'dimension' => Piwik::translate('Actions_ColumnSearchCategory'),
- 'metrics' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
- 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearch'),
- 'exit_rate' => Piwik::translate('Actions_ColumnSearchExits'),
- ),
- 'metricsDocumentation' => array(
- 'nb_visits' => Piwik::translate('Actions_ColumnSearchesDocumentation'),
- 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearchDocumentation'),
- 'exit_rate' => Piwik::translate('Actions_ColumnSearchExitsDocumentation'),
- ),
- 'documentation' => Piwik::translate('Actions_SiteSearchCategories1') . '<br/>' . Piwik::translate('Actions_SiteSearchCategories2'),
- 'processedMetrics' => false,
- 'order' => 17
- );
- }
-
- $documentation = Piwik::translate('Actions_SiteSearchFollowingPagesDoc') . '<br/>' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
- // Pages URLs following Search
- $reports[] = array(
- 'category' => Piwik::translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik::translate('Actions_WidgetPageUrlsFollowingSearch'),
- 'module' => 'Actions',
- 'action' => 'getPageUrlsFollowingSiteSearch',
- 'dimension' => Piwik::translate('General_ColumnDestinationPage'),
- 'metrics' => array(
- 'nb_hits_following_search' => Piwik::translate('General_ColumnViewedAfterSearch'),
- 'nb_hits' => Piwik::translate('General_ColumnTotalPageviews'),
- ),
- 'metricsDocumentation' => array(
- 'nb_hits_following_search' => Piwik::translate('General_ColumnViewedAfterSearchDocumentation'),
- 'nb_hits' => Piwik::translate('General_ColumnPageviewsDocumentation'),
- ),
- 'documentation' => $documentation,
- 'processedMetrics' => false,
- 'order' => 18
- );
- // Pages Titles following Search
- $reports[] = array(
- 'category' => Piwik::translate('Actions_SubmenuSitesearch'),
- 'name' => Piwik::translate('Actions_WidgetPageTitlesFollowingSearch'),
- 'module' => 'Actions',
- 'action' => 'getPageTitlesFollowingSiteSearch',
- 'dimension' => Piwik::translate('General_ColumnDestinationPage'),
- 'metrics' => array(
- 'nb_hits_following_search' => Piwik::translate('General_ColumnViewedAfterSearch'),
- 'nb_hits' => Piwik::translate('General_ColumnTotalPageviews'),
- ),
- 'metricsDocumentation' => array(
- 'nb_hits_following_search' => Piwik::translate('General_ColumnViewedAfterSearchDocumentation'),
- 'nb_hits' => Piwik::translate('General_ColumnPageviewsDocumentation'),
- ),
- 'documentation' => $documentation,
- 'processedMetrics' => false,
- 'order' => 19
- );
- }
- }
-
public function isSiteSearchEnabled()
{
$idSite = Common::getRequestVar('idSite', 0, 'int');
@@ -495,48 +137,6 @@ class Actions extends \Piwik\Plugin
public function configureViewDataTable(ViewDataTable $view)
{
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'Actions.getPageUrls':
- $this->configureViewForPageUrls($view);
- break;
- case 'Actions.getEntryPageUrls':
- $this->configureViewForEntryPageUrls($view);
- break;
- case 'Actions.getExitPageUrls':
- $this->configureViewForExitPageUrls($view);
- break;
- case 'Actions.getSiteSearchKeywords':
- $this->configureViewForSiteSearchKeywords($view);
- break;
- case 'Actions.getSiteSearchNoResultKeywords':
- $this->configureViewForSiteSearchNoResultKeywords($view);
- break;
- case 'Actions.getSiteSearchCategories':
- $this->configureViewForSiteSearchCategories($view);
- break;
- case 'Actions.getPageUrlsFollowingSiteSearch':
- $this->configureViewForGetPageUrlsOrTitlesFollowingSiteSearch($view, false);
- break;
- case 'Actions.getPageTitlesFollowingSiteSearch':
- $this->configureViewForGetPageUrlsOrTitlesFollowingSiteSearch($view, true);
- break;
- case 'Actions.getPageTitles':
- $this->configureViewForGetPageTitles($view);
- break;
- case 'Actions.getEntryPageTitles':
- $this->configureViewForGetEntryPageTitles($view);
- break;
- case 'Actions.getExitPageTitles':
- $this->configureViewForGetExitPageTitles($view);
- break;
- case 'Actions.getDownloads':
- $this->configureViewForGetDownloads($view);
- break;
- case 'Actions.getOutlinks':
- $this->configureViewForGetOutlinks($view);
- break;
- }
-
if ($this->pluginName == $view->requestConfig->getApiModuleToRequest()) {
if ($view->isRequestingSingleDataTable()) {
// make sure custom visualizations are shown on actions reports
@@ -548,36 +148,6 @@ class Actions extends \Piwik\Plugin
}
}
- private function addBaseDisplayProperties(ViewDataTable $view)
- {
- $view->config->datatable_js_type = 'ActionsDataTable';
- $view->config->search_recursive = true;
- $view->config->show_table_all_columns = false;
- $view->requestConfig->filter_limit = self::ACTIONS_REPORT_ROWS_DISPLAY;
- $view->config->show_all_views_icons = false;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->show_embedded_subtable = true;
- }
-
- if (Request::shouldLoadExpanded()) {
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->show_expanded = true;
- }
-
- $view->config->filters[] = function ($dataTable) {
- Actions::setDataTableRowLevels($dataTable);
- };
- }
-
- $view->config->filters[] = function ($dataTable) use ($view) {
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->datatable_css_class = 'dataTableActions';
- }
- };
- }
-
/**
* @param \Piwik\DataTable $dataTable
* @param int $level
@@ -594,297 +164,6 @@ class Actions extends \Piwik\Plugin
}
}
- private function addExcludeLowPopDisplayProperties(ViewDataTable $view)
- {
- if (Common::getRequestVar('enable_filter_excludelowpop', '0', 'string') != '0') {
- $view->requestConfig->filter_excludelowpop = 'nb_hits';
- $view->requestConfig->filter_excludelowpop_value = function () {
- // computing minimum value to exclude (2 percent of the total number of actions)
- $visitsInfo = \Piwik\Plugins\VisitsSummary\Controller::getVisitsSummary()->getFirstRow();
- $nbActions = $visitsInfo->getColumn('nb_actions');
- $nbActionsLowPopulationThreshold = floor(0.02 * $nbActions);
-
- // we remove 1 to make sure some actions/downloads are displayed in the case we have a very few of them
- // and each of them has 1 or 2 hits...
- return min($visitsInfo->getColumn('max_actions') - 1, $nbActionsLowPopulationThreshold - 1);
- };
- }
- }
-
- private function addPageDisplayProperties(ViewDataTable $view)
- {
- $view->config->addTranslations(array(
- 'nb_hits' => Piwik::translate('General_ColumnPageviews'),
- 'nb_visits' => Piwik::translate('General_ColumnUniquePageviews'),
- 'avg_time_on_page' => Piwik::translate('General_ColumnAverageTimeOnPage'),
- 'bounce_rate' => Piwik::translate('General_ColumnBounceRate'),
- 'exit_rate' => Piwik::translate('General_ColumnExitRate'),
- 'avg_time_generation' => Piwik::translate('General_ColumnAverageGenerationTime'),
- ));
-
- // prettify avg_time_on_page column
- $getPrettyTimeFromSeconds = '\Piwik\MetricsFormatter::getPrettyTimeFromSeconds';
- $view->config->filters[] = array('ColumnCallbackReplace', array('avg_time_on_page', $getPrettyTimeFromSeconds));
-
- // prettify avg_time_generation column
- $avgTimeCallback = function ($time) {
- return $time ? MetricsFormatter::getPrettyTimeFromSeconds($time, true, true, false) : "-";
- };
- $view->config->filters[] = array('ColumnCallbackReplace', array('avg_time_generation', $avgTimeCallback));
-
- // add avg_generation_time tooltip
- $tooltipCallback = function ($hits, $min, $max) {
- if (!$hits) {
- return false;
- }
-
- return Piwik::translate("Actions_AvgGenerationTimeTooltip", array(
- $hits,
- "<br />",
- MetricsFormatter::getPrettyTimeFromSeconds($min),
- MetricsFormatter::getPrettyTimeFromSeconds($max)
- ));
- };
- $view->config->filters[] = array('ColumnCallbackAddMetadata',
- array(
- array('nb_hits_with_time_generation', 'min_time_generation', 'max_time_generation'),
- 'avg_time_generation_tooltip',
- $tooltipCallback
- )
- );
-
- $this->addExcludeLowPopDisplayProperties($view);
- }
-
- public function configureViewForPageUrls(ViewDataTable $view)
- {
- $view->config->addTranslation('label', Piwik::translate('Actions_ColumnPageURL'));
- $view->config->columns_to_display = array('label', 'nb_hits', 'nb_visits', 'bounce_rate',
- 'avg_time_on_page', 'exit_rate', 'avg_time_generation');
-
- $this->addPageDisplayProperties($view);
- $this->addBaseDisplayProperties($view);
- }
-
- public function configureViewForEntryPageUrls(ViewDataTable $view)
- {
- // link to the page, not just the report, but only if not a widget
- $widget = Common::getRequestVar('widget', false);
-
- $view->config->self_url = Request::getCurrentUrlWithoutGenericFilters(array(
- 'module' => 'Actions',
- 'action' => $widget === false ? 'indexEntryPageUrls' : 'getEntryPageUrls'
- ));
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Actions_ColumnEntryPageURL'),
- 'entry_bounce_count' => Piwik::translate('General_ColumnBounces'),
- 'entry_nb_visits' => Piwik::translate('General_ColumnEntrances'))
- );
-
- $view->config->title = Piwik::translate('Actions_SubmenuPagesEntry');
- $view->config->addRelatedReport('Actions.getEntryPageTitles', Piwik::translate('Actions_EntryPageTitles'));
- $view->config->columns_to_display = array('label', 'entry_nb_visits', 'entry_bounce_count', 'bounce_rate');
- $view->requestConfig->filter_sort_column = 'entry_nb_visits';
- $view->requestConfig->filter_sort_order = 'desc';
-
- $this->addPageDisplayProperties($view);
- $this->addBaseDisplayProperties($view);
- }
-
- public function configureViewForExitPageUrls(ViewDataTable $view)
- {
- // link to the page, not just the report, but only if not a widget
- $widget = Common::getRequestVar('widget', false);
-
- $view->config->self_url = Request::getCurrentUrlWithoutGenericFilters(array(
- 'module' => 'Actions',
- 'action' => $widget === false ? 'indexExitPageUrls' : 'getExitPageUrls'
- ));
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Actions_ColumnExitPageURL'),
- 'exit_nb_visits' => Piwik::translate('General_ColumnExits'))
- );
-
- $view->config->title = Piwik::translate('Actions_SubmenuPagesExit');
- $view->config->addRelatedReport('Actions.getExitPageTitles', Piwik::translate('Actions_ExitPageTitles'));
-
- $view->config->columns_to_display = array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate');
- $view->requestConfig->filter_sort_column = 'exit_nb_visits';
- $view->requestConfig->filter_sort_order = 'desc';
-
- $this->addPageDisplayProperties($view);
- $this->addBaseDisplayProperties($view);
- }
-
- private function addSiteSearchDisplayProperties(ViewDataTable $view)
- {
- $view->config->addTranslations(array(
- 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
- 'exit_rate' => str_replace("% ", "%&nbsp;", Piwik::translate('Actions_ColumnSearchExits')),
- 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearch')
- ));
-
- $view->config->show_bar_chart = false;
- $view->config->show_table_all_columns = false;
- }
-
- public function configureViewForSiteSearchKeywords(ViewDataTable $view)
- {
- $view->config->addTranslation('label', Piwik::translate('General_ColumnKeyword'));
- $view->config->columns_to_display = array('label', 'nb_visits', 'nb_pages_per_search', 'exit_rate');
-
- $this->addSiteSearchDisplayProperties($view);
- }
-
- public function configureViewForSiteSearchNoResultKeywords(ViewDataTable $view)
- {
- $view->config->addTranslation('label', Piwik::translate('Actions_ColumnNoResultKeyword'));
- $view->config->columns_to_display = array('label', 'nb_visits', 'exit_rate');
-
- $this->addSiteSearchDisplayProperties($view);
- }
-
- public function configureViewForSiteSearchCategories(ViewDataTable $view)
- {
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Actions_ColumnSearchCategory'),
- 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
- 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearch')
- ));
-
- $view->config->columns_to_display = array('label', 'nb_visits', 'nb_pages_per_search');
- $view->config->show_table_all_columns = false;
- $view->config->show_bar_chart = false;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->disable_row_evolution = false;
- }
- }
-
- public function configureViewForGetPageUrlsOrTitlesFollowingSiteSearch(ViewDataTable $view, $isTitle)
- {
- $title = $isTitle ? Piwik::translate('Actions_WidgetPageTitlesFollowingSearch')
- : Piwik::translate('Actions_WidgetPageUrlsFollowingSearch');
-
- $relatedReports = array(
- 'Actions.getPageTitlesFollowingSiteSearch' => Piwik::translate('Actions_WidgetPageTitlesFollowingSearch'),
- 'Actions.getPageUrlsFollowingSiteSearch' => Piwik::translate('Actions_WidgetPageUrlsFollowingSearch'),
- );
-
- $view->config->addRelatedReports($relatedReports);
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('General_ColumnDestinationPage'),
- 'nb_hits_following_search' => Piwik::translate('General_ColumnViewedAfterSearch'),
- 'nb_hits' => Piwik::translate('General_ColumnTotalPageviews')
- ));
-
- $view->config->title = $title;
- $view->config->columns_to_display = array('label', 'nb_hits_following_search', 'nb_hits');
- $view->config->show_exclude_low_population = false;
- $view->requestConfig->filter_sort_column = 'nb_hits_following_search';
- $view->requestConfig->filter_sort_order = 'desc';
-
- $this->addExcludeLowPopDisplayProperties($view);
- $this->addBaseDisplayProperties($view);
- }
-
- public function configureViewForGetPageTitles(ViewDataTable $view)
- {
- // link to the page, not just the report, but only if not a widget
- $widget = Common::getRequestVar('widget', false);
-
- $view->config->self_url = Request::getCurrentUrlWithoutGenericFilters(array(
- 'module' => 'Actions',
- 'action' => $widget === false ? 'indexPageTitles' : 'getPageTitles'
- ));
-
- $view->config->title = Piwik::translate('Actions_SubmenuPageTitles');
- $view->config->addRelatedReports(array(
- 'Actions.getEntryPageTitles' => Piwik::translate('Actions_EntryPageTitles'),
- 'Actions.getExitPageTitles' => Piwik::translate('Actions_ExitPageTitles'),
- ));
-
- $view->config->addTranslation('label', Piwik::translate('Actions_ColumnPageName'));
- $view->config->columns_to_display = array('label', 'nb_hits', 'nb_visits', 'bounce_rate',
- 'avg_time_on_page', 'exit_rate', 'avg_time_generation');
-
- $this->addPageDisplayProperties($view);
- $this->addBaseDisplayProperties($view);
- }
-
- public function configureViewForGetEntryPageTitles(ViewDataTable $view)
- {
- $entryPageUrlAction =
- Common::getRequestVar('widget', false) === false ? 'indexEntryPageUrls' : 'getEntryPageUrls';
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Actions_ColumnEntryPageTitle'),
- 'entry_bounce_count' => Piwik::translate('General_ColumnBounces'),
- 'entry_nb_visits' => Piwik::translate('General_ColumnEntrances'),
- ));
- $view->config->addRelatedReports(array(
- 'Actions.getPageTitles' => Piwik::translate('Actions_SubmenuPageTitles'),
- "Actions.$entryPageUrlAction" => Piwik::translate('Actions_SubmenuPagesEntry')
- ));
-
- $view->config->columns_to_display = array('label', 'entry_nb_visits', 'entry_bounce_count', 'bounce_rate');
- $view->config->title = Piwik::translate('Actions_EntryPageTitles');
-
- $view->requestConfig->filter_sort_column = 'entry_nb_visits';
-
- $this->addPageDisplayProperties($view);
- $this->addBaseDisplayProperties($view);
- }
-
- public function configureViewForGetExitPageTitles(ViewDataTable $view)
- {
- $exitPageUrlAction =
- Common::getRequestVar('widget', false) === false ? 'indexExitPageUrls' : 'getExitPageUrls';
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Actions_ColumnExitPageTitle'),
- 'exit_nb_visits' => Piwik::translate('General_ColumnExits'),
- ));
- $view->config->addRelatedReports(array(
- 'Actions.getPageTitles' => Piwik::translate('Actions_SubmenuPageTitles'),
- "Actions.$exitPageUrlAction" => Piwik::translate('Actions_SubmenuPagesExit'),
- ));
-
- $view->config->title = Piwik::translate('Actions_ExitPageTitles');
- $view->config->columns_to_display = array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate');
-
- $this->addPageDisplayProperties($view);
- $this->addBaseDisplayProperties($view);
- }
-
- public function configureViewForGetDownloads(ViewDataTable $view)
- {
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Actions_ColumnDownloadURL'),
- 'nb_visits' => Piwik::translate('Actions_ColumnUniqueDownloads'),
- 'nb_hits' => Piwik::translate('General_Downloads'),
- ));
-
- $view->config->columns_to_display = array('label', 'nb_visits', 'nb_hits');
- $view->config->show_exclude_low_population = false;
-
- $this->addBaseDisplayProperties($view);
- }
-
- public function configureViewForGetOutlinks(ViewDataTable $view)
- {
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Actions_ColumnClickedURL'),
- 'nb_visits' => Piwik::translate('Actions_ColumnUniqueClicks'),
- 'nb_hits' => Piwik::translate('Actions_ColumnClicks'),
- ));
-
- $view->config->columns_to_display = array('label', 'nb_visits', 'nb_hits');
- $view->config->show_exclude_low_population = false;
-
- $this->addBaseDisplayProperties($view);
- }
}
diff --git a/core/Tracker/ActionClickUrl.php b/plugins/Actions/Actions/ActionClickUrl.php
index cd05491293..030c80f3c0 100644
--- a/core/Tracker/ActionClickUrl.php
+++ b/plugins/Actions/Actions/ActionClickUrl.php
@@ -7,37 +7,46 @@
*
*/
-namespace Piwik\Tracker;
+namespace Piwik\Plugins\Actions\Actions;
use Piwik\Common;
-use Piwik\Tracker;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visit;
/**
- * This class represents a download or an outlink.
+ * This class represents an outlink.
* This is a particular type of Action: it has no 'name'
*
*/
class ActionClickUrl extends Action
{
- function __construct($type, $url, Request $request)
+ public function __construct(Request $request)
{
- parent::__construct($type, $request);
- $this->setActionUrl($url);
+ parent::__construct(self::TYPE_OUTLINK, $request);
+ $this->setActionUrl($request->getParam('link'));
+ }
+
+ public static function shouldHandle(Request $request)
+ {
+ $outlinkUrl = $request->getParam('link');
+
+ return !empty($outlinkUrl);
}
protected function getActionsToLookup()
{
return array(
- // Note: we do not normalize download/oulink URL
+ // Note: we do not normalize outlink URL
'idaction_url' => array($this->getActionUrl(), $this->getActionType())
);
}
- function writeDebugInfo()
+ public function writeDebugInfo()
{
parent::writeDebugInfo();
- if (self::detectActionIsOutlinkOnAliasHost($this, $this->request->getIdSite())) {
+ if ($this->detectActionIsOutlinkOnAliasHost($this, $this->request->getIdSite())) {
Common::printDebug("INFO: The outlink URL host is one of the known host for this website. ");
}
}
@@ -48,16 +57,15 @@ class ActionClickUrl extends Action
* @param Action $action
* @return bool true if the outlink the visitor clicked on points to one of the known hosts for this website
*/
- public static function detectActionIsOutlinkOnAliasHost(Action $action, $idSite)
+ protected function detectActionIsOutlinkOnAliasHost(Action $action, $idSite)
{
- if ($action->getActionType() != Action::TYPE_OUTLINK) {
- return false;
- }
$decodedActionUrl = $action->getActionUrl();
- $actionUrlParsed = @parse_url($decodedActionUrl);
+ $actionUrlParsed = @parse_url($decodedActionUrl);
+
if (!isset($actionUrlParsed['host'])) {
return false;
}
+
return Visit::isHostKnownAliasHost($actionUrlParsed['host'], $idSite);
}
}
diff --git a/plugins/Actions/Actions/ActionDownloadUrl.php b/plugins/Actions/Actions/ActionDownloadUrl.php
new file mode 100644
index 0000000000..5d01c07aca
--- /dev/null
+++ b/plugins/Actions/Actions/ActionDownloadUrl.php
@@ -0,0 +1,41 @@
+<?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\Actions;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+
+/**
+ * This class represents a download.
+ * This is a particular type of Action: it has no 'name'
+ */
+class ActionDownloadUrl extends Action
+{
+ public function __construct(Request $request)
+ {
+ parent::__construct(self::TYPE_DOWNLOAD, $request);
+ $this->setActionUrl($request->getParam('download'));
+ }
+
+ public static function shouldHandle(Request $request)
+ {
+ $downloadUrl = $request->getParam('download');
+
+ return !empty($downloadUrl);
+ }
+
+ protected function getActionsToLookup()
+ {
+ return array(
+ // Note: we do not normalize download URL
+ 'idaction_url' => array($this->getActionUrl(), $this->getActionType())
+ );
+ }
+
+}
diff --git a/core/Tracker/ActionSiteSearch.php b/plugins/Actions/Actions/ActionSiteSearch.php
index 8b76a52c96..275adb83b2 100644
--- a/core/Tracker/ActionSiteSearch.php
+++ b/plugins/Actions/Actions/ActionSiteSearch.php
@@ -7,10 +7,13 @@
*
*/
-namespace Piwik\Tracker;
+namespace Piwik\Plugins\Actions\Actions;
use Piwik\Common;
-use Piwik\Tracker;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\PageUrl;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Cache;
use Piwik\UrlHelper;
/**
@@ -30,11 +33,21 @@ class ActionSiteSearch extends Action
const CVAR_INDEX_SEARCH_CATEGORY = '4';
const CVAR_INDEX_SEARCH_COUNT = '5';
-
- function __construct($url, Request $request)
+ public function __construct(Request $request, $detect = true)
{
parent::__construct(Action::TYPE_SITE_SEARCH, $request);
- $this->originalUrl = $url;
+ $this->originalUrl = $request->getParam('url');
+
+ if ($detect) {
+ $this->isSearchDetected();
+ }
+ }
+
+ public static function shouldHandle(Request $request)
+ {
+ $search = new self($request, false);
+
+ return $search->detectSiteSearch($request->getParam('url'));
}
protected function getActionsToLookup()
@@ -56,7 +69,7 @@ class ActionSiteSearch extends Action
return $this->request->getPageGenerationTime();
}
- function isSearchDetected()
+ protected function isSearchDetected()
{
$siteSearch = $this->detectSiteSearch($this->originalUrl);
@@ -78,7 +91,6 @@ class ActionSiteSearch extends Action
return true;
}
-
public function getCustomVariables()
{
$customVariables = parent::getCustomVariables();
@@ -184,7 +196,7 @@ class ActionSiteSearch extends Action
return is_numeric($count) && $count >= 0;
}
- protected function detectSiteSearch($originalUrl)
+ public function detectSiteSearch($originalUrl)
{
$website = Cache::getCacheWebsiteAttributes($this->request->getIdSite());
if (empty($website['sitesearch'])) {
diff --git a/plugins/Actions/Archiver.php b/plugins/Actions/Archiver.php
index 2829ce47ab..758e3acb85 100644
--- a/plugins/Actions/Archiver.php
+++ b/plugins/Actions/Archiver.php
@@ -12,7 +12,7 @@ use Piwik\DataTable;
use Piwik\Metrics;
use Piwik\RankingQuery;
use Piwik\Tracker\Action;
-use Piwik\Tracker\ActionSiteSearch;
+use Piwik\Plugins\Actions\Actions\ActionSiteSearch;
/**
* Class encapsulating logic to process Day/Period Archiving for the Actions reports
diff --git a/plugins/Actions/Columns/ClickedUrl.php b/plugins/Actions/Columns/ClickedUrl.php
new file mode 100644
index 0000000000..6f5fc29010
--- /dev/null
+++ b/plugins/Actions/Columns/ClickedUrl.php
@@ -0,0 +1,21 @@
+<?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;
+
+class ClickedUrl extends ActionDimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnClickedURL');
+ }
+
+}
diff --git a/plugins/Actions/Columns/DestinationPage.php b/plugins/Actions/Columns/DestinationPage.php
new file mode 100644
index 0000000000..76ea3e3fae
--- /dev/null
+++ b/plugins/Actions/Columns/DestinationPage.php
@@ -0,0 +1,20 @@
+<?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\Columns\Dimension;
+use Piwik\Piwik;
+
+class DestinationPage extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('General_ColumnDestinationPage');
+ }
+} \ No newline at end of file
diff --git a/plugins/Actions/Columns/DownloadUrl.php b/plugins/Actions/Columns/DownloadUrl.php
new file mode 100644
index 0000000000..230069a9ed
--- /dev/null
+++ b/plugins/Actions/Columns/DownloadUrl.php
@@ -0,0 +1,21 @@
+<?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;
+
+class DownloadUrl extends ActionDimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnDownloadURL');
+ }
+
+}
diff --git a/plugins/Actions/Columns/EntryPageTitle.php b/plugins/Actions/Columns/EntryPageTitle.php
new file mode 100644
index 0000000000..0da5b2b4ce
--- /dev/null
+++ b/plugins/Actions/Columns/EntryPageTitle.php
@@ -0,0 +1,52 @@
+<?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\Plugins\Actions\Segment;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class EntryPageTitle extends VisitDimension
+{
+ protected $columnName = 'visit_entry_idaction_name';
+ protected $columnType = 'INTEGER(11) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('entryPageTitle');
+ $segment->setName('Actions_ColumnEntryPageTitle');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $idActionName = false;
+
+ if (!empty($action)) {
+ $idActionName = $action->getIdActionNameForEntryAndExitIds();
+ }
+
+ return (int) $idActionName;
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnEntryPageTitle');
+ }
+}
diff --git a/plugins/Actions/Columns/EntryPageUrl.php b/plugins/Actions/Columns/EntryPageUrl.php
new file mode 100644
index 0000000000..7256105b57
--- /dev/null
+++ b/plugins/Actions/Columns/EntryPageUrl.php
@@ -0,0 +1,53 @@
+<?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\Plugins\Actions\Segment;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class EntryPageUrl extends VisitDimension
+{
+ protected $columnName = 'visit_entry_idaction_url';
+ protected $columnType = 'INTEGER(11) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('entryPageUrl');
+ $segment->setName('Actions_ColumnEntryPageURL');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $idActionUrl = false;
+
+ if (!empty($action)) {
+ $idActionUrl = $action->getIdActionUrlForEntryAndExitIds();
+ }
+
+ return (int) $idActionUrl;
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnEntryPageURL');
+ }
+
+}
diff --git a/plugins/Actions/Columns/ExitPageTitle.php b/plugins/Actions/Columns/ExitPageTitle.php
new file mode 100644
index 0000000000..8078461da2
--- /dev/null
+++ b/plugins/Actions/Columns/ExitPageTitle.php
@@ -0,0 +1,67 @@
+<?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\Plugins\Actions\Segment;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class ExitPageTitle extends VisitDimension
+{
+ protected $columnName = 'visit_exit_idaction_name';
+ protected $columnType = 'INTEGER(11) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('exitPageTitle');
+ $segment->setName('Actions_ColumnExitPageTitle');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int|bool
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $idActionName = false;
+
+ if (!empty($action)) {
+ $idActionName = $action->getIdActionNameForEntryAndExitIds();
+ }
+
+ return (int) $idActionName;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int|bool
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ if (empty($action)) {
+ return false;
+ }
+
+ return $action->getIdActionNameForEntryAndExitIds();
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnExitPageTitle');
+ }
+}
diff --git a/plugins/Actions/Columns/ExitPageUrl.php b/plugins/Actions/Columns/ExitPageUrl.php
new file mode 100644
index 0000000000..1ef487f06b
--- /dev/null
+++ b/plugins/Actions/Columns/ExitPageUrl.php
@@ -0,0 +1,73 @@
+<?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\Plugins\Actions\Segment;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class ExitPageUrl extends VisitDimension
+{
+ protected $columnName = 'visit_exit_idaction_url';
+ protected $columnType = 'INTEGER(11) UNSIGNED NULL DEFAULT 0';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('exitPageUrl');
+ $segment->setName('Actions_ColumnExitPageURL');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int|bool
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $idActionUrl = false;
+
+ if (!empty($action)) {
+ $idActionUrl = $action->getIdActionUrlForEntryAndExitIds();
+ }
+
+ return (int) $idActionUrl;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ if (empty($action)) {
+ return false;
+ }
+
+ $id = $action->getIdActionUrlForEntryAndExitIds();
+
+ if (!empty($id)) {
+ $id = (int) $id;
+ }
+
+ return $id;
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnExitPageURL');
+ }
+}
diff --git a/plugins/Actions/Columns/Keyword.php b/plugins/Actions/Columns/Keyword.php
new file mode 100644
index 0000000000..71c93bd648
--- /dev/null
+++ b/plugins/Actions/Columns/Keyword.php
@@ -0,0 +1,20 @@
+<?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\Columns\Dimension;
+use Piwik\Piwik;
+
+class Keyword extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('General_ColumnKeyword');
+ }
+} \ No newline at end of file
diff --git a/plugins/Actions/Columns/KeywordwithNoSearchResult.php b/plugins/Actions/Columns/KeywordwithNoSearchResult.php
new file mode 100644
index 0000000000..b7a19726a7
--- /dev/null
+++ b/plugins/Actions/Columns/KeywordwithNoSearchResult.php
@@ -0,0 +1,20 @@
+<?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\Columns\Dimension;
+use Piwik\Piwik;
+
+class KeywordwithNoSearchResult extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnNoResultKeyword');
+ }
+} \ No newline at end of file
diff --git a/plugins/Actions/Columns/PageTitle.php b/plugins/Actions/Columns/PageTitle.php
new file mode 100644
index 0000000000..6517bede92
--- /dev/null
+++ b/plugins/Actions/Columns/PageTitle.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\Actions\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugins\Actions\Segment;
+
+class PageTitle extends ActionDimension
+{
+ protected $columnName = 'idaction_name';
+ protected $columnType = 'INTEGER(10) UNSIGNED';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('pageTitle');
+ $segment->setName('Actions_ColumnPageName');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnPageName');
+ }
+
+}
diff --git a/plugins/Actions/Columns/PageUrl.php b/plugins/Actions/Columns/PageUrl.php
new file mode 100644
index 0000000000..1f9a7035e5
--- /dev/null
+++ b/plugins/Actions/Columns/PageUrl.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\Actions\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugins\Actions\Segment;
+
+class PageUrl extends ActionDimension
+{
+ protected $columnName = 'idaction_url';
+ protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('pageUrl');
+ $segment->setName('Actions_ColumnPageURL');
+ $segment->setAcceptedValues('All these segments must be URL encoded, for example: ' . urlencode('http://example.com/path/page?query'));
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnPageURL');
+ }
+}
diff --git a/plugins/Actions/Columns/SearchCategory.php b/plugins/Actions/Columns/SearchCategory.php
new file mode 100644
index 0000000000..7073c105fb
--- /dev/null
+++ b/plugins/Actions/Columns/SearchCategory.php
@@ -0,0 +1,20 @@
+<?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\Columns\Dimension;
+use Piwik\Piwik;
+
+class SearchCategory extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnSearchCategory');
+ }
+} \ No newline at end of file
diff --git a/plugins/Actions/Columns/SearchDestinationPage.php b/plugins/Actions/Columns/SearchDestinationPage.php
new file mode 100644
index 0000000000..bf36621a9c
--- /dev/null
+++ b/plugins/Actions/Columns/SearchDestinationPage.php
@@ -0,0 +1,20 @@
+<?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\Columns\Dimension;
+use Piwik\Piwik;
+
+class SearchDestinationPage extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('General_ColumnDestinationPage');
+ }
+}
diff --git a/plugins/Actions/Columns/SearchKeyword.php b/plugins/Actions/Columns/SearchKeyword.php
new file mode 100644
index 0000000000..f3248da5cf
--- /dev/null
+++ b/plugins/Actions/Columns/SearchKeyword.php
@@ -0,0 +1,30 @@
+<?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 SearchKeyword extends ActionDimension
+{
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('siteSearchKeyword');
+ $segment->setName('Actions_SiteSearchKeyword');
+ $segment->setSqlSegment('log_link_visit_action.idaction_name');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('General_ColumnKeyword');
+ }
+}
diff --git a/plugins/Actions/Columns/SearchNoResultKeyword.php b/plugins/Actions/Columns/SearchNoResultKeyword.php
new file mode 100644
index 0000000000..f4b57c6431
--- /dev/null
+++ b/plugins/Actions/Columns/SearchNoResultKeyword.php
@@ -0,0 +1,20 @@
+<?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\Columns\Dimension;
+use Piwik\Piwik;
+
+class SearchNoResultKeyword extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Actions_ColumnNoResultKeyword');
+ }
+}
diff --git a/plugins/Actions/Columns/ServerTime.php b/plugins/Actions/Columns/ServerTime.php
new file mode 100644
index 0000000000..75f1f9fbca
--- /dev/null
+++ b/plugins/Actions/Columns/ServerTime.php
@@ -0,0 +1,43 @@
+<?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\Common;
+use Piwik\Db;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker;
+
+class ServerTime extends ActionDimension
+{
+ protected $columnName = 'server_time';
+ protected $columnType = 'DATETIME NOT NULL';
+
+ public function install()
+ {
+ $changes = parent::install();
+ $changes['log_link_visit_action'][] = "ADD INDEX index_idsite_servertime ( idsite, server_time )";
+
+ return $changes;
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ public function onNewAction(Request $request, Visitor $visitor, Action $action)
+ {
+ $timestamp = $request->getCurrentTimestamp();
+
+ return Tracker::getDatetimeFromTimestamp($timestamp);
+ }
+}
diff --git a/plugins/Actions/Columns/TimeSpentRefAction.php b/plugins/Actions/Columns/TimeSpentRefAction.php
new file mode 100644
index 0000000000..6b6d49d411
--- /dev/null
+++ b/plugins/Actions/Columns/TimeSpentRefAction.php
@@ -0,0 +1,36 @@
+<?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\Plugin\Dimension\ActionDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class TimeSpentRefAction extends ActionDimension
+{
+ protected $columnName = 'time_spent_ref_action';
+ protected $columnType = 'INTEGER(10) UNSIGNED NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ public function onNewAction(Request $request, Visitor $visitor, Action $action)
+ {
+ $timeSpent = $visitor->getVisitorColumn('time_spent_ref_action');
+
+ if (empty($timeSpent)) {
+ return 0;
+ }
+
+ return $timeSpent;
+ }
+}
diff --git a/plugins/Actions/Columns/VisitTotalActions.php b/plugins/Actions/Columns/VisitTotalActions.php
new file mode 100644
index 0000000000..c65b3d3b50
--- /dev/null
+++ b/plugins/Actions/Columns/VisitTotalActions.php
@@ -0,0 +1,95 @@
+<?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\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker;
+use Piwik\Tracker\Visitor;
+
+class VisitTotalActions extends VisitDimension
+{
+ protected $columnName = 'visit_total_actions';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setType(Segment::TYPE_METRIC);
+ $segment->setSegment('actions');
+ $segment->setName('General_NbActions');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $actionType = false;
+ if ($action) {
+ $actionType = $action->getActionType();
+ }
+
+ $actions = array(
+ Action::TYPE_PAGE_URL,
+ Action::TYPE_DOWNLOAD,
+ Action::TYPE_OUTLINK,
+ Action::TYPE_SITE_SEARCH,
+ Action::TYPE_EVENT
+ );
+
+ // if visit starts with something else (e.g. ecommerce order), don't record as an action
+ if (in_array($actionType, $actions)) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ if (!$action) {
+ return false;
+ }
+
+ $increment = 'visit_total_actions + 1';
+
+ $idActionUrl = $action->getIdActionUrlForEntryAndExitIds();
+
+ if ($idActionUrl !== false) {
+ return $increment;
+ }
+
+ $actionType = $action->getActionType();
+
+ if (in_array($actionType, array(Action::TYPE_SITE_SEARCH, Action::TYPE_EVENT))) {
+ return $increment;
+ }
+
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/Actions/Columns/VisitTotalSearches.php b/plugins/Actions/Columns/VisitTotalSearches.php
new file mode 100644
index 0000000000..e39f7055d7
--- /dev/null
+++ b/plugins/Actions/Columns/VisitTotalSearches.php
@@ -0,0 +1,77 @@
+<?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\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker;
+use Piwik\Tracker\Visitor;
+
+class VisitTotalSearches extends VisitDimension
+{
+ protected $columnName = 'visit_total_searches';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setType(Segment::TYPE_METRIC);
+ $segment->setSegment('searches');
+ $segment->setName('General_NbSearches');
+ $segment->setAcceptedValues('To select all visits who used internal Site Search, use: &segment=searches>0');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ if ($this->isSiteSearchAction($action)) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ if ($this->isSiteSearchAction($action)) {
+ return 'visit_total_searches + 1';
+ }
+
+ return false;
+ }
+
+ /**
+ * @param Action|null $action
+ * @return bool
+ */
+ private function isSiteSearchAction($action)
+ {
+ return ($action && $action->getActionType() == Action::TYPE_SITE_SEARCH);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/Actions/Controller.php b/plugins/Actions/Controller.php
index 2a298dc335..f28ba54ca2 100644
--- a/plugins/Actions/Controller.php
+++ b/plugins/Actions/Controller.php
@@ -8,7 +8,11 @@
*/
namespace Piwik\Plugins\Actions;
-use Piwik\Piwik;
+use Piwik\Plugin\Report;
+use Piwik\Plugins\Actions\Reports\GetPageUrlsFollowingSiteSearch;
+use Piwik\Plugins\Actions\Reports\GetSiteSearchCategories;
+use Piwik\Plugins\Actions\Reports\GetSiteSearchKeywords;
+use Piwik\Plugins\Actions\Reports\GetSiteSearchNoResultKeywords;
use Piwik\View;
/**
@@ -21,130 +25,25 @@ class Controller extends \Piwik\Plugin\Controller
// Actions that render whole pages
//
- public function indexPageUrls()
- {
- return View::singleReport(
- Piwik::translate('General_Pages'),
- $this->getPageUrls(true));
- }
-
- public function indexEntryPageUrls()
- {
- return View::singleReport(
- Piwik::translate('Actions_SubmenuPagesEntry'),
- $this->getEntryPageUrls(true));
- }
-
- public function indexExitPageUrls()
- {
- return View::singleReport(
- Piwik::translate('Actions_SubmenuPagesExit'),
- $this->getExitPageUrls(true));
- }
-
public function indexSiteSearch()
{
$view = new View('@Actions/indexSiteSearch');
- $view->keywords = $this->getSiteSearchKeywords(true);
- $view->noResultKeywords = $this->getSiteSearchNoResultKeywords(true);
- $view->pagesUrlsFollowingSiteSearch = $this->getPageUrlsFollowingSiteSearch(true);
+ $keyword = new GetSiteSearchKeywords();
+ $noResult = new GetSiteSearchNoResultKeywords();
+ $pageUrls = new GetPageUrlsFollowingSiteSearch();
+
+ $view->keywords = $keyword->render();
+ $view->noResultKeywords = $noResult->render();
+ $view->pagesUrlsFollowingSiteSearch = $pageUrls->render();
- $categoryTrackingEnabled = \Piwik\Plugin\Manager::getInstance()->isPluginActivated('CustomVariables');
+ $categoryTrackingEnabled = Actions::isCustomVariablesPluginsEnabled();
if ($categoryTrackingEnabled) {
- $view->categories = $this->getSiteSearchCategories(true);
+ $categories = new GetSiteSearchCategories();
+ $view->categories = $categories->render();
}
return $view->render();
}
- public function indexPageTitles()
- {
- return View::singleReport(
- Piwik::translate('Actions_SubmenuPageTitles'),
- $this->getPageTitles(true));
- }
-
- public function indexDownloads()
- {
- return View::singleReport(
- Piwik::translate('General_Downloads'),
- $this->getDownloads(true));
- }
-
- public function indexOutlinks()
- {
- return View::singleReport(
- Piwik::translate('General_Outlinks'),
- $this->getOutlinks(true));
- }
-
- //
- // Actions that render individual reports
- //
-
- public function getPageUrls()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getEntryPageUrls()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getExitPageUrls()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getSiteSearchKeywords()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getSiteSearchNoResultKeywords()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getSiteSearchCategories()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getPageUrlsFollowingSiteSearch()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getPageTitlesFollowingSiteSearch()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getPageTitles()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getEntryPageTitles()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getExitPageTitles()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getDownloads()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getOutlinks()
- {
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/Actions/Menu.php b/plugins/Actions/Menu.php
index 740b5a69ae..3e8a113bb2 100644
--- a/plugins/Actions/Menu.php
+++ b/plugins/Actions/Menu.php
@@ -14,13 +14,12 @@ class Menu extends \Piwik\Plugin\Menu
{
public function configureReportingMenu(MenuReporting $menu)
{
- $menu->add('General_Actions', '', array('module' => 'Actions', 'action' => 'indexPageUrls'), true, 15);
- $menu->add('General_Actions', 'General_Pages', array('module' => 'Actions', 'action' => 'indexPageUrls'), true, 1);
- $menu->add('General_Actions', 'Actions_SubmenuPagesEntry', array('module' => 'Actions', 'action' => 'indexEntryPageUrls'), true, 2);
- $menu->add('General_Actions', 'Actions_SubmenuPagesExit', array('module' => 'Actions', 'action' => 'indexExitPageUrls'), true, 3);
- $menu->add('General_Actions', 'Actions_SubmenuPageTitles', array('module' => 'Actions', 'action' => 'indexPageTitles'), true, 4);
- $menu->add('General_Actions', 'General_Outlinks', array('module' => 'Actions', 'action' => 'indexOutlinks'), true, 6);
- $menu->add('General_Actions', 'General_Downloads', array('module' => 'Actions', 'action' => 'indexDownloads'), true, 7);
+ $urlParams = array(
+ 'module' => 'Actions',
+ 'action' => 'menuGetPageUrls'
+ );
+
+ $menu->add('General_Actions', '', $urlParams, true, 15);
$actions = new Actions();
if ($actions->isSiteSearchEnabled()) {
diff --git a/plugins/Actions/Reports/Base.php b/plugins/Actions/Reports/Base.php
new file mode 100644
index 0000000000..fb1158e6a9
--- /dev/null
+++ b/plugins/Actions/Reports/Base.php
@@ -0,0 +1,119 @@
+<?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\Reports;
+
+use Piwik\Common;
+use Piwik\MetricsFormatter;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Actions;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\API\Request;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'General_Actions';
+ $this->processedMetrics = false;
+ }
+
+ protected function addBaseDisplayProperties(ViewDataTable $view)
+ {
+ $view->config->datatable_js_type = 'ActionsDataTable';
+ $view->config->search_recursive = true;
+ $view->config->show_table_all_columns = false;
+ $view->requestConfig->filter_limit = Actions::ACTIONS_REPORT_ROWS_DISPLAY;
+ $view->config->show_all_views_icons = false;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->show_embedded_subtable = true;
+ }
+
+ if (Request::shouldLoadExpanded()) {
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->show_expanded = true;
+ }
+
+ $view->config->filters[] = function ($dataTable) {
+ Actions::setDataTableRowLevels($dataTable);
+ };
+ }
+
+ $view->config->filters[] = function ($dataTable) use ($view) {
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->datatable_css_class = 'dataTableActions';
+ }
+ };
+ }
+
+ protected function addPageDisplayProperties(ViewDataTable $view)
+ {
+ $view->config->addTranslations(array(
+ 'nb_hits' => Piwik::translate('General_ColumnPageviews'),
+ 'nb_visits' => Piwik::translate('General_ColumnUniquePageviews'),
+ 'avg_time_on_page' => Piwik::translate('General_ColumnAverageTimeOnPage'),
+ 'bounce_rate' => Piwik::translate('General_ColumnBounceRate'),
+ 'exit_rate' => Piwik::translate('General_ColumnExitRate'),
+ 'avg_time_generation' => Piwik::translate('General_ColumnAverageGenerationTime'),
+ ));
+
+ // prettify avg_time_on_page column
+ $getPrettyTimeFromSeconds = '\Piwik\MetricsFormatter::getPrettyTimeFromSeconds';
+ $view->config->filters[] = array('ColumnCallbackReplace', array('avg_time_on_page', $getPrettyTimeFromSeconds));
+
+ // prettify avg_time_generation column
+ $avgTimeCallback = function ($time) {
+ return $time ? MetricsFormatter::getPrettyTimeFromSeconds($time, true, true, false) : "-";
+ };
+ $view->config->filters[] = array('ColumnCallbackReplace', array('avg_time_generation', $avgTimeCallback));
+
+ // add avg_generation_time tooltip
+ $tooltipCallback = function ($hits, $min, $max) {
+ if (!$hits) {
+ return false;
+ }
+
+ return Piwik::translate("Actions_AvgGenerationTimeTooltip", array(
+ $hits,
+ "<br />",
+ MetricsFormatter::getPrettyTimeFromSeconds($min),
+ MetricsFormatter::getPrettyTimeFromSeconds($max)
+ ));
+ };
+ $view->config->filters[] = array('ColumnCallbackAddMetadata',
+ array(
+ array('nb_hits_with_time_generation', 'min_time_generation', 'max_time_generation'),
+ 'avg_time_generation_tooltip',
+ $tooltipCallback
+ )
+ );
+
+ $this->addExcludeLowPopDisplayProperties($view);
+ }
+
+ protected function addExcludeLowPopDisplayProperties(ViewDataTable $view)
+ {
+ if (Common::getRequestVar('enable_filter_excludelowpop', '0', 'string') != '0') {
+ $view->requestConfig->filter_excludelowpop = 'nb_hits';
+ $view->requestConfig->filter_excludelowpop_value = function () {
+ // computing minimum value to exclude (2 percent of the total number of actions)
+ $visitsInfo = \Piwik\Plugins\VisitsSummary\Controller::getVisitsSummary()->getFirstRow();
+ $nbActions = $visitsInfo->getColumn('nb_actions');
+ $nbActionsLowPopulationThreshold = floor(0.02 * $nbActions);
+
+ // we remove 1 to make sure some actions/downloads are displayed in the case we have a very few of them
+ // and each of them has 1 or 2 hits...
+ return min($visitsInfo->getColumn('max_actions') - 1, $nbActionsLowPopulationThreshold - 1);
+ };
+ }
+ }
+
+}
diff --git a/plugins/Actions/Reports/Get.php b/plugins/Actions/Reports/Get.php
new file mode 100644
index 0000000000..612666c32a
--- /dev/null
+++ b/plugins/Actions/Reports/Get.php
@@ -0,0 +1,34 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+
+class Get extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('General_Actions') . ' - ' . Piwik::translate('General_MainMetrics');
+ $this->documentation = ''; // TODO
+ $this->order = 1;
+ $this->metrics = array(
+ 'nb_pageviews',
+ 'nb_uniq_pageviews',
+ 'nb_downloads',
+ 'nb_uniq_downloads',
+ 'nb_outlinks',
+ 'nb_uniq_outlinks',
+ 'nb_searches',
+ 'nb_keywords',
+ 'avg_time_generation'
+ );
+ }
+}
diff --git a/plugins/Actions/Reports/GetDownloads.php b/plugins/Actions/Reports/GetDownloads.php
new file mode 100644
index 0000000000..f168cba878
--- /dev/null
+++ b/plugins/Actions/Reports/GetDownloads.php
@@ -0,0 +1,58 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\DownloadUrl;
+
+class GetDownloads extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new DownloadUrl();
+ $this->name = Piwik::translate('General_Downloads');
+ $this->documentation = Piwik::translate('Actions_DownloadsReportDocumentation', '<br />');
+ $this->metrics = array('nb_visits', 'nb_hits');
+
+ $this->actionToLoadSubTables = $this->action;
+ $this->order = 9;
+
+ $this->menuTitle = 'General_Downloads';
+ $this->widgetTitle = 'General_Downloads';
+ }
+
+ public function getMetrics()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnUniqueDownloads'),
+ 'nb_hits' => Piwik::translate('General_Downloads')
+ );
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnUniqueClicksDocumentation'),
+ 'nb_hits' => Piwik::translate('Actions_ColumnClicksDocumentation')
+ );
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->columns_to_display = array('label', 'nb_visits', 'nb_hits');
+ $view->config->show_exclude_low_population = false;
+
+ $this->addBaseDisplayProperties($view);
+ }
+}
diff --git a/plugins/Actions/Reports/GetEntryPageTitles.php b/plugins/Actions/Reports/GetEntryPageTitles.php
new file mode 100644
index 0000000000..70b56136d4
--- /dev/null
+++ b/plugins/Actions/Reports/GetEntryPageTitles.php
@@ -0,0 +1,61 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Common;
+use Piwik\Plugins\Actions\Columns\EntryPageTitle;
+
+class GetEntryPageTitles extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new EntryPageTitle();
+ $this->name = Piwik::translate('Actions_EntryPageTitles');
+ $this->documentation = Piwik::translate('Actions_ExitPageTitlesReportDocumentation', '<br />')
+ . ' ' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+ $this->metrics = array('entry_nb_visits', 'entry_bounce_count', 'bounce_rate');
+ $this->order = 6;
+ $this->actionToLoadSubTables = $this->action;
+
+ $this->widgetTitle = 'Actions_WidgetEntryPageTitles';
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ $metrics = parent::getMetricsDocumentation();
+ $metrics['bounce_rate'] = Piwik::translate('General_ColumnBounceRateForPageDocumentation');
+
+ return $metrics;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->columns_to_display = array('label', 'entry_nb_visits', 'entry_bounce_count', 'bounce_rate');
+ $view->config->title = $this->name;
+
+ $view->requestConfig->filter_sort_column = 'entry_nb_visits';
+
+ $this->addPageDisplayProperties($view);
+ $this->addBaseDisplayProperties($view);
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetPageTitles(),
+ new GetEntryPageUrls()
+ );
+ }
+}
diff --git a/plugins/Actions/Reports/GetEntryPageUrls.php b/plugins/Actions/Reports/GetEntryPageUrls.php
new file mode 100644
index 0000000000..5ec0f763ac
--- /dev/null
+++ b/plugins/Actions/Reports/GetEntryPageUrls.php
@@ -0,0 +1,72 @@
+<?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\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\API\Request;
+use Piwik\Plugins\Actions\Columns\EntryPageUrl;
+
+class GetEntryPageUrls extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new EntryPageUrl();
+ $this->name = Piwik::translate('Actions_SubmenuPagesEntry');
+ $this->documentation = Piwik::translate('Actions_EntryPagesReportDocumentation', '<br />')
+ . '<br />' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+
+ $this->metrics = array('entry_nb_visits', 'entry_bounce_count', 'bounce_rate');
+ $this->order = 3;
+
+ $this->actionToLoadSubTables = $this->action;
+
+ $this->menuTitle = 'Actions_SubmenuPagesEntry';
+ $this->widgetTitle = 'Actions_WidgetPagesEntry';
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ $metrics = parent::getMetricsDocumentation();
+ $metrics['bounce_rate'] = Piwik::translate('General_ColumnBounceRateForPageDocumentation');
+
+ return $metrics;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ // link to the page, not just the report, but only if not a widget
+ $widget = Common::getRequestVar('widget', false);
+
+ $view->config->self_url = Request::getCurrentUrlWithoutGenericFilters(array(
+ 'module' => 'Actions',
+ 'action' => $widget === false ? 'indexEntryPageUrls' : 'getEntryPageUrls'
+ ));
+
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->title = $this->name;
+ $view->config->columns_to_display = array('label', 'entry_nb_visits', 'entry_bounce_count', 'bounce_rate');
+ $view->requestConfig->filter_sort_column = 'entry_nb_visits';
+ $view->requestConfig->filter_sort_order = 'desc';
+
+ $this->addPageDisplayProperties($view);
+ $this->addBaseDisplayProperties($view);
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetEntryPageTitles()
+ );
+ }
+}
diff --git a/plugins/Actions/Reports/GetExitPageTitles.php b/plugins/Actions/Reports/GetExitPageTitles.php
new file mode 100644
index 0000000000..a9d29bd552
--- /dev/null
+++ b/plugins/Actions/Reports/GetExitPageTitles.php
@@ -0,0 +1,68 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\ExitPageTitle;
+
+class GetExitPageTitles extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new ExitPageTitle();
+ $this->name = Piwik::translate('Actions_ExitPageTitles');
+ $this->documentation = Piwik::translate('Actions_EntryPageTitlesReportDocumentation', '<br />')
+ . ' ' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+
+ $this->metrics = array('exit_nb_visits', 'nb_visits', 'exit_rate');
+ $this->order = 7;
+
+ $this->actionToLoadSubTables = $this->action;
+
+ $this->widgetTitle = 'Actions_WidgetExitPageTitles';
+ }
+
+ public function getMetrics()
+ {
+ $metrics = parent::getMetrics();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviews');
+
+ return $metrics;
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ $metrics = parent::getMetricsDocumentation();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviewsDocumentation');
+
+ return $metrics;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->title = $this->name;
+ $view->config->columns_to_display = array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate');
+
+ $this->addPageDisplayProperties($view);
+ $this->addBaseDisplayProperties($view);
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetPageTitles(),
+ new GetExitPageUrls()
+ );
+ }
+}
diff --git a/plugins/Actions/Reports/GetExitPageUrls.php b/plugins/Actions/Reports/GetExitPageUrls.php
new file mode 100644
index 0000000000..e0629a7006
--- /dev/null
+++ b/plugins/Actions/Reports/GetExitPageUrls.php
@@ -0,0 +1,84 @@
+<?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\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\API;
+use Piwik\API\Request;
+use Piwik\Plugins\Actions\Columns\ExitPageUrl;
+use Piwik\Plugins\Actions\Columns\PageUrl;
+
+class GetExitPageUrls extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new ExitPageUrl();
+ $this->name = Piwik::translate('Actions_SubmenuPagesExit');
+ $this->documentation = Piwik::translate('Actions_ExitPagesReportDocumentation', '<br />')
+ . '<br />' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+
+ $this->metrics = array('exit_nb_visits', 'nb_visits', 'exit_rate');
+ $this->actionToLoadSubTables = $this->action;
+
+ $this->order = 4;
+
+ $this->menuTitle = 'Actions_SubmenuPagesExit';
+ $this->widgetTitle = 'Actions_WidgetPagesExit';
+ }
+
+ public function getMetrics()
+ {
+ $metrics = parent::getMetrics();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviews');
+
+ return $metrics;
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ $metrics = parent::getMetricsDocumentation();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviewsDocumentation');
+
+ return $metrics;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ // link to the page, not just the report, but only if not a widget
+ $widget = Common::getRequestVar('widget', false);
+
+ $view->config->self_url = Request::getCurrentUrlWithoutGenericFilters(array(
+ 'module' => 'Actions',
+ 'action' => $widget === false ? 'indexExitPageUrls' : 'getExitPageUrls'
+ ));
+
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->title = $this->name;
+
+ $view->config->columns_to_display = array('label', 'exit_nb_visits', 'nb_visits', 'exit_rate');
+ $view->requestConfig->filter_sort_column = 'exit_nb_visits';
+ $view->requestConfig->filter_sort_order = 'desc';
+
+ $this->addPageDisplayProperties($view);
+ $this->addBaseDisplayProperties($view);
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetExitPageTitles()
+ );
+ }
+
+}
diff --git a/plugins/Actions/Reports/GetOutlinks.php b/plugins/Actions/Reports/GetOutlinks.php
new file mode 100644
index 0000000000..9c048b6a5c
--- /dev/null
+++ b/plugins/Actions/Reports/GetOutlinks.php
@@ -0,0 +1,65 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\API;
+use Piwik\API\Request;
+use Piwik\Common;
+use Piwik\Plugins\Actions\Columns\ClickedUrl;
+use Piwik\Plugins\Actions\Columns\PageTitle;
+
+class GetOutlinks extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new ClickedUrl();
+ $this->name = Piwik::translate('General_Outlinks');
+ $this->documentation = Piwik::translate('Actions_OutlinksReportDocumentation') . ' '
+ . Piwik::translate('Actions_OutlinkDocumentation') . '<br />'
+ . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+
+ $this->metrics = array('nb_visits', 'nb_hits');
+ $this->order = 8;
+
+ $this->actionToLoadSubTables = $this->action;
+
+ $this->menuTitle = 'General_Outlinks';
+ $this->widgetTitle = 'General_Outlinks';
+ }
+
+ public function getMetrics()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnUniqueClicks'),
+ 'nb_hits' => Piwik::translate('Actions_ColumnClicks')
+ );
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnUniqueClicksDocumentation'),
+ 'nb_hits' => Piwik::translate('Actions_ColumnClicksDocumentation')
+ );
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->columns_to_display = array('label', 'nb_visits', 'nb_hits');
+ $view->config->show_exclude_low_population = false;
+
+ $this->addBaseDisplayProperties($view);
+ }
+}
diff --git a/plugins/Actions/Reports/GetPageTitles.php b/plugins/Actions/Reports/GetPageTitles.php
new file mode 100644
index 0000000000..1df0d8e5d8
--- /dev/null
+++ b/plugins/Actions/Reports/GetPageTitles.php
@@ -0,0 +1,82 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\API;
+use Piwik\API\Request;
+use Piwik\Common;
+use Piwik\Plugins\Actions\Columns\PageTitle;
+
+class GetPageTitles extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new PageTitle();
+ $this->name = Piwik::translate('Actions_SubmenuPageTitles');
+ $this->documentation = Piwik::translate('Actions_PageTitlesReportDocumentation',
+ array('<br />', htmlentities('<title>')));
+
+ $this->order = 5;
+ $this->metrics = array('nb_hits', 'nb_visits', 'bounce_rate', 'avg_time_on_page', 'exit_rate', 'avg_time_generation');
+
+ $this->actionToLoadSubTables = $this->action;
+
+ $this->menuTitle = 'Actions_SubmenuPageTitles';
+ $this->widgetTitle = 'Actions_WidgetPageTitles';
+ }
+
+ public function getMetrics()
+ {
+ $metrics = parent::getMetrics();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviews');
+
+ return $metrics;
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ $metrics = parent::getMetricsDocumentation();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviewsDocumentation');
+ $metrics['bounce_rate'] = Piwik::translate('General_ColumnPageBounceRateDocumentation');
+
+ return $metrics;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ // link to the page, not just the report, but only if not a widget
+ $widget = Common::getRequestVar('widget', false);
+
+ $view->config->self_url = Request::getCurrentUrlWithoutGenericFilters(array(
+ 'module' => $this->module,
+ 'action' => $widget === false ? 'indexPageTitles' : 'getPageTitles'
+ ));
+
+ $view->config->title = $this->name;
+
+ $view->config->addTranslation('label', $this->dimension->getName());
+ $view->config->columns_to_display = array('label', 'nb_hits', 'nb_visits', 'bounce_rate',
+ 'avg_time_on_page', 'exit_rate', 'avg_time_generation');
+
+ $this->addPageDisplayProperties($view);
+ $this->addBaseDisplayProperties($view);
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetEntryPageTitles(),
+ new GetExitPageTitles()
+ );
+ }
+}
diff --git a/plugins/Actions/Reports/GetPageTitlesFollowingSiteSearch.php b/plugins/Actions/Reports/GetPageTitlesFollowingSiteSearch.php
new file mode 100644
index 0000000000..51177e7878
--- /dev/null
+++ b/plugins/Actions/Reports/GetPageTitlesFollowingSiteSearch.php
@@ -0,0 +1,71 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\DestinationPage;
+
+class GetPageTitlesFollowingSiteSearch extends SiteSearchBase
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new DestinationPage();
+ $this->name = Piwik::translate('Actions_WidgetPageTitlesFollowingSearch');
+ $this->documentation = Piwik::translate('Actions_SiteSearchFollowingPagesDoc') . '<br/>' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+ $this->metrics = array('nb_hits_following_search', 'nb_hits');
+ $this->order = 19;
+ $this->widgetTitle = 'Actions_WidgetPageTitlesFollowingSearch';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $title = Piwik::translate('Actions_WidgetPageUrlsFollowingSearch');
+
+ $this->configureViewForUrlAndTitle($view, $title);
+ }
+
+ public function getMetrics()
+ {
+ return array(
+ 'nb_hits_following_search' => Piwik::translate('General_ColumnViewedAfterSearch'),
+ 'nb_hits' => Piwik::translate('General_ColumnTotalPageviews'),
+ );
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ return array(
+ 'nb_hits_following_search' => Piwik::translate('General_ColumnViewedAfterSearchDocumentation'),
+ 'nb_hits' => Piwik::translate('General_ColumnPageviewsDocumentation'),
+ );
+ }
+
+ protected function configureViewForUrlAndTitle(ViewDataTable $view, $title)
+ {
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->title = $title;
+ $view->config->columns_to_display = array('label', 'nb_hits_following_search', 'nb_hits');
+ $view->config->show_exclude_low_population = false;
+ $view->requestConfig->filter_sort_column = 'nb_hits_following_search';
+ $view->requestConfig->filter_sort_order = 'desc';
+
+ $this->addExcludeLowPopDisplayProperties($view);
+ $this->addBaseDisplayProperties($view);
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetPageUrlsFollowingSiteSearch()
+ );
+ }
+}
diff --git a/plugins/Actions/Reports/GetPageUrls.php b/plugins/Actions/Reports/GetPageUrls.php
new file mode 100644
index 0000000000..17ad2b1750
--- /dev/null
+++ b/plugins/Actions/Reports/GetPageUrls.php
@@ -0,0 +1,62 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\PageUrl;
+
+class GetPageUrls extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->dimension = new PageUrl();
+ $this->name = Piwik::translate('Actions_PageUrls');
+ $this->documentation = Piwik::translate('Actions_PagesReportDocumentation', '<br />')
+ . '<br />' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+
+ $this->actionToLoadSubTables = $this->action;
+ $this->order = 2;
+ $this->metrics = array('nb_hits', 'nb_visits', 'bounce_rate', 'avg_time_on_page', 'exit_rate', 'avg_time_generation');
+
+ $this->segmentSql = 'log_visit.visit_entry_idaction_url';
+
+ $this->menuTitle = 'General_Pages';
+ $this->widgetTitle = 'General_Pages';
+ }
+
+ public function getMetrics()
+ {
+ $metrics = parent::getMetrics();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviews');
+
+ return $metrics;
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ $metrics = parent::getMetricsDocumentation();
+ $metrics['nb_visits'] = Piwik::translate('General_ColumnUniquePageviewsDocumentation');
+ $metrics['bounce_rate'] = Piwik::translate('General_ColumnPageBounceRateDocumentation');
+
+ return $metrics;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslation('label', $this->dimension->getName());
+ $view->config->columns_to_display = array('label', 'nb_hits', 'nb_visits', 'bounce_rate',
+ 'avg_time_on_page', 'exit_rate', 'avg_time_generation');
+
+ $this->addPageDisplayProperties($view);
+ $this->addBaseDisplayProperties($view);
+ }
+}
diff --git a/plugins/Actions/Reports/GetPageUrlsFollowingSiteSearch.php b/plugins/Actions/Reports/GetPageUrlsFollowingSiteSearch.php
new file mode 100644
index 0000000000..032fdadafc
--- /dev/null
+++ b/plugins/Actions/Reports/GetPageUrlsFollowingSiteSearch.php
@@ -0,0 +1,40 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\DestinationPage;
+
+class GetPageUrlsFollowingSiteSearch extends GetPageTitlesFollowingSiteSearch
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new DestinationPage();
+ $this->name = Piwik::translate('Actions_WidgetPageUrlsFollowingSearch');
+ $this->documentation = Piwik::translate('Actions_SiteSearchFollowingPagesDoc') . '<br/>' . Piwik::translate('General_UsePlusMinusIconsDocumentation');
+ $this->order = 18;
+ $this->widgetTitle = 'Actions_WidgetPageUrlsFollowingSearch';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $title = Piwik::translate('Actions_WidgetPageTitlesFollowingSearch');
+
+ $this->configureViewForUrlAndTitle($view, $title);
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetPageTitlesFollowingSiteSearch()
+ );
+ }
+}
diff --git a/plugins/Actions/Reports/GetSiteSearchCategories.php b/plugins/Actions/Reports/GetSiteSearchCategories.php
new file mode 100644
index 0000000000..5acf9e93ae
--- /dev/null
+++ b/plugins/Actions/Reports/GetSiteSearchCategories.php
@@ -0,0 +1,65 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Actions;
+use Piwik\Plugins\Actions\Columns\SearchCategory;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+class GetSiteSearchCategories extends SiteSearchBase
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new SearchCategory();
+ $this->name = Piwik::translate('Actions_WidgetSearchCategories');
+ $this->documentation = Piwik::translate('Actions_SiteSearchCategories1') . '<br/>' . Piwik::translate('Actions_SiteSearchCategories2');
+ $this->metrics = array('nb_visits', 'nb_pages_per_search', 'exit_rate');
+ $this->order = 17;
+ $this->widgetTitle = 'Actions_WidgetSearchCategories';
+ }
+
+ public function isEnabled()
+ {
+ return parent::isEnabled() && Actions::isCustomVariablesPluginsEnabled();
+ }
+
+ public function getMetrics()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
+ 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearch'),
+ 'exit_rate' => Piwik::translate('Actions_ColumnSearchExits'),
+ );
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnSearchesDocumentation'),
+ 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearchDocumentation'),
+ 'exit_rate' => Piwik::translate('Actions_ColumnSearchExitsDocumentation'),
+ );
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+
+ $view->config->columns_to_display = array('label', 'nb_visits', 'nb_pages_per_search');
+ $view->config->show_table_all_columns = false;
+ $view->config->show_bar_chart = false;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->disable_row_evolution = false;
+ }
+ }
+}
diff --git a/plugins/Actions/Reports/GetSiteSearchKeywords.php b/plugins/Actions/Reports/GetSiteSearchKeywords.php
new file mode 100644
index 0000000000..61fc0a84ed
--- /dev/null
+++ b/plugins/Actions/Reports/GetSiteSearchKeywords.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\Actions\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\Keyword;
+
+class GetSiteSearchKeywords extends SiteSearchBase
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Keyword();
+ $this->name = Piwik::translate('Actions_WidgetSearchKeywords');
+ $this->documentation = Piwik::translate('Actions_SiteSearchKeywordsDocumentation') . '<br/><br/>' . Piwik::translate('Actions_SiteSearchIntro') . '<br/><br/>'
+ . '<a href="http://piwik.org/docs/site-search/" target="_blank">' . Piwik::translate('Actions_LearnMoreAboutSiteSearchLink') . '</a>';
+ $this->metrics = array('nb_visits', 'nb_pages_per_search', 'exit_rate');
+ $this->order = 15;
+ $this->widgetTitle = 'Actions_WidgetSearchKeywords';
+ }
+
+ public function getMetrics()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
+ 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearch'),
+ 'exit_rate' => Piwik::translate('Actions_ColumnSearchExits'),
+ );
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnSearchesDocumentation'),
+ 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearchDocumentation'),
+ 'exit_rate' => Piwik::translate('Actions_ColumnSearchExitsDocumentation'),
+ );
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslation('label', $this->dimension->getName());
+ $view->config->columns_to_display = array('label', 'nb_visits', 'nb_pages_per_search', 'exit_rate');
+
+ $this->addSiteSearchDisplayProperties($view);
+ }
+}
diff --git a/plugins/Actions/Reports/GetSiteSearchNoResultKeywords.php b/plugins/Actions/Reports/GetSiteSearchNoResultKeywords.php
new file mode 100644
index 0000000000..df39684c2e
--- /dev/null
+++ b/plugins/Actions/Reports/GetSiteSearchNoResultKeywords.php
@@ -0,0 +1,51 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\KeywordwithNoSearchResult;
+
+class GetSiteSearchNoResultKeywords extends SiteSearchBase
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new KeywordwithNoSearchResult();
+ $this->name = Piwik::translate('Actions_WidgetSearchNoResultKeywords');
+ $this->documentation = Piwik::translate('Actions_SiteSearchIntro') . '<br /><br />' . Piwik::translate('Actions_SiteSearchKeywordsNoResultDocumentation');
+ $this->metrics = array('nb_visits', 'exit_rate');
+ $this->order = 16;
+ $this->widgetTitle = 'Actions_WidgetSearchNoResultKeywords';
+ }
+
+ public function getMetrics()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
+ 'exit_rate' => Piwik::translate('Actions_ColumnSearchExits'),
+ );
+ }
+
+ protected function getMetricsDocumentation()
+ {
+ return array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnSearchesDocumentation'),
+ 'exit_rate' => Piwik::translate('Actions_ColumnSearchExitsDocumentation'),
+ );
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->addTranslation('label', $this->dimension->getName());
+ $view->config->columns_to_display = array('label', 'nb_visits', 'exit_rate');
+
+ $this->addSiteSearchDisplayProperties($view);
+ }
+}
diff --git a/plugins/Actions/Reports/SiteSearchBase.php b/plugins/Actions/Reports/SiteSearchBase.php
new file mode 100644
index 0000000000..5212732e49
--- /dev/null
+++ b/plugins/Actions/Reports/SiteSearchBase.php
@@ -0,0 +1,40 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Actions;
+
+abstract class SiteSearchBase extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->category = 'Actions_SubmenuSitesearch';
+ }
+
+ public function isEnabled()
+ {
+ $actions = new Actions();
+ return $actions->isSiteSearchEnabled();
+ }
+
+ protected function addSiteSearchDisplayProperties(ViewDataTable $view)
+ {
+ $view->config->addTranslations(array(
+ 'nb_visits' => Piwik::translate('Actions_ColumnSearches'),
+ 'exit_rate' => str_replace("% ", "%&nbsp;", Piwik::translate('Actions_ColumnSearchExits')),
+ 'nb_pages_per_search' => Piwik::translate('Actions_ColumnPagesPerSearch')
+ ));
+
+ $view->config->show_bar_chart = false;
+ $view->config->show_table_all_columns = false;
+ }
+}
diff --git a/plugins/Actions/Segment.php b/plugins/Actions/Segment.php
new file mode 100644
index 0000000000..36745dd508
--- /dev/null
+++ b/plugins/Actions/Segment.php
@@ -0,0 +1,22 @@
+<?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;
+
+/**
+ * Actions segment base class
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+ protected function init()
+ {
+ $this->setCategory('General_Actions');
+ $this->setSqlFilter('\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment');
+ }
+}
+
diff --git a/plugins/Actions/Widgets.php b/plugins/Actions/Widgets.php
deleted file mode 100644
index cd5950ecbc..0000000000
--- a/plugins/Actions/Widgets.php
+++ /dev/null
@@ -1,51 +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
- *
- */
-namespace Piwik\Plugins\Actions;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
-
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'General_Actions';
- $controller = 'Actions';
-
- $widgetsList->add($category, 'General_Pages', $controller, 'getPageUrls');
- $widgetsList->add($category, 'Actions_WidgetPageTitles', $controller, 'getPageTitles');
- $widgetsList->add($category, 'General_Outlinks', $controller, 'getOutlinks');
- $widgetsList->add($category, 'General_Downloads', $controller, 'getDownloads');
- $widgetsList->add($category, 'Actions_WidgetPagesEntry', $controller, 'getEntryPageUrls');
- $widgetsList->add($category, 'Actions_WidgetPagesExit', $controller, 'getExitPageUrls');
- $widgetsList->add($category, 'Actions_WidgetEntryPageTitles', $controller, 'getEntryPageTitles');
- $widgetsList->add($category, 'Actions_WidgetExitPageTitles', $controller, 'getExitPageTitles');
-
- $actions = new Actions();
- if ($actions->isSiteSearchEnabled()) {
- $this->addSearchWidgets($widgetsList, $controller);
- }
- }
-
- private function addSearchWidgets(WidgetsList $widgetsList, $controller)
- {
- $category = 'Actions_SubmenuSitesearch';
-
- $widgetsList->add($category, 'Actions_WidgetSearchKeywords', $controller, 'getSiteSearchKeywords');
-
- if (Actions::isCustomVariablesPluginsEnabled()) {
- $widgetsList->add($category, 'Actions_WidgetSearchCategories', $controller, 'getSiteSearchCategories');
- }
-
- $widgetsList->add($category, 'Actions_WidgetSearchNoResultKeywords', $controller, 'getSiteSearchNoResultKeywords');
- $widgetsList->add($category, 'Actions_WidgetPageUrlsFollowingSearch', $controller, 'getPageUrlsFollowingSiteSearch');
- $widgetsList->add($category, 'Actions_WidgetPageTitlesFollowingSearch', $controller, 'getPageTitlesFollowingSiteSearch');
- }
-
-}
diff --git a/plugins/CoreConsole/Commands/DevelopmentEnable.php b/plugins/CoreConsole/Commands/DevelopmentEnable.php
new file mode 100644
index 0000000000..ffcb8f83cb
--- /dev/null
+++ b/plugins/CoreConsole/Commands/DevelopmentEnable.php
@@ -0,0 +1,63 @@
+<?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\CoreConsole\Commands;
+
+use Piwik\Config;
+use Piwik\Filesystem;
+use Piwik\Plugin\ConsoleCommand;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ */
+class DevelopmentEnable extends ConsoleCommand
+{
+ protected function configure()
+ {
+ $this->setName('development:enable');
+ $this->setAliases(array('development:disable'));
+ $this->setDescription('Enable or disable development mode. See config/global.ini.php in section [Development] for more information');
+ $this->addOption('full', null, InputOption::VALUE_NONE, 'If set, it will enable/disable more developer options such as disable merged assets as well and not only the [Development:enabled] option.');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $commandName = $input->getFirstArgument();
+ $enable = (false !== strpos($commandName, 'enable'));
+ $full = $input->getOption('full');
+
+ $config = Config::getInstance();
+ $development = $config->Development;
+
+ if ($enable) {
+ $development['enabled'] = 1;
+ if ($full) {
+ $development['disable_merged_assets'] = 1;
+ }
+ $message = 'Development mode enabled';
+ } else {
+ $development['enabled'] = 0;
+ if ($full) {
+ $development['disable_merged_assets'] = 0;
+ }
+ $message = 'Development mode disabled';
+ }
+
+ $config->Development = $development;
+ $config->forceSave();
+
+ Filesystem::deleteAllCacheOnUpdate();
+
+ $this->writeSuccessMessage($output, array($message));
+ }
+
+}
diff --git a/plugins/CoreConsole/Commands/ManageTestFiles.php b/plugins/CoreConsole/Commands/DevelopmentManageTestFiles.php
index af75e32a2c..429612ae9c 100644
--- a/plugins/CoreConsole/Commands/ManageTestFiles.php
+++ b/plugins/CoreConsole/Commands/DevelopmentManageTestFiles.php
@@ -13,7 +13,7 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-class ManageTestFiles extends ConsoleCommand
+class DevelopmentManageTestFiles extends ConsoleCommand
{
protected function configure()
{
diff --git a/plugins/CoreConsole/Commands/SyncUITestScreenshots.php b/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php
index 1e5d3de610..593faf0f17 100644
--- a/plugins/CoreConsole/Commands/SyncUITestScreenshots.php
+++ b/plugins/CoreConsole/Commands/DevelopmentSyncUITestScreenshots.php
@@ -17,7 +17,7 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
*/
-class SyncUITestScreenshots extends ConsoleCommand
+class DevelopmentSyncUITestScreenshots extends ConsoleCommand
{
protected function configure()
{
diff --git a/plugins/CoreConsole/Commands/GenerateDimension.php b/plugins/CoreConsole/Commands/GenerateDimension.php
new file mode 100644
index 0000000000..ad752b0a78
--- /dev/null
+++ b/plugins/CoreConsole/Commands/GenerateDimension.php
@@ -0,0 +1,245 @@
+<?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\CoreConsole\Commands;
+
+use Piwik\Common;
+use Piwik\DbHelper;
+use Piwik\Plugin\Report;
+use Piwik\Translate;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * TODO automatically create or modify translation file for instance for dimension name
+ */
+class GenerateDimension extends GeneratePluginBase
+{
+ protected function configure()
+ {
+ $this->setName('generate:dimension')
+ ->setDescription('Adds a new dimension to an existing plugin. This allows you to persist new values during tracking.')
+ ->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin which does not have a menu defined yet')
+ ->addOption('type', null, InputOption::VALUE_REQUIRED, 'Whether you want to create a "Visit", an "Action" or a "Conversion" dimension')
+ ->addOption('dimensionname', null, InputOption::VALUE_REQUIRED, 'A human readable name of the dimension which will be for instance visible in the UI')
+ ->addOption('columnname', null, InputOption::VALUE_REQUIRED, 'The name of the column in the MySQL database the dimension will be stored under')
+ ->addOption('columntype', null, InputOption::VALUE_REQUIRED, 'The MySQL type for your dimension, for instance "VARCHAR(255) NOT NULL".');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $pluginName = $this->getPluginName($input, $output);
+ $type = $this->getDimensionType($input, $output);
+ $dimensionName = $this->getDimensionName($input, $output);
+ $columnName = $this->getColumnName($input, $output, $type);
+ $columType = $this->getColumnType($input, $output);
+
+ $dimensionClassName = $this->getDimensionClassName($dimensionName);
+
+ $exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
+ $replace = array('example_action_dimension' => strtolower($columnName),
+ 'example_visit_dimension' => strtolower($columnName),
+ 'example_conversion_dimension' => strtolower($columnName),
+ 'INTEGER(11) DEFAULT 0 NOT NULL' => strtoupper($columType),
+ 'VARCHAR(255) DEFAULT NULL' => strtoupper($columType),
+ 'ExampleVisitDimension' => $dimensionClassName,
+ 'ExampleActionDimension' => $dimensionClassName,
+ 'ExampleConversionDimension' => $dimensionClassName,
+ 'ExamplePlugin_DimensionName' => ucfirst($dimensionName),
+ 'ExamplePlugin' => $pluginName,
+ );
+
+ $whitelistFiles = array('/Columns');
+
+ if ('visit' == $type) {
+ $whitelistFiles[] = '/Columns/ExampleVisitDimension.php';
+ } elseif ('action' == $type) {
+ $whitelistFiles[] = '/Columns/ExampleActionDimension.php';
+ } elseif ('conversion' == $type) {
+ $whitelistFiles[] = '/Columns/ExampleConversionDimension.php';
+ } else {
+ throw new \InvalidArgumentException('This dimension type is not available');
+ }
+
+ $this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
+
+ $this->writeSuccessMessage($output, array(
+ sprintf('Columns/%s.php for %s generated.', ucfirst($dimensionClassName), $pluginName),
+ 'You should now implement the events within this file',
+ 'Enjoy!'
+ ));
+ }
+
+ private function getDimensionClassName($dimensionName)
+ {
+ $dimensionName = trim($dimensionName);
+ $dimensionName = str_replace(' ', '', $dimensionName);
+ $dimensionName = preg_replace("/[^A-Za-z0-9]/", '', $dimensionName);
+
+ $dimensionName = ucfirst($dimensionName);
+
+ return $dimensionName;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getDimensionName(InputInterface $input, OutputInterface $output)
+ {
+ $validate = function ($dimensionName) {
+ if (empty($dimensionName)) {
+ throw new \InvalidArgumentException('Please enter the name of your dimension');
+ }
+
+ if (preg_match("/[^A-Za-z0-9 ]/", $dimensionName)) {
+ throw new \InvalidArgumentException('Only alpha numerical characters and whitespaces are allowed');
+ }
+
+ return $dimensionName;
+ };
+
+ $dimensionName = $input->getOption('dimensionname');
+
+ if (empty($dimensionName)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $dimensionName = $dialog->askAndValidate($output, 'Enter a human readable name of your dimension, for instance "Browser": ', $validate);
+ } else {
+ $validate($dimensionName);
+ }
+
+ $dimensionName = ucfirst($dimensionName);
+
+ return $dimensionName;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getColumnName(InputInterface $input, OutputInterface $output, $type)
+ {
+ $validate = function ($columnName) use ($type) {
+ if (empty($columnName)) {
+ throw new \InvalidArgumentException('Please enter the name of the dimension column');
+ }
+
+ if (preg_match("/[^A-Za-z0-9_ ]/", $columnName)) {
+ throw new \InvalidArgumentException('Only alpha numerical characters, underscores and whitespaces are allowed');
+ }
+
+ if ('visit' == $type) {
+ $columns = array_keys(DbHelper::getTableColumns(Common::prefixTable('log_visit')));
+ } elseif ('action' == $type) {
+ $columns = array_keys(DbHelper::getTableColumns(Common::prefixTable('log_link_visit_action')));
+ } elseif ('conversion' == $type) {
+ $columns = array_keys(DbHelper::getTableColumns(Common::prefixTable('log_conversion')));
+ } else {
+ $columns = array();
+ }
+
+ foreach ($columns as $column) {
+ if (strtolower($column) === strtolower($columnName)) {
+ throw new \InvalidArgumentException('This column name is already in use.');
+ }
+ }
+
+ return $columnName;
+ };
+
+ $columnName = $input->getOption('columnname');
+
+ if (empty($columnName)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $columnName = $dialog->askAndValidate($output, 'Enter the name of the column under which it should be stored in the MySQL database, for instance "visit_total_time": ', $validate);
+ } else {
+ $validate($columnName);
+ }
+
+ return $columnName;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getColumnType(InputInterface $input, OutputInterface $output)
+ {
+ $validate = function ($columnType) {
+ if (empty($columnType)) {
+ throw new \InvalidArgumentException('Please enter the type of the dimension column');
+ }
+
+ return $columnType;
+ };
+
+ $columnType = $input->getOption('columntype');
+
+ if (empty($columnType)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $columnType = $dialog->askAndValidate($output, 'Enter the type of the column under which it should be stored in the MySQL database, for instance "VARCHAR(255) NOT NULL": ', $validate);
+ } else {
+ $validate($columnType);
+ }
+
+ return $columnType;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getDimensionType(InputInterface $input, OutputInterface $output)
+ {
+ $acceptedValues = array('visit', 'action', 'conversion');
+
+ $validate = function ($type) use ($acceptedValues) {
+ if (empty($type) || !in_array($type, $acceptedValues)) {
+ throw new \InvalidArgumentException('Please enter a valid dimension type (' . implode(', ', $acceptedValues) . '): ');
+ }
+
+ return $type;
+ };
+
+ $type = $input->getOption('type');
+
+ if (empty($type)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $type = $dialog->askAndValidate($output, 'Please choose the type of dimension you want to create (' . implode(', ', $acceptedValues) . '): ', $validate, false, null, $acceptedValues);
+ } else {
+ $validate($type);
+ }
+
+ return $type;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getPluginName(InputInterface $input, OutputInterface $output)
+ {
+ $pluginNames = $this->getPluginNames();
+ $invalidName = 'You have to enter a name of an existing plugin.';
+
+ return $this->askPluginNameAndValidate($input, $output, $pluginNames, $invalidName);
+ }
+
+}
diff --git a/plugins/CoreConsole/Commands/GenerateReport.php b/plugins/CoreConsole/Commands/GenerateReport.php
new file mode 100644
index 0000000000..7288fb6a16
--- /dev/null
+++ b/plugins/CoreConsole/Commands/GenerateReport.php
@@ -0,0 +1,280 @@
+<?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\CoreConsole\Commands;
+
+use Piwik\Plugin\Report;
+use Piwik\Translate;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * TODO we should automatically create a method in the API (works currently only if there is no API.php yet)
+ * TODO automatically create or modify translation file for instance for report name
+ */
+class GenerateReport extends GeneratePluginBase
+{
+ protected function configure()
+ {
+ $this->setName('generate:report')
+ ->setDescription('Adds a new report to an existing plugin')
+ ->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin which does not have a menu defined yet')
+ ->addOption('reportname', null, InputOption::VALUE_REQUIRED, 'The name of the report you want to create')
+ ->addOption('category', null, InputOption::VALUE_REQUIRED, 'The name of the category the report belongs to')
+ ->addOption('dimension', null, InputOption::VALUE_OPTIONAL, 'The name of the dimension in case your report has a dimension')
+ ->addOption('documentation', null, InputOption::VALUE_REQUIRED, 'A documentation that explains what your report is about');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $pluginName = $this->getPluginName($input, $output);
+ $reportName = $this->getReportName($input, $output);
+ $category = $this->getCategory($input, $output, $pluginName);
+ $documentation = $this->getDocumentation($input, $output);
+ list($dimension, $dimensionClass) = $this->getDimension($input, $output);
+
+ $order = $this->getOrder($category);
+ $apiName = $this->getApiName($reportName);
+
+ $exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
+ $replace = array('ExamplePlugin' => $pluginName,
+ 'GetExampleReport' => ucfirst($apiName),
+ 'getExampleReport' => lcfirst($apiName),
+ 'getApiReport' => lcfirst($apiName),
+ 'ExampleCategory' => $category,
+ 'ExampleReportName' => $reportName,
+ 'ExampleReportDocumentation' => $documentation,
+ '999' => $order,
+ 'new ExitPageUrl()' => $dimension,
+ 'use Piwik\Plugins\Actions\Columns\ExitPageUrl;' => $dimensionClass
+ );
+ $whitelistFiles = array('/Reports', '/Reports/Base.php', '/Reports/GetExampleReport.php', '/API.php');
+
+ $this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
+
+ $this->writeSuccessMessage($output, array(
+ sprintf('Reports/%s.php for %s generated.', ucfirst($apiName), $pluginName),
+ 'You should now implement the method called "' . lcfirst($apiName) . '" in API.php',
+ // 'Read more about this here: link to developer guide',
+ 'Enjoy!'
+ ));
+ }
+
+ private function getOrder($category)
+ {
+ $order = 1;
+
+ foreach (Report::getAllReports() as $report) {
+ if ($report->getCategory() === $category) {
+ if ($report->getOrder() > $order) {
+ $order = $report->getOrder() + 1;
+ }
+ }
+ }
+
+ return $order;
+ }
+
+ private function getApiName($reportName)
+ {
+ $reportName = trim($reportName);
+ $reportName = str_replace(' ', '', $reportName);
+ $reportName = preg_replace("/[^A-Za-z0-9]/", '', $reportName);
+
+ $apiName = 'get' . ucfirst($reportName);
+
+ return $apiName;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getReportName(InputInterface $input, OutputInterface $output)
+ {
+ $validate = function ($reportName) {
+ if (empty($reportName)) {
+ throw new \InvalidArgumentException('Please enter the name of your report');
+ }
+
+ if (preg_match("/[^A-Za-z0-9 ]/", $reportName)) {
+ throw new \InvalidArgumentException('Only alpha numerical characters and whitespaces are allowed');
+ }
+
+ return $reportName;
+ };
+
+ $reportName = $input->getOption('reportname');
+
+ if (empty($reportName)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $reportName = $dialog->askAndValidate($output, 'Enter the name of your report, for instance "Browser Families": ', $validate);
+ } else {
+ $validate($reportName);
+ }
+
+ $reportName = ucfirst($reportName);
+
+ return $reportName;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getDocumentation(InputInterface $input, OutputInterface $output)
+ {
+ $validate = function ($documentation) {
+ if (empty($documentation)) {
+ return '';
+ }
+
+ return $documentation;
+ };
+
+ $documentation = $input->getOption('documentation');
+
+ if (empty($documentation)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $documentation = $dialog->askAndValidate($output, 'Enter a documentation that describes the data of your report (you can leave it empty and define it later): ', $validate);
+ } else {
+ $validate($documentation);
+ }
+
+ $documentation = ucfirst($documentation);
+
+ return $documentation;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @param string $pluginName
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getCategory(InputInterface $input, OutputInterface $output, $pluginName)
+ {
+ $path = $this->getPluginPath($pluginName) . '/Reports/Base.php';
+ if (file_exists($path)) {
+ // category is already defined in base.php
+ return '';
+ }
+
+ $validate = function ($category) {
+ if (empty($category)) {
+ throw new \InvalidArgumentException('Please enter the name of the category your report belongs to');
+ }
+
+ return $category;
+ };
+
+ $category = $input->getOption('category');
+
+ $categories = array();
+ foreach (Report::getAllReports() as $report) {
+ if ($report->getCategory()) {
+ $categories[] = $report->getCategory();
+ }
+ }
+ $categories = array_values(array_unique($categories));
+
+ if (empty($category)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $category = $dialog->askAndValidate($output, 'Enter the report category, for instance "Visitor" (you can reuse any existing category or define a new one): ', $validate, false, null, $categories);
+ } else {
+ $validate($category);
+ }
+
+ $translationKey = Translate::findTranslationKeyForTranslation($category);
+ if (!empty($translationKey)) {
+ return $translationKey;
+ }
+
+ $category = ucfirst($category);
+
+ return $category;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getDimension(InputInterface $input, OutputInterface $output)
+ {
+ $dimensions = array();
+ $dimensionNames = array();
+
+ foreach (Report::getAllReports() as $report) {
+ $dimension = $report->getDimension();
+ if (is_object($dimension)) {
+ $name = $dimension->getName();
+ if (!empty($name)) {
+ $dimensions[$name] = get_class($dimension);
+ $dimensionNames[] = $name;
+ }
+ }
+ }
+
+ $dimensionNames = array_values(array_unique($dimensionNames));
+
+ $validate = function ($dimension) use ($dimensions) {
+ if (empty($dimension)) {
+ return '';
+ }
+
+ if (!empty($dimension) && !array_key_exists($dimension, $dimensions)) {
+ throw new \InvalidArgumentException('Leave dimension either empty or use an existing one. You can also create a new dimension by calling .console generate:dimension before generating this report.');
+ }
+
+ return $dimension;
+ };
+
+ $actualDimension = $input->getOption('dimension');
+
+ if (null === $actualDimension) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $actualDimension = $dialog->askAndValidate($output, 'Enter the report dimension, for instance "Browser" (you can leave it either empty or use an existing one): ', $validate, false, null, $dimensionNames);
+ } else {
+ $validate($actualDimension);
+ }
+
+ if (empty($actualDimension)) {
+ return array('null', '');
+ }
+
+ $className = $dimensions[$actualDimension];
+ $parts = explode('\\', $className);
+ $name = end($parts);
+
+ return array('new ' . $name . '()', 'use ' . $className . ';');
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
+ protected function getPluginName(InputInterface $input, OutputInterface $output)
+ {
+ $pluginNames = $this->getPluginNames();
+ $invalidName = 'You have to enter a name of an existing plugin.';
+
+ return $this->askPluginNameAndValidate($input, $output, $pluginNames, $invalidName);
+ }
+
+}
diff --git a/plugins/CoreConsole/Commands/GenerateWidget.php b/plugins/CoreConsole/Commands/GenerateWidget.php
index c3360e10fe..605b336a23 100644
--- a/plugins/CoreConsole/Commands/GenerateWidget.php
+++ b/plugins/CoreConsole/Commands/GenerateWidget.php
@@ -9,6 +9,9 @@
namespace Piwik\Plugins\CoreConsole\Commands;
+use Piwik\Piwik;
+use Piwik\Plugin\Widgets;
+use Piwik\Translate;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -21,15 +24,18 @@ class GenerateWidget extends GeneratePluginBase
{
$this->setName('generate:widget')
->setDescription('Adds a plugin widget class to an existing plugin')
- ->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin which does not have any widgets defined yet');
+ ->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin which does not have any widgets defined yet')
+ ->addOption('category', null, InputOption::VALUE_REQUIRED, 'The name of the category the widget should belong to');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$pluginName = $this->getPluginName($input, $output);
+ $category = $this->getCategory($input, $output);
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
- $replace = array('ExampleRssWidget' => $pluginName);
+ $replace = array('ExampleRssWidget' => $pluginName,
+ 'Example Category' => $category);
$whitelistFiles = array('/Widgets.php');
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
@@ -47,6 +53,49 @@ class GenerateWidget extends GeneratePluginBase
* @return array
* @throws \RunTimeException
*/
+ protected function getCategory(InputInterface $input, OutputInterface $output)
+ {
+ $validate = function ($category) {
+ if (empty($category)) {
+ throw new \InvalidArgumentException('Please enter the name of the category your widget should belong to');
+ }
+
+ return $category;
+ };
+
+ $category = $input->getOption('category');
+
+ $categories = array();
+ foreach (Widgets::getAllWidgets() as $widget) {
+ if ($widget->getCategory()) {
+ $categories[] = Piwik::translate($widget->getCategory());
+ }
+ }
+ $categories = array_values(array_unique($categories));
+
+ if (empty($category)) {
+ $dialog = $this->getHelperSet()->get('dialog');
+ $category = $dialog->askAndValidate($output, 'Enter the widget category, for instance "Visitor" (you can reuse any existing category or define a new one): ', $validate, false, null, $categories);
+ } else {
+ $validate($category);
+ }
+
+ $translationKey = Translate::findTranslationKeyForTranslation($category);
+ if (!empty($translationKey)) {
+ return $translationKey;
+ }
+
+ $category = ucfirst($category);
+
+ return $category;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return array
+ * @throws \RunTimeException
+ */
protected function getPluginName(InputInterface $input, OutputInterface $output)
{
$pluginNames = $this->getPluginNamesHavingNotSpecificFile('Widgets.php');
diff --git a/plugins/CoreConsole/Commands/RunTests.php b/plugins/CoreConsole/Commands/TestsRun.php
index 7dc7d43d66..87e8a4a1f1 100644
--- a/plugins/CoreConsole/Commands/RunTests.php
+++ b/plugins/CoreConsole/Commands/TestsRun.php
@@ -17,7 +17,7 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
*/
-class RunTests extends ConsoleCommand
+class TestsRun extends ConsoleCommand
{
protected function configure()
{
diff --git a/plugins/CoreConsole/Commands/RunUITests.php b/plugins/CoreConsole/Commands/TestsRunUI.php
index c2b210ff3e..4cce1e6446 100644
--- a/plugins/CoreConsole/Commands/RunUITests.php
+++ b/plugins/CoreConsole/Commands/TestsRunUI.php
@@ -13,7 +13,7 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-class RunUITests extends ConsoleCommand
+class TestsRunUI extends ConsoleCommand
{
protected function configure()
{
diff --git a/plugins/CoreConsole/Commands/SetupFixture.php b/plugins/CoreConsole/Commands/TestsSetupFixture.php
index e2c8889232..1d38f9f3bf 100644
--- a/plugins/CoreConsole/Commands/SetupFixture.php
+++ b/plugins/CoreConsole/Commands/TestsSetupFixture.php
@@ -42,7 +42,7 @@ use Symfony\Component\Console\Output\OutputInterface;
*
* ./console tests:setup-fixture OmniFixture --sqldump=OmniFixtureDump.sql
*/
-class SetupFixture extends ConsoleCommand
+class TestsSetupFixture extends ConsoleCommand
{
protected function configure()
{
@@ -254,4 +254,4 @@ class SetupFixture extends ConsoleCommand
@ini_set('include_path', PIWIK_INCLUDE_SEARCH_PATH);
@set_include_path(PIWIK_INCLUDE_SEARCH_PATH);
}
-} \ No newline at end of file
+}
diff --git a/plugins/CoreHome/Columns/IdSite.php b/plugins/CoreHome/Columns/IdSite.php
new file mode 100644
index 0000000000..65da72dccc
--- /dev/null
+++ b/plugins/CoreHome/Columns/IdSite.php
@@ -0,0 +1,52 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker;
+use Piwik\Tracker\Visitor;
+
+class IdSite extends VisitDimension
+{
+ protected $columnName = 'idsite';
+ // we do not install or define column definition here as we need to create this column when installing as there is
+ // an index on it. Currently we do not define the index here... although we could overwrite the install() method
+ // and add column 'idsite' and add index. Problem is there is also an index
+ // INDEX(idsite, config_id, visit_last_action_time) and we maybe not be sure whether config_id already exists at
+ // installing point (we do not know whether visit_last_action_time or idsite column would be added first).
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $request->getIdSite();
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $request->getIdSite();
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitFirstActionTime.php b/plugins/CoreHome/Columns/VisitFirstActionTime.php
new file mode 100644
index 0000000000..6aabb99199
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitFirstActionTime.php
@@ -0,0 +1,37 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker;
+use Piwik\Tracker\Visitor;
+
+class VisitFirstActionTime extends VisitDimension
+{
+ protected $columnName = 'visit_first_action_time';
+ protected $columnType = 'DATETIME NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Tracker::getDatetimeFromTimestamp($request->getCurrentTimestamp());
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitGoalBuyer.php b/plugins/CoreHome/Columns/VisitGoalBuyer.php
new file mode 100644
index 0000000000..447bc216f8
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitGoalBuyer.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\CoreHome\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitGoalBuyer extends VisitDimension
+{
+ // log_visit.visit_goal_buyer
+ const TYPE_BUYER_NONE = 0;
+ const TYPE_BUYER_ORDERED = 1;
+ const TYPE_BUYER_OPEN_CART = GoalManager::TYPE_BUYER_OPEN_CART;
+ const TYPE_BUYER_ORDERED_AND_OPEN_CART = GoalManager::TYPE_BUYER_ORDERED_AND_OPEN_CART;
+
+ static protected $visitEcommerceStatus = array(
+ self::TYPE_BUYER_NONE => 'none',
+ self::TYPE_BUYER_ORDERED => 'ordered',
+ self::TYPE_BUYER_OPEN_CART => 'abandonedCart',
+ self::TYPE_BUYER_ORDERED_AND_OPEN_CART => 'orderedThenAbandonedCart',
+ );
+
+ protected $columnName = 'visit_goal_buyer';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ protected function configureSegments()
+ {
+ $example = Piwik::translate('General_EcommerceVisitStatusEg', '"&segment=visitEcommerceStatus==ordered,visitEcommerceStatus==orderedThenAbandonedCart"');
+ $acceptedValues = implode(", ", self::$visitEcommerceStatus) . '. ' . $example;
+
+ $segment = new Segment();
+ $segment->setSegment('visitEcommerceStatus');
+ $segment->setName('General_EcommerceVisitStatusDesc');
+ $segment->setAcceptedValues($acceptedValues);
+ $segment->setSqlFilterValue(__NAMESPACE__ . '\VisitGoalBuyer::getVisitEcommerceStatus');
+
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getBuyerType($request);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ $goalBuyer = $visitor->getVisitorColumn($this->columnName);
+
+ // Ecommerce buyer status
+ $visitEcommerceStatus = $this->getBuyerType($request, $goalBuyer);
+
+ if($visitEcommerceStatus != self::TYPE_BUYER_NONE
+ // only update if the value has changed (prevents overwriting the value in case a request has
+ // updated it in the meantime)
+ && $visitEcommerceStatus != $goalBuyer) {
+
+ return $visitEcommerceStatus;
+ }
+
+ return false;
+ }
+
+ static public function getVisitEcommerceStatus($status)
+ {
+ $id = array_search($status, self::$visitEcommerceStatus);
+
+ if ($id === false) {
+ throw new \Exception("Invalid 'visitEcommerceStatus' segment value $status");
+ }
+
+ return $id;
+ }
+
+ /**
+ * @ignore
+ */
+ static public function getVisitEcommerceStatusFromId($id)
+ {
+ if (!isset(self::$visitEcommerceStatus[$id])) {
+ throw new \Exception("Unexpected ECommerce status value ");
+ }
+
+ return self::$visitEcommerceStatus[$id];
+ }
+
+ private function getBuyerType(Request $request, $existingType = self::TYPE_BUYER_NONE)
+ {
+ $goalManager = new GoalManager($request);
+
+ if (!$goalManager->requestIsEcommerce) {
+ return $existingType;
+ }
+
+ if ($goalManager->isGoalAnOrder()) {
+ return self::TYPE_BUYER_ORDERED;
+ }
+
+ // request is Add to Cart
+ if ($existingType == self::TYPE_BUYER_ORDERED
+ || $existingType == self::TYPE_BUYER_ORDERED_AND_OPEN_CART
+ ) {
+ return self::TYPE_BUYER_ORDERED_AND_OPEN_CART;
+ }
+
+ return self::TYPE_BUYER_OPEN_CART;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitGoalConverted.php b/plugins/CoreHome/Columns/VisitGoalConverted.php
new file mode 100644
index 0000000000..38b7e3cbff
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitGoalConverted.php
@@ -0,0 +1,57 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitGoalConverted extends VisitDimension
+{
+ protected $columnName = 'visit_goal_converted';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('visitConverted');
+ $segment->setName('General_VisitConvertedGoal');
+ $segment->setAcceptedValues('0, 1');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return 0;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onConvertedVisit(Request $request, Visitor $visitor, $action)
+ {
+ return 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitLastActionTime.php b/plugins/CoreHome/Columns/VisitLastActionTime.php
new file mode 100644
index 0000000000..25a8683331
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitLastActionTime.php
@@ -0,0 +1,52 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker;
+use Piwik\Tracker\Visitor;
+
+class VisitLastActionTime extends VisitDimension
+{
+ protected $columnName = 'visit_last_action_time';
+ // we do not install or define column definition here as we need to create this column when installing as there is
+ // an index on it. Currently we do not define the index here... although we could overwrite the install() method
+ // and add column 'visit_last_action_time' and add index. Problem is there is also an index
+ // INDEX(idsite, config_id, visit_last_action_time) and we maybe not be sure whether idsite already exists at
+ // installing point (we do not know whether idsite column will be added first).
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Tracker::getDatetimeFromTimestamp($request->getCurrentTimestamp());
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $this->onNewVisit($request, $visitor, $action);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitTotalTime.php b/plugins/CoreHome/Columns/VisitTotalTime.php
new file mode 100644
index 0000000000..d1bc1d735e
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitTotalTime.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\CoreHome\Columns;
+
+use Piwik\Config;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitTotalTime extends VisitDimension
+{
+ protected $columnName = 'visit_total_time';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('visitDuration');
+ $segment->setName('General_ColumnVisitDuration');
+ $segment->setType(Segment::TYPE_METRIC);
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $totalTime = Config::getInstance()->Tracker['default_time_one_page_visit'];
+ $totalTime = $this->cleanupVisitTotalTime($totalTime);
+
+ return $totalTime;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ $firstActionTime = $visitor->getVisitorColumn('visit_first_action_time');
+
+ $totalTime = 1 + $request->getCurrentTimestamp() - $firstActionTime;
+ $totalTime = $this->cleanupVisitTotalTime($totalTime);
+
+ return $totalTime;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onConvertedVisit(Request $request, Visitor $visitor, $action)
+ {
+ if (!$visitor->isVisitorKnown()) {
+ return false;
+ }
+
+ $goalManager = new GoalManager($request);
+
+ $totalTime = $visitor->getVisitorColumn('visit_total_time');
+
+ // If a pageview and goal conversion in the same second, with previously a goal conversion recorded
+ // the request would not "update" the row since all values are the same as previous
+ // therefore the request below throws exception, instead we make sure the UPDATE will affect the row
+ $totalTime = $totalTime + $goalManager->idGoal;
+ // +2 to offset idgoal=-1 and idgoal=0
+ $totalTime = $totalTime + 2;
+
+ return $this->cleanupVisitTotalTime($totalTime);
+ }
+
+ public function getRequiredVisitFields()
+ {
+ return array('visit_first_action_time');
+ }
+
+ private function cleanupVisitTotalTime($t)
+ {
+ $t = (int)$t;
+
+ if ($t < 0) {
+ $t = 0;
+ }
+
+ $smallintMysqlLimit = 65534;
+
+ if ($t > $smallintMysqlLimit) {
+ $t = $smallintMysqlLimit;
+ }
+
+ return $t;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php b/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php
new file mode 100644
index 0000000000..91cc3d3ccf
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php
@@ -0,0 +1,57 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitorDaysSinceFirst extends VisitDimension
+{
+ protected $columnName = 'visitor_days_since_first';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setType(Segment::TYPE_METRIC);
+ $segment->setSegment('daysSinceFirstVisit');
+ $segment->setName('General_DaysSinceFirstVisit');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $request->getDaysSinceFirstVisit();
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php b/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php
new file mode 100644
index 0000000000..65707e81d7
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php
@@ -0,0 +1,64 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitorDaysSinceOrder extends VisitDimension
+{
+ protected $columnName = 'visitor_days_since_order';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('daysSinceLastEcommerceOrder');
+ $segment->setName('General_DaysSinceLastEcommerceOrder');
+ $segment->setType(Segment::TYPE_METRIC);
+
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $daysSinceLastOrder = $request->getDaysSinceLastOrder();
+
+ if ($daysSinceLastOrder === false) {
+ $daysSinceLastOrder = 0;
+ }
+
+ return $daysSinceLastOrder;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitorReturning.php b/plugins/CoreHome/Columns/VisitorReturning.php
new file mode 100644
index 0000000000..57267973b2
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitorReturning.php
@@ -0,0 +1,84 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitorReturning extends VisitDimension
+{
+ const IS_RETURNING_CUSTOMER = 2;
+ const IS_RETURNING = 1;
+ const IS_NEW = 0;
+
+ protected $columnName = 'visitor_returning';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+ protected $conversionField = true;
+
+ protected function configureSegments()
+ {
+ $acceptedValues = 'new, returning, returningCustomer. ';
+ $acceptedValues .= Piwik::translate('General_VisitTypeExample', '"&segment=visitorType==returning,visitorType==returningCustomer"');
+
+ $segment = new Segment();
+ $segment->setSegment('visitorType');
+ $segment->setName('General_VisitType');
+ $segment->setAcceptedValues($acceptedValues);
+ $segment->setSqlFilterValue(function ($type) {
+ return $type == "new" ? 0 : ($type == "returning" ? 1 : 2);
+ });
+
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $visitCount = $request->getVisitCount();
+ $daysSinceLastVisit = $request->getDaysSinceLastVisit();
+
+ $daysSinceLastOrder = $request->getDaysSinceLastOrder();
+ $isReturningCustomer = ($daysSinceLastOrder !== false);
+
+ if ($isReturningCustomer) {
+ return self::IS_RETURNING_CUSTOMER;
+ }
+
+ if ($visitCount > 1 || $visitor->isVisitorKnown() || $daysSinceLastVisit > 0) {
+ return self::IS_RETURNING;
+ }
+
+ return self::IS_NEW;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Columns/VisitsCount.php b/plugins/CoreHome/Columns/VisitsCount.php
new file mode 100644
index 0000000000..a5392972db
--- /dev/null
+++ b/plugins/CoreHome/Columns/VisitsCount.php
@@ -0,0 +1,57 @@
+<?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\CoreHome\Columns;
+
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitsCount extends VisitDimension
+{
+ protected $columnName = 'visitor_count_visits';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setType(Segment::TYPE_METRIC);
+ $segment->setSegment('visitCount');
+ $segment->setName('General_NumberOfVisits');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $request->getVisitCount();
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/CoreHome/Controller.php b/plugins/CoreHome/Controller.php
index 1e01e1dc15..dae18b3ddf 100644
--- a/plugins/CoreHome/Controller.php
+++ b/plugins/CoreHome/Controller.php
@@ -16,6 +16,7 @@ use Piwik\FrontController;
use Piwik\Menu\MenuMain;
use Piwik\Notification\Manager as NotificationManager;
use Piwik\Piwik;
+use Piwik\Plugin\Report;
use Piwik\Plugins\CoreHome\DataTableRowAction\MultiRowEvolution;
use Piwik\Plugins\CoreHome\DataTableRowAction\RowEvolution;
use Piwik\Plugins\CorePluginsAdmin\MarketplaceApiClient;
@@ -26,10 +27,8 @@ use Piwik\UpdateCheck;
use Piwik\Url;
use Piwik\View;
use Piwik\ViewDataTable\Manager as ViewDataTableManager;
+use Piwik\Plugin\Widgets as PluginWidgets;
-/**
- *
- */
class Controller extends \Piwik\Plugin\Controller
{
function getDefaultAction()
@@ -37,6 +36,60 @@ class Controller extends \Piwik\Plugin\Controller
return 'redirectToCoreHomeIndex';
}
+ public function renderReportMenu($reportModule = null, $reportAction = null)
+ {
+ Piwik::checkUserHasSomeViewAccess();
+ $this->checkSitePermission();
+
+ $report = Report::factory($reportModule, $reportAction);
+
+ if (empty($report)) {
+ throw new Exception(Piwik::translate('General_ExceptionReportNotFound'));
+ }
+
+ $report->checkIsEnabled();
+
+ $menuTitle = $report->getMenuTitle();
+
+ if (empty($menuTitle)) {
+ throw new Exception('This report is not supposed to be displayed in the menu, please define a $menuTitle in your report.');
+ }
+
+ $menuTitle = Piwik::translate($menuTitle);
+ $content = $this->renderReportWidget($reportModule, $reportAction);
+
+ return View::singleReport($menuTitle, $content);
+ }
+
+ public function renderReportWidget($reportModule = null, $reportAction = null)
+ {
+ Piwik::checkUserHasSomeViewAccess();
+ $this->checkSitePermission();
+
+ $report = Report::factory($reportModule, $reportAction);
+
+ if (empty($report)) {
+ throw new Exception(Piwik::translate('General_ExceptionReportNotFound'));
+ }
+
+ $report->checkIsEnabled();
+
+ return $report->render();
+ }
+
+ public function renderWidget($widgetModule = null, $widgetAction = null)
+ {
+ Piwik::checkUserHasSomeViewAccess();
+
+ $widget = PluginWidgets::factory($widgetModule, $widgetAction);
+
+ if (!empty($widget)) {
+ return $widget->$widgetAction();
+ }
+
+ throw new Exception(Piwik::translate('General_ExceptionWidgetNotFound'));
+ }
+
function redirectToCoreHomeIndex()
{
$defaultReport = API::getInstance()->getUserPreference(Piwik::getCurrentUserLogin(), API::PREFERENCE_DEFAULT_REPORT);
@@ -183,32 +236,6 @@ class Controller extends \Piwik\Plugin\Controller
}
/**
- * Renders and echo's the in-app donate form w/ slider.
- */
- public function getDonateForm()
- {
- $view = new View('@CoreHome/getDonateForm');
- if (Common::getRequestVar('widget', false)
- && Piwik::hasUserSuperUserAccess()
- ) {
- $view->footerMessage = Piwik::translate('CoreHome_OnlyForSuperUserAccess');
- }
- return $view->render();
- }
-
- /**
- * Renders and echo's HTML that displays the Piwik promo video.
- */
- public function getPromoVideo()
- {
- $view = new View('@CoreHome/getPromoVideo');
- $view->shareText = Piwik::translate('CoreHome_SharePiwikShort');
- $view->shareTextLong = Piwik::translate('CoreHome_SharePiwikLong');
- $view->promoVideoUrl = 'https://www.youtube.com/watch?v=OslfF_EH81g';
- return $view->render();
- }
-
- /**
* Redirects the user to a paypal so they can donate to Piwik.
*/
public function redirectToPaypal()
diff --git a/plugins/CoreHome/Segment.php b/plugins/CoreHome/Segment.php
new file mode 100644
index 0000000000..3751648eeb
--- /dev/null
+++ b/plugins/CoreHome/Segment.php
@@ -0,0 +1,21 @@
+<?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\CoreHome;
+
+/**
+ * CoreHome segment base class
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+ protected function init()
+ {
+ $this->setCategory('General_Visit');
+ }
+}
+
diff --git a/plugins/CoreHome/Widgets.php b/plugins/CoreHome/Widgets.php
index c2bfc76448..68812f0749 100644
--- a/plugins/CoreHome/Widgets.php
+++ b/plugins/CoreHome/Widgets.php
@@ -8,17 +8,45 @@
*/
namespace Piwik\Plugins\CoreHome;
-use Piwik\WidgetsList;
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\View;
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
+ protected $category = 'Example Widgets';
+
+ protected function init()
+ {
+ $this->addWidget('CoreHome_SupportPiwik', 'getDonateForm');
+ $this->addWidget('Installation_Welcome', 'getPromoVideo');
+ }
+
+ /**
+ * Renders and echo's the in-app donate form w/ slider.
+ */
+ public function getDonateForm()
{
- $category = 'Example Widgets';
- $controller = 'CoreHome';
+ $view = new View('@CoreHome/getDonateForm');
- $widgetsList->add($category, 'CoreHome_SupportPiwik', $controller, 'getDonateForm');
- $widgetsList->add($category, 'Installation_Welcome', $controller, 'getPromoVideo');
+ if (Common::getRequestVar('widget', false)
+ && Piwik::hasUserSuperUserAccess()) {
+ $view->footerMessage = Piwik::translate('CoreHome_OnlyForSuperUserAccess');
+ }
+
+ return $view->render();
}
+ /**
+ * Renders and echo's HTML that displays the Piwik promo video.
+ */
+ public function getPromoVideo()
+ {
+ $view = new View('@CoreHome/getPromoVideo');
+ $view->shareText = Piwik::translate('CoreHome_SharePiwikShort');
+ $view->shareTextLong = Piwik::translate('CoreHome_SharePiwikLong');
+ $view->promoVideoUrl = 'https://www.youtube.com/watch?v=OslfF_EH81g';
+
+ return $view->render();
+ }
}
diff --git a/plugins/CoreHome/javascripts/menu.js b/plugins/CoreHome/javascripts/menu.js
index 820ecbbd2c..33cd37cb3d 100644
--- a/plugins/CoreHome/javascripts/menu.js
+++ b/plugins/CoreHome/javascripts/menu.js
@@ -62,8 +62,10 @@ menu.prototype =
return;
}
var url = href.substr(1);
- var module = broadcast.getValueFromUrl("module", url);
- var action = broadcast.getValueFromUrl("action", url);
+
+ var module = broadcast.getValueFromUrl('module', url);
+ var action = broadcast.getValueFromUrl('action', url);
+
var moduleId = broadcast.getValueFromUrl("idGoal", url) || broadcast.getValueFromUrl("idDashboard", url);
var main_menu = $(this).parent().hasClass('Menu-tabList') ? true : false;
if (main_menu) {
diff --git a/plugins/CorePluginsAdmin/PluginInstaller.php b/plugins/CorePluginsAdmin/PluginInstaller.php
index 83ee44a862..58fd074909 100644
--- a/plugins/CorePluginsAdmin/PluginInstaller.php
+++ b/plugins/CorePluginsAdmin/PluginInstaller.php
@@ -48,6 +48,8 @@ class PluginInstaller
$this->makeSureThereAreNoMissingRequirements($metadata);
$this->copyPluginToDestination($tmpPluginFolder);
+ Filesystem::deleteAllCacheOnUpdate($this->pluginName);
+
} catch (\Exception $e) {
$this->removeFileIfExists($tmpPluginZip);
@@ -78,6 +80,8 @@ class PluginInstaller
$this->fixPluginFolderIfNeeded($tmpPluginFolder);
$this->copyPluginToDestination($tmpPluginFolder);
+ Filesystem::deleteAllCacheOnUpdate($this->pluginName);
+
} catch (\Exception $e) {
$this->removeFileIfExists($pathToZip);
diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php
index de10b7ca32..c2977088aa 100644
--- a/plugins/CoreUpdater/Controller.php
+++ b/plugins/CoreUpdater/Controller.php
@@ -379,6 +379,7 @@ class Controller extends \Piwik\Plugin\Controller
$view->new_piwik_version = Version::VERSION;
$view->commandUpgradePiwik = "<br /><code>php " . Filesystem::getPathToPiwikRoot() . "/console core:update </code>";
$pluginNamesToUpdate = array();
+ $dimensionsToUpdate = array();
$coreToUpdate = false;
// handle case of existing database with no tables
@@ -397,6 +398,8 @@ class Controller extends \Piwik\Plugin\Controller
foreach ($componentsWithUpdateFile as $name => $filenames) {
if ($name == 'core') {
$coreToUpdate = true;
+ } elseif (0 === strpos($name, 'log_')) {
+ $dimensionsToUpdate[] = $name;
} else {
$pluginNamesToUpdate[] = $name;
}
@@ -418,6 +421,7 @@ class Controller extends \Piwik\Plugin\Controller
$view->errorMessages = $this->errorMessages;
$view->current_piwik_version = $currentVersion;
$view->pluginNamesToUpdate = $pluginNamesToUpdate;
+ $view->dimensionsToUpdate = $dimensionsToUpdate;
$view->coreToUpdate = $coreToUpdate;
}
diff --git a/plugins/CoreUpdater/CoreUpdater.php b/plugins/CoreUpdater/CoreUpdater.php
index cbd563e8b0..05bb59d538 100644
--- a/plugins/CoreUpdater/CoreUpdater.php
+++ b/plugins/CoreUpdater/CoreUpdater.php
@@ -14,7 +14,7 @@ use Piwik\Common;
use Piwik\Filesystem;
use Piwik\FrontController;
use Piwik\Piwik;
-use Piwik\ScheduledTask;
+use Piwik\Columns\Updater as ColumnsUpdater;
use Piwik\ScheduledTime;
use Piwik\UpdateCheck;
use Piwik\Updater;
@@ -64,7 +64,7 @@ class CoreUpdater extends \Piwik\Plugin
if ($name == 'core') {
$coreError = true;
break;
- } else {
+ } elseif (\Piwik\Plugin\Manager::getInstance()->isPluginActivated($name)) {
\Piwik\Plugin\Manager::getInstance()->deactivatePlugin($name);
$deactivatedPlugins[] = $name;
}
@@ -94,15 +94,24 @@ class CoreUpdater extends \Piwik\Plugin
$manager = \Piwik\Plugin\Manager::getInstance();
$plugins = $manager->getLoadedPlugins();
foreach ($plugins as $pluginName => $plugin) {
- if($manager->isPluginInstalled($pluginName)) {
+ if ($manager->isPluginInstalled($pluginName)) {
$updater->addComponentToCheck($pluginName, $plugin->getVersion());
}
}
+ $columnsVersions = ColumnsUpdater::getAllVersions();
+ foreach ($columnsVersions as $component => $version) {
+ $updater->addComponentToCheck($component, $version);
+ }
+
$componentsWithUpdateFile = $updater->getComponentsWithUpdateFile();
- if (count($componentsWithUpdateFile) == 0
- && !$updater->hasNewVersion('core')) {
- return null;
+
+ if (count($componentsWithUpdateFile) == 0) {
+ ColumnsUpdater::onNoUpdateAvailable($columnsVersions);
+
+ if (!$updater->hasNewVersion('core')) {
+ return null;
+ }
}
return $componentsWithUpdateFile;
diff --git a/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome.twig b/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome.twig
index 098ffa387c..b6318e5c6a 100644
--- a/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome.twig
+++ b/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome.twig
@@ -23,7 +23,7 @@
</ul>
</p>
{% else %}
- {% if coreToUpdate or pluginNamesToUpdate|length > 0 %}
+ {% if coreToUpdate or pluginNamesToUpdate|length > 0 or dimensionsToUpdate|length > 0 %}
<p style='font-size:110%;padding-top:1em;'><strong id='titleUpdate'>{{ 'CoreUpdater_DatabaseUpgradeRequired'|translate }}</strong></p>
<p>{{ 'CoreUpdater_YourDatabaseIsOutOfDate'|translate }}</p>
{% if coreToUpdate %}
@@ -34,6 +34,12 @@
{% set listOfPlugins=pluginNamesToUpdate|join(', ') %}
<p>{{ 'CoreUpdater_TheFollowingPluginsWillBeUpgradedX'|translate(listOfPlugins) }}</p>
{% endif %}
+
+ {% if dimensionsToUpdate|length > 0 %}
+ {% set listOfDimensions=dimensionsToUpdate|join(', ') %}
+ <p>{{ 'CoreUpdater_TheFollowingDimensionsWillBeUpgradedX'|translate(listOfDimensions) }}</p>
+ {% endif %}
+
<h3 id='titleUpdate'>{{ 'CoreUpdater_NoteForLargePiwikInstances'|translate }}</h3>
{% if isMajor %}
<p class="warning normalFontSize">
@@ -73,7 +79,7 @@
</p>
{% endif %}
- {% if coreToUpdate or pluginNamesToUpdate|length > 0 %}
+ {% if coreToUpdate or pluginNamesToUpdate|length > 0 or dimensionsToUpdate|length > 0 %}
<br/>
<form action="index.php" id="upgradeCorePluginsForm">
<input type="hidden" name="updateCorePlugins" value="1"/>
diff --git a/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig b/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig
index b912632971..33c21a15e3 100644
--- a/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig
+++ b/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig
@@ -16,7 +16,7 @@
* {{ helpMessage }}
-{% elseif coreToUpdate or pluginNamesToUpdate|length > 0 %}
+{% elseif coreToUpdate or pluginNamesToUpdate|length > 0 or dimensionsToUpdate|length > 0 %}
{{ 'CoreUpdater_DatabaseUpgradeRequired'|translate }}
@@ -31,6 +31,11 @@
{{ 'CoreUpdater_TheFollowingPluginsWillBeUpgradedX'|translate( listOfPlugins) }}
{% endif %}
+{%- if dimensionsToUpdate|length > 0 %}
+ {%- set listOfDimensions %}{{ dimensionsToUpdate|implode(', ') }}{% endset %}
+ {{ 'CoreUpdater_TheFollowingDimensionsWillBeUpgradedX'|translate( listOfDimensions) }}
+{% endif %}
+
{# dry run #}
{% if queries is defined and queries is not empty %}
*** Note: this is a Dry Run ***
diff --git a/plugins/CoreVisualizations/CoreVisualizations.php b/plugins/CoreVisualizations/CoreVisualizations.php
index ae86d51896..112858d499 100644
--- a/plugins/CoreVisualizations/CoreVisualizations.php
+++ b/plugins/CoreVisualizations/CoreVisualizations.php
@@ -43,10 +43,7 @@ class CoreVisualizations extends \Piwik\Plugin
public function getAvailableDataTableVisualizations(&$visualizations)
{
- $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\Sparkline';
- $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\HtmlTable';
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\HtmlTable\\AllColumns';
- $visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\Cloud';
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Pie';
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Bar';
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Evolution';
diff --git a/plugins/CustomVariables/API.php b/plugins/CustomVariables/API.php
index 406306638d..1f03f873fe 100644
--- a/plugins/CustomVariables/API.php
+++ b/plugins/CustomVariables/API.php
@@ -13,7 +13,7 @@ use Piwik\DataTable;
use Piwik\Date;
use Piwik\Metrics;
use Piwik\Piwik;
-use Piwik\Tracker\ActionSiteSearch;
+use Piwik\Plugins\Actions\Actions\ActionSiteSearch;
/**
* The Custom Variables API lets you access reports for your <a href='http://piwik.org/docs/custom-variables/' target='_blank'>Custom Variables</a> names and values.
diff --git a/plugins/CustomVariables/Columns/CustomVariableName.php b/plugins/CustomVariables/Columns/CustomVariableName.php
new file mode 100644
index 0000000000..a9a0139447
--- /dev/null
+++ b/plugins/CustomVariables/Columns/CustomVariableName.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class CustomVariableName extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('CustomVariables_ColumnCustomVariableName');
+ }
+} \ No newline at end of file
diff --git a/plugins/CustomVariables/Columns/CustomVariableValue.php b/plugins/CustomVariables/Columns/CustomVariableValue.php
new file mode 100644
index 0000000000..4591e14ea3
--- /dev/null
+++ b/plugins/CustomVariables/Columns/CustomVariableValue.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class CustomVariableValue extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('CustomVariables_ColumnCustomVariableValue');
+ }
+} \ No newline at end of file
diff --git a/plugins/CustomVariables/Controller.php b/plugins/CustomVariables/Controller.php
index a2b6b30dc6..59a4a949de 100644
--- a/plugins/CustomVariables/Controller.php
+++ b/plugins/CustomVariables/Controller.php
@@ -8,28 +8,7 @@
*/
namespace Piwik\Plugins\CustomVariables;
-use Piwik\Piwik;
-use Piwik\View;
-
-/**
- */
class Controller extends \Piwik\Plugin\Controller
{
- public function index()
- {
- return View::singleReport(
- Piwik::translate('CustomVariables_CustomVariables'),
- $this->getCustomVariables(true));
- }
-
- public function getCustomVariables()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getCustomVariablesValuesFromNameId()
- {
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/CustomVariables/CustomVariables.php b/plugins/CustomVariables/CustomVariables.php
index 5f1c790f1c..e667002286 100644
--- a/plugins/CustomVariables/CustomVariables.php
+++ b/plugins/CustomVariables/CustomVariables.php
@@ -10,12 +10,9 @@ namespace Piwik\Plugins\CustomVariables;
use Piwik\ArchiveProcessor;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
use Piwik\Tracker\Cache;
use Piwik\Tracker;
-/**
- */
class CustomVariables extends \Piwik\Plugin
{
public function getInformation()
@@ -30,13 +27,9 @@ class CustomVariables extends \Piwik\Plugin
*/
public function getListHooksRegistered()
{
- $hooks = array(
- 'Goals.getReportsWithGoalMetrics' => 'getReportsWithGoalMetrics',
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable'
+ return array(
+ 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata'
);
- return $hooks;
}
public function install()
@@ -83,33 +76,6 @@ class CustomVariables extends \Piwik\Plugin
return $cache[$cacheKey];
}
- /**
- * Returns metadata for available reports
- */
- public function getReportMetadata(&$reports)
- {
- $documentation = Piwik::translate('CustomVariables_CustomVariablesReportDocumentation',
- array('<br />', '<a href="http://piwik.org/docs/custom-variables/" target="_blank">', '</a>'));
-
- $reports[] = array('category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('CustomVariables_CustomVariables'),
- 'module' => 'CustomVariables',
- 'action' => 'getCustomVariables',
- 'actionToLoadSubTables' => 'getCustomVariablesValuesFromNameId',
- 'dimension' => Piwik::translate('CustomVariables_ColumnCustomVariableName'),
- 'documentation' => $documentation,
- 'order' => 10);
-
- $reports[] = array('category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('CustomVariables_CustomVariables'),
- 'module' => 'CustomVariables',
- 'action' => 'getCustomVariablesValuesFromNameId',
- 'dimension' => Piwik::translate('CustomVariables_ColumnCustomVariableValue'),
- 'documentation' => $documentation,
- 'isSubtableReport' => true,
- 'order' => 15);
- }
-
public function getSegmentsMetadata(&$segments)
{
$maxCustomVariables = self::getMaxCustomVariables();
@@ -150,48 +116,4 @@ class CustomVariables extends \Piwik\Plugin
}
}
- /**
- * Adds Goal dimensions, so that the dimensions are displayed in the UI Goal Overview page
- */
- public function getReportsWithGoalMetrics(&$dimensions)
- {
- $dimensions[] = array('category' => Piwik::translate('General_Visit'),
- 'name' => Piwik::translate('CustomVariables_CustomVariables'),
- 'module' => 'CustomVariables',
- 'action' => 'getCustomVariables',
- );
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'CustomVariables.getCustomVariables':
- $this->configureViewForGetCustomVariables($view);
- break;
- case 'CustomVariables.getCustomVariablesValuesFromNameId':
- $this->configureViewForGetCustomVariablesValuesFromNameId($view);
- break;
- }
- }
-
- private function configureViewForGetCustomVariables(ViewDataTable $view)
- {
- $view->config->columns_to_display = array('label', 'nb_actions', 'nb_visits');
- $view->config->show_goals = true;
- $view->config->subtable_controller_action = 'getCustomVariablesValuesFromNameId';
- $view->config->addTranslation('label', Piwik::translate('CustomVariables_ColumnCustomVariableName'));
- $view->requestConfig->filter_sort_column = 'nb_actions';
- $view->requestConfig->filter_sort_order = 'desc';
- }
-
- private function configureViewForGetCustomVariablesValuesFromNameId(ViewDataTable $view)
- {
- $view->config->columns_to_display = array('label', 'nb_actions', 'nb_visits');
- $view->config->show_goals = true;
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('CustomVariables_ColumnCustomVariableValue'));
- $view->requestConfig->filter_sort_column = 'nb_actions';
- $view->requestConfig->filter_sort_order = 'desc';
- }
}
diff --git a/plugins/CustomVariables/Menu.php b/plugins/CustomVariables/Menu.php
deleted file mode 100644
index fd2658b85e..0000000000
--- a/plugins/CustomVariables/Menu.php
+++ /dev/null
@@ -1,24 +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
- *
- */
-namespace Piwik\Plugins\CustomVariables;
-
-use Piwik\Db;
-use Piwik\Menu\MenuReporting;
-
-/**
- */
-class Menu extends \Piwik\Plugin\Menu
-{
-
- public function configureReportingMenu(MenuReporting $menu)
- {
- $menu->add('General_Visitors', 'CustomVariables_CustomVariables', array('module' => 'CustomVariables', 'action' => 'index'), $display = true, $order = 50);
- }
-
-}
diff --git a/plugins/CustomVariables/Reports/Base.php b/plugins/CustomVariables/Reports/Base.php
new file mode 100644
index 0000000000..4a19c0a763
--- /dev/null
+++ b/plugins/CustomVariables/Reports/Base.php
@@ -0,0 +1,18 @@
+<?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\Reports;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'General_Visitors';
+ }
+
+}
diff --git a/plugins/CustomVariables/Reports/GetCustomVariables.php b/plugins/CustomVariables/Reports/GetCustomVariables.php
new file mode 100644
index 0000000000..9b90c3ed0b
--- /dev/null
+++ b/plugins/CustomVariables/Reports/GetCustomVariables.php
@@ -0,0 +1,39 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CustomVariables\Columns\CustomVariableName;
+
+class GetCustomVariables extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new CustomVariableName();
+ $this->name = Piwik::translate('CustomVariables_CustomVariables');
+ $this->documentation = Piwik::translate('CustomVariables_CustomVariablesReportDocumentation',
+ array('<br />', '<a href="http://piwik.org/docs/custom-variables/" target="_blank">', '</a>'));
+ $this->actionToLoadSubTables = 'getCustomVariablesValuesFromNameId';
+ $this->order = 10;
+ $this->widgetTitle = 'CustomVariables_CustomVariables';
+ $this->menuTitle = 'CustomVariables_CustomVariables';
+ $this->hasGoalMetrics = true;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->columns_to_display = array('label', 'nb_actions', 'nb_visits');
+ $view->config->show_goals = true;
+ $view->config->addTranslation('label', Piwik::translate('CustomVariables_ColumnCustomVariableName'));
+ $view->requestConfig->filter_sort_column = 'nb_actions';
+ $view->requestConfig->filter_sort_order = 'desc';
+ }
+}
diff --git a/plugins/CustomVariables/Reports/GetCustomVariablesValuesFromNameId.php b/plugins/CustomVariables/Reports/GetCustomVariablesValuesFromNameId.php
new file mode 100644
index 0000000000..8b88fb20bb
--- /dev/null
+++ b/plugins/CustomVariables/Reports/GetCustomVariablesValuesFromNameId.php
@@ -0,0 +1,39 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CustomVariables\Columns\CustomVariableValue;
+
+class GetCustomVariablesValuesFromNameId extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new CustomVariableValue();
+ $this->name = Piwik::translate('CustomVariables_CustomVariables');
+ $this->documentation = Piwik::translate('CustomVariables_CustomVariablesReportDocumentation',
+ array('<br />', '<a href="http://piwik.org/docs/custom-variables/" target="_blank">', '</a>'));
+ $this->isSubtableReport = true;
+ $this->order = 15;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->columns_to_display = array('label', 'nb_actions', 'nb_visits');
+ $view->config->show_goals = true;
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate('CustomVariables_ColumnCustomVariableValue'));
+ $view->requestConfig->filter_sort_column = 'nb_actions';
+ $view->requestConfig->filter_sort_order = 'desc';
+ }
+
+}
diff --git a/plugins/CustomVariables/Widgets.php b/plugins/CustomVariables/Widgets.php
deleted file mode 100644
index c20f34373d..0000000000
--- a/plugins/CustomVariables/Widgets.php
+++ /dev/null
@@ -1,20 +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
- *
- */
-namespace Piwik\Plugins\CustomVariables;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- WidgetsList::add('General_Visitors', 'CustomVariables_CustomVariables', 'CustomVariables', 'getCustomVariables');
- }
-
-}
diff --git a/plugins/DBStats/Controller.php b/plugins/DBStats/Controller.php
index f8ec667893..de36313264 100644
--- a/plugins/DBStats/Controller.php
+++ b/plugins/DBStats/Controller.php
@@ -10,6 +10,11 @@ namespace Piwik\Plugins\DBStats;
use Piwik\MetricsFormatter;
use Piwik\Piwik;
+use Piwik\Plugins\DBStats\Reports\GetAdminDataSummary;
+use Piwik\Plugins\DBStats\Reports\GetDatabaseUsageSummary;
+use Piwik\Plugins\DBStats\Reports\GetMetricDataSummary;
+use Piwik\Plugins\DBStats\Reports\GetReportDataSummary;
+use Piwik\Plugins\DBStats\Reports\GetTrackerDataSummary;
use Piwik\View;
/**
@@ -29,131 +34,18 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$view = new View('@DBStats/index');
$this->setBasicVariablesView($view);
- $view->databaseUsageSummary = $this->getDatabaseUsageSummary(true);
- $view->trackerDataSummary = $this->getTrackerDataSummary(true);
- $view->metricDataSummary = $this->getMetricDataSummary(true);
- $view->reportDataSummary = $this->getReportDataSummary(true);
- $view->adminDataSummary = $this->getAdminDataSummary(true);
+ $view->databaseUsageSummary = $this->renderReport(new GetDatabaseUsageSummary());
+ $view->trackerDataSummary = $this->renderReport(new GetTrackerDataSummary());
+ $view->metricDataSummary = $this->renderReport(new GetMetricDataSummary());
+ $view->reportDataSummary = $this->renderReport(new GetReportDataSummary());
+ $view->adminDataSummary = $this->renderReport(new GetAdminDataSummary());
list($siteCount, $userCount, $totalSpaceUsed) = API::getInstance()->getGeneralInformation();
- $view->siteCount = MetricsFormatter::getPrettyNumber($siteCount);
- $view->userCount = MetricsFormatter::getPrettyNumber($userCount);
+
+ $view->siteCount = MetricsFormatter::getPrettyNumber($siteCount);
+ $view->userCount = MetricsFormatter::getPrettyNumber($userCount);
$view->totalSpaceUsed = MetricsFormatter::getPrettySizeFromBytes($totalSpaceUsed);
return $view->render();
}
-
- /**
- * Shows a datatable that displays how much space the tracker tables, numeric
- * archive tables, report tables and other tables take up in the MySQL database.
- *
- * @return string
- */
- public function getDatabaseUsageSummary()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays the amount of space each individual log table
- * takes up in the MySQL database.
- * @return string|void
- */
- public function getTrackerDataSummary()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays the amount of space each numeric archive table
- * takes up in the MySQL database.
- *
- * @return string|void
- */
- public function getMetricDataSummary()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays the amount of space each numeric archive table
- * takes up in the MySQL database, for each year of numeric data.
- *
- * @return string|void
- */
- public function getMetricDataSummaryByYear()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays the amount of space each blob archive table
- * takes up in the MySQL database.
- *
- * @return string|void
- */
- public function getReportDataSummary()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays the amount of space each blob archive table
- * takes up in the MySQL database, for each year of blob data.
- *
- * @return string|void
- */
- public function getReportDataSummaryByYear()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays how many occurances there are of each individual
- * report type stored in the MySQL database.
- *
- * Goal reports and reports of the format: .*_[0-9]+ are grouped together.
- *
- * @return string|void
- */
- public function getIndividualReportsSummary()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays how many occurances there are of each individual
- * metric type stored in the MySQL database.
- *
- * Goal metrics, metrics of the format .*_[0-9]+ and 'done...' metrics are grouped together.
- *
- * @return string|void
- */
- public function getIndividualMetricsSummary()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Shows a datatable that displays the amount of space each 'admin' table takes
- * up in the MySQL database.
- *
- * An 'admin' table is a table that is not central to analytics functionality.
- * So any table that isn't an archive table or a log table is an 'admin' table.
- *
- * @return string|void
- */
- public function getAdminDataSummary()
- {
- Piwik::checkUserHasSuperUserAccess();
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/DBStats/DBStats.php b/plugins/DBStats/DBStats.php
index ebf7f1eff6..1f5f9d7609 100644
--- a/plugins/DBStats/DBStats.php
+++ b/plugins/DBStats/DBStats.php
@@ -8,12 +8,9 @@
*/
namespace Piwik\Plugins\DBStats;
-use Piwik\Option;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
-use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Pie;
class DBStats extends \Piwik\Plugin
{
@@ -26,8 +23,6 @@ class DBStats extends \Piwik\Plugin
{
return array(
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
- 'ViewDataTable.configure' => 'configureViewDataTable',
- 'ViewDataTable.getDefaultType' => 'getDefaultTypeViewDataTable',
"TestingEnvironment.addHooks" => 'setupTestEnvironment'
);
}
@@ -37,321 +32,6 @@ class DBStats extends \Piwik\Plugin
$stylesheets[] = "plugins/DBStats/stylesheets/dbStatsTable.less";
}
- /** Returns the date when the cacheDataByArchiveNameReports was last run. */
- public static function getDateOfLastCachingRun()
- {
- return Option::get(self::TIME_OF_LAST_TASK_RUN_OPTION);
- }
-
- public function getDefaultTypeViewDataTable(&$defaultViewTypes)
- {
- $defaultViewTypes['DBStats.getDatabaseUsageSummary'] = Pie::ID;
- $defaultViewTypes['DBStats.getTrackerDataSummary'] = HtmlTable::ID;
- $defaultViewTypes['DBStats.getMetricDataSummary'] = HtmlTable::ID;
- $defaultViewTypes['DBStats.getMetricDataSummaryByYear'] = HtmlTable::ID;
- $defaultViewTypes['DBStats.getReportDataSummary'] = HtmlTable::ID;
- $defaultViewTypes['DBStats.getReportDataSummaryByYear'] = HtmlTable::ID;
- $defaultViewTypes['DBStats.getIndividualReportsSummary'] = HtmlTable::ID;
- $defaultViewTypes['DBStats.getIndividualMetricsSummary'] = HtmlTable::ID;
- $defaultViewTypes['DBStats.getAdminDataSummary'] = HtmlTable::ID;
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'DBStats.getDatabaseUsageSummary':
- $this->configureViewForGetDatabaseUsageSummary($view);
- break;
- case 'DBStats.getTrackerDataSummary':
- $this->configureViewForGetTrackerDataSummary($view);
- break;
- case 'DBStats.getMetricDataSummary':
- $this->configureViewForGetMetricDataSummary($view);
- break;
- case 'DBStats.getMetricDataSummaryByYear':
- $this->configureViewForGetMetricDataSummaryByYear($view);
- break;
- case 'DBStats.getReportDataSummary':
- $this->configureViewForGetReportDataSummary($view);
- break;
- case 'DBStats.getReportDataSummaryByYear':
- $this->configureViewForGetReportDataSummaryByYear($view);
- break;
- case 'DBStats.getIndividualReportsSummary':
- $this->configureViewForGetIndividualReportsSummary($view);
- break;
- case 'DBStats.getIndividualMetricsSummary':
- $this->configureViewForGetIndividualMetricsSummary($view);
- break;
- case 'DBStats.getAdminDataSummary':
- $this->configureViewForGetAdminDataSummary($view);
- break;
- }
- }
-
- private function configureViewForGetDatabaseUsageSummary(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view, $addTotalSizeColumn = true, $addPercentColumn = true);
-
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->show_all_ticks = true;
- }
-
- // translate the labels themselves
- $valueToTranslationStr = array(
- 'tracker_data' => 'DBStats_TrackerTables',
- 'report_data' => 'DBStats_ReportTables',
- 'metric_data' => 'DBStats_MetricTables',
- 'other_data' => 'DBStats_OtherTables'
- );
-
- $translateSummaryLabel = function ($value) use ($valueToTranslationStr) {
- return isset($valueToTranslationStr[$value])
- ? Piwik::translate($valueToTranslationStr[$value])
- : $value;
- };
-
- $view->config->filters[] = array('ColumnCallbackReplace',
- array(
- 'label',
- $translateSummaryLabel
- ),
- $isPriority = true
- );
- }
-
- private function configureViewForGetTrackerDataSummary(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view);
-
- $view->requestConfig->filter_sort_order = 'asc';
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- }
-
- private function configureViewForGetMetricDataSummary(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view);
-
- $view->config->title = Piwik::translate('DBStats_MetricTables');
- $view->config->addRelatedReports(array(
- 'DBStats.getMetricDataSummaryByYear' => Piwik::translate('DBStats_MetricDataByYear')
- ));
- }
-
- private function configureViewForGetMetricDataSummaryByYear(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view);
-
- $view->config->title = Piwik::translate('DBStats_MetricDataByYear');
- $view->config->addTranslation('label', Piwik::translate('CoreHome_PeriodYear'));
- $view->config->addRelatedReports(array(
- 'DBStats.getMetricDataSummary' => Piwik::translate('DBStats_MetricTables')
- ));
- }
-
- private function configureViewForGetReportDataSummary(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view);
-
- $view->config->title = Piwik::translate('DBStats_ReportTables');
- $view->config->addRelatedReports(array(
- 'DBStats.getReportDataSummaryByYear' => Piwik::translate('DBStats_ReportDataByYear')
- ));
- }
-
- private function configureViewForGetReportDataSummaryByYear(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view);
-
- $view->config->title = Piwik::translate('DBStats_ReportDataByYear');
- $view->config->addTranslation('label', Piwik::translate('CoreHome_PeriodYear'));
- $view->config->addRelatedReports(array(
- 'DBStats.getReportDataSummary' => Piwik::translate('DBStats_ReportTables')
- ));
- }
-
- private function configureViewForGetIndividualReportsSummary(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view, $addTotalSizeColumn = false, $addPercentColumn = false,
- $sizeColumns = array('estimated_size'));
-
- $view->requestConfig->filter_sort_order = 'asc';
- $view->config->addTranslation('label', Piwik::translate('General_Report'));
-
- // this report table has some extra columns that shouldn't be shown
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->columns_to_display = array('label', 'row_count', 'estimated_size');
- }
-
- $this->setIndividualSummaryFooterMessage($view);
- }
-
- private function configureViewForGetIndividualMetricsSummary(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view, $addTotalSizeColumn = false, $addPercentColumn = false,
- $sizeColumns = array('estimated_size'));
-
- $view->requestConfig->filter_sort_order = 'asc';
- $view->config->addTranslation('label', Piwik::translate('General_Metric'));
-
- $this->setIndividualSummaryFooterMessage($view);
- }
-
- private function configureViewForGetAdminDataSummary(ViewDataTable $view)
- {
- $this->addBaseDisplayProperties($view);
- $this->addPresentationFilters($view);
-
- $view->requestConfig->filter_sort_order = 'asc';
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- }
-
- private function addBaseDisplayProperties(ViewDataTable $view)
- {
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'desc';
- $view->requestConfig->filter_limit = 25;
-
- $view->config->show_exclude_low_population = false;
- $view->config->show_table_all_columns = false;
- $view->config->show_tag_cloud = false;
- $view->config->show_search = false;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->keep_summary_row = true;
- $view->config->disable_row_evolution = true;
- $view->config->highlight_summary_row = true;
- }
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->show_series_picker = false;
- }
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('DBStats_Table'),
- 'year' => Piwik::translate('CoreHome_PeriodYear'),
- 'data_size' => Piwik::translate('DBStats_DataSize'),
- 'index_size' => Piwik::translate('DBStats_IndexSize'),
- 'total_size' => Piwik::translate('DBStats_TotalSize'),
- 'row_count' => Piwik::translate('DBStats_RowCount'),
- 'percent_total' => '%&nbsp;' . Piwik::translate('DBStats_DBSize'),
- 'estimated_size' => Piwik::translate('DBStats_EstimatedSize')
- ));
- }
-
- private function addPresentationFilters(ViewDataTable $view, $addTotalSizeColumn = true, $addPercentColumn = false,
- $sizeColumns = array('data_size', 'index_size'))
- {
- // add total_size column
- if ($addTotalSizeColumn) {
- $getTotalTableSize = function ($dataSize, $indexSize) {
- return $dataSize + $indexSize;
- };
-
- $view->config->filters[] = array('ColumnCallbackAddColumn',
- array(
- array('data_size', 'index_size'),
- 'total_size',
- $getTotalTableSize
- ),
- $isPriority = true
- );
-
- $sizeColumns[] = 'total_size';
- }
-
- $runPrettySizeFilterBeforeGeneric = false;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
-
- // add summary row only if displaying a table
- $view->config->filters[] = array('AddSummaryRow', Piwik::translate('General_Total'));
-
- // add percentage column if desired
- if ($addPercentColumn
- && $addTotalSizeColumn
- ) {
- $view->config->filters[] = array('ColumnCallbackAddColumnPercentage',
- array(
- 'percent_total',
- 'total_size',
- 'total_size',
- $quotientPrecision = 0,
- $shouldSkipRows = false,
- $getDivisorFromSummaryRow = true
- ),
- $isPriority = false
- );
-
- $view->requestConfig->filter_sort_column = 'percent_total';
- }
-
- } else if ($view->isViewDataTableId(Graph::ID)) {
- if ($addTotalSizeColumn) {
- $view->config->columns_to_display = array('label', 'total_size');
-
- // when displaying a graph, we force sizes to be shown as the same unit so axis labels
- // will be readable. NOTE: The unit should depend on the smallest value of the data table,
- // however there's no way to know this information, short of creating a custom filter. For
- // now, just assume KB.
- $fixedMemoryUnit = 'K';
- $view->config->y_axis_unit = ' K';
- $view->requestConfig->filter_sort_column = 'total_size';
- $view->requestConfig->filter_sort_order = 'desc';
-
- $runPrettySizeFilterBeforeGeneric = true;
- } else {
- $view->config->columns_to_display = array('label', 'row_count');
- $view->config->y_axis_unit = ' ' . Piwik::translate('General_Rows');
-
- $view->requestConfig->filter_sort_column = 'row_count';
- $view->requestConfig->filter_sort_order = 'desc';
- }
- $view->config->selectable_rows = array();
- }
-
- $getPrettySize = array('\Piwik\MetricsFormatter', 'getPrettySizeFromBytes');
- $params = !isset($fixedMemoryUnit) ? array() : array($fixedMemoryUnit);
-
- $view->config->filters[] = array('ColumnCallbackReplace', array($sizeColumns, $getPrettySize, $params), $runPrettySizeFilterBeforeGeneric);
-
- // jqPlot will display &nbsp; as, well, '&nbsp;', so don't replace the spaces when rendering as a graph
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $replaceSpaces = function ($value) {
- return str_replace(' ', '&nbsp;', $value);
- };
-
- $view->config->filters[] = array('ColumnCallbackReplace', array($sizeColumns, $replaceSpaces));
- }
-
- $getPrettyNumber = array('\Piwik\MetricsFormatter', 'getPrettyNumber');
- $view->config->filters[] = array('ColumnCallbackReplace', array('row_count', $getPrettyNumber));
- }
-
- /**
- * Sets the footer message for the Individual...Summary reports.
- */
- private function setIndividualSummaryFooterMessage(ViewDataTable $view)
- {
- $lastGenerated = self::getDateOfLastCachingRun();
- if ($lastGenerated !== false) {
- $view->config->show_footer_message = Piwik::translate('Mobile_LastUpdated', $lastGenerated);
- }
- }
-
public function setupTestEnvironment($environment)
{
Piwik::addAction("MySQLMetadataProvider.createDao", function (&$dao) {
diff --git a/plugins/DBStats/Reports/Base.php b/plugins/DBStats/Reports/Base.php
new file mode 100644
index 0000000000..d81a54ff15
--- /dev/null
+++ b/plugins/DBStats/Reports/Base.php
@@ -0,0 +1,158 @@
+<?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\DBStats\Reports;
+
+use Piwik\Option;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\DBStats\DBStats;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+
+ public function isEnabled()
+ {
+ return Piwik::hasUserSuperUserAccess();
+ }
+
+ public function configureReportMetadata(&$availableReports, $info)
+ {
+ // DBStats is not supposed to appear in report metadata
+ }
+
+ protected function addBaseDisplayProperties(ViewDataTable $view)
+ {
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'desc';
+ $view->requestConfig->filter_limit = 25;
+
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->show_tag_cloud = false;
+ $view->config->show_search = false;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->keep_summary_row = true;
+ $view->config->disable_row_evolution = true;
+ $view->config->highlight_summary_row = true;
+ }
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->show_series_picker = false;
+ }
+
+ $view->config->addTranslations(array(
+ 'label' => Piwik::translate('DBStats_Table'),
+ 'year' => Piwik::translate('CoreHome_PeriodYear'),
+ 'data_size' => Piwik::translate('DBStats_DataSize'),
+ 'index_size' => Piwik::translate('DBStats_IndexSize'),
+ 'total_size' => Piwik::translate('DBStats_TotalSize'),
+ 'row_count' => Piwik::translate('DBStats_RowCount'),
+ 'percent_total' => '%&nbsp;' . Piwik::translate('DBStats_DBSize'),
+ 'estimated_size' => Piwik::translate('DBStats_EstimatedSize')
+ ));
+ }
+
+ protected function addPresentationFilters(ViewDataTable $view, $addTotalSizeColumn = true, $addPercentColumn = false,
+ $sizeColumns = array('data_size', 'index_size'))
+ {
+ // add total_size column
+ if ($addTotalSizeColumn) {
+ $getTotalTableSize = function ($dataSize, $indexSize) {
+ return $dataSize + $indexSize;
+ };
+
+ $view->config->filters[] = array('ColumnCallbackAddColumn',
+ array(array('data_size', 'index_size'), 'total_size', $getTotalTableSize), $isPriority = true);
+
+ $sizeColumns[] = 'total_size';
+ }
+
+ $runPrettySizeFilterBeforeGeneric = false;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+
+ // add summary row only if displaying a table
+ $view->config->filters[] = array('AddSummaryRow', Piwik::translate('General_Total'));
+
+ // add percentage column if desired
+ if ($addPercentColumn
+ && $addTotalSizeColumn
+ ) {
+ $view->config->filters[] = array(
+ 'ColumnCallbackAddColumnPercentage',
+ array('percent_total', 'total_size', 'total_size', $quotientPrecision = 0,
+ $shouldSkipRows = false, $getDivisorFromSummaryRow = true),
+ $isPriority = false
+ );
+
+ $view->requestConfig->filter_sort_column = 'percent_total';
+ }
+
+ } else if ($view->isViewDataTableId(Graph::ID)) {
+ if ($addTotalSizeColumn) {
+ $view->config->columns_to_display = array('label', 'total_size');
+
+ // when displaying a graph, we force sizes to be shown as the same unit so axis labels
+ // will be readable. NOTE: The unit should depend on the smallest value of the data table,
+ // however there's no way to know this information, short of creating a custom filter. For
+ // now, just assume KB.
+ $fixedMemoryUnit = 'K';
+ $view->config->y_axis_unit = ' K';
+ $view->requestConfig->filter_sort_column = 'total_size';
+ $view->requestConfig->filter_sort_order = 'desc';
+
+ $runPrettySizeFilterBeforeGeneric = true;
+ } else {
+ $view->config->columns_to_display = array('label', 'row_count');
+ $view->config->y_axis_unit = ' ' . Piwik::translate('General_Rows');
+
+ $view->requestConfig->filter_sort_column = 'row_count';
+ $view->requestConfig->filter_sort_order = 'desc';
+ }
+ $view->config->selectable_rows = array();
+ }
+
+ $getPrettySize = array('\Piwik\MetricsFormatter', 'getPrettySizeFromBytes');
+ $params = !isset($fixedMemoryUnit) ? array() : array($fixedMemoryUnit);
+
+ $view->config->filters[] = array('ColumnCallbackReplace', array($sizeColumns, $getPrettySize, $params), $runPrettySizeFilterBeforeGeneric);
+
+ // jqPlot will display &nbsp; as, well, '&nbsp;', so don't replace the spaces when rendering as a graph
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $replaceSpaces = function ($value) {
+ return str_replace(' ', '&nbsp;', $value);
+ };
+
+ $view->config->filters[] = array('ColumnCallbackReplace', array($sizeColumns, $replaceSpaces));
+ }
+
+ $getPrettyNumber = array('\Piwik\MetricsFormatter', 'getPrettyNumber');
+ $view->config->filters[] = array('ColumnCallbackReplace', array('row_count', $getPrettyNumber));
+ }
+
+ /**
+ * Sets the footer message for the Individual...Summary reports.
+ */
+ protected function setIndividualSummaryFooterMessage(ViewDataTable $view)
+ {
+ $lastGenerated = self::getDateOfLastCachingRun();
+ if ($lastGenerated !== false) {
+ $view->config->show_footer_message = Piwik::translate('Mobile_LastUpdated', $lastGenerated);
+ }
+ }
+
+ /** Returns the date when the cacheDataByArchiveNameReports was last run. */
+ private static function getDateOfLastCachingRun()
+ {
+ return Option::get(DBStats::TIME_OF_LAST_TASK_RUN_OPTION);
+ }
+}
diff --git a/plugins/DBStats/Reports/GetAdminDataSummary.php b/plugins/DBStats/Reports/GetAdminDataSummary.php
new file mode 100644
index 0000000000..cec185cc85
--- /dev/null
+++ b/plugins/DBStats/Reports/GetAdminDataSummary.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\DBStats\Reports;
+
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+/**
+ * Shows a datatable that displays the amount of space each 'admin' table takes
+ * up in the MySQL database.
+ *
+ * An 'admin' table is a table that is not central to analytics functionality.
+ * So any table that isn't an archive table or a log table is an 'admin' table.
+ */
+class GetAdminDataSummary extends Base
+{
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view);
+
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ }
+}
diff --git a/plugins/DBStats/Reports/GetDatabaseUsageSummary.php b/plugins/DBStats/Reports/GetDatabaseUsageSummary.php
new file mode 100644
index 0000000000..4e588aa311
--- /dev/null
+++ b/plugins/DBStats/Reports/GetDatabaseUsageSummary.php
@@ -0,0 +1,56 @@
+<?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\DBStats\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Pie;
+
+/**
+ * Shows a datatable that displays how much space the tracker tables, numeric
+ * archive tables, report tables and other tables take up in the MySQL database.
+ */
+class GetDatabaseUsageSummary extends Base
+{
+ public function getDefaultTypeViewDataTable()
+ {
+ return Pie::ID;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view, $addTotalSizeColumn = true, $addPercentColumn = true);
+
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->show_all_ticks = true;
+ }
+
+ // translate the labels themselves
+ $valueToTranslationStr = array(
+ 'tracker_data' => 'DBStats_TrackerTables',
+ 'report_data' => 'DBStats_ReportTables',
+ 'metric_data' => 'DBStats_MetricTables',
+ 'other_data' => 'DBStats_OtherTables'
+ );
+
+ $translateSummaryLabel = function ($value) use ($valueToTranslationStr) {
+ return isset($valueToTranslationStr[$value])
+ ? Piwik::translate($valueToTranslationStr[$value])
+ : $value;
+ };
+
+ $view->config->filters[] = array('ColumnCallbackReplace', array('label', $translateSummaryLabel), $isPriority = true);
+ }
+
+}
diff --git a/plugins/DBStats/Reports/GetIndividualMetricsSummary.php b/plugins/DBStats/Reports/GetIndividualMetricsSummary.php
new file mode 100644
index 0000000000..598ab723d0
--- /dev/null
+++ b/plugins/DBStats/Reports/GetIndividualMetricsSummary.php
@@ -0,0 +1,36 @@
+<?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\DBStats\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+/**
+ * Shows a datatable that displays how many occurances there are of each individual
+ * metric type stored in the MySQL database.
+ *
+ * Goal metrics, metrics of the format .*_[0-9]+ and 'done...' metrics are grouped together.
+ */
+class GetIndividualMetricsSummary extends Base
+{
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view, $addTotalSizeColumn = false, $addPercentColumn = false,
+ $sizeColumns = array('estimated_size'));
+
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->config->addTranslation('label', Piwik::translate('General_Metric'));
+
+ $this->setIndividualSummaryFooterMessage($view);
+ }
+
+}
diff --git a/plugins/DBStats/Reports/GetIndividualReportsSummary.php b/plugins/DBStats/Reports/GetIndividualReportsSummary.php
new file mode 100644
index 0000000000..a7ef06af09
--- /dev/null
+++ b/plugins/DBStats/Reports/GetIndividualReportsSummary.php
@@ -0,0 +1,41 @@
+<?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\DBStats\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+
+/**
+ * Shows a datatable that displays how many occurances there are of each individual
+ * report type stored in the MySQL database.
+ *
+ * Goal reports and reports of the format: .*_[0-9]+ are grouped together.
+ */
+class GetIndividualReportsSummary extends Base
+{
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view, $addTotalSizeColumn = false, $addPercentColumn = false,
+ $sizeColumns = array('estimated_size'));
+
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->config->addTranslation('label', Piwik::translate('General_Report'));
+
+ // this report table has some extra columns that shouldn't be shown
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->columns_to_display = array('label', 'row_count', 'estimated_size');
+ }
+
+ $this->setIndividualSummaryFooterMessage($view);
+ }
+
+}
diff --git a/plugins/DBStats/Reports/GetMetricDataSummary.php b/plugins/DBStats/Reports/GetMetricDataSummary.php
new file mode 100644
index 0000000000..ed88a50803
--- /dev/null
+++ b/plugins/DBStats/Reports/GetMetricDataSummary.php
@@ -0,0 +1,39 @@
+<?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\DBStats\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+/**
+ * Shows a datatable that displays the amount of space each numeric archive table
+ * takes up in the MySQL database.
+ */
+class GetMetricDataSummary extends Base
+{
+ protected function init()
+ {
+ $this->name = Piwik::translate('DBStats_MetricTables');
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view);
+
+ $view->config->title = $this->name;
+ }
+
+ public function getRelatedReports()
+ {
+ return array(new GetMetricDataSummaryByYear());
+ }
+
+}
diff --git a/plugins/DBStats/Reports/GetMetricDataSummaryByYear.php b/plugins/DBStats/Reports/GetMetricDataSummaryByYear.php
new file mode 100644
index 0000000000..4d370fc642
--- /dev/null
+++ b/plugins/DBStats/Reports/GetMetricDataSummaryByYear.php
@@ -0,0 +1,40 @@
+<?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\DBStats\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+/**
+ * Shows a datatable that displays the amount of space each numeric archive table
+ * takes up in the MySQL database, for each year of numeric data.
+ */
+class GetMetricDataSummaryByYear extends Base
+{
+ protected function init()
+ {
+ $this->name = Piwik::translate('DBStats_MetricDataByYear');
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view);
+
+ $view->config->title = $this->name;
+ $view->config->addTranslation('label', Piwik::translate('CoreHome_PeriodYear'));
+ }
+
+ public function getRelatedReports()
+ {
+ return array(new GetMetricDataSummary());
+ }
+
+}
diff --git a/plugins/DBStats/Reports/GetReportDataSummary.php b/plugins/DBStats/Reports/GetReportDataSummary.php
new file mode 100644
index 0000000000..35f87df25d
--- /dev/null
+++ b/plugins/DBStats/Reports/GetReportDataSummary.php
@@ -0,0 +1,39 @@
+<?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\DBStats\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+/**
+ * Shows a datatable that displays the amount of space each blob archive table
+ * takes up in the MySQL database.
+ */
+class GetReportDataSummary extends Base
+{
+ protected function init()
+ {
+ $this->name = Piwik::translate('DBStats_ReportTables');
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view);
+
+ $view->config->title = $this->name;
+ }
+
+
+ public function getRelatedReports()
+ {
+ return array(new GetReportDataSummaryByYear());
+ }
+}
diff --git a/plugins/DBStats/Reports/GetReportDataSummaryByYear.php b/plugins/DBStats/Reports/GetReportDataSummaryByYear.php
new file mode 100644
index 0000000000..3b538fc26f
--- /dev/null
+++ b/plugins/DBStats/Reports/GetReportDataSummaryByYear.php
@@ -0,0 +1,40 @@
+<?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\DBStats\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+/**
+ * Shows a datatable that displays the amount of space each blob archive table
+ * takes up in the MySQL database, for each year of blob data.
+ */
+class GetReportDataSummaryByYear extends Base
+{
+ protected function init()
+ {
+ $this->name = Piwik::translate('DBStats_ReportDataByYear');
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view);
+
+ $view->config->title = $this->name;
+ $view->config->addTranslation('label', Piwik::translate('CoreHome_PeriodYear'));
+ }
+
+ public function getRelatedReports()
+ {
+ return array(new GetReportDataSummary());
+ }
+
+}
diff --git a/plugins/DBStats/Reports/GetTrackerDataSummary.php b/plugins/DBStats/Reports/GetTrackerDataSummary.php
new file mode 100644
index 0000000000..cc4e853837
--- /dev/null
+++ b/plugins/DBStats/Reports/GetTrackerDataSummary.php
@@ -0,0 +1,30 @@
+<?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\DBStats\Reports;
+
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+/**
+ * Shows a datatable that displays the amount of space each individual log table
+ * takes up in the MySQL database.
+ */
+class GetTrackerDataSummary extends Base
+{
+ public function configureView(ViewDataTable $view)
+ {
+ $this->addBaseDisplayProperties($view);
+ $this->addPresentationFilters($view);
+
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ }
+
+}
diff --git a/plugins/Dashboard/Dashboard.php b/plugins/Dashboard/Dashboard.php
index b5af7b736d..4fcbeb086d 100644
--- a/plugins/Dashboard/Dashboard.php
+++ b/plugins/Dashboard/Dashboard.php
@@ -8,15 +8,10 @@
*/
namespace Piwik\Plugins\Dashboard;
-use Exception;
use Piwik\Common;
use Piwik\Db;
use Piwik\DbHelper;
-use Piwik\Menu\MenuAbstract;
-use Piwik\Menu\MenuMain;
-use Piwik\Menu\MenuTop;
use Piwik\Piwik;
-use Piwik\Site;
use Piwik\WidgetsList;
/**
diff --git a/plugins/DevicesDetection/Columns/Base.php b/plugins/DevicesDetection/Columns/Base.php
new file mode 100644
index 0000000000..7194527f6a
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/Base.php
@@ -0,0 +1,20 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\DeviceDetectorFactory;
+use Piwik\Plugin\Dimension\VisitDimension;
+
+abstract class Base extends VisitDimension
+{
+ protected function getUAParser($userAgent)
+ {
+ return DeviceDetectorFactory::getInstance($userAgent);
+ }
+}
diff --git a/plugins/DevicesDetection/Columns/BrowserName.php b/plugins/DevicesDetection/Columns/BrowserName.php
new file mode 100644
index 0000000000..1237d6676b
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/BrowserName.php
@@ -0,0 +1,45 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\Piwik;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class BrowserName extends Base
+{
+ protected $columnName = 'config_browser_name';
+
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_BrowserFamilies');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $userAgent = $request->getUserAgent();
+ $parser = $this->getUAParser($userAgent);
+
+ $aBrowserInfo = $parser->getClient();
+
+ if (!empty($aBrowserInfo['short_name'])) {
+
+ return $aBrowserInfo['short_name'];
+ }
+
+ return 'UNK';
+ }
+}
diff --git a/plugins/DevicesDetection/Columns/BrowserVersion.php b/plugins/DevicesDetection/Columns/BrowserVersion.php
new file mode 100644
index 0000000000..1fa60f3ab2
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/BrowserVersion.php
@@ -0,0 +1,45 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\Piwik;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class BrowserVersion extends Base
+{
+ protected $columnName = 'config_browser_version';
+
+ public function getName()
+ {
+ return Piwik::translate('DevicesDetection_BrowserVersions');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $userAgent = $request->getUserAgent();
+ $parser = $this->getUAParser($userAgent);
+
+ $aBrowserInfo = $parser->getClient();
+
+ if (!empty($aBrowserInfo['version'])) {
+
+ return $aBrowserInfo['version'];
+ }
+
+ return '';
+ }
+}
diff --git a/plugins/DevicesDetection/Columns/DeviceBrand.php b/plugins/DevicesDetection/Columns/DeviceBrand.php
new file mode 100644
index 0000000000..d5b06617ec
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/DeviceBrand.php
@@ -0,0 +1,39 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\Piwik;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class DeviceBrand extends Base
+{
+ protected $columnName = 'config_device_brand';
+ protected $columnType = 'VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL';
+
+ public function getName()
+ {
+ return Piwik::translate('DevicesDetection_DeviceBrand');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $userAgent = $request->getUserAgent();
+ $parser = $this->getUAParser($userAgent);
+
+ return $parser->getBrand();
+ }
+}
diff --git a/plugins/DevicesDetection/Columns/DeviceModel.php b/plugins/DevicesDetection/Columns/DeviceModel.php
new file mode 100644
index 0000000000..488eeb615e
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/DeviceModel.php
@@ -0,0 +1,39 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\Piwik;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class DeviceModel extends Base
+{
+ protected $columnName = 'config_device_model';
+ protected $columnType = 'VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL';
+
+ public function getName()
+ {
+ return Piwik::translate('DevicesDetection_DeviceModel');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $userAgent = $request->getUserAgent();
+ $parser = $this->getUAParser($userAgent);
+
+ return $parser->getModel();
+ }
+}
diff --git a/plugins/DevicesDetection/Columns/DeviceType.php b/plugins/DevicesDetection/Columns/DeviceType.php
new file mode 100644
index 0000000000..37b7cc0679
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/DeviceType.php
@@ -0,0 +1,64 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Segment;
+use Piwik\Tracker\Request;
+use DeviceDetector;
+use Exception;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+use DeviceDetector\Parser\Device\DeviceParserAbstract as DeviceParser;
+
+class DeviceType extends Base
+{
+ protected $columnName = 'config_device_type';
+ protected $columnType = 'TINYINT( 100 ) NULL DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $deviceTypes = DeviceParser::getAvailableDeviceTypeNames();
+ $deviceTypeList = implode(", ", $deviceTypes);
+
+ $segment = new Segment();
+ $segment->setCategory('General_Visit');
+ $segment->setSegment('deviceType');
+ $segment->setName('DevicesDetection_DeviceType');
+ $segment->setAcceptedValues($deviceTypeList);
+ $segment->setSqlFilter(function ($type) use ($deviceTypeList, $deviceTypes) {
+ $index = array_search(strtolower(trim(urldecode($type))), $deviceTypes);
+ if ($index === false) {
+ throw new Exception("deviceType segment must be one of: $deviceTypeList");
+ }
+ return $index;
+ });
+
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('DevicesDetection_DeviceType');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $userAgent = $request->getUserAgent();
+ $parser = $this->getUAParser($userAgent);
+
+ return $parser->getDevice();
+ }
+}
diff --git a/plugins/DevicesDetection/Columns/Os.php b/plugins/DevicesDetection/Columns/Os.php
new file mode 100644
index 0000000000..599edb3285
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/Os.php
@@ -0,0 +1,46 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\Piwik;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Settings;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class Os extends Base
+{
+ protected $columnName = 'config_os';
+
+ public function getName()
+ {
+ return Piwik::translate('DevicesDetection_OperatingSystemFamilies');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $userAgent = $request->getUserAgent();
+ $parser = $this->getUAParser($userAgent);
+
+ if ($parser->isBot()) {
+ $os = Settings::OS_BOT;
+ } else {
+ $os = $parser->getOS();
+ $os = empty($os['short_name']) ? 'UNK' : $os['short_name'];
+ }
+
+ return $os;
+ }
+}
diff --git a/plugins/DevicesDetection/Columns/OsVersion.php b/plugins/DevicesDetection/Columns/OsVersion.php
new file mode 100644
index 0000000000..e9913f740e
--- /dev/null
+++ b/plugins/DevicesDetection/Columns/OsVersion.php
@@ -0,0 +1,39 @@
+<?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\DevicesDetection\Columns;
+
+use Piwik\Piwik;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class OsVersion extends Base
+{
+ protected $columnName = 'config_os_version';
+ protected $columnType = 'VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL';
+
+ public function getName()
+ {
+ return Piwik::translate('DevicesDetection_OperatingSystemVersions');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $userAgent = $request->getUserAgent();
+ $parser = $this->getUAParser($userAgent);
+
+ return $parser->getOs('version');
+ }
+}
diff --git a/plugins/DevicesDetection/Controller.php b/plugins/DevicesDetection/Controller.php
index 57196991fa..bb3190bf2d 100644
--- a/plugins/DevicesDetection/Controller.php
+++ b/plugins/DevicesDetection/Controller.php
@@ -13,6 +13,11 @@ use Piwik\Common;
use Piwik\Db;
use Piwik\Piwik;
use Piwik\Plugin\ControllerAdmin;
+use Piwik\Plugins\DevicesDetection\Reports\GetBrand;
+use Piwik\Plugins\DevicesDetection\Reports\GetBrowserFamilies;
+use Piwik\Plugins\DevicesDetection\Reports\GetModel;
+use Piwik\Plugins\DevicesDetection\Reports\GetOsFamilies;
+use Piwik\Plugins\DevicesDetection\Reports\GetType;
use Piwik\View;
class Controller extends \Piwik\Plugin\Controller
@@ -21,49 +26,14 @@ class Controller extends \Piwik\Plugin\Controller
{
$view = new View('@DevicesDetection/index');
$view->deviceTypes = $view->deviceModels = $view->deviceBrands = $view->osReport = $view->browserReport = "blank";
- $view->deviceTypes = $this->getType(true);
- $view->deviceBrands = $this->getBrand(true);
- $view->deviceModels = $this->getModel(true);
- $view->osReport = $this->getOsFamilies(true);
- $view->browserReport = $this->getBrowserFamilies(true);
+ $view->deviceTypes = $this->renderReport(new GetType());
+ $view->deviceBrands = $this->renderReport(new GetBrand());
+ $view->deviceModels = $this->renderReport(new GetModel());
+ $view->osReport = $this->renderReport(new GetOsFamilies());
+ $view->browserReport = $this->renderReport(new GetBrowserFamilies());
return $view->render();
}
- public function getType()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getBrand()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getModel()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getOsFamilies()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getOsVersions()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getBrowserFamilies()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getBrowserVersions()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
public function deviceDetection()
{
Piwik::checkUserHasSomeAdminAccess();
diff --git a/plugins/DevicesDetection/DevicesDetection.php b/plugins/DevicesDetection/DevicesDetection.php
index 47902401a0..f06747f408 100644
--- a/plugins/DevicesDetection/DevicesDetection.php
+++ b/plugins/DevicesDetection/DevicesDetection.php
@@ -9,13 +9,9 @@
namespace Piwik\Plugins\DevicesDetection;
-use DeviceDetector\Parser\Device\DeviceParserAbstract AS DeviceParser;
-use Exception;
use Piwik\ArchiveProcessor;
-use Piwik\Common;
use Piwik\Db;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
require_once PIWIK_INCLUDE_PATH . '/plugins/DevicesDetection/functions.php';
@@ -35,290 +31,4 @@ class DevicesDetection extends \Piwik\Plugin
);
}
- /** The set of related reports displayed under the 'Operating Systems' header. */
- private $osRelatedReports = null;
- private $browserRelatedReports = null;
-
- public function __construct()
- {
- parent::__construct();
- $this->osRelatedReports = array(
- 'DevicesDetection.getOsFamilies' => Piwik::translate('DevicesDetection_OperatingSystemFamilies'),
- 'DevicesDetection.getOsVersions' => Piwik::translate('DevicesDetection_OperatingSystemVersions')
- );
- $this->browserRelatedReports = array(
- 'DevicesDetection.getBrowserFamilies' => Piwik::translate('UserSettings_BrowserFamilies'),
- 'DevicesDetection.getBrowserVersions' => Piwik::translate('DevicesDetection_BrowserVersions')
- );
- }
-
- protected function getRawMetadataDeviceType()
- {
- $deviceTypeList = implode(", ", DeviceParser::getAvailableDeviceTypeNames());
-
- $deviceTypeLabelToCode = function ($type) use ($deviceTypeList) {
- $index = array_search(strtolower(trim(urldecode($type))), DeviceParser::getAvailableDeviceTypeNames());
- if ($index === false) {
- throw new Exception("deviceType segment must be one of: $deviceTypeList");
- }
- return $index;
- };
-
- return array(
- 'DevicesDetection_DevicesDetection',
- 'DevicesDetection_DeviceType',
- 'DevicesDetection',
- 'getType',
- 'DevicesDetection_DeviceType',
-
- // Segment
- 'deviceType',
- 'log_visit.config_device_type',
- $deviceTypeList,
- $deviceTypeLabelToCode
- );
- }
-
- /**
- * @see Piwik\Plugin::getListHooksRegistered
- */
- public function getListHooksRegistered()
- {
- return array(
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable',
- );
- }
-
- /**
- * Defines API reports.
- * Also used to define Widgets, and Segment(s)
- *
- * @return array Category, Report Name, API Module, API action, Translated column name, & optional segment info
- */
- public function getRawMetadataReports()
- {
-
- $report = array(
- // device type report (tablet, desktop, mobile...)
- $this->getRawMetadataDeviceType(),
-
- // device brands report
- array(
- 'DevicesDetection_DevicesDetection',
- 'DevicesDetection_DeviceBrand',
- 'DevicesDetection',
- 'getBrand',
- 'DevicesDetection_DeviceBrand',
- ),
- // device model report
- array(
- 'DevicesDetection_DevicesDetection',
- 'DevicesDetection_DeviceModel',
- 'DevicesDetection',
- 'getModel',
- 'DevicesDetection_DeviceModel',
- ),
- // device OS family report
- array(
- 'DevicesDetection_DevicesDetection',
- 'DevicesDetection_OperatingSystemFamilies',
- 'DevicesDetection',
- 'getOsFamilies',
- 'DevicesDetection_OperatingSystemFamilies',
- ),
- // device OS version report
- array(
- 'DevicesDetection_DevicesDetection',
- 'DevicesDetection_OperatingSystemVersions',
- 'DevicesDetection',
- 'getOsVersions',
- 'DevicesDetection_OperatingSystemVersions',
- ),
- // Browser family report
- array(
- 'DevicesDetection_DevicesDetection',
- 'UserSettings_BrowserFamilies',
- 'DevicesDetection',
- 'getBrowserFamilies',
- 'UserSettings_BrowserFamilies',
- ),
- // Browser versions report
- array(
- 'DevicesDetection_DevicesDetection',
- 'DevicesDetection_BrowserVersions',
- 'DevicesDetection',
- 'getBrowserVersions',
- 'DevicesDetection_BrowserVersions',
- ),
- );
- return $report;
- }
-
- /**
- * Get segments meta data
- */
- public function getSegmentsMetadata(&$segments)
- {
- // Note: only one field segmented so far: deviceType
- foreach ($this->getRawMetadataReports() as $report) {
- @list($category, $name, $apiModule, $apiAction, $columnName, $segment, $sqlSegment, $acceptedValues, $sqlFilter) = $report;
-
- if (empty($segment)) continue;
-
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => $columnName,
- 'segment' => $segment,
- 'acceptedValues' => $acceptedValues,
- 'sqlSegment' => $sqlSegment,
- 'sqlFilter' => isset($sqlFilter) ? $sqlFilter : false
- );
- }
- }
-
- public function getReportMetadata(&$reports)
- {
- $i = 0;
- foreach ($this->getRawMetadataReports() as $report) {
- list($category, $name, $apiModule, $apiAction, $columnName) = $report;
- if ($category == false)
- continue;
-
- $report = array(
- 'category' => Piwik::translate($category),
- 'name' => Piwik::translate($name),
- 'module' => $apiModule,
- 'action' => $apiAction,
- 'dimension' => Piwik::translate($columnName),
- 'order' => $i++
- );
-
- $translation = $name . 'Documentation';
- $translated = Piwik::translate($translation, '<br />');
- if ($translated != $translation) {
- $report['documentation'] = $translated;
- }
-
- $reports[] = $report;
- }
- }
-
- public function install()
- {
- try {
- $q1 = "ALTER TABLE `" . Common::prefixTable("log_visit") . "`
- ADD `config_os_version` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL AFTER `config_os` ,
- ADD `config_device_type` TINYINT( 100 ) NULL DEFAULT NULL AFTER `config_browser_version` ,
- ADD `config_device_brand` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL AFTER `config_device_type` ,
- ADD `config_device_model` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL AFTER `config_device_brand`";
- Db::exec($q1);
-
- } catch (Exception $e) {
- if (!Db::get()->isErrNo($e, '1060')) {
- throw $e;
- }
- }
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'DevicesDetection.getType':
- $this->configureViewForGetType($view);
- break;
- case 'DevicesDetection.getBrand':
- $this->configureViewForGetBrand($view);
- break;
- case 'DevicesDetection.getModel':
- $this->configureViewForGetModel($view);
- break;
- case 'DevicesDetection.getOsFamilies':
- $this->configureViewForGetOsFamilies($view);
- break;
- case 'DevicesDetection.getOsVersions':
- $this->configureViewForGetOsVersions($view);
- break;
- case 'DevicesDetection.getBrowserFamilies':
- $this->configureViewForGetBrowserFamilies($view);
- break;
- case 'DevicesDetection.getBrowserVersions':
- $this->configureViewForGetBrowserVersions($view);
- break;
- }
- }
-
- private function configureViewForGetType(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelTypes"));
- }
-
- private function configureViewForGetBrand(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelBrands"));
- }
-
- private function configureViewForGetModel(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelModels"));
- }
-
- private function configureViewForGetOsFamilies(ViewDataTable $view)
- {
- $view->config->title = Piwik::translate('DevicesDetection_OperatingSystemFamilies');
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate("UserSettings_OperatingSystemFamily"));
- $view->config->addRelatedReports($this->getOsRelatedReports());
- }
-
- private function configureViewForGetOsVersions(ViewDataTable $view)
- {
- $view->config->title = Piwik::translate('DevicesDetection_OperatingSystemVersions');
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelSystemVersion"));
- $view->config->addRelatedReports($this->getOsRelatedReports());
- }
-
- private function configureViewForGetBrowserFamilies(ViewDataTable $view)
- {
- $view->config->title = Piwik::translate('UserSettings_BrowserFamilies');
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelBrowserFamily"));
- $view->config->addRelatedReports($this->getBrowserRelatedReports());
- }
-
- private function configureViewForGetBrowserVersions(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate("UserSettings_ColumnBrowserVersion"));
- $view->config->addRelatedReports($this->getBrowserRelatedReports());
- }
-
- private function getOsRelatedReports()
- {
- return array(
- 'DevicesDetection.getOsFamilies' => Piwik::translate('DevicesDetection_OperatingSystemFamilies'),
- 'DevicesDetection.getOsVersions' => Piwik::translate('DevicesDetection_OperatingSystemVersions')
- );
- }
-
- private function getBrowserRelatedReports()
- {
- return array(
- 'DevicesDetection.getBrowserFamilies' => Piwik::translate('UserSettings_BrowserFamilies'),
- 'DevicesDetection.getBrowserVersions' => Piwik::translate('DevicesDetection_BrowserVersions')
- );
- }
}
diff --git a/plugins/DevicesDetection/Reports/Base.php b/plugins/DevicesDetection/Reports/Base.php
new file mode 100644
index 0000000000..0131466c03
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/Base.php
@@ -0,0 +1,19 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'DevicesDetection_DevicesDetection';
+ }
+}
diff --git a/plugins/DevicesDetection/Reports/GetBrand.php b/plugins/DevicesDetection/Reports/GetBrand.php
new file mode 100644
index 0000000000..3cc7cc23dd
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/GetBrand.php
@@ -0,0 +1,34 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\DevicesDetection\Columns\Devicebrand;
+
+class GetBrand extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Devicebrand();
+ $this->name = Piwik::translate('DevicesDetection_DeviceBrand');
+ $this->documentation = ''; // TODO
+ $this->order = 1;
+ $this->widgetTitle = 'DevicesDetection_DeviceBrand';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelBrands"));
+ }
+
+}
diff --git a/plugins/DevicesDetection/Reports/GetBrowserFamilies.php b/plugins/DevicesDetection/Reports/GetBrowserFamilies.php
new file mode 100644
index 0000000000..0c2c5cd621
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/GetBrowserFamilies.php
@@ -0,0 +1,41 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\DevicesDetection\Columns\BrowserName;
+
+class GetBrowserFamilies extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new BrowserName();
+ $this->name = Piwik::translate('UserSettings_BrowserFamilies');
+ $this->documentation = ''; // TODO
+ $this->order = 5;
+ $this->widgetTitle = 'UserSettings_BrowserFamilies';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->title = $this->name;
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelBrowserFamily"));
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetBrowserVersions()
+ );
+ }
+}
diff --git a/plugins/DevicesDetection/Reports/GetBrowserVersions.php b/plugins/DevicesDetection/Reports/GetBrowserVersions.php
new file mode 100644
index 0000000000..b66b94e561
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/GetBrowserVersions.php
@@ -0,0 +1,40 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\DevicesDetection\Columns\Browserversion;
+
+class GetBrowserVersions extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Browserversion();
+ $this->name = Piwik::translate('DevicesDetection_BrowserVersions');
+ $this->documentation = ''; // TODO
+ $this->order = 6;
+ $this->widgetTitle = 'DevicesDetection_BrowserVersions';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate("UserSettings_ColumnBrowserVersion"));
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetBrowserFamilies()
+ );
+ }
+}
diff --git a/plugins/DevicesDetection/Reports/GetModel.php b/plugins/DevicesDetection/Reports/GetModel.php
new file mode 100644
index 0000000000..0a99c891a4
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/GetModel.php
@@ -0,0 +1,34 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\DevicesDetection\Columns\Devicemodel;
+
+class GetModel extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Devicemodel();
+ $this->name = Piwik::translate('DevicesDetection_DeviceModel');
+ $this->documentation = ''; // TODO
+ $this->order = 2;
+ $this->widgetTitle = 'DevicesDetection_DeviceModel';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelModels"));
+ }
+
+}
diff --git a/plugins/DevicesDetection/Reports/GetOsFamilies.php b/plugins/DevicesDetection/Reports/GetOsFamilies.php
new file mode 100644
index 0000000000..703b42830e
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/GetOsFamilies.php
@@ -0,0 +1,42 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\DevicesDetection\Columns\Os;
+
+class GetOsFamilies extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Os();
+ $this->name = Piwik::translate('DevicesDetection_OperatingSystemFamilies');
+ $this->documentation = ''; // TODO
+ $this->order = 3;
+ $this->widgetTitle = 'DevicesDetection_OperatingSystemFamilies';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->title = $this->name;
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate("UserSettings_OperatingSystemFamily"));
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetOsVersions()
+ );
+ }
+
+}
diff --git a/plugins/DevicesDetection/Reports/GetOsVersions.php b/plugins/DevicesDetection/Reports/GetOsVersions.php
new file mode 100644
index 0000000000..4596a4dd74
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/GetOsVersions.php
@@ -0,0 +1,41 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\DevicesDetection\Columns\OsVersion;
+
+class GetOsVersions extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new OsVersion();
+ $this->name = Piwik::translate('DevicesDetection_OperatingSystemVersions');
+ $this->documentation = ''; // TODO
+ $this->order = 4;
+ $this->widgetTitle = 'DevicesDetection_OperatingSystemVersions';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->title = $this->name;
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelSystemVersion"));
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetOsFamilies()
+ );
+ }
+}
diff --git a/plugins/DevicesDetection/Reports/GetType.php b/plugins/DevicesDetection/Reports/GetType.php
new file mode 100644
index 0000000000..4861d12ee5
--- /dev/null
+++ b/plugins/DevicesDetection/Reports/GetType.php
@@ -0,0 +1,34 @@
+<?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\DevicesDetection\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\DevicesDetection\Columns\Devicetype;
+
+class GetType extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Devicetype();
+ $this->name = Piwik::translate('DevicesDetection_DeviceType');
+ $this->documentation = ''; // TODO
+ $this->order = 0;
+ $this->widgetTitle = 'DevicesDetection_DeviceType';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate("DevicesDetection_dataTableLabelTypes"));
+ }
+
+}
diff --git a/plugins/DevicesDetection/Widgets.php b/plugins/DevicesDetection/Widgets.php
deleted file mode 100644
index d337fbfc75..0000000000
--- a/plugins/DevicesDetection/Widgets.php
+++ /dev/null
@@ -1,27 +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
- *
- */
-namespace Piwik\Plugins\DevicesDetection;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- $detection = new DevicesDetection();
-
- foreach ($detection->getRawMetadataReports() as $report) {
- list($category, $name, $controllerName, $controllerAction) = $report;
- if ($category == false)
- continue;
- $widgetsList->add($category, $name, $controllerName, $controllerAction);
- }
- }
-
-}
diff --git a/core/Tracker/ActionEvent.php b/plugins/Events/Actions/ActionEvent.php
index 73441a5a0d..3791de794d 100644
--- a/core/Tracker/ActionEvent.php
+++ b/plugins/Events/Actions/ActionEvent.php
@@ -7,9 +7,11 @@
*
*/
-namespace Piwik\Tracker;
+namespace Piwik\Plugins\Events\Actions;
use Piwik\Common;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
use Piwik\Tracker;
/**
@@ -18,37 +20,34 @@ use Piwik\Tracker;
*/
class ActionEvent extends Action
{
- function __construct($eventCategory, $eventAction, $url, Request $request)
+ public function __construct(Request $request)
{
parent::__construct(Action::TYPE_EVENT, $request);
+
+ $url = $request->getParam('url');
+
$this->setActionUrl($url);
- $this->eventCategory = trim($eventCategory);
- $this->eventAction = trim($eventAction);
- $this->eventName = trim($request->getParam('e_n'));
$this->eventValue = trim($request->getParam('e_v'));
}
- function getCustomFloatValue()
+ public static function shouldHandle(Request $request)
+ {
+ $eventCategory = $request->getParam('e_c');
+ $eventAction = $request->getParam('e_a');
+
+ return (strlen($eventCategory) > 0 && strlen($eventAction) > 0);
+ }
+
+ public function getCustomFloatValue()
{
return $this->eventValue;
}
protected function getActionsToLookup()
{
- $actions = array(
+ return array(
'idaction_url' => $this->getUrlAndType()
);
-
- if(strlen($this->eventName) > 0) {
- $actions['idaction_name'] = array($this->eventName, Action::TYPE_EVENT_NAME);
- }
- if(strlen($this->eventCategory) > 0) {
- $actions['idaction_event_category'] = array($this->eventCategory, Action::TYPE_EVENT_CATEGORY);
- }
- if(strlen($this->eventAction) > 0) {
- $actions['idaction_event_action'] = array($this->eventAction, Action::TYPE_EVENT_ACTION);
- }
- return $actions;
}
// Do not track this Event URL as Entry/Exit Page URL (leave the existing entry/exit)
@@ -66,13 +65,9 @@ class ActionEvent extends Action
public function writeDebugInfo()
{
$write = parent::writeDebugInfo();
- if($write) {
- Common::printDebug("Event Category = " . $this->eventCategory . ",
- Event Action = " . $this->eventAction . ",
- Event Name = " . $this->eventName . ",
- Event Value = " . $this->getCustomFloatValue());
+ if ($write) {
+ Common::printDebug("Event Value = " . $this->getCustomFloatValue());
}
return $write;
}
-
}
diff --git a/plugins/Events/Columns/EventAction.php b/plugins/Events/Columns/EventAction.php
new file mode 100644
index 0000000000..26a460c985
--- /dev/null
+++ b/plugins/Events/Columns/EventAction.php
@@ -0,0 +1,56 @@
+<?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\Events\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugins\Events\Segment;
+use Piwik\Plugins\Events\Actions\ActionEvent;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+
+class EventAction extends ActionDimension
+{
+ protected $columnName = 'idaction_event_action';
+ protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('eventAction');
+ $segment->setName('Events_EventAction');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Events_EventAction');
+ }
+
+ public function getActionId()
+ {
+ return Action::TYPE_EVENT_ACTION;
+ }
+
+ public function onLookupAction(Request $request, Action $action)
+ {
+ if (!($action instanceof ActionEvent)) {
+ return false;
+ }
+
+ $eventAction = $request->getParam('e_a');
+ $eventAction = trim($eventAction);
+
+ if (strlen($eventAction) > 0) {
+ return $eventAction;
+ }
+
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/Events/Columns/EventCategory.php b/plugins/Events/Columns/EventCategory.php
new file mode 100644
index 0000000000..eae0ff906d
--- /dev/null
+++ b/plugins/Events/Columns/EventCategory.php
@@ -0,0 +1,56 @@
+<?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\Events\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugins\Events\Segment;
+use Piwik\Plugins\Events\Actions\ActionEvent;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+
+class EventCategory extends ActionDimension
+{
+ protected $columnName = 'idaction_event_category';
+ protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('eventCategory');
+ $segment->setName('Events_EventCategory');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Events_EventCategory');
+ }
+
+ public function getActionId()
+ {
+ return Action::TYPE_EVENT_CATEGORY;
+ }
+
+ public function onLookupAction(Request $request, Action $action)
+ {
+ if (!($action instanceof ActionEvent)) {
+ return false;
+ }
+
+ $eventCategory = $request->getParam('e_c');
+ $eventCategory = trim($eventCategory);
+
+ if (strlen($eventCategory) > 0) {
+ return $eventCategory;
+ }
+
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/Events/Columns/EventName.php b/plugins/Events/Columns/EventName.php
new file mode 100644
index 0000000000..e027136943
--- /dev/null
+++ b/plugins/Events/Columns/EventName.php
@@ -0,0 +1,55 @@
+<?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\Events\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugins\Events\Segment;
+use Piwik\Plugins\Events\Actions\ActionEvent;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+
+class EventName extends ActionDimension
+{
+ protected $columnName = 'idaction_name';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('eventName');
+ $segment->setName('Events_EventName');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Events_EventName');
+ }
+
+ public function getActionId()
+ {
+ return Action::TYPE_EVENT_NAME;
+ }
+
+ public function onLookupAction(Request $request, Action $action)
+ {
+ if (!($action instanceof ActionEvent)) {
+ return false;
+ }
+
+ $eventName = $request->getParam('e_n');
+ $eventName = trim($eventName);
+
+ if (strlen($eventName) > 0) {
+ return $eventName;
+ }
+
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/Events/Columns/TotalEvents.php b/plugins/Events/Columns/TotalEvents.php
new file mode 100644
index 0000000000..c0b17bcaac
--- /dev/null
+++ b/plugins/Events/Columns/TotalEvents.php
@@ -0,0 +1,77 @@
+<?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\Events\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugin\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class TotalEvents extends VisitDimension
+{
+ protected $columnName = 'visit_total_events';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('events');
+ $segment->setName('Events_TotalEvents');
+ $segment->setAcceptedValues('To select all visits who triggered an Event, use: &segment=events>0');
+ $segment->setCategory('General_Visit');
+ $segment->setType(Segment::TYPE_METRIC);
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Events_EventName');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ if ($this->isEventAction($action)) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ if ($this->isEventAction($action)) {
+ return 'visit_total_events + 1';
+ }
+
+ return false;
+ }
+
+ /**
+ * @param Action|null $action
+ * @return bool
+ */
+ private function isEventAction($action)
+ {
+ return ($action && $action->getActionType() == Action::TYPE_EVENT);
+ }
+} \ No newline at end of file
diff --git a/plugins/Events/Controller.php b/plugins/Events/Controller.php
index 5521b1007e..3429443b88 100644
--- a/plugins/Events/Controller.php
+++ b/plugins/Events/Controller.php
@@ -53,21 +53,6 @@ class Controller extends \Piwik\Plugin\Controller
return $this->indexEvent(__FUNCTION__);
}
- public function getCategory()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getAction()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getName()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
public function getActionFromCategoryId()
{
return $this->renderReport(__FUNCTION__);
@@ -104,9 +89,16 @@ class Controller extends \Piwik\Plugin\Controller
$apiMethod = str_replace('index', 'get', $controllerMethod, $count);
$events = new Events;
$title = $events->getReportTitleTranslation($apiMethod);
+
+ if (method_exists($this, $apiMethod)) {
+ $content = $this->$apiMethod();
+ } else {
+ $content = $this->renderReport($apiMethod);
+ }
+
return View::singleReport(
$title,
- $this->$apiMethod()
+ $content
);
}
}
diff --git a/plugins/Events/Events.php b/plugins/Events/Events.php
index bdc7522e54..4992ca3452 100644
--- a/plugins/Events/Events.php
+++ b/plugins/Events/Events.php
@@ -10,10 +10,7 @@ namespace Piwik\Plugins\Events;
use Piwik\Common;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
-/**
- */
class Events extends \Piwik\Plugin
{
/**
@@ -22,11 +19,8 @@ class Events extends \Piwik\Plugin
public function getListHooksRegistered()
{
return array(
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
- 'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations',
- 'API.getReportMetadata' => 'getReportMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable',
-
+ 'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations',
+ 'Metrics.getDefaultMetricDocumentationTranslations' => 'addMetricDocumentationTranslations'
);
}
@@ -35,6 +29,11 @@ class Events extends \Piwik\Plugin
$translations = array_merge($translations, $this->getMetricTranslations());
}
+ public function addMetricDocumentationTranslations(&$translations)
+ {
+ $translations = array_merge($translations, $this->getMetricDocumentation());
+ }
+
public function getMetricDocumentation()
{
$documentation = array(
@@ -87,26 +86,6 @@ class Events extends \Piwik\Plugin
public function getSegmentsMetadata(&$segments)
{
- $sqlFilter = '\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment';
-
- foreach($this->metadataDimensions as $dimension => $metadata) {
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Events_Events',
- 'name' => $metadata[0],
- 'segment' => $dimension,
- 'sqlSegment' => $metadata[1],
- 'sqlFilter' => $sqlFilter,
- );
- }
- $segments[] = array(
- 'type' => 'metric',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'Events_TotalEvents',
- 'segment' => 'events',
- 'sqlSegment' => 'log_visit.visit_total_events',
- 'acceptedValues' => 'To select all visits who triggered an Event, use: &segment=events>0',
- );
// $segments[] = array(
// 'type' => 'metric',
// 'category' => 'Events_Events',
@@ -128,33 +107,6 @@ class Events extends \Piwik\Plugin
// );
// }
- public function getReportMetadata(&$reports)
- {
- $metrics = $this->getMetricTranslations();
- $documentation = $this->getMetricDocumentation();
- $labelTranslations = $this->getLabelTranslations();
-
- $order = 0;
- foreach($labelTranslations as $action => $translations) {
- $secondaryDimension = $this->getSecondaryDimensionFromRequest();
- $actionToLoadSubtables = API::getInstance()->getActionToLoadSubtables($action, $secondaryDimension);
- $reports[] = array(
- 'category' => Piwik::translate('Events_Events'),
- 'name' => Piwik::translate($translations[0]),
- 'module' => 'Events',
- 'action' => $action,
- 'dimension' => Piwik::translate($translations[1]),
- 'metrics' => $metrics,
- 'metricsDocumentation' => $documentation,
- 'processedMetrics' => false,
- 'actionToLoadSubTables' => $actionToLoadSubtables,
- 'order' => $order++
- );
-
- }
- }
-
-
/**
* Given getCategory, returns "Event Categories"
*
@@ -190,97 +142,10 @@ class Events extends \Piwik\Plugin
throw new \Exception("Translation not found for report $apiMethod");
}
- public function configureViewDataTable(ViewDataTable $view)
- {
- if($view->requestConfig->getApiModuleToRequest() != 'Events') {
- return;
- }
-
- // eg. 'Events.getCategory'
- $apiMethod = $view->requestConfig->getApiMethodToRequest();
-
- $secondaryDimension = $this->getSecondaryDimensionFromRequest();
- $view->config->subtable_controller_action = API::getInstance()->getActionToLoadSubtables($apiMethod, $secondaryDimension);
- $view->config->columns_to_display = array('label', 'nb_events', 'sum_event_value');
- $view->config->show_flatten_table = true;
- $view->config->show_table_all_columns = false;
- $view->requestConfig->filter_sort_column = 'nb_events';
-
- $labelTranslation = $this->getColumnTranslation($apiMethod);
- $view->config->addTranslation('label', $labelTranslation);
- $view->config->addTranslations($this->getMetricTranslations());
- $this->addRelatedReports($view, $secondaryDimension);
- $this->addTooltipEventValue($view);
- }
-
- protected function addRelatedReports($view, $secondaryDimension)
- {
- if(empty($secondaryDimension)) {
- // eg. Row Evolution
- return;
- }
- $view->config->show_related_reports = true;
-
- $apiMethod = $view->requestConfig->getApiMethodToRequest();
- $secondaryDimensions = API::getInstance()->getSecondaryDimensions($apiMethod);
-
- if(empty($secondaryDimensions)) {
- return;
- }
-
- $secondaryDimensionTranslation = $this->getDimensionLabel($secondaryDimension);
- $view->config->related_reports_title =
- Piwik::translate('Events_SecondaryDimension', $secondaryDimensionTranslation)
- . "<br/>"
- . Piwik::translate('Events_SwitchToSecondaryDimension', '');
-
- foreach($secondaryDimensions as $dimension) {
- if($dimension == $secondaryDimension) {
- // don't show as related report the currently selected dimension
- continue;
- }
-
- $dimensionTranslation = $this->getDimensionLabel($dimension);
- $view->config->addRelatedReport(
- $view->requestConfig->apiMethodToRequestDataTable,
- $dimensionTranslation,
- array('secondaryDimension' => $dimension)
- );
- }
-
- }
-
- protected function addTooltipEventValue($view)
- {
- // Creates the tooltip message for Event Value column
- $tooltipCallback = function ($hits, $min, $max, $avg) {
- if (!$hits) {
- return false;
- }
- $msgEventMinMax = Piwik::translate("Events_EventValueTooltip", array($hits, "<br />", $min, $max));
- $msgEventAvg = Piwik::translate("Events_AvgEventValue", $avg);
- return $msgEventMinMax . "<br/>" . $msgEventAvg;
- };
-
- // Add tooltip metadata column to the DataTable
- $view->config->filters[] = array('ColumnCallbackAddMetadata',
- array(
- array(
- 'nb_events',
- 'min_event_value',
- 'max_event_value',
- 'avg_event_value'
- ),
- 'sum_event_value_tooltip',
- $tooltipCallback
- )
- );
- }
-
/**
* @return mixed
*/
- protected function getSecondaryDimensionFromRequest()
+ public function getSecondaryDimensionFromRequest()
{
return Common::getRequestVar('secondaryDimension', false, 'string');
}
diff --git a/plugins/Events/Reports/Base.php b/plugins/Events/Reports/Base.php
new file mode 100644
index 0000000000..20441109ca
--- /dev/null
+++ b/plugins/Events/Reports/Base.php
@@ -0,0 +1,117 @@
+<?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\Events\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Events\API;
+use Piwik\Plugins\Events\Events;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'Events_Events';
+ $this->processedMetrics = false;
+
+ $this->widgetParams = array(
+ 'secondaryDimension' => API::getInstance()->getDefaultSecondaryDimension($this->action)
+ );
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ if ($view->requestConfig->getApiModuleToRequest() != 'Events') {
+ return;
+ }
+
+ // eg. 'Events.getCategory'
+ $apiMethod = $view->requestConfig->getApiMethodToRequest();
+
+ $events = new Events();
+ $secondaryDimension = $events->getSecondaryDimensionFromRequest();
+ $view->config->subtable_controller_action = API::getInstance()->getActionToLoadSubtables($apiMethod, $secondaryDimension);
+ $view->config->columns_to_display = array('label', 'nb_events', 'sum_event_value');
+ $view->config->show_flatten_table = true;
+ $view->config->show_table_all_columns = false;
+ $view->requestConfig->filter_sort_column = 'nb_events';
+
+ $labelTranslation = $events->getColumnTranslation($apiMethod);
+ $view->config->addTranslation('label', $labelTranslation);
+ $view->config->addTranslations($events->getMetricTranslations());
+ $this->addRelatedReports($view, $secondaryDimension);
+ $this->addTooltipEventValue($view);
+ }
+
+ private function addRelatedReports($view, $secondaryDimension)
+ {
+ if(empty($secondaryDimension)) {
+ // eg. Row Evolution
+ return;
+ }
+
+ $events = new Events();
+ $view->config->show_related_reports = true;
+
+ $apiMethod = $view->requestConfig->getApiMethodToRequest();
+ $secondaryDimensions = API::getInstance()->getSecondaryDimensions($apiMethod);
+
+ if(empty($secondaryDimensions)) {
+ return;
+ }
+
+ $secondaryDimensionTranslation = $events->getDimensionLabel($secondaryDimension);
+ $view->config->related_reports_title =
+ Piwik::translate('Events_SecondaryDimension', $secondaryDimensionTranslation)
+ . "<br/>"
+ . Piwik::translate('Events_SwitchToSecondaryDimension', '');
+
+ foreach($secondaryDimensions as $dimension) {
+ if($dimension == $secondaryDimension) {
+ // don't show as related report the currently selected dimension
+ continue;
+ }
+
+ $dimensionTranslation = $events->getDimensionLabel($dimension);
+ $view->config->addRelatedReport(
+ $view->requestConfig->apiMethodToRequestDataTable,
+ $dimensionTranslation,
+ array('secondaryDimension' => $dimension)
+ );
+ }
+
+ }
+
+ private function addTooltipEventValue($view)
+ {
+ // Creates the tooltip message for Event Value column
+ $tooltipCallback = function ($hits, $min, $max, $avg) {
+ if (!$hits) {
+ return false;
+ }
+ $msgEventMinMax = Piwik::translate("Events_EventValueTooltip", array($hits, "<br />", $min, $max));
+ $msgEventAvg = Piwik::translate("Events_AvgEventValue", $avg);
+ return $msgEventMinMax . "<br/>" . $msgEventAvg;
+ };
+
+ // Add tooltip metadata column to the DataTable
+ $view->config->filters[] = array('ColumnCallbackAddMetadata',
+ array(
+ array(
+ 'nb_events',
+ 'min_event_value',
+ 'max_event_value',
+ 'avg_event_value'
+ ),
+ 'sum_event_value_tooltip',
+ $tooltipCallback
+ )
+ );
+ }
+}
diff --git a/plugins/Events/Reports/GetAction.php b/plugins/Events/Reports/GetAction.php
new file mode 100644
index 0000000000..04ed51bd21
--- /dev/null
+++ b/plugins/Events/Reports/GetAction.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\Plugins\Events\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugins\Events\Columns\EventAction;
+
+class GetAction extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new EventAction();
+ $this->name = Piwik::translate('Events_EventActions');
+ $this->documentation = ''; // TODO
+ $this->metrics = array('nb_events', 'sum_event_value', 'min_event_value', 'max_event_value', 'avg_event_value', 'nb_events_with_value');
+ $this->actionToLoadSubTables = 'getNameFromActionId';
+ $this->order = 1;
+ $this->widgetTitle = 'Events_EventActions';
+ }
+}
diff --git a/plugins/Events/Reports/GetCategory.php b/plugins/Events/Reports/GetCategory.php
new file mode 100644
index 0000000000..f91736eb3f
--- /dev/null
+++ b/plugins/Events/Reports/GetCategory.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\Events\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Events\Columns\EventCategory;
+
+class GetCategory extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new EventCategory();
+ $this->name = Piwik::translate('Events_EventCategories');
+ $this->documentation = ''; // TODO
+ $this->metrics = array('nb_events', 'sum_event_value', 'min_event_value', 'max_event_value', 'avg_event_value', 'nb_events_with_value');
+ $this->actionToLoadSubTables = 'getActionFromCategoryId';
+ $this->order = 0;
+ $this->widgetTitle = 'Events_EventCategories';
+ }
+}
diff --git a/plugins/Events/Reports/GetName.php b/plugins/Events/Reports/GetName.php
new file mode 100644
index 0000000000..c68255e68e
--- /dev/null
+++ b/plugins/Events/Reports/GetName.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\Events\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Events\Columns\EventName;
+
+class GetName extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new EventName();
+ $this->name = Piwik::translate('Events_EventNames');
+ $this->documentation = ''; // TODO
+ $this->metrics = array('nb_events', 'sum_event_value', 'min_event_value', 'max_event_value', 'avg_event_value', 'nb_events_with_value');
+ $this->actionToLoadSubTables = 'getActionFromNameId';
+ $this->order = 2;
+ $this->widgetTitle = 'Events_EventNames';
+ }
+}
diff --git a/plugins/Events/Segment.php b/plugins/Events/Segment.php
new file mode 100644
index 0000000000..aa586e3987
--- /dev/null
+++ b/plugins/Events/Segment.php
@@ -0,0 +1,22 @@
+<?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\Events;
+
+/**
+ * Events segment base class.
+ *
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+ protected function init()
+ {
+ $this->setCategory('Events_Events');
+ $this->setSqlFilter('\Piwik\Tracker\TableLogAction::getIdActionFromSegment');
+ }
+}
diff --git a/plugins/Events/Widgets.php b/plugins/Events/Widgets.php
deleted file mode 100644
index b3b82c3a09..0000000000
--- a/plugins/Events/Widgets.php
+++ /dev/null
@@ -1,25 +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
- *
- */
-namespace Piwik\Plugins\Events;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- foreach(Events::getLabelTranslations() as $apiMethod => $labels) {
- $params = array(
- 'secondaryDimension' => API::getInstance()->getDefaultSecondaryDimension($apiMethod)
- );
- $widgetsList->add('Events_Events', $labels[0], 'Events', $apiMethod, $params);
- }
- }
-
-}
diff --git a/plugins/ExamplePlugin/API.php b/plugins/ExamplePlugin/API.php
index ffa887761f..2ad0704d66 100644
--- a/plugins/ExamplePlugin/API.php
+++ b/plugins/ExamplePlugin/API.php
@@ -8,6 +8,9 @@
*/
namespace Piwik\Plugins\ExamplePlugin;
+use Piwik\DataTable;
+use Piwik\DataTable\Row;
+
/**
* API for plugin ExamplePlugin
*
@@ -33,4 +36,17 @@ class API extends \Piwik\Plugin\API
return 24;
}
+
+ /**
+ * Another example method that returns a data table.
+ * @return DataTable
+ */
+ public function getExampleReport()
+ {
+ $table = new DataTable();
+
+ $table->addRowFromArray(array(Row::COLUMNS => array('nb_visits' => 5)));
+
+ return $table;
+ }
}
diff --git a/plugins/ExamplePlugin/Columns/ExampleActionDimension.php b/plugins/ExamplePlugin/Columns/ExampleActionDimension.php
new file mode 100644
index 0000000000..9d85cde038
--- /dev/null
+++ b/plugins/ExamplePlugin/Columns/ExampleActionDimension.php
@@ -0,0 +1,134 @@
+<?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\ExamplePlugin\Columns;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Plugin\Segment;
+use Piwik\Tracker\ActionPageview;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+/**
+ * This example dimension recognizes a new tracking url parameter that is supposed to save the keywords that were used
+ * on a certain page. Please note that dimension instances are usually cached during one tracking request so they
+ * should be stateless (meaning an instance of this dimension will be reused if requested multiple times).
+ */
+class ExampleActionDimension extends ActionDimension
+{
+ /**
+ * This will be the name of the column in the log_link_visit_action table if a $columnType is specified.
+ * @var string
+ */
+ protected $columnName = 'example_action_dimension';
+
+ /**
+ * If a columnType is defined, we will create this a column in the MySQL table having this type. Please make sure
+ * MySQL will understand this type. Once you change the column type the Piwik platform will notify the user to
+ * perform an update which can sometimes take a long time so be careful when choosing the correct column type.
+ * @var string
+ */
+ protected $columnType = 'VARCHAR(255) DEFAULT NULL';
+
+ /**
+ * 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('ExamplePlugin_DimensionName');
+ }
+
+ /**
+ * By defining one or multiple segments a user will be able to filter their visitors by this column. For instance
+ * show all actions only considering users having more than 10 achievement points. If you do not want to define a
+ * segment for this dimension just remove the column.
+ */
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('keywords');
+ $segment->setCategory('General_Actions');
+ $segment->setName('ExamplePlugin_DimensionName');
+ $segment->setAcceptedValues('Here you should explain which values are accepted/useful: Any word, for instance MyKeyword1, MyKeyword2');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * This event is triggered before a new action is logged to the log_link_visit_action table. It overwrites any
+ * looked up action so it makes usually no sense to implement both methods but it sometimes does. You can assign
+ * any value to the column or return boolan false in case you do not want to save any value.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action $action
+ *
+ * @return mixed|false
+ */
+ public function onNewAction(Request $request, Visitor $visitor, Action $action)
+ {
+ if (!($action instanceof ActionPageview)) {
+ // save value only in case it is a page view.
+ return false;
+ }
+
+ $value = Common::getRequestVar('my_page_keywords', false, 'string', $request->getParams());
+
+ if (false === $value) {
+ return $value;
+ }
+
+ $value = trim($value);
+
+ return substr($value, 0, 255);
+ }
+
+ /**
+ * If the value you want to save for your dimension is something like a page title or page url, you usually do not
+ * want to save the raw value over and over again to save bytes in the database. Instead you want to save each value
+ * once in the log_action table and refer to this value by its ID in the log_link_visit_action table. You can do
+ * this by returning an action id in "getActionId()" and by returning a value here. If a value should be ignored
+ * or not persisted just return boolean false. Please note if you return a value here and you implement the event
+ * "onNewAction" the value will be probably overwritten by the other event. So make sure to implement only one of
+ * those.
+ *
+ * @param Request $request
+ * @param Action $action
+ *
+ * @return false|mixed
+ public function onLookupAction(Request $request, Action $action)
+ {
+ if (!($action instanceof ActionPageview)) {
+ // save value only in case it is a page view.
+ return false;
+ }
+
+ $value = Common::getRequestVar('my_page_keywords', false, 'string', $request->getParams());
+
+ if (false === $value) {
+ return $value;
+ }
+
+ $value = trim($value);
+
+ return substr($value, 0, 255);
+ }
+ */
+
+ /**
+ * An action id. The value returned by the lookup action will be associated with this id in the log_action table.
+ * @return int
+ public function getActionId()
+ {
+ return Action::TYPE_PAGE_URL;
+ }
+ */
+} \ No newline at end of file
diff --git a/plugins/ExamplePlugin/Columns/ExampleConversionDimension.php b/plugins/ExamplePlugin/Columns/ExampleConversionDimension.php
new file mode 100644
index 0000000000..436c403bfa
--- /dev/null
+++ b/plugins/ExamplePlugin/Columns/ExampleConversionDimension.php
@@ -0,0 +1,131 @@
+<?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\ExamplePlugin\Columns;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ConversionDimension;
+use Piwik\Plugin\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\GoalManager;
+
+/**
+ * This example dimension counts achievement points for each user. A user gets one achievement point for each action
+ * plus five extra achievement points for each conversion. This would allow you to create a ranking showing the most
+ * active/valueable users. It is just an example, you can log pretty much everything and even just store any custom
+ * request url property. Please note that dimension instances are usually cached during one tracking request so they
+ * should be stateless (meaning an instance of this dimension will be reused if requested multiple times).
+ */
+class ExampleConversionDimension extends ConversionDimension
+{
+ /**
+ * This will be the name of the column in the log_conversion table if a $columnType is specified.
+ * @var string
+ */
+ protected $columnName = 'example_conversion_dimension';
+
+ /**
+ * If a columnType is defined, we will create this a column in the MySQL table having this type. Please make sure
+ * MySQL will understand this type. Once you change the column type the Piwik platform will notify the user to
+ * perform an update which can sometimes take a long time so be careful when choosing the correct column type.
+ * @var string
+ */
+ protected $columnType = 'INTEGER(11) DEFAULT 0 NOT NULL';
+
+ /**
+ * 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('ExamplePlugin_DimensionName');
+ }
+
+ /**
+ * By defining one or multiple segments a user will be able to filter their visitors by this column. For instance
+ * show all reports only considering users having more than 10 achievement points. If you do not want to define a
+ * segment for this dimension just remove the column.
+ */
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('myConversionSegmentName');
+ $segment->setCategory('General_Visit');
+ $segment->setName('ExamplePlugin_DimensionName');
+ $segment->setAcceptedValues('Here you should explain which values are accepted/useful: Any number, for instance 1, 2, 3 , 99');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * This event is triggered when an ecommerce order is converted. In this example we would store a "0" in case it
+ * was the visitors first action or "1" otherwise.
+ * Return boolean false if you do not want to change the value in some cases. If you do not want to perform any
+ * action on an ecommerce order at all it is recommended to just remove this method.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceOrderConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ if ($visitor->isVisitorKnown()) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /**
+ * This event is triggered when an ecommerce cart update is converted. In this example we would store a
+ * the value of the tracking url parameter "myCustomParam" in the "example_conversion_dimension" column.
+ * Return boolean false if you do not want to change the value in some cases. If you do not want to perform any
+ * action on an ecommerce order at all it is recommended to just remove this method.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceCartUpdateConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return Common::getRequestVar('myCustomParam', $default = false, 'int', $request->getParams());
+ }
+
+ /**
+ * This event is triggered when an any custom goal is converted. In this example we would store a the id of the
+ * goal in the 'example_conversion_dimension' column if the visitor is known and nothing otherwise.
+ * Return boolean false if you do not want to change the value in some cases. If you do not want to perform any
+ * action on an ecommerce order at all it is recommended to just remove this method.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onGoalConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ $goalId = $goalManager->getGoalColumn('idgoal');
+
+ if ($visitor->isVisitorKnown()) {
+ return $goalId;
+ }
+
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/ExamplePlugin/Columns/ExampleVisitDimension.php b/plugins/ExamplePlugin/Columns/ExampleVisitDimension.php
new file mode 100644
index 0000000000..58bced1d7b
--- /dev/null
+++ b/plugins/ExamplePlugin/Columns/ExampleVisitDimension.php
@@ -0,0 +1,155 @@
+<?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\ExamplePlugin\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugin\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+/**
+ * This example dimension counts achievement points for each user. A user gets one achievement point for each action
+ * plus five extra achievement points for each conversion. This would allow you to create a ranking showing the most
+ * active/valueable users. It is just an example, you can log pretty much everything and even just store any custom
+ * request url property. Please note that dimension instances are usually cached during one tracking request so they
+ * should be stateless (meaning an instance of this dimension will be reused if requested multiple times).
+ */
+class ExampleVisitDimension extends VisitDimension
+{
+ /**
+ * This will be the name of the column in the log_visit table if a $columnType is specified.
+ * @var string
+ */
+ protected $columnName = 'example_visit_dimension';
+
+ /**
+ * If a columnType is defined, we will create this a column in the MySQL table having this type. Please make sure
+ * MySQL will understand this type. Once you change the column type the Piwik platform will notify the user to
+ * perform an update which can sometimes take a long time so be careful when choosing the correct column type.
+ * @var string
+ */
+ protected $columnType = 'INTEGER(11) DEFAULT 0 NOT NULL';
+
+ /**
+ * 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('ExamplePlugin_DimensionName');
+ }
+
+ /**
+ * By defining one or multiple segments a user will be able to filter their visitors by this column. For instance
+ * show all reports only considering users having more than 10 achievement points. If you do not want to define a
+ * segment for this dimension just remove the column.
+ */
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('achievementPoints');
+ $segment->setCategory('General_Visit');
+ $segment->setName('ExamplePlugin_DimensionName');
+ $segment->setAcceptedValues('Here you should explain which values are accepted/useful: Any number, for instance 1, 2, 3 , 99');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * The onNewVisit method is triggered when a new visitor is detected. This means here you can define an initial
+ * value for this user. By returning boolean false no value will be saved. Once the user makes another action the
+ * event "onExistingVisit" is executed. That means for each visitor this method is executed once. If you do not want
+ * to perform any action on a new visit you can just remove this method.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed|false
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ if (empty($action)) {
+ return 0;
+ }
+
+ return 1;
+
+ // you could also easily save any custom tracking url parameters
+ // return Common::getRequestVar('myCustomTrackingParam', 'default', 'string', $request->getParams());
+ // return Common::getRequestVar('linuxversion', false, 'string', $request->getParams());
+ }
+
+ /**
+ * The onExistingVisit method is triggered when a visitor was recognized meaning it is not a new visitor.
+ * If you want you can overwrite any previous value set by the event onNewVisit. By returning boolean false no value
+ * will be updated. If you do not want to perform any action on a new visit you can just remove this method.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ *
+ * @return mixed|false
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ if (empty($action)) {
+ return false; // Do not change an already persisted value
+ }
+
+ return $visitor->getVisitorColumn($this->columnName) + 1;
+ }
+
+ /**
+ * This event is executed shortly after "onNewVisit" or "onExistingVisit" in case the visitor converted a goal.
+ * In this example we give the user 5 extra points for this achievement. Usually this event is not needed and you
+ * can simply remove this method therefore. An example would be for instance to persist the last converted
+ * action url. Return boolean false if you do not want to change the value in some cases or just remove the value.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ *
+ * @return mixed|false
+ */
+ public function onConvertedVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName) + 5; // give this visitor 5 extra achievement points
+ }
+
+ /**
+ * By implementing this event you can persist a value to the log_conversion table persisting this value for a
+ * specific conversion. The persisted value will be logged along the conversion and will not be changed afterwards.
+ * This allows you to generate reports that shows for instance which url was called how often for a speicifc
+ * conversion. Once you implement this event and a $columnType is defined a column in the log_conversion MySQL table
+ * will be automatically created.
+ *
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ *
+ * @return mixed
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+ */
+
+ /**
+ * Sometimes you may want to make sure another dimension is executed before your dimension so you can persist
+ * a value depending on the value of other dimensions. You can do this by defining an array of dimension names.
+ * If you access any value of any other column within your events, you should require them here. Otherwise those
+ * values may not be available.
+ * @return array
+ public function getRequiredVisitFields()
+ {
+ return array('idsite', 'server_time');
+ }
+ */
+} \ No newline at end of file
diff --git a/plugins/ExamplePlugin/Reports/Base.php b/plugins/ExamplePlugin/Reports/Base.php
new file mode 100644
index 0000000000..e23a058ebb
--- /dev/null
+++ b/plugins/ExamplePlugin/Reports/Base.php
@@ -0,0 +1,19 @@
+<?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\ExamplePlugin\Reports;
+
+use Piwik\Plugin\Report;
+
+abstract class Base extends Report
+{
+ protected function init()
+ {
+ $this->category = 'ExampleCategory';
+ }
+}
diff --git a/plugins/ExamplePlugin/Reports/GetExampleReport.php b/plugins/ExamplePlugin/Reports/GetExampleReport.php
new file mode 100644
index 0000000000..9fd00bd8c1
--- /dev/null
+++ b/plugins/ExamplePlugin/Reports/GetExampleReport.php
@@ -0,0 +1,111 @@
+<?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\ExamplePlugin\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Report;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Actions\Columns\ExitPageUrl;
+use Piwik\View;
+
+class GetExampleReport extends Base
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('ExampleReportName');
+ $this->dimension = new ExitPageUrl();
+ $this->documentation = Piwik::translate('ExampleReportDocumentation');
+
+ // This defines in which order your report appears in the mobile app, in the menu and in the list of widgets
+ $this->order = 999;
+
+ // By default standard metrics are defined but you can customize them by defining an array of metric names
+ // $this->metrics = array('nb_visits', 'nb_hits');
+
+ // Uncomment the next line if your report does not contain any processed metrics, otherwise default
+ // processed metrics will be assigned
+ // $this->processedMetrics = array();
+
+ // Uncomment the next line if your report defines goal metrics
+ // $this->hasGoalMetrics = true;
+
+ // Uncomment the next line if your report should be able to load subtables. You can define any action here
+ // $this->actionToLoadSubTables = $this->action;
+
+ // Uncomment the next line if your report always returns a constant count of rows, for instance always
+ // 24 rows for 1-24hours
+ // $this->constantRowsCount = true;
+
+ // If a menu title is specified, the report will be displayed in the menu
+ // $this->menuTitle = 'ExampleReportName';
+
+ // If a widget title is specified, the report will be displayed in the list of widgets and the report can be
+ // exported as a widget
+ // $this->widgetTitle = 'ExampleReportName';
+ }
+
+ /**
+ * Here you can configure how your report should be displayed. For instance whether your report supports a search
+ * etc. You can also change the default request config. For instance change how many rows are displayed by default.
+ *
+ * @param ViewDataTable $view
+ */
+ public function configureView(ViewDataTable $view)
+ {
+ if (!empty($this->dimension)) {
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+ }
+
+ // $view->config->show_search = false;
+ // $view->requestConfig->filter_sort_column = 'nb_visits';
+ // $view->requestConfig->filter_limit = 10';
+
+ $view->config->columns_to_display = array_merge(array('label'), $this->metrics);
+ }
+
+ /**
+ * Here you can define related reports that will be shown below the reports. Just return an array of related
+ * report instances if there are any.
+ *
+ * @return \Piwik\Plugin\Report[]
+ */
+ public function getRelatedReports()
+ {
+ return array(); // eg return array(new XyzReport());
+ }
+
+ /**
+ * A report is usually completely automatically rendered for you but you can render the report completely
+ * customized if you wish. Just overwrite the method and make sure to return a string containing the content of the
+ * report. Don't forget to create the defined twig template within the templates folder of your plugin in order to
+ * make it work. Usually you should NOT have to overwrite this render method.
+ *
+ * @return string
+ public function render()
+ {
+ $view = new View('@ExamplePlugin/getExampleReport');
+ $view->myData = array();
+
+ return $view->render();
+ }
+ */
+
+ /**
+ * By default your report is available to all users having at least view access. If you do not want this, you can
+ * limit the audience by overwriting this method.
+ *
+ * @return bool
+ public function isEnabled()
+ {
+ return Piwik::hasUserSuperUserAccess()
+ }
+ */
+}
diff --git a/plugins/ExamplePlugin/Widgets.php b/plugins/ExamplePlugin/Widgets.php
index c213d91ee8..2d0e607fa8 100644
--- a/plugins/ExamplePlugin/Widgets.php
+++ b/plugins/ExamplePlugin/Widgets.php
@@ -8,18 +8,49 @@
*/
namespace Piwik\Plugins\ExamplePlugin;
-use Piwik\WidgetsList;
+use Piwik\View;
/**
- * This class allows you to add or remove widgets.
+ * This class allows you to add your own widgets to the Piwik platform. In case you want to remove widgets from another
+ * plugin please have a look at the "configureWidgetsList()" method.
* To configure a widget simply call the corresponding methods as described in the API-Reference:
- * http://developer.piwik.org/api-reference/Piwik/WidgetsList
+ * http://developer.piwik.org/api-reference/Piwik/Plugin\Widgets
*/
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
+ /**
+ * Here you can define the category the widget belongs to. You can reuse any existing widget category or define
+ * your own category.
+ * @var string
+ */
+ protected $category = 'Example Category';
+
+ /**
+ * Here you can add one or multiple widgets. You can add a widget by calling the method "addWidget" and pass the
+ * name of the widget as well as a method name that should be called to render the widget. The method can be
+ * defined either directly here in this widget class or in the controller in case you want to reuse the same action
+ * for instance in the menu etc.
+ */
+ protected function init()
{
- // $widgetsList->add('Example Category', 'Example Widget Name', $controller = 'ExamplePlugin', $action = 'index');
+ // $this->addWidget('Example Widget Name', $method = 'myExampleWidget');
+ // $this->addWidget('Example Widget 2', $method = 'myExampleWidget', $params = array('myparam' => 'myvalue'));
+ }
+
+ /**
+ * This method renders a widget as defined in "init()". It's on you how to generate the content of the
+ * widget. As long as you return a string everything is fine. You can use for instance a "Piwik\View" to render a
+ * twig template. In such a case don't forget to create a twig template (eg. myViewTemplate.twig) in the
+ * "templates" directory of your plugin.
+ *
+ * @return string
+ */
+ public function myExampleWidget()
+ {
+ // $view = new View('@ExamplePlugin/myViewTemplate');
+ // return $view->render();
+
+ return 'My Widget Text';
}
}
diff --git a/plugins/ExamplePlugin/javascripts/plugin.js b/plugins/ExamplePlugin/javascripts/plugin.js
index 7c082d4826..1a0d0dee7a 100644
--- a/plugins/ExamplePlugin/javascripts/plugin.js
+++ b/plugins/ExamplePlugin/javascripts/plugin.js
@@ -10,7 +10,7 @@ $(document).ready(function () {
* Please note that this JavaScript file will be loaded only if you
* enable the following setting in your config:
*
- * [Debug]
+ * [Development]
* disable_merged_assets = 1
*/
diff --git a/plugins/ExamplePlugin/lang/en.json b/plugins/ExamplePlugin/lang/en.json
new file mode 100644
index 0000000000..3ec2fab503
--- /dev/null
+++ b/plugins/ExamplePlugin/lang/en.json
@@ -0,0 +1,5 @@
+{
+ "ExamplePlugin": {
+ "DimensionName": "Example Dimension"
+ }
+} \ No newline at end of file
diff --git a/plugins/ExampleRssWidget/Controller.php b/plugins/ExampleRssWidget/Controller.php
deleted file mode 100644
index 8255c0fd51..0000000000
--- a/plugins/ExampleRssWidget/Controller.php
+++ /dev/null
@@ -1,53 +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
- *
- */
-
-namespace Piwik\Plugins\ExampleRssWidget;
-
-use Exception;
-use Piwik\Piwik;
-
-/**
- *
- */
-class Controller extends \Piwik\Plugin\Controller
-{
- public function rssPiwik()
- {
- try {
- $rss = new RssRenderer('http://feeds.feedburner.com/Piwik');
- $rss->showDescription(true);
- return $rss->get();
- } catch (Exception $e) {
- return $this->error($e);
- }
- }
-
- public function rssChangelog()
- {
- try {
- $rss = new RssRenderer('http://feeds.feedburner.com/PiwikReleases');
- $rss->setCountPosts(1);
- $rss->showDescription(true);
- $rss->showContent(false);
- return $rss->get();
- } catch (Exception $e) {
- return $this->error($e);
- }
- }
-
- /**
- * @param \Exception $e
- */
- protected function error($e)
- {
- return '<div class="pk-emptyDataTable">'
- . Piwik::translate('General_ErrorRequest')
- . ' - ' . $e->getMessage() . '</div>';
- }
-}
diff --git a/plugins/ExampleRssWidget/Widgets.php b/plugins/ExampleRssWidget/Widgets.php
index cd31ef95e0..ec2b55141a 100644
--- a/plugins/ExampleRssWidget/Widgets.php
+++ b/plugins/ExampleRssWidget/Widgets.php
@@ -8,17 +8,56 @@
*/
namespace Piwik\Plugins\ExampleRssWidget;
-use Piwik\WidgetsList;
+use Piwik\Piwik;
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
+ protected $category = 'Example Widgets';
+
+ protected function init()
+ {
+ $this->addWidget('Piwik.org Blog', 'rssPiwik');
+ $this->addWidget('Piwik Changelog', 'rssChangelog');
+ }
+
+ public function rssPiwik()
+ {
+ try {
+ $rss = new RssRenderer('http://feeds.feedburner.com/Piwik');
+ $rss->showDescription(true);
+
+ return $rss->get();
+
+ } catch (\Exception $e) {
+
+ return $this->error($e);
+ }
+ }
+
+ public function rssChangelog()
{
- $category = 'Example Widgets';
- $controller = 'ExampleRssWidget';
+ try {
+ $rss = new RssRenderer('http://feeds.feedburner.com/PiwikReleases');
+ $rss->setCountPosts(1);
+ $rss->showDescription(true);
+ $rss->showContent(false);
+
+ return $rss->get();
- $widgetsList->add($category, 'Piwik.org Blog', $controller, 'rssPiwik');
- $widgetsList->add($category, 'Piwik Changelog', $controller, 'rssChangelog');
+ } catch (\Exception $e) {
+
+ return $this->error($e);
+ }
}
+ /**
+ * @param \Exception $e
+ * @return string
+ */
+ private function error($e)
+ {
+ return '<div class="pk-emptyDataTable">'
+ . Piwik::translate('General_ErrorRequest')
+ . ' - ' . $e->getMessage() . '</div>';
+ }
}
diff --git a/plugins/ExampleVisualization/ExampleVisualization.php b/plugins/ExampleVisualization/ExampleVisualization.php
index e0f7edb085..f0c42a9598 100644
--- a/plugins/ExampleVisualization/ExampleVisualization.php
+++ b/plugins/ExampleVisualization/ExampleVisualization.php
@@ -12,18 +12,4 @@ namespace Piwik\Plugins\ExampleVisualization;
*/
class ExampleVisualization extends \Piwik\Plugin
{
- /**
- * @see Piwik\Plugin::getListHooksRegistered
- */
- public function getListHooksRegistered()
- {
- return array(
- 'ViewDataTable.addViewDataTable' => 'getAvailableVisualizations'
- );
- }
-
- public function getAvailableVisualizations(&$visualizations)
- {
- $visualizations[] = __NAMESPACE__ . '\\SimpleTable';
- }
}
diff --git a/plugins/ExampleVisualization/SimpleTable.php b/plugins/ExampleVisualization/Visualizations/SimpleTable.php
index 6aca5e83ec..8aeeec7f3b 100644
--- a/plugins/ExampleVisualization/SimpleTable.php
+++ b/plugins/ExampleVisualization/Visualizations/SimpleTable.php
@@ -7,7 +7,7 @@
*
*/
-namespace Piwik\Plugins\ExampleVisualization;
+namespace Piwik\Plugins\ExampleVisualization\Visualizations;
use Piwik\DataTable;
use Piwik\Plugin\ViewDataTable;
diff --git a/plugins/Feedback/API.php b/plugins/Feedback/API.php
index bcaeb77650..ce6acdce20 100644
--- a/plugins/Feedback/API.php
+++ b/plugins/Feedback/API.php
@@ -78,20 +78,6 @@ class API extends \Piwik\Plugin\API
@$mail->send();
}
- private function findTranslationKeyForFeatureName($featureName)
- {
- if (empty($GLOBALS['Piwik_translations'])) {
- return;
- }
-
- foreach ($GLOBALS['Piwik_translations'] as $key => $translations) {
- $possibleKey = array_search($featureName, $translations);
- if (!empty($possibleKey)) {
- return $key . '_' . $possibleKey;
- }
- }
- }
-
private function getEnglishTranslationForFeatureName($featureName)
{
$loadedLanguage = Translate::getLanguageLoaded();
@@ -100,7 +86,7 @@ class API extends \Piwik\Plugin\API
return $featureName;
}
- $translationKeyForFeature = $this->findTranslationKeyForFeatureName($featureName);
+ $translationKeyForFeature = Translate::findTranslationKeyForTranslation($featureName);
if (!empty($translationKeyForFeature)) {
Translate::reloadLanguage('en');
diff --git a/plugins/Goals/Archiver.php b/plugins/Goals/Archiver.php
index 78aa5a59a2..4d727adbd6 100644
--- a/plugins/Goals/Archiver.php
+++ b/plugins/Goals/Archiver.php
@@ -13,8 +13,6 @@ use Piwik\DataAccess\LogAggregator;
use Piwik\DataArray;
use Piwik\DataTable;
use Piwik\Metrics;
-use Piwik\PluginsArchiver;
-use Piwik\PluginsManager;
use Piwik\Tracker\GoalManager;
class Archiver extends \Piwik\Plugin\Archiver
diff --git a/plugins/Goals/Columns/BaseConversion.php b/plugins/Goals/Columns/BaseConversion.php
new file mode 100644
index 0000000000..d2c3e24dd7
--- /dev/null
+++ b/plugins/Goals/Columns/BaseConversion.php
@@ -0,0 +1,34 @@
+<?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\Goals\Columns;
+
+use Piwik\Plugin\Dimension\ConversionDimension;
+use Piwik\Tracker\GoalManager;
+
+abstract class BaseConversion extends ConversionDimension
+{
+ /**
+ * Returns rounded decimal revenue, or if revenue is integer, then returns as is.
+ *
+ * @param int|float $revenue
+ * @return int|float
+ */
+ protected function roundRevenueIfNeeded($revenue)
+ {
+ if (false === $revenue) {
+ return false;
+ }
+
+ if (round($revenue) == $revenue) {
+ return $revenue;
+ }
+
+ return round($revenue, GoalManager::REVENUE_PRECISION);
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/DaysToConversion.php b/plugins/Goals/Columns/DaysToConversion.php
new file mode 100644
index 0000000000..d6eef4970c
--- /dev/null
+++ b/plugins/Goals/Columns/DaysToConversion.php
@@ -0,0 +1,20 @@
+<?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\Goals\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class DaysToConversion extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Goals_DaysToConv');
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/IdGoal.php b/plugins/Goals/Columns/IdGoal.php
new file mode 100644
index 0000000000..2243dbdb1f
--- /dev/null
+++ b/plugins/Goals/Columns/IdGoal.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\Goals\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\ConversionDimension;
+use Piwik\Plugin\Segment;
+
+class IdGoal extends ConversionDimension
+{
+ protected $columnName = 'idgoal';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setCategory('General_Visit');
+ $segment->setName('General_VisitConvertedGoalId');
+ $segment->setSegment('visitConvertedGoalId');
+ $segment->setAcceptedValues('1, 2, 3, etc.');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('General_VisitConvertedGoalId');
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/ProductCategory.php b/plugins/Goals/Columns/ProductCategory.php
new file mode 100644
index 0000000000..27565bfb2c
--- /dev/null
+++ b/plugins/Goals/Columns/ProductCategory.php
@@ -0,0 +1,20 @@
+<?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\Goals\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class ProductCategory extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Goals_ProductCategory');
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/ProductName.php b/plugins/Goals/Columns/ProductName.php
new file mode 100644
index 0000000000..50a30f259d
--- /dev/null
+++ b/plugins/Goals/Columns/ProductName.php
@@ -0,0 +1,20 @@
+<?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\Goals\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class ProductName extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Goals_ProductName');
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/ProductSku.php b/plugins/Goals/Columns/ProductSku.php
new file mode 100644
index 0000000000..85742f82e5
--- /dev/null
+++ b/plugins/Goals/Columns/ProductSku.php
@@ -0,0 +1,20 @@
+<?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\Goals\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class ProductSku extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Goals_ProductSKU');
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/Revenue.php b/plugins/Goals/Columns/Revenue.php
new file mode 100644
index 0000000000..343204c932
--- /dev/null
+++ b/plugins/Goals/Columns/Revenue.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\Goals\Columns;
+
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class Revenue extends BaseConversion
+{
+ protected $columnName = 'revenue';
+ protected $columnType = 'float default NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onGoalConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ $defaultRevenue = $goalManager->getGoalColumn('revenue');
+ $revenue = $request->getGoalRevenue($defaultRevenue);
+
+ return $this->roundRevenueIfNeeded($revenue);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceOrderConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ $defaultRevenue = 0;
+ $revenue = $request->getGoalRevenue($defaultRevenue);
+
+ return $this->roundRevenueIfNeeded($revenue);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceCartUpdateConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return $this->onEcommerceOrderConversion($request, $visitor, $action, $goalManager);
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/RevenueDiscount.php b/plugins/Goals/Columns/RevenueDiscount.php
new file mode 100644
index 0000000000..d5022ed4dc
--- /dev/null
+++ b/plugins/Goals/Columns/RevenueDiscount.php
@@ -0,0 +1,38 @@
+<?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\Goals\Columns;
+
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class RevenueDiscount extends BaseConversion
+{
+ protected $columnName = 'revenue_discount';
+ protected $columnType = 'float default NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceOrderConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return $this->roundRevenueIfNeeded($request->getParam('ec_dt'));
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/RevenueShipping.php b/plugins/Goals/Columns/RevenueShipping.php
new file mode 100644
index 0000000000..db68e065fa
--- /dev/null
+++ b/plugins/Goals/Columns/RevenueShipping.php
@@ -0,0 +1,38 @@
+<?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\Goals\Columns;
+
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class RevenueShipping extends BaseConversion
+{
+ protected $columnName = 'revenue_shipping';
+ protected $columnType = 'float default NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceOrderConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return $this->roundRevenueIfNeeded($request->getParam('ec_sh'));
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/RevenueSubtotal.php b/plugins/Goals/Columns/RevenueSubtotal.php
new file mode 100644
index 0000000000..e4e7f8c20a
--- /dev/null
+++ b/plugins/Goals/Columns/RevenueSubtotal.php
@@ -0,0 +1,38 @@
+<?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\Goals\Columns;
+
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class RevenueSubtotal extends BaseConversion
+{
+ protected $columnName = 'revenue_subtotal';
+ protected $columnType = 'float default NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceOrderConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return $this->roundRevenueIfNeeded($request->getParam('ec_st'));
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/RevenueTax.php b/plugins/Goals/Columns/RevenueTax.php
new file mode 100644
index 0000000000..3ecae31b78
--- /dev/null
+++ b/plugins/Goals/Columns/RevenueTax.php
@@ -0,0 +1,38 @@
+<?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\Goals\Columns;
+
+use Piwik\Tracker\GoalManager;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class RevenueTax extends BaseConversion
+{
+ protected $columnName = 'revenue_tax';
+ protected $columnType = 'float default NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @param GoalManager $goalManager
+ *
+ * @return mixed|false
+ */
+ public function onEcommerceOrderConversion(Request $request, Visitor $visitor, $action, GoalManager $goalManager)
+ {
+ return $this->roundRevenueIfNeeded($request->getParam('ec_tx'));
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Columns/VisitsUntilConversion.php b/plugins/Goals/Columns/VisitsUntilConversion.php
new file mode 100644
index 0000000000..390f75ba75
--- /dev/null
+++ b/plugins/Goals/Columns/VisitsUntilConversion.php
@@ -0,0 +1,20 @@
+<?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\Goals\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class VisitsUntilConversion extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Goals_VisitsUntilConv');
+ }
+} \ No newline at end of file
diff --git a/plugins/Goals/Controller.php b/plugins/Goals/Controller.php
index 47b62c2a33..f5a3f1f735 100644
--- a/plugins/Goals/Controller.php
+++ b/plugins/Goals/Controller.php
@@ -471,33 +471,4 @@ class Controller extends \Piwik\Plugin\Controller
return $goalReportsByDimension->render();
}
-
- //
- // Report rendering actions
- //
-
- public function getItemsSku()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getItemsName()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getItemsCategory()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getVisitsUntilConversion()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getDaysToConversion()
- {
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/Goals/Goals.php b/plugins/Goals/Goals.php
index b3b26e5230..0aea5cb842 100644
--- a/plugins/Goals/Goals.php
+++ b/plugins/Goals/Goals.php
@@ -12,8 +12,7 @@ use Piwik\ArchiveProcessor;
use Piwik\Common;
use Piwik\Db;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
-use Piwik\Site;
+use Piwik\Plugin\Report;
use Piwik\Tracker\GoalManager;
use Piwik\Translate;
@@ -31,12 +30,6 @@ class Goals extends \Piwik\Plugin
return $info;
}
- protected $ecommerceReports = array(
- array('Goals_ProductSKU', 'Goals', 'getItemsSku'),
- array('Goals_ProductName', 'Goals', 'getItemsName'),
- array('Goals_ProductCategory', 'Goals', 'getItemsCategory')
- );
-
static public function getReportsWithGoalMetrics()
{
$dimensions = self::getAllReportsWithGoalMetrics();
@@ -52,18 +45,20 @@ class Goals extends \Piwik\Plugin
return $dimensionsByGroup;
}
- public function getEcommerceReports()
- {
- return $this->ecommerceReports;
- }
-
public static function sortGoalDimensionsByModule($a, $b)
{
- $order = array(
- Piwik::translate('Referrers_Referrers'),
- Piwik::translate('General_Visit'),
- Piwik::translate('VisitTime_ColumnServerTime'),
- );
+ static $order = null;
+
+ if (is_null($order)) {
+ $order = array(
+ Piwik::translate('Referrers_Referrers'),
+ Piwik::translate('General_Visit'),
+ Piwik::translate('General_Visitors'),
+ Piwik::translate('VisitsSummary_VisitsSummary'),
+ Piwik::translate('VisitTime_ColumnServerTime'),
+ );
+ }
+
$orderA = array_search($a, $order);
$orderB = array_search($b, $order);
return $orderA > $orderB;
@@ -105,26 +100,40 @@ class Goals extends \Piwik\Plugin
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'Tracker.Cache.getSiteAttributes' => 'fetchGoalsFromDb',
- 'API.getReportMetadata.end' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
+ 'API.getReportMetadata.end' => 'getReportMetadataEnd',
'SitesManager.deleteSite.end' => 'deleteSiteGoals',
'Goals.getReportsWithGoalMetrics' => 'getActualReportsWithGoalMetrics',
- 'ViewDataTable.configure' => 'configureViewDataTable',
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
- 'ViewDataTable.addViewDataTable' => 'getAvailableDataTableVisualizations'
+ 'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations'
);
return $hooks;
}
- public function getAvailableDataTableVisualizations(&$visualizations)
+ public function addMetricTranslations(&$translations)
{
- $visualizations[] = 'Piwik\\Plugins\\Goals\\Visualizations\\Goals';
+ $metrics = array(
+ 'orders' => 'General_EcommerceOrders',
+ 'ecommerce_revenue' => 'General_ProductRevenue',
+ 'revenue_per_visit' => 'General_ColumnValuePerVisit',
+ 'quantity' => 'General_Quantity',
+ 'avg_price' => 'General_AveragePrice',
+ 'avg_quantity' => 'General_AverageQuantity',
+ 'revenue_subtotal' => 'General_Subtotal',
+ 'revenue_tax' => 'General_Tax',
+ 'revenue_shipping' => 'General_Shipping',
+ 'revenue_discount' => 'General_Discount',
+ 'avg_order_revenue' => 'General_AverageOrderValue'
+ );
+
+ $metrics = array_map(array('\\Piwik\\Piwik', 'translate'), $metrics);
+
+ $translations = array_merge($translations, $metrics);
}
/**
* Delete goals recorded for this site
*/
- function deleteSiteGoals($idSite)
+ public function deleteSiteGoals($idSite)
{
Db::query("DELETE FROM " . Common::prefixTable('goal') . " WHERE idsite = ? ", array($idSite));
}
@@ -136,10 +145,8 @@ class Goals extends \Piwik\Plugin
*
* Also, this will update metadata of all other reports that have Goal segmentation
*/
- public function getReportMetadata(&$reports, $info)
+ public function getReportMetadataEnd(&$reports, $info)
{
- $idSites = $info['idSites'];
-
// Processed in AddColumnsProcessedMetricsGoal
// These metrics will also be available for some reports, for each goal
// Example: Conversion rate for Goal 2 for the keyword 'piwik'
@@ -148,210 +155,11 @@ class Goals extends \Piwik\Plugin
);
$goalMetrics = array(
- 'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
- 'nb_visits_converted' => Piwik::translate('General_ColumnVisitsWithConversions'),
- 'conversion_rate' => Piwik::translate('General_ColumnConversionRate'),
- 'revenue' => Piwik::translate('General_ColumnRevenue')
+ 'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
+ 'conversion_rate' => Piwik::translate('General_ColumnConversionRate'),
+ 'revenue' => Piwik::translate('General_ColumnRevenue')
);
- $conversionReportMetrics = array(
- 'nb_conversions' => Piwik::translate('Goals_ColumnConversions')
- );
-
- // General Goal metrics: conversions, conv rate, revenue
- $goalsCategory = Piwik::translate('Goals_Goals');
- $reports[] = array(
- 'category' => $goalsCategory,
- 'name' => Piwik::translate('Goals_Goals'),
- 'module' => 'Goals',
- 'action' => 'get',
- 'metrics' => $goalMetrics,
- 'processedMetrics' => array(),
- 'order' => 1
- );
-
- // If only one website is selected, we add the Goal metrics
- if (count($idSites) == 1) {
- $idSite = reset($idSites);
- $goals = API::getInstance()->getGoals($idSite);
-
- // Add overall visits to conversion report
- $reports[] = array(
- 'category' => $goalsCategory,
- 'name' => Piwik::translate('Goals_VisitsUntilConv'),
- 'module' => 'Goals',
- 'action' => 'getVisitsUntilConversion',
- 'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
- 'constantRowsCount' => true,
- 'parameters' => array(),
- 'metrics' => $conversionReportMetrics,
- 'order' => 5
- );
-
- // Add overall days to conversion report
- $reports[] = array(
- 'category' => $goalsCategory,
- 'name' => Piwik::translate('Goals_DaysToConv'),
- 'module' => 'Goals',
- 'action' => 'getDaysToConversion',
- 'dimension' => Piwik::translate('Goals_DaysToConv'),
- 'constantRowsCount' => true,
- 'parameters' => array(),
- 'metrics' => $conversionReportMetrics,
- 'order' => 10
- );
-
- foreach ($goals as $goal) {
- // Add the general Goal metrics: ie. total Goal conversions,
- // Goal conv rate or Goal total revenue.
- // This API call requires a custom parameter
- $goal['name'] = Common::sanitizeInputValue($goal['name']);
- $reports[] = array(
- 'category' => $goalsCategory,
- 'name' => Piwik::translate('Goals_GoalX', $goal['name']),
- 'module' => 'Goals',
- 'action' => 'get',
- 'parameters' => array('idGoal' => $goal['idgoal']),
- 'metrics' => $goalMetrics,
- 'processedMetrics' => false,
- 'order' => 50 + $goal['idgoal'] * 3
- );
-
- // Add visits to conversion report
- $reports[] = array(
- 'category' => $goalsCategory,
- 'name' => $goal['name'] . ' - ' . Piwik::translate('Goals_VisitsUntilConv'),
- 'module' => 'Goals',
- 'action' => 'getVisitsUntilConversion',
- 'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
- 'constantRowsCount' => true,
- 'parameters' => array('idGoal' => $goal['idgoal']),
- 'metrics' => $conversionReportMetrics,
- 'order' => 51 + $goal['idgoal'] * 3
- );
-
- // Add days to conversion report
- $reports[] = array(
- 'category' => $goalsCategory,
- 'name' => $goal['name'] . ' - ' . Piwik::translate('Goals_DaysToConv'),
- 'module' => 'Goals',
- 'action' => 'getDaysToConversion',
- 'dimension' => Piwik::translate('Goals_DaysToConv'),
- 'constantRowsCount' => true,
- 'parameters' => array('idGoal' => $goal['idgoal']),
- 'metrics' => $conversionReportMetrics,
- 'order' => 52 + $goal['idgoal'] * 3
- );
- }
-
- $site = new Site($idSite);
- if ($site->isEcommerceEnabled()) {
- $category = Piwik::translate('Goals_Ecommerce');
- $ecommerceMetrics = array_merge($goalMetrics, array(
- 'revenue_subtotal' => Piwik::translate('General_Subtotal'),
- 'revenue_tax' => Piwik::translate('General_Tax'),
- 'revenue_shipping' => Piwik::translate('General_Shipping'),
- 'revenue_discount' => Piwik::translate('General_Discount'),
- 'items' => Piwik::translate('General_PurchasedProducts'),
- 'avg_order_revenue' => Piwik::translate('General_AverageOrderValue')
- ));
- $ecommerceMetrics['nb_conversions'] = Piwik::translate('General_EcommerceOrders');
-
- // General Ecommerce metrics
- $reports[] = array(
- 'category' => $category,
- 'name' => Piwik::translate('General_EcommerceOrders'),
- 'module' => 'Goals',
- 'action' => 'get',
- 'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER),
- 'metrics' => $ecommerceMetrics,
- 'processedMetrics' => false,
- 'order' => 10
- );
- $reports[] = array(
- 'category' => $category,
- 'name' => Piwik::translate('General_EcommerceOrders') . ' - ' . Piwik::translate('Goals_VisitsUntilConv'),
- 'module' => 'Goals',
- 'action' => 'getVisitsUntilConversion',
- 'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
- 'constantRowsCount' => true,
- 'metrics' => $conversionReportMetrics,
- 'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER),
- 'order' => 11
- );
- $reports[] = array(
- 'category' => $category,
- 'name' => Piwik::translate('General_EcommerceOrders') . ' - ' . Piwik::translate('Goals_DaysToConv'),
- 'module' => 'Goals',
- 'action' => 'getDaysToConversion',
- 'dimension' => Piwik::translate('Goals_DaysToConv'),
- 'constantRowsCount' => true,
- 'metrics' => $conversionReportMetrics,
- 'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER),
- 'order' => 12
- );
-
- // Abandoned cart general metrics
- $abandonedCartMetrics = $goalMetrics;
- $abandonedCartMetrics['nb_conversions'] = Piwik::translate('General_AbandonedCarts');
- $abandonedCartMetrics['revenue'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_ColumnRevenue'));
- $abandonedCartMetrics['items'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('Goals_Products'));
- unset($abandonedCartMetrics['nb_visits_converted']);
-
- // Abandoned Cart metrics
- $reports[] = array(
- 'category' => $category,
- 'name' => Piwik::translate('General_AbandonedCarts'),
- 'module' => 'Goals',
- 'action' => 'get',
- 'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART),
- 'metrics' => $abandonedCartMetrics,
- 'processedMetrics' => false,
- 'order' => 15
- );
-
- $reports[] = array(
- 'category' => $category,
- 'name' => Piwik::translate('General_AbandonedCarts') . ' - ' . Piwik::translate('Goals_VisitsUntilConv'),
- 'module' => 'Goals',
- 'action' => 'getVisitsUntilConversion',
- 'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
- 'constantRowsCount' => true,
- 'metrics' => $conversionReportMetrics,
- 'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART),
- 'order' => 20
- );
- $reports[] = array(
- 'category' => $category,
- 'name' => Piwik::translate('General_AbandonedCarts') . ' - ' . Piwik::translate('Goals_DaysToConv'),
- 'module' => 'Goals',
- 'action' => 'getDaysToConversion',
- 'dimension' => Piwik::translate('Goals_DaysToConv'),
- 'constantRowsCount' => true,
- 'metrics' => $conversionReportMetrics,
- 'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART),
- 'order' => 25
- );
-
- // Product reports metadata
- $productColumns = self::getProductReportColumns();
- foreach ($this->ecommerceReports as $i => $ecommerceReport) {
- $reports[] = array(
- 'category' => $category,
- 'name' => Piwik::translate($ecommerceReport[0]),
- 'module' => 'Goals',
- 'action' => $ecommerceReport[2],
- 'dimension' => Piwik::translate($ecommerceReport[0]),
- 'metrics' => $productColumns,
- 'processedMetrics' => false,
- 'order' => 30 + $i
- );
- }
- }
- }
-
- unset($goalMetrics['nb_visits_converted']);
-
$reportsWithGoals = self::getAllReportsWithGoalMetrics();
foreach ($reportsWithGoals as $reportWithGoals) {
@@ -360,7 +168,7 @@ class Goals extends \Piwik\Plugin
foreach ($reports as &$apiReportToUpdate) {
if ($apiReportToUpdate['module'] == $reportWithGoals['module']
&& $apiReportToUpdate['action'] == $reportWithGoals['action']
- ) {
+ && empty($apiReportToUpdate['parameters'])) {
$apiReportToUpdate['metricsGoal'] = $goalMetrics;
$apiReportToUpdate['processedMetricsGoal'] = $goalProcessedMetrics;
break;
@@ -373,15 +181,26 @@ class Goals extends \Piwik\Plugin
{
$reportsWithGoals = array();
+ foreach (Report::getAllReports() as $report) {
+ if ($report->hasGoalMetrics()) {
+ $reportsWithGoals[] = array(
+ 'category' => $report->getCategory(),
+ 'name' => $report->getName(),
+ 'module' => $report->getModule(),
+ 'action' => $report->getAction(),
+ );
+ }
+ }
+
/**
* Triggered when gathering all reports that contain Goal metrics. The list of reports
* will be displayed on the left column of the bottom of every _Goals_ page.
- *
+ *
* If plugins define reports that contain goal metrics (such as **conversions** or **revenue**),
* they can use this event to make sure their reports can be viewed on Goals pages.
- *
+ *
* **Example**
- *
+ *
* public function getReportsWithGoalMetrics(&$reports)
* {
* $reports[] = array(
@@ -391,34 +210,23 @@ class Goals extends \Piwik\Plugin
* 'action' => 'getMyReport'
* );
* }
- *
+ *
* @param array &$reportsWithGoals The list of arrays describing reports that have Goal metrics.
* Each element of this array must be an array with the following
* properties:
- *
+ *
* - **category**: The report category. This should be a translated string.
* - **name**: The report's translated name.
* - **module**: The plugin the report is in, eg, `'UserCountry'`.
* - **action**: The API method of the report, eg, `'getCountry'`.
+ * @ignore
+ * @deprecated since 2.5.0
*/
Piwik::postEvent('Goals.getReportsWithGoalMetrics', array(&$reportsWithGoals));
return $reportsWithGoals;
}
- static public function getProductReportColumns()
- {
- return array(
- 'revenue' => Piwik::translate('General_ProductRevenue'),
- 'quantity' => Piwik::translate('General_Quantity'),
- 'orders' => Piwik::translate('General_UniquePurchases'),
- 'avg_price' => Piwik::translate('General_AveragePrice'),
- 'avg_quantity' => Piwik::translate('General_AverageQuantity'),
- 'nb_visits' => Piwik::translate('General_ColumnNbVisits'),
- 'conversion_rate' => Piwik::translate('General_ProductConversionRate'),
- );
- }
-
/**
* This function executes when the 'Goals.getReportsWithGoalMetrics' event fires. It
* adds the 'visits to conversion' report metadata to the list of goal reports so
@@ -443,18 +251,6 @@ class Goals extends \Piwik\Plugin
$dimensions = array_merge($dimensions, $reportWithGoalMetrics);
}
- public function getSegmentsMetadata(&$segments)
- {
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => 'General_VisitConvertedGoalId',
- 'segment' => 'visitConvertedGoalId',
- 'sqlSegment' => 'log_conversion.idgoal',
- 'acceptedValues' => '1, 2, 3, etc.',
- );
- }
-
public function getJsFiles(&$jsFiles)
{
$jsFiles[] = "plugins/Goals/javascripts/goalsForm.js";
@@ -471,141 +267,6 @@ class Goals extends \Piwik\Plugin
$array['goals'] = API::getInstance()->getGoals($idSite);
}
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'Goals.getItemsSku':
- $this->configureViewForGetItemsSku($view);
- break;
- case 'Goals.getItemsName':
- $this->configureViewForGetItemsName($view);
- break;
- case 'Goals.getItemsCategory':
- $this->configureViewForGetItemsCategory($view);
- break;
- case 'Goals.getVisitsUntilConversion':
- $this->configureViewForGetVisitsUntilConversion($view);
- break;
- case 'Goals.getDaysToConversion':
- $this->configureViewForGetDaysToConversion($view);
- break;
- }
- }
-
- private function configureViewForGetItemsSku(ViewDataTable $view)
- {
- return $this->configureViewForItemsReport($view, Piwik::translate('Goals_ProductSKU'));
- }
-
- private function configureViewForGetItemsName(ViewDataTable $view)
- {
- return $this->configureViewForItemsReport($view, Piwik::translate('Goals_ProductName'));
- }
-
- private function configureViewForGetItemsCategory(ViewDataTable $view)
- {
- return $this->configureViewForItemsReport($view, Piwik::translate('Goals_ProductCategory'));
- }
-
- private function configureViewForGetVisitsUntilConversion(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->show_table_all_columns = false;
- $view->config->columns_to_display = array('label', 'nb_conversions');
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_all_views_icons = false;
-
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'asc';
- $view->requestConfig->filter_limit = count(Archiver::$visitCountRanges);
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Goals_VisitsUntilConv'),
- 'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
- ));
- }
-
- private function configureViewForGetDaysToConversion(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->show_table_all_columns = false;
- $view->config->show_all_views_icons = false;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->columns_to_display = array('label', 'nb_conversions');
-
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'asc';
- $view->requestConfig->filter_limit = count(Archiver::$daysToConvRanges);
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('Goals_DaysToConv'),
- 'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
- ));
- }
-
- private function configureViewForItemsReport(ViewDataTable $view, $label)
- {
- $idSite = Common::getRequestVar('idSite');
-
- $moneyColumns = array('revenue', 'avg_price');
- $prettifyMoneyColumns = array(
- 'ColumnCallbackReplace', array($moneyColumns, '\Piwik\MetricsFormatter::getPrettyMoney', array($idSite)));
-
- $view->config->show_ecommerce = true;
- $view->config->show_table = false;
- $view->config->show_all_views_icons = false;
- $view->config->show_exclude_low_population = false;
- $view->config->show_table_all_columns = false;
- $view->config->addTranslation('label', $label);
- $view->config->filters[] = $prettifyMoneyColumns;
-
- $view->requestConfig->filter_limit = 10;
- $view->requestConfig->filter_sort_column = 'revenue';
- $view->requestConfig->filter_sort_order = 'desc';
-
- // set columns/translations which differ based on viewDataTable TODO: shouldn't have to do this check... amount of reports should be dynamic, but metadata should be static
- $columns = Goals::getProductReportColumns();
-
- $abandonedCart = Common::getRequestVar('viewDataTable', 'ecommerceOrder', 'string') == 'ecommerceAbandonedCart';
- if ($abandonedCart) {
- $columns['abandoned_carts'] = Piwik::translate('General_AbandonedCarts');
- $columns['revenue'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_ProductRevenue'));
- $columns['quantity'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_Quantity'));
- $columns['avg_quantity'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_AverageQuantity'));
- unset($columns['orders']);
- unset($columns['conversion_rate']);
-
- $view->requestConfig->request_parameters_to_modify['abandonedCarts'] = '1';
- }
-
- $translations = array_merge(array('label' => $label), $columns);
-
- $view->config->addTranslations($translations);
- $view->config->columns_to_display = array_keys($translations);
-
- // set metrics documentation in normal ecommerce report
- if (!$abandonedCart) {
- $view->config->metrics_documentation = array(
- 'revenue' => Piwik::translate('Goals_ColumnRevenueDocumentation',
- Piwik::translate('Goals_DocumentationRevenueGeneratedByProductSales')),
- 'quantity' => Piwik::translate('Goals_ColumnQuantityDocumentation', $label),
- 'orders' => Piwik::translate('Goals_ColumnOrdersDocumentation', $label),
- 'avg_price' => Piwik::translate('Goals_ColumnAveragePriceDocumentation', $label),
- 'avg_quantity' => Piwik::translate('Goals_ColumnAverageQuantityDocumentation', $label),
- 'nb_visits' => Piwik::translate('Goals_ColumnVisitsProductDocumentation', $label),
- 'conversion_rate' => Piwik::translate('Goals_ColumnConversionRateProductDocumentation', $label),
- );
- }
-
- $view->config->custom_parameters['viewDataTable'] =
- $abandonedCart ? Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART : Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER;
- }
-
-
public function getClientSideTranslationKeys(&$translationKeys)
{
$translationKeys[] = 'Goals_AddGoal';
diff --git a/plugins/Goals/Reports/BaseEcommerce.php b/plugins/Goals/Reports/BaseEcommerce.php
new file mode 100644
index 0000000000..c7ee16a01b
--- /dev/null
+++ b/plugins/Goals/Reports/BaseEcommerce.php
@@ -0,0 +1,73 @@
+<?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\Goals\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\Report;
+use Piwik\Site;
+
+abstract class BaseEcommerce extends Report
+{
+ protected function init()
+ {
+ $this->category = 'Goals_Ecommerce';
+ }
+
+ public function isEnabled()
+ {
+ $idSite = Common::getRequestVar('idSite', false, 'int');
+
+ if (empty($idSite)) {
+ return false;
+ }
+
+ return $this->isEcommerceEnabled($idSite);
+ }
+
+ public function checkIsEnabled()
+ {
+ if (!$this->isEnabled()) {
+ $message = Piwik::translate('General_ExceptionReportNotEnabled');
+
+ if (Piwik::hasUserSuperUserAccess()) {
+ $message .= ' Most likely Ecommerce is not enabled for the requested site.';
+ }
+
+ throw new \Exception($message);
+ }
+ }
+
+ public function configureReportMetadata(&$availableReports, $infos)
+ {
+ if ($this->isEcommerceEnabledByInfos($infos)) {
+ $availableReports[] = $this->buildReportMetadata();
+ }
+ }
+
+ private function isEcommerceEnabledByInfos($infos)
+ {
+ $idSites = $infos['idSites'];
+
+ if (count($idSites) != 1) {
+ return false;
+ }
+
+ $idSite = reset($idSites);
+
+ return $this->isEcommerceEnabled($idSite);
+ }
+
+ private function isEcommerceEnabled($idSite)
+ {
+ $site = new Site($idSite);
+
+ return $site->isEcommerceEnabled();
+ }
+}
diff --git a/plugins/Goals/Reports/BaseEcommerceItem.php b/plugins/Goals/Reports/BaseEcommerceItem.php
new file mode 100644
index 0000000000..b0eccaf770
--- /dev/null
+++ b/plugins/Goals/Reports/BaseEcommerceItem.php
@@ -0,0 +1,103 @@
+<?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\Goals\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\Report;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Goals\Goals;
+
+abstract class BaseEcommerceItem extends BaseEcommerce
+{
+ protected function init()
+ {
+ parent::init();
+ $this->processedMetrics = false;
+ $this->metrics = array(
+ 'revenue', 'quantity', 'orders', 'avg_price', 'avg_quantity', 'nb_visits', 'conversion_rate'
+ );
+ }
+
+ public function getMetrics()
+ {
+ $metrics = parent::getMetrics();
+ $metrics['revenue'] = Piwik::translate('General_ProductRevenue');
+ $metrics['orders'] = Piwik::translate('General_UniquePurchases');
+ $metrics['conversion_rate'] = Piwik::translate('General_ProductConversionRate');
+
+ return $metrics;
+ }
+
+ public function getMetricsDocumentation()
+ {
+ if ($this->isAbandonedCart()) {
+ return array(
+ 'revenue' => Piwik::translate('Goals_ColumnRevenueDocumentation',
+ Piwik::translate('Goals_DocumentationRevenueGeneratedByProductSales')),
+ 'quantity' => Piwik::translate('Goals_ColumnQuantityDocumentation', $this->name),
+ 'orders' => Piwik::translate('Goals_ColumnOrdersDocumentation', $this->name),
+ 'avg_price' => Piwik::translate('Goals_ColumnAveragePriceDocumentation', $this->name),
+ 'avg_quantity' => Piwik::translate('Goals_ColumnAverageQuantityDocumentation', $this->name),
+ 'nb_visits' => Piwik::translate('Goals_ColumnVisitsProductDocumentation', $this->name),
+ 'conversion_rate' => Piwik::translate('Goals_ColumnConversionRateProductDocumentation', $this->name),
+ );
+ }
+
+ return array();
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $idSite = Common::getRequestVar('idSite');
+
+ $view->config->show_ecommerce = true;
+ $view->config->show_table = false;
+ $view->config->show_all_views_icons = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_table_all_columns = false;
+
+ $moneyColumns = array('revenue', 'avg_price');
+ $formatter = '\Piwik\MetricsFormatter::getPrettyMoney';
+ $view->config->filters[] = array('ColumnCallbackReplace', array($moneyColumns, $formatter, array($idSite)));
+
+ $view->requestConfig->filter_limit = 10;
+ $view->requestConfig->filter_sort_column = 'revenue';
+ $view->requestConfig->filter_sort_order = 'desc';
+
+ // set columns/translations which differ based on viewDataTable TODO: shouldn't have to do this check...
+ // amount of reports should be dynamic, but metadata should be static
+ $columns = $this->getMetrics();
+
+ $abandonedCart = $this->isAbandonedCart();
+ if ($abandonedCart) {
+ $columns['abandoned_carts'] = Piwik::translate('General_AbandonedCarts');
+ $columns['revenue'] = Piwik::translate('Goals_LeftInCart', $columns['revenue']);
+ $columns['quantity'] = Piwik::translate('Goals_LeftInCart', $columns['quantity']);
+ $columns['avg_quantity'] = Piwik::translate('Goals_LeftInCart', $columns['avg_quantity']);
+ unset($columns['orders']);
+ unset($columns['conversion_rate']);
+
+ $view->requestConfig->request_parameters_to_modify['abandonedCarts'] = '1';
+ }
+
+ $translations = array_merge(array('label' => $this->name), $columns);
+
+ $view->config->addTranslations($translations);
+ $view->config->columns_to_display = array_keys($translations);
+
+ $view->config->custom_parameters['viewDataTable'] =
+ $abandonedCart ? Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART : Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER;
+ }
+
+ private function isAbandonedCart()
+ {
+ return Common::getRequestVar('viewDataTable', 'ecommerceOrder', 'string') == 'ecommerceAbandonedCart';
+ }
+}
diff --git a/plugins/Goals/Reports/BaseGoal.php b/plugins/Goals/Reports/BaseGoal.php
new file mode 100644
index 0000000000..9e66edee65
--- /dev/null
+++ b/plugins/Goals/Reports/BaseGoal.php
@@ -0,0 +1,63 @@
+<?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\Goals\Reports;
+
+use Piwik\Common;
+use Piwik\Plugins\Goals\API;
+use Piwik\Plugins\Goals\Goals;
+
+abstract class BaseGoal extends \Piwik\Plugin\Report
+{
+ protected $orderGoal = 50;
+
+ protected function init()
+ {
+ $this->category = 'Goals_Goals';
+ }
+
+ protected function addReportMetadataForEachGoal(&$availableReports, $infos, $goalNameFormatter)
+ {
+ $idSite = $this->getIdSiteFromInfos($infos);
+ $goals = $this->getGoalsForIdSite($idSite);
+
+ foreach ($goals as $goal) {
+ $goal['name'] = Common::sanitizeInputValue($goal['name']);
+
+ $this->name = $goalNameFormatter($goal);
+ $this->parameters = array('idGoal' => $goal['idgoal']);
+ $this->order = $this->orderGoal + $goal['idgoal'] * 3;
+
+ $availableReports[] = $this->buildReportMetadata($availableReports, $infos);
+ }
+
+ $this->init();
+ }
+
+ protected function getIdSiteFromInfos($infos)
+ {
+ $idSites = $infos['idSites'];
+
+ if (count($idSites) != 1) {
+ return null;
+ }
+
+ $idSite = reset($idSites);
+
+ return $idSite;
+ }
+
+ private function getGoalsForIdSite($idSite)
+ {
+ if (empty($idSite)) {
+ return array();
+ }
+
+ return API::getInstance()->getGoals($idSite);
+ }
+}
diff --git a/plugins/Goals/Reports/Get.php b/plugins/Goals/Reports/Get.php
new file mode 100644
index 0000000000..7fd804ec26
--- /dev/null
+++ b/plugins/Goals/Reports/Get.php
@@ -0,0 +1,40 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+
+class Get extends BaseGoal
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('Goals_Goals');
+ $this->processedMetrics = array();
+ $this->documentation = ''; // TODO
+ $this->order = 1;
+ $this->orderGoal = 50;
+ $this->metrics = array('nb_conversions', 'nb_visits_converted', 'conversion_rate', 'revenue');
+ $this->parameters = null;
+ }
+
+ public function configureReportMetadata(&$availableReports, $infos)
+ {
+ if (!$this->isEnabled()) {
+ return;
+ }
+
+ parent::configureReportMetadata($availableReports, $infos);
+
+ $this->addReportMetadataForEachGoal($availableReports, $infos, function ($goal) {
+ return Piwik::translate('Goals_GoalX', $goal['name']);
+ });
+ }
+}
diff --git a/plugins/Goals/Reports/GetDaysToConversion.php b/plugins/Goals/Reports/GetDaysToConversion.php
new file mode 100644
index 0000000000..de99a04b60
--- /dev/null
+++ b/plugins/Goals/Reports/GetDaysToConversion.php
@@ -0,0 +1,66 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Goals\Columns\DaysToConversion;
+use Piwik\Plugins\Goals\Archiver;
+
+class GetDaysToConversion extends BaseGoal
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('Goals_DaysToConv');
+ $this->dimension = new DaysToConversion();
+ $this->constantRowsCount = true;
+ $this->processedMetrics = false;
+ $this->parameters = array();
+
+ $this->metrics = array('nb_conversions');
+ $this->order = 10;
+ $this->orderGoal = 52;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->show_all_views_icons = false;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->columns_to_display = array('label', 'nb_conversions');
+
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->requestConfig->filter_limit = count(Archiver::$daysToConvRanges);
+
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+ }
+
+ public function configureReportMetadata(&$availableReports, $infos)
+ {
+ if (!$this->isEnabled()) {
+ return;
+ }
+
+ if (null !== $this->getIdSiteFromInfos($infos)) {
+ parent::configureReportMetadata($availableReports, $infos);
+ }
+
+ $name = $this->name;
+
+ $this->addReportMetadataForEachGoal($availableReports, $infos, function ($goal) use ($name) {
+ return $goal['name'] . ' - ' . $name;
+ });
+ }
+}
diff --git a/plugins/Goals/Reports/GetDaysToConversionAbandonedCart.php b/plugins/Goals/Reports/GetDaysToConversionAbandonedCart.php
new file mode 100644
index 0000000000..624fdf25c1
--- /dev/null
+++ b/plugins/Goals/Reports/GetDaysToConversionAbandonedCart.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\Goals\Reports;
+
+use Piwik\Metrics;
+use Piwik\Piwik;
+use Piwik\Plugins\Goals\Columns\DaysToConversion;
+
+class GetDaysToConversionAbandonedCart extends BaseEcommerce
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->action = 'getDaysToConversion';
+ $this->name = Piwik::translate('General_AbandonedCarts') . ' - ' . Piwik::translate('Goals_DaysToConv');
+ $this->dimension = new DaysToConversion();
+ $this->constantRowsCount = true;
+ $this->processedMetrics = false;
+ $this->metrics = array('nb_conversions');
+ $this->order = 25;
+
+ $this->parameters = array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART);
+ }
+
+}
diff --git a/plugins/Goals/Reports/GetDaysToConversionEcommerceOrder.php b/plugins/Goals/Reports/GetDaysToConversionEcommerceOrder.php
new file mode 100644
index 0000000000..1e0ac0bc96
--- /dev/null
+++ b/plugins/Goals/Reports/GetDaysToConversionEcommerceOrder.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\Goals\Reports;
+
+use Piwik\Metrics;
+use Piwik\Piwik;
+use Piwik\Plugins\Goals\Columns\DaysToConversion;
+
+class GetDaysToConversionEcommerceOrder extends BaseEcommerce
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->action = 'getDaysToConversion';
+ $this->name = Piwik::translate('General_EcommerceOrders') . ' - ' . Piwik::translate('Goals_DaysToConv');
+ $this->dimension = new DaysToConversion();
+ $this->constantRowsCount = true;
+ $this->processedMetrics = false;
+ $this->metrics = array('nb_conversions');
+ $this->order = 12;
+
+ $this->parameters = array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER);
+ }
+
+}
diff --git a/plugins/Goals/Reports/GetEcommerceAbandonedCart.php b/plugins/Goals/Reports/GetEcommerceAbandonedCart.php
new file mode 100644
index 0000000000..97c1e7e26c
--- /dev/null
+++ b/plugins/Goals/Reports/GetEcommerceAbandonedCart.php
@@ -0,0 +1,36 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+
+class GetEcommerceAbandonedCart extends BaseEcommerce
+{
+ protected function init()
+ {
+ parent::init();
+ $this->action = 'get';
+ $this->name = Piwik::translate('General_AbandonedCarts');
+ $this->processedMetrics = false;
+ $this->order = 15;
+ $this->metrics = array('nb_conversions', 'conversion_rate', 'revenue', 'items');
+
+ $this->parameters = array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART);
+ }
+
+ public function getMetrics() {
+ $metrics = parent::getMetrics();
+
+ $metrics['nb_conversions'] = Piwik::translate('General_AbandonedCarts');
+ $metrics['revenue'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_ColumnRevenue'));
+ $metrics['items'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('Goals_Products'));
+
+ return $metrics;
+ }
+}
diff --git a/plugins/Goals/Reports/GetEcommerceOrder.php b/plugins/Goals/Reports/GetEcommerceOrder.php
new file mode 100644
index 0000000000..74a7a8841c
--- /dev/null
+++ b/plugins/Goals/Reports/GetEcommerceOrder.php
@@ -0,0 +1,46 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+
+class GetEcommerceOrder extends BaseEcommerce
+{
+ protected function init()
+ {
+ parent::init();
+ $this->action = 'get';
+ $this->name = Piwik::translate('General_EcommerceOrders');
+ $this->processedMetrics = false;
+ $this->order = 10;
+ $this->metrics = array(
+ 'nb_conversions',
+ 'nb_visits_converted',
+ 'conversion_rate',
+ 'revenue',
+ 'revenue_subtotal',
+ 'revenue_tax',
+ 'revenue_shipping',
+ 'revenue_discount',
+ 'items',
+ 'avg_order_revenue'
+ );
+
+ $this->parameters = array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER);
+ }
+
+ public function getMetrics() {
+ $metrics = parent::getMetrics();
+
+ $metrics['nb_conversions'] = Piwik::translate('General_EcommerceOrders');
+ $metrics['items'] = Piwik::translate('General_PurchasedProducts');
+
+ return $metrics;
+ }
+}
diff --git a/plugins/Goals/Reports/GetItemsCategory.php b/plugins/Goals/Reports/GetItemsCategory.php
new file mode 100644
index 0000000000..adcbd398c6
--- /dev/null
+++ b/plugins/Goals/Reports/GetItemsCategory.php
@@ -0,0 +1,25 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugins\Goals\Columns\ProductCategory;
+
+class GetItemsCategory extends BaseEcommerceItem
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('Goals_ProductCategory');
+ $this->dimension = new ProductCategory();
+ $this->order = 32;
+ $this->widgetTitle = 'Goals_ProductCategory';
+ }
+}
diff --git a/plugins/Goals/Reports/GetItemsName.php b/plugins/Goals/Reports/GetItemsName.php
new file mode 100644
index 0000000000..93f493d7d2
--- /dev/null
+++ b/plugins/Goals/Reports/GetItemsName.php
@@ -0,0 +1,25 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugins\Goals\Columns\ProductName;
+
+class GetItemsName extends BaseEcommerceItem
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('Goals_ProductName');
+ $this->dimension = new ProductName();
+ $this->order = 31;
+ $this->widgetTitle = 'Goals_ProductName';
+ }
+}
diff --git a/plugins/Goals/Reports/GetItemsSku.php b/plugins/Goals/Reports/GetItemsSku.php
new file mode 100644
index 0000000000..183162a98a
--- /dev/null
+++ b/plugins/Goals/Reports/GetItemsSku.php
@@ -0,0 +1,26 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugins\Goals\Columns\ProductSku;
+
+class GetItemsSku extends BaseEcommerceItem
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('Goals_ProductSKU');
+ $this->dimension = new ProductSku();
+ $this->order = 30;
+ $this->widgetTitle = 'Goals_ProductSKU';
+ }
+
+}
diff --git a/plugins/Goals/Reports/GetVisitsUntilConversion.php b/plugins/Goals/Reports/GetVisitsUntilConversion.php
new file mode 100644
index 0000000000..6be172a866
--- /dev/null
+++ b/plugins/Goals/Reports/GetVisitsUntilConversion.php
@@ -0,0 +1,66 @@
+<?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\Goals\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Goals\Columns\VisitsUntilConversion;
+use Piwik\Plugins\Goals\Archiver;
+
+class GetVisitsUntilConversion extends BaseGoal
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->name = Piwik::translate('Goals_VisitsUntilConv');
+ $this->dimension = new VisitsUntilConversion();
+ $this->constantRowsCount = true;
+ $this->processedMetrics = false;
+ $this->parameters = array();
+ $this->metrics = array('nb_conversions');
+ $this->order = 5;
+ $this->orderGoal = 51;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->columns_to_display = array('label', 'nb_conversions');
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_all_views_icons = false;
+
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->requestConfig->filter_limit = count(Archiver::$visitCountRanges);
+
+ $view->config->addTranslations(array('label' => $this->dimension->getName()));
+ }
+
+ public function configureReportMetadata(&$availableReports, $infos)
+ {
+ if (!$this->isEnabled()) {
+ return;
+ }
+
+ if (null !== $this->getIdSiteFromInfos($infos)) {
+ parent::configureReportMetadata($availableReports, $infos);
+ }
+
+ $name = $this->name;
+
+ $this->addReportMetadataForEachGoal($availableReports, $infos, function ($goal) use ($name) {
+ return $goal['name'] . ' - ' . $name;
+ });
+ }
+
+}
diff --git a/plugins/Goals/Reports/GetVisitsUntilConversionAbandonedCart.php b/plugins/Goals/Reports/GetVisitsUntilConversionAbandonedCart.php
new file mode 100644
index 0000000000..f28b052f2e
--- /dev/null
+++ b/plugins/Goals/Reports/GetVisitsUntilConversionAbandonedCart.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\Goals\Reports;
+
+use Piwik\Metrics;
+use Piwik\Piwik;
+use Piwik\Plugins\Goals\Columns\VisitsUntilConversion;
+
+class GetVisitsUntilConversionAbandonedCart extends BaseEcommerce
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->action = 'getVisitsUntilConversion';
+ $this->name = Piwik::translate('General_AbandonedCarts') . ' - ' . Piwik::translate('Goals_VisitsUntilConv');
+ $this->dimension = new VisitsUntilConversion();
+ $this->constantRowsCount = true;
+ $this->processedMetrics = false;
+ $this->metrics = array('nb_conversions');
+ $this->order = 20;
+
+ $this->parameters = array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART);
+ }
+
+}
diff --git a/plugins/Goals/Reports/GetVisitsUntilConversionEcommerceOrder.php b/plugins/Goals/Reports/GetVisitsUntilConversionEcommerceOrder.php
new file mode 100644
index 0000000000..ba292c8b71
--- /dev/null
+++ b/plugins/Goals/Reports/GetVisitsUntilConversionEcommerceOrder.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\Goals\Reports;
+
+use Piwik\Metrics;
+use Piwik\Piwik;
+use Piwik\Plugins\Goals\Columns\VisitsUntilConversion;
+
+class GetVisitsUntilConversionEcommerceOrder extends BaseEcommerce
+{
+ protected function init()
+ {
+ parent::init();
+
+ $this->action = 'getVisitsUntilConversion';
+ $this->name = Piwik::translate('General_EcommerceOrders') . ' - ' . Piwik::translate('Goals_VisitsUntilConv');
+ $this->dimension = new VisitsUntilConversion();
+ $this->constantRowsCount = true;
+ $this->processedMetrics = false;
+ $this->metrics = array('nb_conversions');
+ $this->order = 11;
+
+ $this->parameters = array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER);
+ }
+
+}
diff --git a/plugins/Goals/Widgets.php b/plugins/Goals/Widgets.php
index bdfa47a924..f0dfddde43 100644
--- a/plugins/Goals/Widgets.php
+++ b/plugins/Goals/Widgets.php
@@ -15,39 +15,34 @@ use Piwik\Piwik;
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
+ protected $category = 'Goals_Goals';
+
+ protected function init()
{
- $idSite = Common::getRequestVar('idSite', null, 'int');
+ $this->addWidget('Goals_GoalsOverview', 'widgetGoalsOverview');
- $site = new Site($idSite);
- if ($site->isEcommerceEnabled()) {
- $this->addEcommerceWidgets($widgetsList);
- }
+ $idSite = $this->getIdSite();
+ $goals = API::getInstance()->getGoals($idSite);
- $this->addGoalsWidgets($widgetsList, $idSite);
- }
+ if (count($goals) > 0) {
+ foreach ($goals as $goal) {
+ $name = Common::sanitizeInputValue($goal['name']);
+ $params = array('idGoal' => $goal['idgoal']);
- private function addEcommerceWidgets(WidgetsList $widgetsList)
- {
- $goals = new Goals();
+ $this->addWidget($name, 'widgetGoalReport', $params);
+ }
+ }
- $widgetsList->add('Goals_Ecommerce', 'Goals_EcommerceOverview', 'Goals', 'widgetGoalReport', array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER));
- $widgetsList->add('Goals_Ecommerce', 'Goals_EcommerceLog', 'Goals', 'getEcommerceLog');
- foreach ($goals->getEcommerceReports() as $widget) {
- $widgetsList->add('Goals_Ecommerce', $widget[0], $widget[1], $widget[2]);
+ $site = new Site($idSite);
+ if ($site->isEcommerceEnabled()) {
+ $this->addWidgetWithCustomCategory('Goals_Ecommerce', 'Goals_EcommerceOverview', 'widgetGoalReport', array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER));
+ $this->addWidgetWithCustomCategory('Goals_Ecommerce', 'Goals_EcommerceLog', 'getEcommerceLog');
}
}
- private function addGoalsWidgets(WidgetsList $widgetsList, $idSite)
+ private function getIdSite()
{
- $widgetsList->add('Goals_Goals', 'Goals_GoalsOverview', 'Goals', 'widgetGoalsOverview');
-
- $goals = API::getInstance()->getGoals($idSite);
- if (count($goals) > 0) {
- foreach ($goals as $goal) {
- $widgetsList->add('Goals_Goals', Common::sanitizeInputValue($goal['name']), 'Goals', 'widgetGoalReport', array('idGoal' => $goal['idgoal']));
- }
- }
+ return Common::getRequestVar('idSite', null, 'int');
}
}
diff --git a/plugins/Insights/Insights.php b/plugins/Insights/Insights.php
index 0d9d5fe1be..82b515d2aa 100644
--- a/plugins/Insights/Insights.php
+++ b/plugins/Insights/Insights.php
@@ -19,16 +19,10 @@ class Insights extends \Piwik\Plugin
{
return array(
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
- 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
- 'ViewDataTable.addViewDataTable' => 'getAvailableVisualizations'
+ 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles'
);
}
- public function getAvailableVisualizations(&$visualizations)
- {
- $visualizations[] = __NAMESPACE__ . '\\Visualizations\\Insight';
- }
-
public function getStylesheetFiles(&$stylesheets)
{
$stylesheets[] = "plugins/Insights/stylesheets/insightVisualization.less";
diff --git a/plugins/Insights/Widgets.php b/plugins/Insights/Widgets.php
index 6ce632d8bc..799662deb5 100644
--- a/plugins/Insights/Widgets.php
+++ b/plugins/Insights/Widgets.php
@@ -8,17 +8,13 @@
*/
namespace Piwik\Plugins\Insights;
-use Piwik\WidgetsList;
-
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'Insights_WidgetCategory';
- $controller = 'Insights';
+ protected $category = 'Insights_WidgetCategory';
- $widgetsList->add($category, 'Insights_OverviewWidgetTitle', $controller, 'getInsightsOverview');
- $widgetsList->add($category, 'Insights_MoversAndShakersWidgetTitle', $controller, 'getOverallMoversAndShakers');
+ public function init()
+ {
+ $this->addWidget('Insights_OverviewWidgetTitle', 'getInsightsOverview');
+ $this->addWidget('Insights_MoversAndShakersWidgetTitle', 'getOverallMoversAndShakers');
}
-
}
diff --git a/plugins/Live/Controller.php b/plugins/Live/Controller.php
index 224cf869ae..8b7b88dbb4 100644
--- a/plugins/Live/Controller.php
+++ b/plugins/Live/Controller.php
@@ -13,6 +13,7 @@ use Piwik\Common;
use Piwik\Config;
use Piwik\MetricsFormatter;
use Piwik\Piwik;
+use Piwik\Plugins\Live\Reports\GetLastVisitsDetails;
use Piwik\Plugins\Goals\API as APIGoals;
use Piwik\Url;
use Piwik\View;
@@ -39,31 +40,6 @@ class Controller extends \Piwik\Plugin\Controller
return $this->render($view);
}
- public function getSimpleLastVisitCount()
- {
- $lastMinutes = Config::getInstance()->General[self::SIMPLE_VISIT_COUNT_WIDGET_LAST_MINUTES_CONFIG_KEY];
-
- $lastNData = Request::processRequest('Live.getCounters', array('lastMinutes' => $lastMinutes));
-
- $view = new View('@Live/getSimpleLastVisitCount');
- $view->lastMinutes = $lastMinutes;
- $view->visitors = MetricsFormatter::getPrettyNumber($lastNData[0]['visitors']);
- $view->visits = MetricsFormatter::getPrettyNumber($lastNData[0]['visits']);
- $view->actions = MetricsFormatter::getPrettyNumber($lastNData[0]['actions']);
- $view->refreshAfterXSecs = Config::getInstance()->General['live_widget_refresh_after_seconds'];
- $view->translations = array(
- 'one_visitor' => Piwik::translate('Live_NbVisitor'),
- 'visitors' => Piwik::translate('Live_NbVisitors'),
- 'one_visit' => Piwik::translate('General_OneVisit'),
- 'visits' => Piwik::translate('General_NVisits'),
- 'one_action' => Piwik::translate('General_OneAction'),
- 'actions' => Piwik::translate('VisitsSummary_NbActionsDescription'),
- 'one_minute' => Piwik::translate('General_OneMinute'),
- 'minutes' => Piwik::translate('General_NMinutes')
- );
- return $this->render($view);
- }
-
public function ajaxTotalVisitors()
{
$view = new View('@Live/ajaxTotalVisitors');
@@ -83,21 +59,16 @@ class Controller extends \Piwik\Plugin\Controller
{
$view = new View('@Live/indexVisitorLog.twig');
$view->filterEcommerce = Common::getRequestVar('filterEcommerce', 0, 'int');
- $view->visitorLog = $this->getLastVisitsDetails();
+ $view->visitorLog = $this->renderReport(new GetLastVisitsDetails());
return $view->render();
}
- public function getLastVisitsDetails()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
/**
* Widget
*/
public function getVisitorLog()
{
- return $this->getLastVisitsDetails();
+ return $this->renderReport(new GetLastVisitsDetails());
}
public function getLastVisitsStart()
diff --git a/plugins/Live/Live.php b/plugins/Live/Live.php
index 31efb4cf7a..ff5bb72985 100644
--- a/plugins/Live/Live.php
+++ b/plugins/Live/Live.php
@@ -26,8 +26,7 @@ class Live extends \Piwik\Plugin
return array(
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
- 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
- 'ViewDataTable.getDefaultType' => 'getDefaultTypeViewDataTable'
+ 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys'
);
}
@@ -52,9 +51,4 @@ class Live extends \Piwik\Plugin
$translationKeys[] = "Live_HideMap";
$translationKeys[] = "Live_PageRefreshed";
}
-
- public function getDefaultTypeViewDataTable(&$defaultViewTypes)
- {
- $defaultViewTypes['Live.getLastVisitsDetails'] = VisitorLog::ID;
- }
} \ No newline at end of file
diff --git a/plugins/Live/Menu.php b/plugins/Live/Menu.php
deleted file mode 100644
index 2ef3466f69..0000000000
--- a/plugins/Live/Menu.php
+++ /dev/null
@@ -1,19 +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
- *
- */
-namespace Piwik\Plugins\Live;
-
-use Piwik\Menu\MenuReporting;
-
-class Menu extends \Piwik\Plugin\Menu
-{
- public function configureReportingMenu(MenuReporting $menu)
- {
- $menu->add('General_Visitors', 'Live_VisitorLog', array('module' => 'Live', 'action' => 'indexVisitorLog'), true, $order = 5);
- }
-}
diff --git a/plugins/Live/Reports/Base.php b/plugins/Live/Reports/Base.php
new file mode 100644
index 0000000000..e64ed55f96
--- /dev/null
+++ b/plugins/Live/Reports/Base.php
@@ -0,0 +1,21 @@
+<?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\Live\Reports;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'Live!';
+ }
+
+ public function configureReportMetadata(&$availableReports, $infos)
+ {
+ }
+}
diff --git a/plugins/Live/Reports/GetLastVisitsDetails.php b/plugins/Live/Reports/GetLastVisitsDetails.php
new file mode 100644
index 0000000000..24ef81d617
--- /dev/null
+++ b/plugins/Live/Reports/GetLastVisitsDetails.php
@@ -0,0 +1,42 @@
+<?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\Live\Reports;
+
+use Piwik\Menu\MenuReporting;
+use Piwik\Plugin\Report;
+use Piwik\Plugins\Live\VisitorLog;
+use Piwik\WidgetsList;
+
+class GetLastVisitsDetails extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->widgetTitle = 'Live_VisitorLog';
+ $this->order = 2;
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return VisitorLog::ID;
+ }
+
+ public function configureReportingMenu(MenuReporting $menu)
+ {
+ $url = array('module' => $this->module, 'action' => 'indexVisitorLog');
+
+ $menu->add('General_Visitors', $this->widgetTitle, $url, $this->isEnabled(), $order = 5);
+ }
+
+ public function configureWidget(WidgetsList $widget)
+ {
+ $widget->add($this->category, $this->widgetTitle, $this->module, 'getVisitorLog', array('small' => 1));
+ }
+
+}
diff --git a/plugins/Live/Reports/GetSimpleLastVisitCount.php b/plugins/Live/Reports/GetSimpleLastVisitCount.php
new file mode 100644
index 0000000000..1b44e4ad69
--- /dev/null
+++ b/plugins/Live/Reports/GetSimpleLastVisitCount.php
@@ -0,0 +1,55 @@
+<?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\Live\Reports;
+
+use Piwik\Config;
+use Piwik\MetricsFormatter;
+use Piwik\Piwik;
+use Piwik\Plugin\Report;
+use Piwik\Plugins\Live\Controller;
+use Piwik\Plugins\Live\VisitorLog;
+use Piwik\API\Request;
+use Piwik\View;
+
+class GetSimpleLastVisitCount extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->widgetTitle = 'Live_RealTimeVisitorCount';
+ $this->order = 3;
+ }
+
+ public function render()
+ {
+ $lastMinutes = Config::getInstance()->General[Controller::SIMPLE_VISIT_COUNT_WIDGET_LAST_MINUTES_CONFIG_KEY];
+
+ $lastNData = Request::processRequest('Live.getCounters', array('lastMinutes' => $lastMinutes));
+
+ $view = new View('@Live/getSimpleLastVisitCount');
+ $view->lastMinutes = $lastMinutes;
+ $view->visitors = MetricsFormatter::getPrettyNumber($lastNData[0]['visitors']);
+ $view->visits = MetricsFormatter::getPrettyNumber($lastNData[0]['visits']);
+ $view->actions = MetricsFormatter::getPrettyNumber($lastNData[0]['actions']);
+ $view->refreshAfterXSecs = Config::getInstance()->General['live_widget_refresh_after_seconds'];
+ $view->translations = array(
+ 'one_visitor' => Piwik::translate('Live_NbVisitor'),
+ 'visitors' => Piwik::translate('Live_NbVisitors'),
+ 'one_visit' => Piwik::translate('General_OneVisit'),
+ 'visits' => Piwik::translate('General_NVisits'),
+ 'one_action' => Piwik::translate('General_OneAction'),
+ 'actions' => Piwik::translate('VisitsSummary_NbActionsDescription'),
+ 'one_minute' => Piwik::translate('General_OneMinute'),
+ 'minutes' => Piwik::translate('General_NMinutes')
+ );
+
+ return $view->render();
+ }
+
+}
diff --git a/plugins/Live/Visitor.php b/plugins/Live/Visitor.php
index 6986edfc15..b09d3344d6 100644
--- a/plugins/Live/Visitor.php
+++ b/plugins/Live/Visitor.php
@@ -15,10 +15,11 @@ use Piwik\Date;
use Piwik\Db;
use Piwik\IP;
use Piwik\Piwik;
-use Piwik\Plugins\API\API as APIMetadata;
+use Piwik\Plugins\CoreHome\Columns\VisitGoalBuyer;
use Piwik\Plugins\CustomVariables\CustomVariables;
use Piwik\Plugins\Referrers\API as APIReferrers;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
+use Piwik\Plugins\Actions\Actions\ActionSiteSearch;
use Piwik\Tracker;
use Piwik\Tracker\Action;
use Piwik\Tracker\GoalManager;
@@ -589,7 +590,7 @@ class Visitor implements VisitorInterface
function getVisitEcommerceStatus()
{
- return APIMetadata::getVisitEcommerceStatusFromId($this->details['visit_goal_buyer']);
+ return VisitGoalBuyer::getVisitEcommerceStatusFromId($this->details['visit_goal_buyer']);
}
function getVisitorGoalConvertedIcon()
@@ -970,8 +971,8 @@ class Visitor implements VisitorInterface
private static function getCustomVariablePrettyKey($key)
{
$rename = array(
- Tracker\ActionSiteSearch::CVAR_KEY_SEARCH_CATEGORY => Piwik::translate('Actions_ColumnSearchCategory'),
- Tracker\ActionSiteSearch::CVAR_KEY_SEARCH_COUNT => Piwik::translate('Actions_ColumnSearchResultsCount'),
+ ActionSiteSearch::CVAR_KEY_SEARCH_CATEGORY => Piwik::translate('Actions_ColumnSearchCategory'),
+ ActionSiteSearch::CVAR_KEY_SEARCH_COUNT => Piwik::translate('Actions_ColumnSearchResultsCount'),
);
if (isset($rename[$key])) {
return $rename[$key];
diff --git a/plugins/Live/Widgets.php b/plugins/Live/Widgets.php
index c216a54841..2fcb98ad29 100644
--- a/plugins/Live/Widgets.php
+++ b/plugins/Live/Widgets.php
@@ -8,19 +8,14 @@
*/
namespace Piwik\Plugins\Live;
-use Piwik\WidgetsList;
-
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'Live!';
- $controller = 'Live';
+ protected $category = 'Live!';
- $widgetsList->add($category, 'Live_VisitorsInRealTime', $controller, 'widget');
- $widgetsList->add($category, 'Live_VisitorLog', $controller, 'getVisitorLog', array('small' => 1));
- $widgetsList->add($category, 'Live_RealTimeVisitorCount', $controller, 'getSimpleLastVisitCount');
- $widgetsList->add($category, 'Live_VisitorProfile', $controller, 'getVisitorProfilePopup');
+ public function init()
+ {
+ $this->addWidget('Live_VisitorsInRealTime', 'widget');
+ $this->addWidget('Live_VisitorProfile', 'getVisitorProfilePopup');
}
}
diff --git a/plugins/MultiSites/Columns/Website.php b/plugins/MultiSites/Columns/Website.php
new file mode 100644
index 0000000000..7bdb1c3e09
--- /dev/null
+++ b/plugins/MultiSites/Columns/Website.php
@@ -0,0 +1,20 @@
+<?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\MultiSites\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class Website extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('General_Website');
+ }
+} \ No newline at end of file
diff --git a/plugins/MultiSites/MultiSites.php b/plugins/MultiSites/MultiSites.php
index c286b9b3dd..e0b78fd027 100644
--- a/plugins/MultiSites/MultiSites.php
+++ b/plugins/MultiSites/MultiSites.php
@@ -10,10 +10,6 @@ namespace Piwik\Plugins\MultiSites;
use Piwik\Piwik;
-
-/**
- *
- */
class MultiSites extends \Piwik\Plugin
{
public function getInformation()
@@ -31,9 +27,25 @@ class MultiSites extends \Piwik\Plugin
return array(
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
- 'API.getReportMetadata' => 'getReportMetadata',
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
+ 'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations'
+ );
+ }
+
+ public function addMetricTranslations(&$translations)
+ {
+ $appendix = " " . Piwik::translate('MultiSites_Evolution');
+ $metrics = array(
+ 'visits_evolution' => Piwik::translate('General_ColumnNbVisits') . $appendix,
+ 'actions_evolution' => Piwik::translate('General_ColumnNbActions') . $appendix,
+ 'pageviews_evolution' => Piwik::translate('General_ColumnPageviews') . $appendix,
+ 'revenue_evolution' => Piwik::translate('General_ColumnRevenue') . $appendix,
+ 'nb_conversions_evolution' => Piwik::translate('Goals_ColumnConversions') . $appendix,
+ 'orders_evolution' => Piwik::translate('General_EcommerceOrders') . $appendix,
+ 'ecommerce_revenue_evolution' => Piwik::translate('General_ProductRevenue') . $appendix,
);
+
+ $translations = array_merge($translations, $metrics);
}
public function getClientSideTranslationKeys(&$translations)
@@ -58,41 +70,6 @@ class MultiSites extends \Piwik\Plugin
$translations[] = 'MultiSites_Pagination';
}
- public function getReportMetadata(&$reports)
- {
- $metadataMetrics = array();
- foreach (API::getApiMetrics($enhanced = true) as $metricName => $metricSettings) {
- $metadataMetrics[$metricName] =
- Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]);
- $metadataMetrics[$metricSettings[API::METRIC_EVOLUTION_COL_NAME_KEY]] =
- Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]) . " " . Piwik::translate('MultiSites_Evolution');
- }
-
- $reports[] = array(
- 'category' => Piwik::translate('General_MultiSitesSummary'),
- 'name' => Piwik::translate('General_AllWebsitesDashboard'),
- 'module' => 'MultiSites',
- 'action' => 'getAll',
- 'dimension' => Piwik::translate('General_Website'), // re-using translation
- 'metrics' => $metadataMetrics,
- 'processedMetrics' => false,
- 'constantRowsCount' => false,
- 'order' => 4
- );
-
- $reports[] = array(
- 'category' => Piwik::translate('General_MultiSitesSummary'),
- 'name' => Piwik::translate('General_SingleWebsitesDashboard'),
- 'module' => 'MultiSites',
- 'action' => 'getOne',
- 'dimension' => Piwik::translate('General_Website'), // re-using translation
- 'metrics' => $metadataMetrics,
- 'processedMetrics' => false,
- 'constantRowsCount' => false,
- 'order' => 5
- );
- }
-
public function getJsFiles(&$jsFiles)
{
$jsFiles[] = "plugins/MultiSites/angularjs/dashboard/dashboard-model.js";
diff --git a/plugins/MultiSites/Reports/Base.php b/plugins/MultiSites/Reports/Base.php
new file mode 100644
index 0000000000..12aa3f7d30
--- /dev/null
+++ b/plugins/MultiSites/Reports/Base.php
@@ -0,0 +1,31 @@
+<?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\MultiSites\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugins\MultiSites\API;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'General_MultiSitesSummary';
+
+ $metadataMetrics = array();
+ foreach (API::getApiMetrics($enhanced = true) as $metricName => $metricSettings) {
+ $metadataMetrics[$metricName] =
+ Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]);
+ $metadataMetrics[$metricSettings[API::METRIC_EVOLUTION_COL_NAME_KEY]] =
+ Piwik::translate($metricSettings[API::METRIC_TRANSLATION_KEY]) . " " . Piwik::translate('MultiSites_Evolution');
+ }
+
+ $this->metrics = array_keys($metadataMetrics);
+ }
+
+}
diff --git a/plugins/MultiSites/Reports/GetAll.php b/plugins/MultiSites/Reports/GetAll.php
new file mode 100644
index 0000000000..e4bf5c22ca
--- /dev/null
+++ b/plugins/MultiSites/Reports/GetAll.php
@@ -0,0 +1,26 @@
+<?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\MultiSites\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugins\MultiSites\Columns\Website;
+
+class GetAll extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Website();
+ $this->name = Piwik::translate('General_AllWebsitesDashboard');
+ $this->documentation = ''; // TODO
+ $this->processedMetrics = false;
+ $this->constantRowsCount = false;
+ $this->order = 4;
+ }
+}
diff --git a/plugins/MultiSites/Reports/GetOne.php b/plugins/MultiSites/Reports/GetOne.php
new file mode 100644
index 0000000000..bb57f6f04e
--- /dev/null
+++ b/plugins/MultiSites/Reports/GetOne.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\Plugins\MultiSites\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugins\MultiSites\Columns\Website;
+
+class GetOne extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Website();
+ $this->name = Piwik::translate('General_SingleWebsitesDashboard');
+ $this->documentation = ''; // TODO
+ $this->constantRowsCount = false;
+ $this->processedMetrics = false;
+ $this->order = 5;
+ }
+
+}
diff --git a/plugins/PrivacyManager/Config.php b/plugins/PrivacyManager/Config.php
index fe7d95e7b6..a1e3929fa5 100644
--- a/plugins/PrivacyManager/Config.php
+++ b/plugins/PrivacyManager/Config.php
@@ -64,6 +64,7 @@ class Config
if (array_key_exists($name, $cache)) {
$value = $cache[$name];
settype($value, $config['type']);
+
return $value;
}
diff --git a/plugins/PrivacyManager/IPAnonymizer.php b/plugins/PrivacyManager/IPAnonymizer.php
index 837cd96496..de588c59fd 100644
--- a/plugins/PrivacyManager/IPAnonymizer.php
+++ b/plugins/PrivacyManager/IPAnonymizer.php
@@ -62,6 +62,7 @@ class IPAnonymizer
$privacyConfig = new Config();
$ip = self::applyIPMask($ip, $privacyConfig->ipAddressMaskLength);
+
Common::printDebug("Visitor IP (was: ". IP::N2P($originalIp) .") has been anonymized: ". IP::N2P($ip));
}
diff --git a/plugins/Provider/Columns/Provider.php b/plugins/Provider/Columns/Provider.php
new file mode 100644
index 0000000000..2c33969cb9
--- /dev/null
+++ b/plugins/Provider/Columns/Provider.php
@@ -0,0 +1,94 @@
+<?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\Provider\Columns;
+
+use Piwik\Common;
+use Piwik\IP;
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugin\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
+use Piwik\Plugins\Provider\Provider as ProviderPlugin;
+
+class Provider extends VisitDimension
+{
+ protected $columnName = 'location_provider';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('provider');
+ $segment->setCategory('Visit Location');
+ $segment->setName('Provider_ColumnProvider');
+ $segment->setAcceptedValues('comcast.net, proxad.net, etc.');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ // if provider info has already been set, abort
+ $locationValue = $visitor->getVisitorColumn('location_provider');
+ if (!empty($locationValue)) {
+ return false;
+ }
+
+ $ip = $visitor->getVisitorColumn('location_ip');
+
+ $privacyConfig = new PrivacyManagerConfig();
+ if (!$privacyConfig->useAnonymizedIpForVisitEnrichment) {
+ $ip = $request->getIp();
+ }
+
+ $ip = IP::N2P($ip);
+
+ // In case the IP was anonymized, we should not continue since the DNS reverse lookup will fail and this will slow down tracking
+ if (substr($ip, -2, 2) == '.0') {
+ Common::printDebug("IP Was anonymized so we skip the Provider DNS reverse lookup...");
+ return false;
+ }
+
+ $hostname = $this->getHost($ip);
+ $hostnameExtension = ProviderPlugin::getCleanHostname($hostname);
+
+ // add the provider value in the table log_visit
+ $locationProvider = substr($hostnameExtension, 0, 100);
+
+ return $locationProvider;
+ }
+
+ public function getRequiredVisitFields()
+ {
+ return array('location_ip');
+ }
+
+ /**
+ * Returns the hostname given the IP address string
+ *
+ * @param string $ip IP Address
+ * @return string hostname (or human-readable IP address)
+ */
+ private function getHost($ip)
+ {
+ return trim(strtolower(@IP::getHostByAddr($ip)));
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Provider_ColumnProvider');
+ }
+} \ No newline at end of file
diff --git a/plugins/Provider/Controller.php b/plugins/Provider/Controller.php
index 54d9a4f322..24c348f00b 100644
--- a/plugins/Provider/Controller.php
+++ b/plugins/Provider/Controller.php
@@ -13,13 +13,5 @@ namespace Piwik\Plugins\Provider;
*/
class Controller extends \Piwik\Plugin\Controller
{
- /**
- * Provider
- * @return string|void
- */
- public function getProvider()
- {
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/Provider/Provider.php b/plugins/Provider/Provider.php
index 710e2a4930..d98d0571b0 100644
--- a/plugins/Provider/Provider.php
+++ b/plugins/Provider/Provider.php
@@ -13,55 +13,10 @@ use Piwik\ArchiveProcessor;
use Piwik\Common;
use Piwik\Db;
use Piwik\FrontController;
-use Piwik\IP;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
-use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
-/**
- *
- */
class Provider extends \Piwik\Plugin
{
- /**
- * @see Piwik\Plugin::getListHooksRegistered
- */
- public function getListHooksRegistered()
- {
- $hooks = array(
- 'Tracker.newVisitorInformation' => 'enrichVisitWithProviderInfo',
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable',
- );
- return $hooks;
- }
-
- public function getReportMetadata(&$reports)
- {
- $reports[] = array(
- 'category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('Provider_ColumnProvider'),
- 'module' => 'Provider',
- 'action' => 'getProvider',
- 'dimension' => Piwik::translate('Provider_ColumnProvider'),
- 'documentation' => Piwik::translate('Provider_ProviderReportDocumentation', '<br />'),
- 'order' => 50
- );
- }
-
- public function getSegmentsMetadata(&$segments)
- {
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Visit Location',
- 'name' => Piwik::translate('Provider_ColumnProvider'),
- 'segment' => 'provider',
- 'acceptedValues' => 'comcast.net, proxad.net, etc.',
- 'sqlSegment' => 'log_visit.location_provider'
- );
- }
-
public function install()
{
// add column hostname / hostname ext in the visit table
@@ -89,40 +44,12 @@ class Provider extends \Piwik\Plugin
Piwik::addAction('Template.footerUserCountry', array('Piwik\Plugins\Provider\Provider', 'footerUserCountry'));
}
- /**
- * Logs the provider in the log_visit table
- */
- public function enrichVisitWithProviderInfo(&$visitorInfo, \Piwik\Tracker\Request $request)
+ static public function footerUserCountry(&$out)
{
- // if provider info has already been set, abort
- if (!empty($visitorInfo['location_provider'])) {
- return;
- }
-
- $privacyConfig = new PrivacyManagerConfig();
- $ip = IP::N2P($privacyConfig->useAnonymizedIpForVisitEnrichment ? $visitorInfo['location_ip'] : $request->getIp());
-
- // In case the IP was anonymized, we should not continue since the DNS reverse lookup will fail and this will slow down tracking
- if (substr($ip, -2, 2) == '.0') {
- Common::printDebug("IP Was anonymized so we skip the Provider DNS reverse lookup...");
- return;
- }
-
- $hostname = $this->getHost($ip);
- $hostnameExtension = $this->getCleanHostname($hostname);
-
- // add the provider value in the table log_visit
- $visitorInfo['location_provider'] = $hostnameExtension;
- $visitorInfo['location_provider'] = substr($visitorInfo['location_provider'], 0, 100);
-
- // improve the country using the provider extension if valid
- $hostnameDomain = substr($hostnameExtension, 1 + strrpos($hostnameExtension, '.'));
- if ($hostnameDomain == 'uk') {
- $hostnameDomain = 'gb';
- }
- if (array_key_exists($hostnameDomain, Common::getCountriesList())) {
- $visitorInfo['location_country'] = $hostnameDomain;
- }
+ $out = '<div>
+ <h2>' . Piwik::translate('Provider_WidgetProviders') . '</h2>';
+ $out .= FrontController::getInstance()->fetchDispatch('Provider', 'getProvider');
+ $out .= '</div>';
}
/**
@@ -133,7 +60,7 @@ class Provider extends \Piwik\Plugin
*
* @return string
*/
- private function getCleanHostname($hostname)
+ public static function getCleanHostname($hostname)
{
$extToExclude = array(
'com', 'net', 'org', 'co'
@@ -149,19 +76,19 @@ class Provider extends \Piwik\Plugin
/**
* Triggered when prettifying a hostname string.
- *
- * This event can be used to customize the way a hostname is displayed in the
+ *
+ * This event can be used to customize the way a hostname is displayed in the
* Providers report.
*
* **Example**
- *
+ *
* public function getCleanHostname(&$cleanHostname, $hostname)
* {
* if ('fvae.VARG.ceaga.site.co.jp' == $hostname) {
* $cleanHostname = 'site.co.jp';
* }
* }
- *
+ *
* @param string &$cleanHostname The hostname string to display. Set by the event
* handler.
* @param string $hostname The full hostname.
@@ -183,37 +110,4 @@ class Provider extends \Piwik\Plugin
}
}
- /**
- * Returns the hostname given the IP address string
- *
- * @param string $ip IP Address
- * @return string hostname (or human-readable IP address)
- */
- private function getHost($ip)
- {
- return trim(strtolower(@IP::getHostByAddr($ip)));
- }
-
- static public function footerUserCountry(&$out)
- {
- $out = '<div>
- <h2>' . Piwik::translate('Provider_WidgetProviders') . '</h2>';
- $out .= FrontController::getInstance()->fetchDispatch('Provider', 'getProvider');
- $out .= '</div>';
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'Provider.getProvider':
- $this->configureViewForGetProvider($view);
- break;
- }
- }
-
- private function configureViewForGetProvider(ViewDataTable $view)
- {
- $view->requestConfig->filter_limit = 5;
- $view->config->addTranslation('label', Piwik::translate('Provider_ColumnProvider'));
- }
}
diff --git a/plugins/Provider/Reports/GetProvider.php b/plugins/Provider/Reports/GetProvider.php
new file mode 100644
index 0000000000..9323deccf1
--- /dev/null
+++ b/plugins/Provider/Reports/GetProvider.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\Provider\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Provider\Columns\Provider;
+
+class GetProvider extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'General_Visitors';
+ $this->dimension = new Provider();
+ $this->name = Piwik::translate('Provider_ColumnProvider');
+ $this->documentation = Piwik::translate('Provider_ProviderReportDocumentation', '<br />');
+ $this->order = 50;
+ $this->widgetTitle = 'Provider_WidgetProviders';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->requestConfig->filter_limit = 5;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+}
diff --git a/plugins/Provider/Widgets.php b/plugins/Provider/Widgets.php
deleted file mode 100644
index db81623dea..0000000000
--- a/plugins/Provider/Widgets.php
+++ /dev/null
@@ -1,20 +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
- *
- */
-namespace Piwik\Plugins\Provider;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- $widgetsList->add('General_Visitors', 'Provider_WidgetProviders', 'Provider', 'getProvider');
- }
-
-}
diff --git a/core/Tracker/Referrer.php b/plugins/Referrers/Columns/Base.php
index 3df2cf46a3..db480b05a6 100644
--- a/core/Tracker/Referrer.php
+++ b/plugins/Referrers/Columns/Base.php
@@ -6,16 +6,22 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
-namespace Piwik\Tracker;
+namespace Piwik\Plugins\Referrers\Columns;
use Piwik\Common;
use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\PageUrl;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visit;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
use Piwik\UrlHelper;
-/**
- */
-class Referrer
+
+abstract class Base extends VisitDimension
{
+
// @see detect*() referrer methods
protected $typeReferrerAnalyzed;
protected $nameReferrerAnalyzed;
@@ -30,6 +36,8 @@ class Referrer
const LABEL_PREFIX_ADWORDS_KEYWORD = '(adwords) ';
const LABEL_ADWORDS_NAME = 'AdWords';
+ private static $cachedReferrer = array();
+
/**
* Returns an array containing the following information:
* - referer_type
@@ -59,8 +67,14 @@ class Referrer
* @param int $idSite
* @return array
*/
- public function getReferrerInformation($referrerUrl, $currentUrl, $idSite)
+ protected function getReferrerInformation($referrerUrl, $currentUrl, $idSite)
{
+ $cacheKey = $referrerUrl . $currentUrl . $idSite;
+
+ if (array_key_exists($cacheKey, self::$cachedReferrer)) {
+ return self::$cachedReferrer[$cacheKey];
+ }
+
$this->idsite = $idSite;
// default values for the referer_* fields
@@ -109,6 +123,8 @@ class Referrer
'referer_url' => $this->referrerUrl,
);
+ self::$cachedReferrer[$cacheKey] = $referrerInformation;
+
return $referrerInformation;
}
@@ -122,15 +138,15 @@ class Referrer
/**
* Triggered when detecting the search engine of a referrer URL.
- *
+ *
* Plugins can use this event to provide custom search engine detection
* logic.
- *
+ *
* @param array &$searchEngineInformation An array with the following information:
- *
+ *
* - **name**: The search engine name.
* - **keywords**: The search keywords used.
- *
+ *
* This parameter is initialized to the results
* of Piwik's default search engine detection
* logic.
@@ -298,4 +314,92 @@ class Referrer
return true;
}
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function getValueForRecordGoal(Request $request, Visitor $visitor)
+ {
+ $referrerTimestamp = $request->getParam('_refts');
+ $referrerUrl = $request->getParam('_ref');
+ $referrerCampaignName = trim(urldecode($request->getParam('_rcn')));
+ $referrerCampaignKeyword = trim(urldecode($request->getParam('_rck')));
+
+ // Attributing the correct Referrer to this conversion.
+ // Priority order is as follows:
+ // 0) In some cases, the campaign is not passed from the JS so we look it up from the current visit
+ // 1) Campaign name/kwd parsed in the JS
+ // 2) Referrer URL stored in the _ref cookie
+ // 3) If no info from the cookie, attribute to the current visit referrer
+
+ // 3) Default values: current referrer
+ $type = $visitor->getVisitorColumn('referer_type');
+ $name = $visitor->getVisitorColumn('referer_name');
+ $keyword = $visitor->getVisitorColumn('referer_keyword');
+ $time = $visitor->getVisitorColumn('visit_first_action_time');
+
+ // 0) In some (unknown!?) cases the campaign is not found in the attribution cookie, but the URL ref was found.
+ // In this case we look up if the current visit is credited to a campaign and will credit this campaign rather than the URL ref (since campaigns have higher priority)
+ if (empty($referrerCampaignName)
+ && $type == Common::REFERRER_TYPE_CAMPAIGN
+ && !empty($name)
+ ) {
+ // Use default values per above
+ } // 1) Campaigns from 1st party cookie
+ elseif (!empty($referrerCampaignName)) {
+ $type = Common::REFERRER_TYPE_CAMPAIGN;
+ $name = $referrerCampaignName;
+ $keyword = $referrerCampaignKeyword;
+ $time = $referrerTimestamp;
+ } // 2) Referrer URL parsing
+ elseif (!empty($referrerUrl)) {
+
+ $idSite = $request->getIdSite();
+ $referrer = $this->getReferrerInformation($referrerUrl, $currentUrl = '', $idSite);
+
+ // if the parsed referrer is interesting enough, ie. website or search engine
+ if (in_array($referrer['referer_type'], array(Common::REFERRER_TYPE_SEARCH_ENGINE, Common::REFERRER_TYPE_WEBSITE))) {
+ $type = $referrer['referer_type'];
+ $name = $referrer['referer_name'];
+ $keyword = $referrer['referer_keyword'];
+ $time = $referrerTimestamp;
+ }
+ }
+
+ $this->setCampaignValuesToLowercase($type, $name, $keyword);
+
+ $fields = array(
+ 'referer_type' => $type,
+ 'referer_name' => $name,
+ 'referer_keyword' => $keyword,
+ // this field is currently unused
+ 'referer_visit_server_date' => date("Y-m-d", $time),
+ );
+
+ if (array_key_exists($this->columnName, $fields)) {
+ return $fields[$this->columnName];
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $type
+ * @param $name
+ * @param $keyword
+ */
+ protected function setCampaignValuesToLowercase($type, &$name, &$keyword)
+ {
+ if ($type === Common::REFERRER_TYPE_CAMPAIGN) {
+ if (!empty($name)) {
+ $name = Common::mb_strtolower($name);
+ }
+ if (!empty($keyword)) {
+ $keyword = Common::mb_strtolower($keyword);
+ }
+ }
+ }
+
}
diff --git a/plugins/Referrers/Columns/Campaign.php b/plugins/Referrers/Columns/Campaign.php
new file mode 100644
index 0000000000..4413cd702f
--- /dev/null
+++ b/plugins/Referrers/Columns/Campaign.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class Campaign extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Referrers_ColumnCampaign');
+ }
+}
diff --git a/plugins/Referrers/Columns/Keyword.php b/plugins/Referrers/Columns/Keyword.php
new file mode 100644
index 0000000000..a5025b63c2
--- /dev/null
+++ b/plugins/Referrers/Columns/Keyword.php
@@ -0,0 +1,66 @@
+<?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\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\Referrers\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class Keyword extends Base
+{
+ protected $columnName = 'referer_keyword';
+ protected $columnType = 'VARCHAR(255) NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('referrerKeyword');
+ $segment->setName('General_ColumnKeyword');
+ $segment->setAcceptedValues('Encoded%20Keyword, keyword');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('General_ColumnKeyword');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $referrerUrl = $request->getParam('urlref');
+ $currentUrl = $request->getParam('url');
+
+ $information = $this->getReferrerInformation($referrerUrl, $currentUrl, $request->getIdSite());
+
+ if (!empty($information['referer_keyword'])) {
+ return substr($information['referer_keyword'], 0, 255);
+ }
+
+ return $information['referer_keyword'];
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getValueForRecordGoal($request, $visitor);
+ }
+}
diff --git a/plugins/Referrers/Columns/Referrer.php b/plugins/Referrers/Columns/Referrer.php
new file mode 100644
index 0000000000..ac22e6f5c9
--- /dev/null
+++ b/plugins/Referrers/Columns/Referrer.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class Referrer extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Referrers_Referrer');
+ }
+} \ No newline at end of file
diff --git a/plugins/Referrers/Columns/ReferrerName.php b/plugins/Referrers/Columns/ReferrerName.php
new file mode 100644
index 0000000000..cf030b2ac8
--- /dev/null
+++ b/plugins/Referrers/Columns/ReferrerName.php
@@ -0,0 +1,66 @@
+<?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\Columns;
+
+use Piwik\Plugins\Referrers\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class ReferrerName extends Base
+{
+ protected $columnName = 'referer_name';
+ protected $columnType = 'VARCHAR(70) NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('referrerName');
+ $segment->setName('Referrers_ReferrerName');
+ $segment->setAcceptedValues('twitter.com, www.facebook.com, Bing, Google, Yahoo, CampaignName');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $referrerUrl = $request->getParam('urlref');
+ $currentUrl = $request->getParam('url');
+
+ $information = $this->getReferrerInformation($referrerUrl, $currentUrl, $request->getIdSite());
+
+ if (!empty($information['referer_name'])) {
+
+ return substr($information['referer_name'], 0, 70);
+ }
+
+ return $information['referer_name'];
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getValueForRecordGoal($request, $visitor);
+ }
+}
diff --git a/plugins/Referrers/Columns/ReferrerType.php b/plugins/Referrers/Columns/ReferrerType.php
new file mode 100644
index 0000000000..f4e688f60e
--- /dev/null
+++ b/plugins/Referrers/Columns/ReferrerType.php
@@ -0,0 +1,63 @@
+<?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\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\Referrers\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class ReferrerType extends Base
+{
+ protected $columnName = 'referer_type';
+ protected $columnType = 'TINYINT(1) UNSIGNED NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('referrerType');
+ $segment->setName('Referrers_Type');
+ $segment->setSqlFilterValue('Piwik\Plugins\Referrers\getReferrerTypeFromShortName');
+ $segment->setAcceptedValues('direct, search, website, campaign');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('Referrers_Type');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $referrerUrl = $request->getParam('urlref');
+ $currentUrl = $request->getParam('url');
+
+ $information = $this->getReferrerInformation($referrerUrl, $currentUrl, $request->getIdSite());
+
+ return $information['referer_type'];
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getValueForRecordGoal($request, $visitor);
+ }
+}
diff --git a/plugins/Referrers/Columns/ReferrerUrl.php b/plugins/Referrers/Columns/ReferrerUrl.php
new file mode 100644
index 0000000000..0b8d779794
--- /dev/null
+++ b/plugins/Referrers/Columns/ReferrerUrl.php
@@ -0,0 +1,50 @@
+<?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\Columns;
+
+use Piwik\Plugins\Referrers\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class ReferrerUrl extends Base
+{
+ protected $columnName = 'referer_url';
+ protected $columnType = 'TEXT NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('referrerUrl');
+ $segment->setName('Live_Referrer_URL');
+ $segment->setAcceptedValues('http%3A%2F%2Fwww.example.org%2Freferer-page.htm');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $referrerUrl = $request->getParam('urlref');
+ $currentUrl = $request->getParam('url');
+
+ $information = $this->getReferrerInformation($referrerUrl, $currentUrl, $request->getIdSite());
+
+ return $information['referer_url'];
+ }
+}
diff --git a/plugins/Referrers/Columns/ReferrerVisitServerDate.php b/plugins/Referrers/Columns/ReferrerVisitServerDate.php
new file mode 100644
index 0000000000..3e7861756f
--- /dev/null
+++ b/plugins/Referrers/Columns/ReferrerVisitServerDate.php
@@ -0,0 +1,35 @@
+<?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\Columns;
+
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class ReferrerVisitServerDate extends Base
+{
+ protected $columnName = 'referer_visit_server_date';
+ protected $columnType = 'date default NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getValueForRecordGoal($request, $visitor);
+ }
+}
diff --git a/plugins/Referrers/Columns/SearchEngine.php b/plugins/Referrers/Columns/SearchEngine.php
new file mode 100644
index 0000000000..4c2a0740e8
--- /dev/null
+++ b/plugins/Referrers/Columns/SearchEngine.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class SearchEngine extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Referrers_ColumnSearchEngine');
+ }
+} \ No newline at end of file
diff --git a/plugins/Referrers/Columns/SocialNetwork.php b/plugins/Referrers/Columns/SocialNetwork.php
new file mode 100644
index 0000000000..62ce964c37
--- /dev/null
+++ b/plugins/Referrers/Columns/SocialNetwork.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class SocialNetwork extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Referrers_ColumnSocial');
+ }
+} \ No newline at end of file
diff --git a/plugins/Referrers/Columns/Website.php b/plugins/Referrers/Columns/Website.php
new file mode 100644
index 0000000000..e0ce2b2845
--- /dev/null
+++ b/plugins/Referrers/Columns/Website.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class Website extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('General_Website');
+ }
+} \ No newline at end of file
diff --git a/plugins/Referrers/Columns/WebsitePage.php b/plugins/Referrers/Columns/WebsitePage.php
new file mode 100644
index 0000000000..5ac2bc63f3
--- /dev/null
+++ b/plugins/Referrers/Columns/WebsitePage.php
@@ -0,0 +1,20 @@
+<?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\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class WebsitePage extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('Referrers_ColumnWebsitePage');
+ }
+} \ No newline at end of file
diff --git a/plugins/Referrers/Controller.php b/plugins/Referrers/Controller.php
index 3875f11f09..26286810fa 100644
--- a/plugins/Referrers/Controller.php
+++ b/plugins/Referrers/Controller.php
@@ -14,6 +14,11 @@ use Piwik\DataTable\Map;
use Piwik\Metrics;
use Piwik\Period\Range;
use Piwik\Piwik;
+use Piwik\Plugins\Referrers\Reports\GetKeywords;
+use Piwik\Plugins\Referrers\Reports\GetReferrerType;
+use Piwik\Plugins\Referrers\Reports\GetSearchEngines;
+use Piwik\Plugins\Referrers\Reports\GetSocials;
+use Piwik\Plugins\Referrers\Reports\GetWebsites;
use Piwik\SettingsPiwik;
use Piwik\View;
@@ -30,7 +35,7 @@ class Controller extends \Piwik\Plugin\Controller
$view->nameGraphEvolutionReferrers = 'Referrers.getEvolutionGraph';
// building the referrers summary report
- $view->dataTableReferrerType = $this->getReferrerType(true);
+ $view->dataTableReferrerType = $this->renderReport(new GetReferrerType());
$nameValues = $this->getReferrersVisitorsByType();
@@ -128,93 +133,20 @@ class Controller extends \Piwik\Plugin\Controller
public function getSearchEnginesAndKeywords()
{
$view = new View('@Referrers/getSearchEnginesAndKeywords');
- $view->searchEngines = $this->getSearchEngines(true);
- $view->keywords = $this->getKeywords(true);
+ $view->searchEngines = $this->renderReport(new GetSearchEngines());
+ $view->keywords = $this->renderReport(new GetKeywords());
return $view->render();
}
- public function getReferrerType()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Returns or echo's a report that shows all search keyword, website and campaign
- * referrer information in one report.
- *
- * @return string The report HTML or nothing if $fetch is set to false.
- */
- public function getAll()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getKeywords()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getSearchEnginesFromKeywordId()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getSearchEngines()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getKeywordsFromSearchEngineId()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
public function indexWebsites()
{
$view = new View('@Referrers/indexWebsites');
- $view->websites = $this->getWebsites(true);
- $view->socials = $this->getSocials(true);
+ $view->websites = $this->renderReport(new GetWebsites());
+ $view->socials = $this->renderReport(new GetSocials());
return $view->render();
}
- public function getWebsites()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getSocials()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getUrlsForSocial()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function indexCampaigns()
- {
- return View::singleReport(
- Piwik::translate('Referrers_Campaigns'),
- $this->getCampaigns(true));
- }
-
- public function getCampaigns()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getKeywordsFromCampaignId()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getUrlsFromWebsiteId()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
protected function getReferrersVisitorsByType($date = false)
{
if ($date === false) {
diff --git a/plugins/Referrers/Menu.php b/plugins/Referrers/Menu.php
index 8022f72168..fc7aaf5820 100644
--- a/plugins/Referrers/Menu.php
+++ b/plugins/Referrers/Menu.php
@@ -18,6 +18,5 @@ class Menu extends \Piwik\Plugin\Menu
$menu->add('Referrers_Referrers', 'General_Overview', array('module' => 'Referrers', 'action' => 'index'), true, 1);
$menu->add('Referrers_Referrers', 'Referrers_SubmenuSearchEngines', array('module' => 'Referrers', 'action' => 'getSearchEnginesAndKeywords'), true, 2);
$menu->add('Referrers_Referrers', 'Referrers_SubmenuWebsites', array('module' => 'Referrers', 'action' => 'indexWebsites'), true, 3);
- $menu->add('Referrers_Referrers', 'Referrers_Campaigns', array('module' => 'Referrers', 'action' => 'indexCampaigns'), true, 4);
}
}
diff --git a/plugins/Referrers/Referrers.php b/plugins/Referrers/Referrers.php
index e2fb25f2c5..f937a4315a 100644
--- a/plugins/Referrers/Referrers.php
+++ b/plugins/Referrers/Referrers.php
@@ -11,11 +11,7 @@ namespace Piwik\Plugins\Referrers;
use Piwik\ArchiveProcessor;
use Piwik\Common;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
-use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable\AllColumns;
-use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Pie;
-use Piwik\SettingsPiwik;
/**
* @see plugins/Referrers/functions.php
@@ -31,15 +27,9 @@ class Referrers extends \Piwik\Plugin
*/
public function getListHooksRegistered()
{
- $hooks = array(
- 'Goals.getReportsWithGoalMetrics' => 'getReportsWithGoalMetrics',
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable',
- 'ViewDataTable.getDefaultType' => 'getDefaultTypeViewDataTable',
+ return array(
'Insights.addReportToOverview' => 'addReportToInsightsOverview'
);
- return $hooks;
}
public function addReportToInsightsOverview(&$reports)
@@ -50,423 +40,6 @@ class Referrers extends \Piwik\Plugin
$reports['Referrers_getSearchEngines'] = array();
}
- public function getReportMetadata(&$reports)
- {
- $reports = array_merge($reports, array(
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Type'),
- 'module' => 'Referrers',
- 'action' => 'getReferrerType',
- 'dimension' => Piwik::translate('Referrers_Type'),
- 'constantRowsCount' => true,
- 'documentation' => Piwik::translate('Referrers_TypeReportDocumentation') . '<br />'
- . '<b>' . Piwik::translate('Referrers_DirectEntry') . ':</b> ' . Piwik::translate('Referrers_DirectEntryDocumentation') . '<br />'
- . '<b>' . Piwik::translate('Referrers_SearchEngines') . ':</b> ' . Piwik::translate('Referrers_SearchEnginesDocumentation',
- array('<br />', '&quot;' . Piwik::translate('Referrers_SubmenuSearchEngines') . '&quot;')) . '<br />'
- . '<b>' . Piwik::translate('Referrers_Websites') . ':</b> ' . Piwik::translate('Referrers_WebsitesDocumentation',
- array('<br />', '&quot;' . Piwik::translate('Referrers_SubmenuWebsites') . '&quot;')) . '<br />'
- . '<b>' . Piwik::translate('Referrers_Campaigns') . ':</b> ' . Piwik::translate('Referrers_CampaignsDocumentation',
- array('<br />', '&quot;' . Piwik::translate('Referrers_Campaigns') . '&quot;')),
- 'order' => 1,
- ),
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_WidgetGetAll'),
- 'module' => 'Referrers',
- 'action' => 'getAll',
- 'dimension' => Piwik::translate('Referrers_Referrer'),
- 'documentation' => Piwik::translate('Referrers_AllReferrersReportDocumentation', '<br />'),
- 'order' => 2,
- ),
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Keywords'),
- 'module' => 'Referrers',
- 'action' => 'getKeywords',
- 'actionToLoadSubTables' => 'getSearchEnginesFromKeywordId',
- 'dimension' => Piwik::translate('General_ColumnKeyword'),
- 'documentation' => Piwik::translate('Referrers_KeywordsReportDocumentation', '<br />'),
- 'order' => 3,
- ),
- array( // subtable report
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Keywords'),
- 'module' => 'Referrers',
- 'action' => 'getSearchEnginesFromKeywordId',
- 'dimension' => Piwik::translate('Referrers_ColumnSearchEngine'),
- 'documentation' => Piwik::translate('Referrers_KeywordsReportDocumentation', '<br />'),
- 'isSubtableReport' => true,
- 'order' => 4
- ),
-
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Websites'),
- 'module' => 'Referrers',
- 'action' => 'getWebsites',
- 'dimension' => Piwik::translate('Referrers_ColumnWebsite'),
- 'documentation' => Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />'),
- 'actionToLoadSubTables' => 'getUrlsFromWebsiteId',
- 'order' => 5
- ),
- array( // subtable report
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Websites'),
- 'module' => 'Referrers',
- 'action' => 'getUrlsFromWebsiteId',
- 'dimension' => Piwik::translate('Referrers_ColumnWebsitePage'),
- 'documentation' => Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />'),
- 'isSubtableReport' => true,
- 'order' => 6,
- ),
-
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_SearchEngines'),
- 'module' => 'Referrers',
- 'action' => 'getSearchEngines',
- 'dimension' => Piwik::translate('Referrers_ColumnSearchEngine'),
- 'documentation' => Piwik::translate('Referrers_SearchEnginesReportDocumentation', '<br />'),
- 'actionToLoadSubTables' => 'getKeywordsFromSearchEngineId',
- 'order' => 7,
- ),
- array( // subtable report
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_SearchEngines'),
- 'module' => 'Referrers',
- 'action' => 'getKeywordsFromSearchEngineId',
- 'dimension' => Piwik::translate('General_ColumnKeyword'),
- 'documentation' => Piwik::translate('Referrers_SearchEnginesReportDocumentation', '<br />'),
- 'isSubtableReport' => true,
- 'order' => 8,
- ),
-
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Campaigns'),
- 'module' => 'Referrers',
- 'action' => 'getCampaigns',
- 'dimension' => Piwik::translate('Referrers_ColumnCampaign'),
- 'documentation' => Piwik::translate('Referrers_CampaignsReportDocumentation',
- array('<br />', '<a href="http://piwik.org/docs/tracking-campaigns/" target="_blank">', '</a>')),
- 'actionToLoadSubTables' => 'getKeywordsFromCampaignId',
- 'order' => 9,
- ),
- array( // subtable report
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Campaigns'),
- 'module' => 'Referrers',
- 'action' => 'getKeywordsFromCampaignId',
- 'dimension' => Piwik::translate('General_ColumnKeyword'),
- 'documentation' => Piwik::translate('Referrers_CampaignsReportDocumentation',
- array('<br />', '<a href="http://piwik.org/docs/tracking-campaigns/" target="_blank">', '</a>')),
- 'isSubtableReport' => true,
- 'order' => 10,
- ),
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Socials'),
- 'module' => 'Referrers',
- 'action' => 'getSocials',
- 'actionToLoadSubTables' => 'getUrlsForSocial',
- 'dimension' => Piwik::translate('Referrers_ColumnSocial'),
- 'documentation' => Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />'),
- 'order' => 11,
- ),
- array(
- 'category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Socials'),
- 'module' => 'Referrers',
- 'action' => 'getUrlsForSocial',
- 'isSubtableReport' => true,
- 'dimension' => Piwik::translate('Referrers_ColumnWebsitePage'),
- 'documentation' => Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />'),
- 'order' => 12,
- ),
- ));
- }
-
- public function getSegmentsMetadata(&$segments)
- {
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Referrers_Referrers',
- 'name' => 'Referrers_Type',
- 'segment' => 'referrerType',
- 'acceptedValues' => 'direct, search, website, campaign',
- 'sqlSegment' => 'log_visit.referer_type',
- 'sqlFilterValue' => __NAMESPACE__ . '\getReferrerTypeFromShortName',
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Referrers_Referrers',
- 'name' => 'General_ColumnKeyword',
- 'segment' => 'referrerKeyword',
- 'acceptedValues' => 'Encoded%20Keyword, keyword',
- 'sqlSegment' => 'log_visit.referer_keyword',
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Referrers_Referrers',
- 'name' => 'Referrers_ReferrerName',
- 'segment' => 'referrerName',
- 'acceptedValues' => 'twitter.com, www.facebook.com, Bing, Google, Yahoo, CampaignName',
- 'sqlSegment' => 'log_visit.referer_name',
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Referrers_Referrers',
- 'name' => 'Live_Referrer_URL',
- 'acceptedValues' => 'http%3A%2F%2Fwww.example.org%2Freferer-page.htm',
- 'segment' => 'referrerUrl',
- 'sqlSegment' => 'log_visit.referer_url',
- );
- }
-
- /**
- * Adds Goal dimensions, so that the dimensions are displayed in the UI Goal Overview page
- */
- public function getReportsWithGoalMetrics(&$dimensions)
- {
- $dimensions = array_merge($dimensions, array(
- array('category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Type'),
- 'module' => 'Referrers',
- 'action' => 'getReferrerType',
- ),
- array('category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Keywords'),
- 'module' => 'Referrers',
- 'action' => 'getKeywords',
- ),
- array('category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_SearchEngines'),
- 'module' => 'Referrers',
- 'action' => 'getSearchEngines',
- ),
- array('category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Websites'),
- 'module' => 'Referrers',
- 'action' => 'getWebsites',
- ),
- array('category' => Piwik::translate('Referrers_Referrers'),
- 'name' => Piwik::translate('Referrers_Campaigns'),
- 'module' => 'Referrers',
- 'action' => 'getCampaigns',
- ),
- ));
- }
-
- public function getDefaultTypeViewDataTable(&$defaultViewTypes)
- {
- $defaultViewTypes['Referrers.getReferrerType'] = AllColumns::ID;
- $defaultViewTypes['Referrers.getSocials'] = Pie::ID;
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'Referrers.getReferrerType':
- $this->configureViewForGetReferrerType($view);
- break;
- case 'Referrers.getAll':
- $this->configureViewForGetAll($view);
- break;
- case 'Referrers.getKeywords':
- $this->configureViewForGetKeywords($view);
- break;
- case 'Referrers.getSearchEnginesFromKeywordId':
- $this->configureViewForGetSearchEnginesFromKeywordId($view);
- break;
- case 'Referrers.getSearchEngines':
- $this->configureViewForGetSearchEngines($view);
- break;
- case 'Referrers.getKeywordsFromSearchEngineId':
- $this->configureViewForGetKeywordsFromSearchEngineId($view);
- break;
- case 'Referrers.getWebsites':
- $this->configureViewForGetWebsites($view);
- break;
- case 'Referrers.getSocials':
- $this->configureViewForGetSocials($view);
- break;
- case 'Referrers.getUrlsForSocial':
- $this->configureViewForGetUrlsForSocial($view);
- break;
- case 'Referrers.getCampaigns':
- $this->configureViewForGetCampaigns($view);
- break;
- case 'Referrers.getKeywordsFromCampaignId':
- $this->configureViewForGetKeywordsFromCampaignId($view);
- break;
- case 'Referrers.getUrlsFromWebsiteId':
- $this->configureViewForGetUrlsFromWebsiteId($view);
- break;
- }
- }
-
- private function configureViewForGetReferrerType(ViewDataTable $view)
- {
- $idSubtable = Common::getRequestVar('idSubtable', false);
- $labelColumnTitle = Piwik::translate('Referrers_Type');
-
- switch ($idSubtable) {
- case Common::REFERRER_TYPE_SEARCH_ENGINE:
- $labelColumnTitle = Piwik::translate('Referrers_ColumnSearchEngine');
- break;
- case Common::REFERRER_TYPE_WEBSITE:
- $labelColumnTitle = Piwik::translate('Referrers_ColumnWebsite');
- break;
- case Common::REFERRER_TYPE_CAMPAIGN:
- $labelColumnTitle = Piwik::translate('Referrers_ColumnCampaign');
- break;
- default:
- break;
- }
-
- $view->config->show_search = false;
- $view->config->show_goals = true;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', $labelColumnTitle);
-
- $view->requestConfig->filter_limit = 10;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->disable_subtable_when_show_goals = true;
- }
- }
-
- private function configureViewForGetAll(ViewDataTable $view)
- {
- $setGetAllHtmlPrefix = array($this, 'setGetAllHtmlPrefix');
-
- $view->config->show_exclude_low_population = false;
- $view->config->show_goals = true;
- $view->config->addTranslation('label', Piwik::translate('Referrers_Referrer'));
-
- $view->requestConfig->filter_limit = 20;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->disable_row_actions = true;
- }
-
- $view->config->filters[] = array('MetadataCallbackAddMetadata', array('referer_type', 'html_label_prefix', $setGetAllHtmlPrefix));
- }
-
- private function configureViewForGetKeywords(ViewDataTable $view)
- {
- $view->config->subtable_controller_action = 'getSearchEnginesFromKeywordId';
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('General_ColumnKeyword'));
- $view->config->show_goals = true;
-
- $view->requestConfig->filter_limit = 25;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->disable_subtable_when_show_goals = true;
- }
- }
-
- private function configureViewForGetSearchEnginesFromKeywordId(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('Referrers_ColumnSearchEngine'));
- }
-
- private function configureViewForGetSearchEngines(ViewDataTable $view)
- {
- $view->config->subtable_controller_action = 'getKeywordsFromSearchEngineId';
- $view->config->show_exclude_low_population = false;
- $view->config->show_search = false;
- $view->config->show_goals = true;
- $view->config->addTranslation('label', Piwik::translate('Referrers_ColumnSearchEngine'));
-
- $view->requestConfig->filter_limit = 25;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->disable_subtable_when_show_goals = true;
- }
- }
-
- private function configureViewForGetKeywordsFromSearchEngineId(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('General_ColumnKeyword'));
- }
-
- private function configureViewForGetWebsites(ViewDataTable $view)
- {
- $view->config->subtable_controller_action = 'getUrlsFromWebsiteId';
- $view->config->show_exclude_low_population = false;
- $view->config->show_goals = true;
- $view->config->addTranslation('label', Piwik::translate('Referrers_ColumnWebsite'));
-
- $view->requestConfig->filter_limit = 25;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->disable_subtable_when_show_goals = true;
- }
- }
-
- private function configureViewForGetSocials(ViewDataTable $view)
- {
- $view->config->subtable_controller_action = 'getUrlsForSocial';
- $view->config->show_exclude_low_population = false;
- $view->config->show_goals = true;
- $view->config->addTranslation('label', Piwik::translate('Referrers_ColumnSocial'));
-
- $view->requestConfig->filter_limit = 10;
-
- if ($view->isViewDataTableId(HtmlTable::ID)) {
- $view->config->disable_subtable_when_show_goals = true;
- }
-
- $widget = Common::getRequestVar('widget', false);
- if (empty($widget)) {
- $view->config->show_footer_message = Piwik::translate('Referrers_SocialFooterMessage');
- }
- }
-
- private function configureViewForGetUrlsForSocial(ViewDataTable $view)
- {
- $view->config->show_goals = true;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('Referrers_ColumnWebsitePage'));
-
- $view->requestConfig->filter_limit = 10;
- }
-
- private function configureViewForGetCampaigns(ViewDataTable $view)
- {
- $view->config->show_goals = true;
- $view->config->subtable_controller_action = 'getKeywordsFromCampaignId';
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('Referrers_ColumnCampaign'));
-
- $view->requestConfig->filter_limit = 25;
- }
-
- private function configureViewForGetKeywordsFromCampaignId(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('General_ColumnKeyword'));
- }
-
- private function configureViewForGetUrlsFromWebsiteId(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
- $view->config->tooltip_metadata_name = 'url';
- $view->config->addTranslation('label', Piwik::translate('Referrers_ColumnWebsitePage'));
- }
-
/**
* DataTable filter callback that returns the HTML prefix for a label in the
* 'getAll' report based on the row's referrer type.
diff --git a/plugins/Referrers/Reports/Base.php b/plugins/Referrers/Reports/Base.php
new file mode 100644
index 0000000000..e4a6394c00
--- /dev/null
+++ b/plugins/Referrers/Reports/Base.php
@@ -0,0 +1,18 @@
+<?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\Reports;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'Referrers_Referrers';
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetAll.php b/plugins/Referrers/Reports/GetAll.php
new file mode 100644
index 0000000000..50ac00dc9c
--- /dev/null
+++ b/plugins/Referrers/Reports/GetAll.php
@@ -0,0 +1,47 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\Referrers\Columns\Referrer;
+use Piwik\Plugins\Referrers\Referrers;
+
+class GetAll extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Referrer();
+ $this->name = Piwik::translate('Referrers_WidgetGetAll');
+ $this->documentation = Piwik::translate('Referrers_AllReferrersReportDocumentation', '<br />');
+ $this->order = 2;
+ $this->widgetTitle = 'Referrers_WidgetGetAll';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $referrers = new Referrers();
+ $setGetAllHtmlPrefix = array($referrers, 'setGetAllHtmlPrefix');
+
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_goals = true;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 20;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->disable_row_actions = true;
+ }
+
+ $view->config->filters[] = array('MetadataCallbackAddMetadata', array('referer_type', 'html_label_prefix', $setGetAllHtmlPrefix));
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetCampaigns.php b/plugins/Referrers/Reports/GetCampaigns.php
new file mode 100644
index 0000000000..6da820a436
--- /dev/null
+++ b/plugins/Referrers/Reports/GetCampaigns.php
@@ -0,0 +1,40 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Referrers\Columns\Campaign;
+
+class GetCampaigns extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Campaign();
+ $this->name = Piwik::translate('Referrers_Campaigns');
+ $this->documentation = Piwik::translate('Referrers_CampaignsReportDocumentation',
+ array('<br />', '<a href="http://piwik.org/docs/tracking-campaigns/" target="_blank">', '</a>'));
+ $this->actionToLoadSubTables = 'getKeywordsFromCampaignId';
+ $this->hasGoalMetrics = true;
+ $this->order = 9;
+ $this->widgetTitle = 'Referrers_Campaigns';
+ $this->menuTitle = 'Referrers_Campaigns';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_goals = true;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 25;
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetKeywords.php b/plugins/Referrers/Reports/GetKeywords.php
new file mode 100644
index 0000000000..7fe5d3d82f
--- /dev/null
+++ b/plugins/Referrers/Reports/GetKeywords.php
@@ -0,0 +1,43 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\Referrers\Columns\Keyword;
+
+class GetKeywords extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Keyword();
+ $this->name = Piwik::translate('Referrers_Keywords');
+ $this->documentation = Piwik::translate('Referrers_KeywordsReportDocumentation', '<br />');
+ $this->actionToLoadSubTables = 'getSearchEnginesFromKeywordId';
+ $this->hasGoalMetrics = true;
+ $this->order = 3;
+ $this->widgetTitle = 'Referrers_WidgetKeywords';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate('General_ColumnKeyword'));
+ $view->config->show_goals = true;
+
+ $view->requestConfig->filter_limit = 25;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->disable_subtable_when_show_goals = true;
+ }
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetKeywordsFromCampaignId.php b/plugins/Referrers/Reports/GetKeywordsFromCampaignId.php
new file mode 100644
index 0000000000..6230faec9f
--- /dev/null
+++ b/plugins/Referrers/Reports/GetKeywordsFromCampaignId.php
@@ -0,0 +1,35 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Referrers\Columns\Keyword;
+
+class GetKeywordsFromCampaignId extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Keyword();
+ $this->name = Piwik::translate('Referrers_Campaigns');
+ $this->documentation = Piwik::translate('Referrers_CampaignsReportDocumentation',
+ array('<br />', '<a href="http://piwik.org/docs/tracking-campaigns/" target="_blank">', '</a>'));
+ $this->isSubtableReport = true;
+ $this->order = 10;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetKeywordsFromSearchEngineId.php b/plugins/Referrers/Reports/GetKeywordsFromSearchEngineId.php
new file mode 100644
index 0000000000..7c869fa147
--- /dev/null
+++ b/plugins/Referrers/Reports/GetKeywordsFromSearchEngineId.php
@@ -0,0 +1,34 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Referrers\Columns\Keyword;
+
+class GetKeywordsFromSearchEngineId extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Keyword();
+ $this->name = Piwik::translate('Referrers_SearchEngines');
+ $this->documentation = Piwik::translate('Referrers_SearchEnginesReportDocumentation', '<br />');
+ $this->isSubtableReport = true;
+ $this->order = 8;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetReferrerType.php b/plugins/Referrers/Reports/GetReferrerType.php
new file mode 100644
index 0000000000..9f1e538e16
--- /dev/null
+++ b/plugins/Referrers/Reports/GetReferrerType.php
@@ -0,0 +1,77 @@
+<?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\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\Referrers\Columns\ReferrerType;
+
+class GetReferrerType extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new ReferrerType();
+ $this->name = Piwik::translate('Referrers_Type');
+ $this->documentation = Piwik::translate('Referrers_TypeReportDocumentation') . '<br />'
+ . '<b>' . Piwik::translate('Referrers_DirectEntry') . ':</b> ' . Piwik::translate('Referrers_DirectEntryDocumentation') . '<br />'
+ . '<b>' . Piwik::translate('Referrers_SearchEngines') . ':</b> ' . Piwik::translate('Referrers_SearchEnginesDocumentation',
+ array('<br />', '&quot;' . Piwik::translate('Referrers_SubmenuSearchEngines') . '&quot;')) . '<br />'
+ . '<b>' . Piwik::translate('Referrers_Websites') . ':</b> ' . Piwik::translate('Referrers_WebsitesDocumentation',
+ array('<br />', '&quot;' . Piwik::translate('Referrers_SubmenuWebsites') . '&quot;')) . '<br />'
+ . '<b>' . Piwik::translate('Referrers_Campaigns') . ':</b> ' . Piwik::translate('Referrers_CampaignsDocumentation',
+ array('<br />', '&quot;' . Piwik::translate('Referrers_Campaigns') . '&quot;'));
+ $this->constantRowsCount = true;
+ $this->hasGoalMetrics = true;
+ $this->order = 1;
+ $this->widgetTitle = 'General_Overview';
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return HtmlTable\AllColumns::ID;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $idSubtable = Common::getRequestVar('idSubtable', false);
+ $labelColumnTitle = $this->name;
+
+ switch ($idSubtable) {
+ case Common::REFERRER_TYPE_SEARCH_ENGINE:
+ $labelColumnTitle = Piwik::translate('Referrers_ColumnSearchEngine');
+ break;
+ case Common::REFERRER_TYPE_WEBSITE:
+ $labelColumnTitle = Piwik::translate('Referrers_ColumnWebsite');
+ break;
+ case Common::REFERRER_TYPE_CAMPAIGN:
+ $labelColumnTitle = Piwik::translate('Referrers_ColumnCampaign');
+ break;
+ default:
+ break;
+ }
+
+ $view->config->show_search = false;
+ $view->config->show_goals = true;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $labelColumnTitle);
+
+ $view->requestConfig->filter_limit = 10;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->disable_subtable_when_show_goals = true;
+ }
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetSearchEngines.php b/plugins/Referrers/Reports/GetSearchEngines.php
new file mode 100644
index 0000000000..17babab9a9
--- /dev/null
+++ b/plugins/Referrers/Reports/GetSearchEngines.php
@@ -0,0 +1,44 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\Referrers\Columns\SearchEngine;
+
+class GetSearchEngines extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new SearchEngine();
+ $this->name = Piwik::translate('Referrers_SearchEngines');
+ $this->documentation = Piwik::translate('Referrers_SearchEnginesReportDocumentation', '<br />');
+ $this->actionToLoadSubTables = 'getKeywordsFromSearchEngineId';
+ $this->hasGoalMetrics = true;
+ $this->order = 7;
+ $this->widgetTitle = 'Referrers_SearchEngines';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_search = false;
+ $view->config->show_goals = true;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 25;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->disable_subtable_when_show_goals = true;
+ }
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetSearchEnginesFromKeywordId.php b/plugins/Referrers/Reports/GetSearchEnginesFromKeywordId.php
new file mode 100644
index 0000000000..7c4c0a498a
--- /dev/null
+++ b/plugins/Referrers/Reports/GetSearchEnginesFromKeywordId.php
@@ -0,0 +1,34 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Referrers\Columns\SearchEngine;
+
+class GetSearchEnginesFromKeywordId extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new SearchEngine();
+ $this->name = Piwik::translate('Referrers_Keywords');
+ $this->documentation = Piwik::translate('Referrers_KeywordsReportDocumentation', '<br />');
+ $this->isSubtableReport = true;
+ $this->order = 4;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetSocials.php b/plugins/Referrers/Reports/GetSocials.php
new file mode 100644
index 0000000000..046360fa51
--- /dev/null
+++ b/plugins/Referrers/Reports/GetSocials.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\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Pie;
+use Piwik\Plugins\Referrers\Columns\SocialNetwork;
+
+class GetSocials extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new SocialNetwork();
+ $this->name = Piwik::translate('Referrers_Socials');
+ $this->documentation = Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />');
+ $this->actionToLoadSubTables = 'getUrlsForSocial';
+ $this->order = 11;
+ $this->widgetTitle = 'Referrers_WidgetSocials';
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return Pie::ID;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_goals = true;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 10;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->disable_subtable_when_show_goals = true;
+ }
+
+ $widget = Common::getRequestVar('widget', false);
+ if (empty($widget)) {
+ $view->config->show_footer_message = Piwik::translate('Referrers_SocialFooterMessage');
+ }
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetUrlsForSocial.php b/plugins/Referrers/Reports/GetUrlsForSocial.php
new file mode 100644
index 0000000000..fbabf7af3a
--- /dev/null
+++ b/plugins/Referrers/Reports/GetUrlsForSocial.php
@@ -0,0 +1,36 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Referrers\Columns\WebsitePage;
+
+class GetUrlsForSocial extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new WebsitePage();
+ $this->name = Piwik::translate('Referrers_Socials');
+ $this->documentation = Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />');
+ $this->isSubtableReport = true;
+ $this->order = 12;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_goals = true;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 10;
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetUrlsFromWebsiteId.php b/plugins/Referrers/Reports/GetUrlsFromWebsiteId.php
new file mode 100644
index 0000000000..cbeb2ec68b
--- /dev/null
+++ b/plugins/Referrers/Reports/GetUrlsFromWebsiteId.php
@@ -0,0 +1,35 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\Referrers\Columns\WebsitePage;
+
+class GetUrlsFromWebsiteId extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new WebsitePage();
+ $this->name = Piwik::translate('CorePluginsAdmin_Websites');
+ $this->documentation = Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />');
+ $this->isSubtableReport = true;
+ $this->order = 6;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->tooltip_metadata_name = 'url';
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+}
diff --git a/plugins/Referrers/Reports/GetWebsites.php b/plugins/Referrers/Reports/GetWebsites.php
new file mode 100644
index 0000000000..ec9a4f401c
--- /dev/null
+++ b/plugins/Referrers/Reports/GetWebsites.php
@@ -0,0 +1,43 @@
+<?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\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\Referrers\Columns\Website;
+
+class GetWebsites extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Website();
+ $this->name = Piwik::translate('CorePluginsAdmin_Websites');
+ $this->documentation = Piwik::translate('Referrers_WebsitesReportDocumentation', '<br />');
+ $this->actionToLoadSubTables = 'getUrlsFromWebsiteId';
+ $this->hasGoalMetrics = true;
+ $this->order = 5;
+ $this->widgetTitle = 'Referrers_WidgetExternalWebsites';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_goals = true;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 25;
+
+ if ($view->isViewDataTableId(HtmlTable::ID)) {
+ $view->config->disable_subtable_when_show_goals = true;
+ }
+ }
+
+}
diff --git a/plugins/Referrers/Segment.php b/plugins/Referrers/Segment.php
new file mode 100644
index 0000000000..c51b4e8230
--- /dev/null
+++ b/plugins/Referrers/Segment.php
@@ -0,0 +1,21 @@
+<?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;
+
+/**
+ * Referrers segment base class.
+ *
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+ protected function init()
+ {
+ $this->setCategory('Referrers_Referrers');
+ }
+}
diff --git a/plugins/Referrers/Widgets.php b/plugins/Referrers/Widgets.php
index 41a36c5cf0..4e23c9f746 100644
--- a/plugins/Referrers/Widgets.php
+++ b/plugins/Referrers/Widgets.php
@@ -9,25 +9,15 @@
namespace Piwik\Plugins\Referrers;
use Piwik\SettingsPiwik;
-use Piwik\WidgetsList;
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'Referrers_Referrers';
- $controller = 'Referrers';
-
- $widgetsList->add($category, 'Referrers_WidgetKeywords', $controller, 'getKeywords');
- $widgetsList->add($category, 'Referrers_WidgetExternalWebsites', $controller, 'getWebsites');
- $widgetsList->add($category, 'Referrers_WidgetSocials', $controller, 'getSocials');
- $widgetsList->add($category, 'Referrers_SearchEngines', $controller, 'getSearchEngines');
- $widgetsList->add($category, 'Referrers_Campaigns', $controller, 'getCampaigns');
- $widgetsList->add($category, 'General_Overview', $controller, 'getReferrerType');
- $widgetsList->add($category, 'Referrers_WidgetGetAll', $controller, 'getAll');
+ protected $category = 'SEO';
+ public function init()
+ {
if (SettingsPiwik::isSegmentationEnabled()) {
- $widgetsList->add('SEO', 'Referrers_WidgetTopKeywordsForPages', $controller, 'getKeywordsForPage');
+ $this->addWidget('Referrers_WidgetTopKeywordsForPages', 'getKeywordsForPage');
}
}
diff --git a/plugins/SEO/Controller.php b/plugins/SEO/Controller.php
deleted file mode 100644
index d9a3f45731..0000000000
--- a/plugins/SEO/Controller.php
+++ /dev/null
@@ -1,47 +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
- *
- */
-namespace Piwik\Plugins\SEO;
-
-use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\Site;
-use Piwik\UrlHelper;
-use Piwik\View;
-
-/**
- */
-class Controller extends \Piwik\Plugin\Controller
-{
- function getRank()
- {
- $idSite = Common::getRequestVar('idSite');
- $site = new Site($idSite);
-
- $url = urldecode(Common::getRequestVar('url', '', 'string'));
-
- if (!empty($url) && strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) {
- $url = 'http://' . $url;
- }
-
- if (empty($url) || !UrlHelper::isLookLikeUrl($url)) {
- $url = $site->getMainUrl();
- }
-
- $dataTable = API::getInstance()->getRank($url);
-
- $view = new View('@SEO/getRank');
- $view->urlToRank = RankChecker::extractDomainFromUrl($url);
-
- /** @var \Piwik\DataTable\Renderer\Php $renderer */
- $renderer = Renderer::factory('php');
- $renderer->setSerialize(false);
- $view->ranks = $renderer->render($dataTable);
- return $view->render();
- }
-}
diff --git a/plugins/SEO/Widgets.php b/plugins/SEO/Widgets.php
index 969c918eb3..bf2e95e0a7 100644
--- a/plugins/SEO/Widgets.php
+++ b/plugins/SEO/Widgets.php
@@ -8,13 +8,47 @@
*/
namespace Piwik\Plugins\SEO;
-use Piwik\WidgetsList;
+use Piwik\Common;
+use Piwik\DataTable\Renderer;
+use Piwik\Site;
+use Piwik\UrlHelper;
+use Piwik\View;
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
+ protected $category = 'SEO';
+
+ public function init()
+ {
+ $this->addWidget('SEO_SeoRankings', 'getRank');
+ }
+
+ public function getRank()
{
- $widgetsList->add('SEO', 'SEO_SeoRankings', 'SEO', 'getRank');
+ $idSite = Common::getRequestVar('idSite');
+ $site = new Site($idSite);
+
+ $url = urldecode(Common::getRequestVar('url', '', 'string'));
+
+ if (!empty($url) && strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) {
+ $url = 'http://' . $url;
+ }
+
+ if (empty($url) || !UrlHelper::isLookLikeUrl($url)) {
+ $url = $site->getMainUrl();
+ }
+
+ $dataTable = API::getInstance()->getRank($url);
+
+ $view = new View('@SEO/getRank');
+ $view->urlToRank = RankChecker::extractDomainFromUrl($url);
+
+ /** @var \Piwik\DataTable\Renderer\Php $renderer */
+ $renderer = Renderer::factory('php');
+ $renderer->setSerialize(false);
+ $view->ranks = $renderer->render($dataTable);
+
+ return $view->render();
}
}
diff --git a/plugins/UserCountry/Columns/Base.php b/plugins/UserCountry/Columns/Base.php
new file mode 100644
index 0000000000..c3ee461183
--- /dev/null
+++ b/plugins/UserCountry/Columns/Base.php
@@ -0,0 +1,165 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
+use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
+use Piwik\IP;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Visit;
+use Piwik\Tracker\Request;
+
+abstract class Base extends VisitDimension
+{
+ private static $cachedLocations = array();
+
+ protected function getUrlOverrideValueIfAllowed($urlParamToOverride, Request $request)
+ {
+ if (!$request->isAuthenticated()) {
+ return false;
+ }
+
+ $value = Common::getRequestVar($urlParamToOverride, false, 'string', $request->getParams());
+ if (!empty($value)) {
+ return $value;
+ }
+
+ return false;
+ }
+
+ public function getRequiredVisitFields()
+ {
+ return array('location_ip', 'location_browser_lang');
+ }
+
+ protected function getLocationDetail($userInfo, $locationKey)
+ {
+ $location = $this->getCachedLocation($userInfo);
+
+ if (!empty($location[$locationKey])) {
+
+ return $location[$locationKey];
+ }
+
+ return false;
+ }
+
+ protected function getUserInfo(Request $request, Visitor $visitor)
+ {
+ $ipAddress = $this->getIpAddress($visitor->getVisitorColumn('location_ip'), $request);
+ $language = $visitor->getVisitorColumn('location_browser_lang');
+
+ $userInfo = array('lang' => $language, 'ip' => $ipAddress);
+
+ return $userInfo;
+ }
+
+ protected function getCachedLocation($userInfo)
+ {
+ require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php";
+
+ $key = md5(implode(',', $userInfo));
+
+ if (array_key_exists($key, self::$cachedLocations) && empty($GLOBALS['PIWIK_TRACKER_LOCAL_TRACKING'])) {
+ return self::$cachedLocations[$key];
+ }
+
+ $provider = $this->getProvider();
+ $location = $this->getLocation($provider, $userInfo);
+
+ if (empty($location)) {
+ $providerId = $provider->getId();
+ Common::printDebug("GEO: couldn't find a location with Geo Module '$providerId'");
+
+ if (!$this->isDefaultProvider($provider)) {
+ Common::printDebug("Using default provider as fallback...");
+ $provider = $this->getDefaultProvider();
+ $location = $this->getLocation($provider, $userInfo);
+ }
+ }
+
+ if (empty($location)) {
+ $location = array();
+ }
+
+ if (empty($location['country_code'])) { // sanity check
+ $location['country_code'] = Visit::UNKNOWN_CODE;
+ }
+
+ self::$cachedLocations[$key] = $location;
+
+ return $location;
+ }
+
+ private function getIpAddress($anonymizedIp, \Piwik\Tracker\Request $request)
+ {
+ $privacyConfig = new PrivacyManagerConfig();
+
+ $ip = $request->getIp();
+
+ if ($privacyConfig->useAnonymizedIpForVisitEnrichment) {
+ $ip = $anonymizedIp;
+ }
+
+ $ipAddress = IP::N2P($ip);
+
+ return $ipAddress;
+ }
+
+ /**
+ * @param \Piwik\Plugins\UserCountry\LocationProvider $provider
+ * @param array $userInfo
+ * @return array|null
+ */
+ private function getLocation($provider, $userInfo)
+ {
+ $location = $provider->getLocation($userInfo);
+ $providerId = $provider->getId();
+ $ipAddress = $userInfo['ip'];
+
+ if ($location === false) {
+ return false;
+ }
+
+ Common::printDebug("GEO: Found IP $ipAddress location (provider '" . $providerId . "'): " . var_export($location, true));
+
+ return $location;
+ }
+
+ private function getDefaultProvider()
+ {
+ $id = DefaultProvider::ID;
+ $provider = LocationProvider::getProviderById($id);
+
+ return $provider;
+ }
+
+ private function isDefaultProvider($provider)
+ {
+ return !empty($provider) && DefaultProvider::ID == $provider->getId();
+ }
+
+ private function getProvider()
+ {
+ $id = Common::getCurrentLocationProviderId();
+ $provider = LocationProvider::getProviderById($id);
+
+ if ($provider === false) {
+ $provider = $this->getDefaultProvider();
+ Common::printDebug("GEO: no current location provider sent, falling back to default '$id' one.");
+ }
+
+ return $provider;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Columns/City.php b/plugins/UserCountry/Columns/City.php
new file mode 100644
index 0000000000..3f97a0b7c8
--- /dev/null
+++ b/plugins/UserCountry/Columns/City.php
@@ -0,0 +1,77 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+use Piwik\Plugins\UserCountry\Segment;
+
+class City extends Base
+{
+ protected $columnName = 'location_city';
+ protected $columnType = 'varchar(255) DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('city');
+ $segment->setName('UserCountry_City');
+ $segment->setAcceptedValues('Sydney, Sao Paolo, Rome, etc.');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserCountry_City');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $value = $this->getUrlOverrideValueIfAllowed('city', $request);
+
+ if ($value !== false) {
+ return $value;
+ }
+
+ $userInfo = $this->getUserInfo($request, $visitor);
+
+ return $this->getLocationDetail($userInfo, LocationProvider::CITY_NAME_KEY);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getUrlOverrideValueIfAllowed('city', $request);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Columns/Continent.php b/plugins/UserCountry/Columns/Continent.php
new file mode 100644
index 0000000000..089215dcf1
--- /dev/null
+++ b/plugins/UserCountry/Columns/Continent.php
@@ -0,0 +1,20 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class Continent extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('UserCountry_Continent');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Columns/Country.php b/plugins/UserCountry/Columns/Country.php
new file mode 100644
index 0000000000..7ffea01d24
--- /dev/null
+++ b/plugins/UserCountry/Columns/Country.php
@@ -0,0 +1,141 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Common;
+use Piwik\Config;
+use Piwik\IP;
+use Piwik\Piwik;
+use Piwik\Plugins\Provider\Provider;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Plugins\UserCountry\Segment;
+use Piwik\Tracker\Visit;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+
+class Country extends Base
+{
+ protected $columnName = 'location_country';
+ protected $columnType = 'CHAR(3) NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('countryCode');
+ $segment->setName('UserCountry_Country');
+ $segment->setAcceptedValues('de, us, fr, in, es, etc.');
+ $this->addSegment($segment);
+
+ $segment = new Segment();
+ $segment->setSegment('continentCode');
+ $segment->setName('UserCountry_Continent');
+ $segment->setSqlFilter('Piwik\Plugins\UserCountry\UserCountry::getCountriesForContinent');
+ $segment->setAcceptedValues('eur, asi, amc, amn, ams, afr, ant, oce');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserCountry_Country');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $value = $this->getUrlOverrideValueIfAllowed('country', $request);
+
+ if ($value !== false) {
+ return $value;
+ }
+
+ $userInfo = $this->getUserInfo($request, $visitor);
+ $country = $this->getLocationDetail($userInfo, LocationProvider::COUNTRY_CODE_KEY);
+
+ if (!empty($country) && $country != Visit::UNKNOWN_CODE) {
+
+ return strtolower($country);
+ }
+
+ $country = $this->getCountryUsingProviderExtensionIfValid($userInfo['ip']);
+
+ if (!empty($country)) {
+ return $country;
+ }
+
+ return Visit::UNKNOWN_CODE;
+ }
+
+ private function getCountryUsingProviderExtensionIfValid($ipAddress)
+ {
+ $hostname = $this->getHost($ipAddress);
+ $hostnameExtension = Provider::getCleanHostname($hostname);
+
+ $hostnameDomain = substr($hostnameExtension, 1 + strrpos($hostnameExtension, '.'));
+ if ($hostnameDomain == 'uk') {
+ $hostnameDomain = 'gb';
+ }
+
+ if (array_key_exists($hostnameDomain, Common::getCountriesList())) {
+ return $hostnameDomain;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the hostname given the IP address string
+ *
+ * @param string $ip IP Address
+ * @return string hostname (or human-readable IP address)
+ */
+ private function getHost($ip)
+ {
+ return trim(strtolower(@IP::getHostByAddr($ip)));
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getUrlOverrideValueIfAllowed('country', $request);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ $country = $visitor->getVisitorColumn($this->columnName);
+
+ if (isset($country) && false !== $country) {
+ return $country;
+ }
+
+ $browserLanguage = $request->getBrowserLanguage();
+ $enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess'];
+ $locationIp = $visitor->getVisitorColumn('location_ip');
+
+ $country = Common::getCountry($browserLanguage, $enableLanguageToCountryGuess, $locationIp);
+
+ return $country;
+ }
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Columns/Latitude.php b/plugins/UserCountry/Columns/Latitude.php
new file mode 100644
index 0000000000..cce2b910e2
--- /dev/null
+++ b/plugins/UserCountry/Columns/Latitude.php
@@ -0,0 +1,77 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Plugins\UserCountry\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class Latitude extends Base
+{
+ protected $columnName = 'location_latitude';
+ protected $columnType = 'float(10, 6) DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('latitude');
+ $segment->setName('UserCountry_Latitude');
+ $segment->setAcceptedValues('-33.578, 40.830, etc.<br/>You can select visitors within a lat/long range using &segment=lat&gt;X;lat&lt;Y;long&gt;M;long&lt;N.');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserCountry_Latitude');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $value = $this->getUrlOverrideValueIfAllowed('lat', $request);
+
+ if ($value !== false) {
+ return $value;
+ }
+
+ $userInfo = $this->getUserInfo($request, $visitor);
+
+ return $this->getLocationDetail($userInfo, LocationProvider::LATITUDE_KEY);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getUrlOverrideValueIfAllowed('lat', $request);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Columns/Longitude.php b/plugins/UserCountry/Columns/Longitude.php
new file mode 100644
index 0000000000..ec63431f6f
--- /dev/null
+++ b/plugins/UserCountry/Columns/Longitude.php
@@ -0,0 +1,77 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Plugins\UserCountry\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class Longitude extends Base
+{
+ protected $columnName = 'location_longitude';
+ protected $columnType = 'float(10, 6) DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('longitude');
+ $segment->setName('UserCountry_Longitude');
+ $segment->setAcceptedValues('-70.664, 14.326, etc.');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserCountry_Latitude');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $value = $this->getUrlOverrideValueIfAllowed('long', $request);
+
+ if ($value !== false) {
+ return $value;
+ }
+
+ $userInfo = $this->getUserInfo($request, $visitor);
+
+ return $this->getLocationDetail($userInfo, LocationProvider::LONGITUDE_KEY);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getUrlOverrideValueIfAllowed('long', $request);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Columns/Provider.php b/plugins/UserCountry/Columns/Provider.php
new file mode 100644
index 0000000000..8bff751659
--- /dev/null
+++ b/plugins/UserCountry/Columns/Provider.php
@@ -0,0 +1,61 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Plugin\Manager;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+
+class Provider extends Base
+{
+ protected $columnName = 'location_provider';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ if (!Manager::getInstance()->isPluginInstalled('Provider')) {
+ return false;
+ }
+
+ $userInfo = $this->getUserInfo($request, $visitor);
+
+ $isp = $this->getLocationDetail($userInfo, LocationProvider::ISP_KEY);
+ $org = $this->getLocationDetail($userInfo, LocationProvider::ORG_KEY);
+
+ // if the location has provider/organization info, set it
+ if (!empty($isp)) {
+ $providerValue = $isp;
+
+ // if the org is set and not the same as the isp, add it to the provider value
+ if (!empty($org) && $org != $providerValue) {
+ $providerValue .= ' - ' . $org;
+ }
+
+ return $providerValue;
+ }
+
+ if (!empty($org)) {
+ return $org;
+ }
+
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Columns/Region.php b/plugins/UserCountry/Columns/Region.php
new file mode 100644
index 0000000000..78dacb4974
--- /dev/null
+++ b/plugins/UserCountry/Columns/Region.php
@@ -0,0 +1,77 @@
+<?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\UserCountry\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Plugins\UserCountry\Segment;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class Region extends Base
+{
+ protected $columnName = 'location_region';
+ protected $columnType = 'char(2) DEFAULT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('regionCode');
+ $segment->setName('UserCountry_Region');
+ $segment->setAcceptedValues('01 02, OR, P8, etc.<br/>eg. region=A1;country=fr');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserCountry_Region');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $value = $this->getUrlOverrideValueIfAllowed('region', $request);
+
+ if ($value !== false) {
+ return $value;
+ }
+
+ $userInfo = $this->getUserInfo($request, $visitor);
+
+ return $this->getLocationDetail($userInfo, LocationProvider::REGION_CODE_KEY);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return int
+ */
+ public function onExistingVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $this->getUrlOverrideValueIfAllowed('region', $request);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
+ {
+ return $visitor->getVisitorColumn($this->columnName);
+ }
+} \ No newline at end of file
diff --git a/plugins/UserCountry/Controller.php b/plugins/UserCountry/Controller.php
index fc0975cba8..483b2d844f 100644
--- a/plugins/UserCountry/Controller.php
+++ b/plugins/UserCountry/Controller.php
@@ -19,6 +19,10 @@ use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\Pecl;
+use Piwik\Plugins\UserCountry\Reports\GetCity;
+use Piwik\Plugins\UserCountry\Reports\GetContinent;
+use Piwik\Plugins\UserCountry\Reports\GetCountry;
+use Piwik\Plugins\UserCountry\Reports\GetRegion;
use Piwik\View;
/**
@@ -33,10 +37,10 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$view->urlSparklineCountries = $this->getUrlSparkline('getLastDistinctCountriesGraph');
$view->numberDistinctCountries = $this->getNumberOfDistinctCountries(true);
- $view->dataTableCountry = $this->getCountry(true);
- $view->dataTableContinent = $this->getContinent(true);
- $view->dataTableRegion = $this->getRegion(true);
- $view->dataTableCity = $this->getCity(true);
+ $view->dataTableCountry = $this->renderReport(new GetCountry());
+ $view->dataTableContinent = $this->renderReport(new GetContinent());
+ $view->dataTableRegion = $this->renderReport(new GetRegion());
+ $view->dataTableCity = $this->renderReport(new GetCity());
return $view->render();
}
@@ -328,36 +332,6 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
return $location;
}
- public function getCountry()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getContinent()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Echo's or returns an HTML view of the visits by region report.
- *
- * @return string
- */
- public function getRegion()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Echo's or returns an HTML view of the visits by city report.
- *
- * @return string
- */
- public function getCity()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
public function getNumberOfDistinctCountries()
{
return $this->getNumericValue('UserCountry.getNumberOfDistinctCountries');
diff --git a/plugins/UserCountry/LocationProvider.php b/plugins/UserCountry/LocationProvider.php
index 141368c075..d0ffd93f51 100755
--- a/plugins/UserCountry/LocationProvider.php
+++ b/plugins/UserCountry/LocationProvider.php
@@ -307,14 +307,21 @@ abstract class LocationProvider
public static function getProviderById($providerId)
{
foreach (self::getAvailableProviders() as $provider) {
- $info = $provider->getInfo();
- if ($info['id'] == $providerId) {
+ if ($provider->getId() == $providerId) {
return $provider;
}
}
+
return false;
}
+ public function getId()
+ {
+ $info = $this->getInfo();
+
+ return $info['id'];
+ }
+
/**
* Tries to fill in any missing information in a location result.
*
diff --git a/plugins/UserCountry/Reports/Base.php b/plugins/UserCountry/Reports/Base.php
new file mode 100644
index 0000000000..9e62b0a6b6
--- /dev/null
+++ b/plugins/UserCountry/Reports/Base.php
@@ -0,0 +1,64 @@
+<?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\UserCountry\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserCountry\UserCountry;
+use Piwik\Url;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'General_Visitors';
+ }
+
+ protected function getGeoIPReportDocSuffix()
+ {
+ return Piwik::translate('UserCountry_GeoIPDocumentationSuffix',
+ array('<a target="_blank" href="http://www.maxmind.com/?rId=piwik">',
+ '</a>',
+ '<a target="_blank" href="http://www.maxmind.com/en/city_accuracy?rId=piwik">',
+ '</a>')
+ );
+ }
+
+ /**
+ * Checks if a datatable for a view is empty and if so, displays a message in the footer
+ * telling users to configure GeoIP.
+ */
+ protected function checkIfNoDataForGeoIpReport(ViewDataTable $view)
+ {
+ $view->config->filters[] = function ($dataTable) use ($view) {
+ // if there's only one row whose label is 'Unknown', display a message saying there's no data
+ if ($dataTable->getRowsCount() == 1
+ && $dataTable->getFirstRow()->getColumn('label') == Piwik::translate('General_Unknown')
+ ) {
+ $footerMessage = Piwik::translate('UserCountry_NoDataForGeoIPReport1');
+
+ $userCountry = new UserCountry();
+ // if GeoIP is working, don't display this part of the message
+ if (!$userCountry->isGeoIPWorking()) {
+ $params = array('module' => 'UserCountry', 'action' => 'adminIndex');
+ $footerMessage .= ' ' . Piwik::translate('UserCountry_NoDataForGeoIPReport2',
+ array('<a target="_blank" href="' . Url::getCurrentQueryStringWithParametersModified($params) . '">',
+ '</a>',
+ '<a target="_blank" href="http://dev.maxmind.com/geoip/geolite?rId=piwik">',
+ '</a>'));
+ } else {
+ $footerMessage .= ' ' . Piwik::translate('UserCountry_ToGeolocateOldVisits',
+ array('<a target="_blank" href="http://piwik.org/faq/how-to/#faq_167">', '</a>'));
+ }
+
+ $view->config->show_footer_message = $footerMessage;
+ }
+ };
+ }
+}
diff --git a/plugins/UserCountry/Reports/GetCity.php b/plugins/UserCountry/Reports/GetCity.php
new file mode 100644
index 0000000000..c338c00e37
--- /dev/null
+++ b/plugins/UserCountry/Reports/GetCity.php
@@ -0,0 +1,42 @@
+<?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\UserCountry\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserCountry\Columns\City;
+
+class GetCity extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new City();
+ $this->name = Piwik::translate('UserCountry_City');
+ $this->documentation = Piwik::translate('UserCountry_getCityDocumentation') . '<br/>' . $this->getGeoIPReportDocSuffix();
+ $this->metrics = array('nb_visits', 'nb_uniq_visitors', 'nb_actions');
+ $this->hasGoalMetrics = true;
+ $this->order = 8;
+ $this->widgetTitle = Piwik::translate('UserCountry_WidgetLocation')
+ . ' (' . Piwik::translate('UserCountry_City') . ')';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_goals = true;
+ $view->config->documentation = $this->documentation;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 5;
+
+ $this->checkIfNoDataForGeoIpReport($view);
+ }
+
+}
diff --git a/plugins/UserCountry/Reports/GetContinent.php b/plugins/UserCountry/Reports/GetContinent.php
new file mode 100644
index 0000000000..28ead2c3f4
--- /dev/null
+++ b/plugins/UserCountry/Reports/GetContinent.php
@@ -0,0 +1,42 @@
+<?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\UserCountry\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserCountry\Columns\Continent;
+
+class GetContinent extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Continent();
+ $this->name = Piwik::translate('UserCountry_Continent');
+ $this->documentation = Piwik::translate('UserCountry_getContinentDocumentation');
+ $this->metrics = array('nb_visits', 'nb_uniq_visitors', 'nb_actions');
+ $this->hasGoalMetrics = true;
+ $this->order = 6;
+ $this->widgetTitle = Piwik::translate('UserCountry_WidgetLocation')
+ . ' (' . Piwik::translate('UserCountry_Continent') . ')';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_goals = true;
+ $view->config->show_search = false;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->documentation = $this->documentation;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+}
diff --git a/plugins/UserCountry/Reports/GetCountry.php b/plugins/UserCountry/Reports/GetCountry.php
new file mode 100644
index 0000000000..ba9b2c63c6
--- /dev/null
+++ b/plugins/UserCountry/Reports/GetCountry.php
@@ -0,0 +1,50 @@
+<?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\UserCountry\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserCountry\Columns\Country;
+use Piwik\Plugins\UserCountry\LocationProvider;
+
+class GetCountry extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Country();
+ $this->name = Piwik::translate('UserCountry_Country');
+ $this->documentation = Piwik::translate('UserCountry_getCountryDocumentation');
+ $this->metrics = array('nb_visits', 'nb_uniq_visitors', 'nb_actions');
+ $this->hasGoalMetrics = true;
+ $this->order = 5;
+ $this->widgetTitle = Piwik::translate('UserCountry_WidgetLocation')
+ . ' (' . Piwik::translate('UserCountry_Country') . ')';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_goals = true;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ $view->config->documentation = $this->documentation;
+
+ $view->requestConfig->filter_limit = 5;
+
+ if (LocationProvider::getCurrentProviderId() == LocationProvider\DefaultProvider::ID) {
+ // if we're using the default location provider, add a note explaining how it works
+ $footerMessage = Piwik::translate("General_Note") . ': '
+ . Piwik::translate('UserCountry_DefaultLocationProviderExplanation',
+ array('<a target="_blank" href="http://piwik.org/docs/geo-locate/">', '</a>'));
+
+ $view->config->show_footer_message = $footerMessage;
+ }
+ }
+
+}
diff --git a/plugins/UserCountry/Reports/GetRegion.php b/plugins/UserCountry/Reports/GetRegion.php
new file mode 100644
index 0000000000..0ec13cb92c
--- /dev/null
+++ b/plugins/UserCountry/Reports/GetRegion.php
@@ -0,0 +1,42 @@
+<?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\UserCountry\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserCountry\Columns\Region;
+
+class GetRegion extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Region();
+ $this->name = Piwik::translate('UserCountry_Region');
+ $this->documentation = Piwik::translate('UserCountry_getRegionDocumentation') . '<br/>' . $this->getGeoIPReportDocSuffix();
+ $this->metrics = array('nb_visits', 'nb_uniq_visitors', 'nb_actions');
+ $this->hasGoalMetrics = true;
+ $this->order = 7;
+ $this->widgetTitle = Piwik::translate('UserCountry_WidgetLocation')
+ . ' (' . Piwik::translate('UserCountry_Region') . ')';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_goals = true;
+ $view->config->documentation = $this->documentation;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 5;
+
+ $this->checkIfNoDataForGeoIpReport($view);
+ }
+
+}
diff --git a/plugins/UserCountry/Segment.php b/plugins/UserCountry/Segment.php
new file mode 100644
index 0000000000..2bae6f2f28
--- /dev/null
+++ b/plugins/UserCountry/Segment.php
@@ -0,0 +1,21 @@
+<?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\UserCountry;
+
+/**
+ * UserCountry segment base class.
+ *
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+ protected function init()
+ {
+ $this->setCategory('Visit Location');
+ }
+}
diff --git a/plugins/UserCountry/UserCountry.php b/plugins/UserCountry/UserCountry.php
index 95e6f389ac..23d4c4c3e3 100644
--- a/plugins/UserCountry/UserCountry.php
+++ b/plugins/UserCountry/UserCountry.php
@@ -11,14 +11,9 @@ namespace Piwik\Plugins\UserCountry;
use Piwik\ArchiveProcessor;
use Piwik\Common;
use Piwik\Config;
-use Piwik\IP;
use Piwik\Piwik;
-use Piwik\Plugin\Manager;
-use Piwik\Plugin\ViewDataTable;
-use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider;
-use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
use Piwik\Url;
/**
@@ -36,19 +31,13 @@ class UserCountry extends \Piwik\Plugin
*/
public function getListHooksRegistered()
{
- $hooks = array(
- 'Goals.getReportsWithGoalMetrics' => 'getReportsWithGoalMetrics',
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
+ return array(
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
- 'Tracker.newVisitorInformation' => 'enrichVisitWithLocation',
- 'ViewDataTable.configure' => 'configureViewDataTable',
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
'Tracker.setTrackerCacheGeneral' => 'setTrackerCacheGeneral',
'Insights.addReportToOverview' => 'addReportToInsightsOverview'
);
- return $hooks;
}
public function addReportToInsightsOverview(&$reports)
@@ -71,223 +60,6 @@ class UserCountry extends \Piwik\Plugin
$jsFiles[] = "plugins/UserCountry/javascripts/userCountry.js";
}
- public function enrichVisitWithLocation(&$visitorInfo, \Piwik\Tracker\Request $request)
- {
- require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php";
-
- $privacyConfig = new PrivacyManagerConfig();
-
- $ipAddress = IP::N2P($privacyConfig->useAnonymizedIpForVisitEnrichment ? $visitorInfo['location_ip'] : $request->getIp());
- $userInfo = array(
- 'lang' => $visitorInfo['location_browser_lang'],
- 'ip' => $ipAddress
- );
-
- $id = Common::getCurrentLocationProviderId();
- $provider = LocationProvider::getProviderById($id);
- if ($provider === false) {
- $id = DefaultProvider::ID;
- $provider = LocationProvider::getProviderById($id);
- Common::printDebug("GEO: no current location provider sent, falling back to default '$id' one.");
- }
-
- $location = $provider->getLocation($userInfo);
-
- // if we can't find a location, use default provider
- if ($location === false) {
- $defaultId = DefaultProvider::ID;
- $provider = LocationProvider::getProviderById($defaultId);
- $location = $provider->getLocation($userInfo);
- Common::printDebug("GEO: couldn't find a location with Geo Module '$id', using Default '$defaultId' provider as fallback...");
- $id = $defaultId;
- }
- Common::printDebug("GEO: Found IP $ipAddress location (provider '" . $id . "'): " . var_export($location, true));
-
- if (empty($location['country_code'])) { // sanity check
- $location['country_code'] = \Piwik\Tracker\Visit::UNKNOWN_CODE;
- }
-
- // add optional location components
- $this->updateVisitInfoWithLocation($visitorInfo, $location);
- }
-
- /**
- * Sets visitor info array with location info.
- *
- * @param array $visitorInfo
- * @param array $location See LocationProvider::getLocation for more info.
- */
- private function updateVisitInfoWithLocation(&$visitorInfo, $location)
- {
- static $logVisitToLowerLocationMapping = array(
- 'location_country' => LocationProvider::COUNTRY_CODE_KEY,
- );
-
- static $logVisitToLocationMapping = array(
- 'location_region' => LocationProvider::REGION_CODE_KEY,
- 'location_city' => LocationProvider::CITY_NAME_KEY,
- 'location_latitude' => LocationProvider::LATITUDE_KEY,
- 'location_longitude' => LocationProvider::LONGITUDE_KEY,
- );
-
- foreach ($logVisitToLowerLocationMapping as $column => $locationKey) {
- if (!empty($location[$locationKey])) {
- $visitorInfo[$column] = strtolower($location[$locationKey]);
- }
- }
-
- foreach ($logVisitToLocationMapping as $column => $locationKey) {
- if (!empty($location[$locationKey])) {
- $visitorInfo[$column] = $location[$locationKey];
- }
- }
-
- // if the location has provider/organization info, set it
- if (!empty($location[LocationProvider::ISP_KEY])) {
- $providerValue = $location[LocationProvider::ISP_KEY];
-
- // if the org is set and not the same as the isp, add it to the provider value
- if (!empty($location[LocationProvider::ORG_KEY])
- && $location[LocationProvider::ORG_KEY] != $providerValue
- ) {
- $providerValue .= ' - ' . $location[LocationProvider::ORG_KEY];
- }
- } else if (!empty($location[LocationProvider::ORG_KEY])) {
- $providerValue = $location[LocationProvider::ORG_KEY];
- }
-
- if (isset($providerValue)
- && Manager::getInstance()->isPluginInstalled('Provider')) {
- $visitorInfo['location_provider'] = $providerValue;
- }
- }
-
- public function getSegmentsMetadata(&$segments)
- {
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Visit Location',
- 'name' => Piwik::translate('UserCountry_Country'),
- 'segment' => 'countryCode',
- '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' => 'continentCode',
- 'sqlSegment' => 'log_visit.location_country',
- 'acceptedValues' => 'eur, asi, amc, amn, ams, afr, ant, oce',
- 'sqlFilter' => __NAMESPACE__ . '\UserCountry::getCountriesForContinent',
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Visit Location',
- 'name' => Piwik::translate('UserCountry_Region'),
- 'segment' => 'regionCode',
- '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' => 'latitude',
- 'sqlSegment' => 'log_visit.location_latitude',
- 'acceptedValues' => '-33.578, 40.830, etc.<br/>You can select visitors within a lat/long range using &segment=lat&gt;X;lat&lt;Y;long&gt;M;long&lt;N.',
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => 'Visit Location',
- 'name' => Piwik::translate('UserCountry_Longitude'),
- 'segment' => 'longitude',
- 'sqlSegment' => 'log_visit.location_longitude',
- 'acceptedValues' => '-70.664, 14.326, etc.',
- );
- }
-
- public function getReportMetadata(&$reports)
- {
- $metrics = array(
- 'nb_visits' => Piwik::translate('General_ColumnNbVisits'),
- 'nb_uniq_visitors' => Piwik::translate('General_ColumnNbUniqVisitors'),
- 'nb_actions' => Piwik::translate('General_ColumnNbActions'),
- );
-
- $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,
- );
- }
-
- public function getReportsWithGoalMetrics(&$dimensions)
- {
- $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'),
- ));
- }
-
/**
* Returns a list of country codes for a given continent code.
*
@@ -307,121 +79,6 @@ class UserCountry extends \Piwik\Plugin
'bind' => '-'); // HACK: SegmentExpression requires a $bind, even if there's nothing to bind
}
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'UserCountry.getCountry':
- $this->configureViewForGetCountry($view);
- break;
- case 'UserCountry.getContinent':
- $this->configureViewForGetContinent($view);
- break;
- case 'UserCountry.getRegion':
- $this->configureViewForGetRegion($view);
- break;
- case 'UserCountry.getCity':
- $this->configureViewForGetCity($view);
- break;
- }
- }
-
- private function configureViewForGetCountry(ViewDataTable $view)
- {
- $view->config->show_goals = true;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('UserCountry_Country'));
- $view->config->documentation = Piwik::translate('UserCountry_getCountryDocumentation');
-
- $view->requestConfig->filter_limit = 5;
-
- if (LocationProvider::getCurrentProviderId() == DefaultProvider::ID) {
- // if we're using the default location provider, add a note explaining how it works
- $footerMessage = Piwik::translate("General_Note") . ': '
- . Piwik::translate('UserCountry_DefaultLocationProviderExplanation',
- array('<a target="_blank" href="http://piwik.org/docs/geo-locate/">', '</a>'));
-
- $view->config->show_footer_message = $footerMessage;
- }
- }
-
- private function configureViewForGetContinent(ViewDataTable $view)
- {
- $view->config->show_exclude_low_population = false;
- $view->config->show_goals = true;
- $view->config->show_search = false;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->documentation = Piwik::translate('UserCountry_getContinentDocumentation');
- $view->config->addTranslation('label', Piwik::translate('UserCountry_Continent'));
- }
-
- private function configureViewForGetRegion(ViewDataTable $view)
- {
- $view->config->show_exclude_low_population = false;
- $view->config->show_goals = true;
- $view->config->documentation = Piwik::translate('UserCountry_getRegionDocumentation') . '<br/>' . $this->getGeoIPReportDocSuffix();
- $view->config->addTranslation('label', Piwik::translate('UserCountry_Region'));
-
- $view->requestConfig->filter_limit = 5;
-
- $this->checkIfNoDataForGeoIpReport($view);
- }
-
- private function configureViewForGetCity(ViewDataTable $view)
- {
- $view->config->show_exclude_low_population = false;
- $view->config->show_goals = true;
- $view->config->documentation = Piwik::translate('UserCountry_getCityDocumentation') . '<br/>' . $this->getGeoIPReportDocSuffix();
- $view->config->addTranslation('label', Piwik::translate('UserCountry_City'));
-
- $view->requestConfig->filter_limit = 5;
-
- $this->checkIfNoDataForGeoIpReport($view);
- }
-
- private function getGeoIPReportDocSuffix()
- {
- return Piwik::translate('UserCountry_GeoIPDocumentationSuffix',
- array('<a target="_blank" href="http://www.maxmind.com/?rId=piwik">',
- '</a>',
- '<a target="_blank" href="http://www.maxmind.com/en/city_accuracy?rId=piwik">',
- '</a>')
- );
- }
-
- /**
- * Checks if a datatable for a view is empty and if so, displays a message in the footer
- * telling users to configure GeoIP.
- */
- private function checkIfNoDataForGeoIpReport(ViewDataTable $view)
- {
- $self = $this;
- $view->config->filters[] = function ($dataTable) use ($self, $view) {
- // if there's only one row whose label is 'Unknown', display a message saying there's no data
- if ($dataTable->getRowsCount() == 1
- && $dataTable->getFirstRow()->getColumn('label') == Piwik::translate('General_Unknown')
- ) {
- $footerMessage = Piwik::translate('UserCountry_NoDataForGeoIPReport1');
-
- // if GeoIP is working, don't display this part of the message
- if (!$self->isGeoIPWorking()) {
- $params = array('module' => 'UserCountry', 'action' => 'adminIndex');
- $footerMessage .= ' ' . Piwik::translate('UserCountry_NoDataForGeoIPReport2',
- array('<a target="_blank" href="' . Url::getCurrentQueryStringWithParametersModified($params) . '">',
- '</a>',
- '<a target="_blank" href="http://dev.maxmind.com/geoip/geolite?rId=piwik">',
- '</a>'));
- } else {
- $footerMessage .= ' ' . Piwik::translate('UserCountry_ToGeolocateOldVisits',
- array('<a target="_blank" href="http://piwik.org/faq/how-to/#faq_167">', '</a>'));
- }
-
- $view->config->show_footer_message = $footerMessage;
- }
- };
- }
-
/**
* Returns true if a GeoIP provider is installed & working, false if otherwise.
*
diff --git a/plugins/UserCountry/Widgets.php b/plugins/UserCountry/Widgets.php
deleted file mode 100644
index 50913e86b5..0000000000
--- a/plugins/UserCountry/Widgets.php
+++ /dev/null
@@ -1,36 +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
- *
- */
-namespace Piwik\Plugins\UserCountry;
-
-use Piwik\WidgetsList;
-use Piwik\Piwik;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- $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') . ')';
-
- $category = 'General_Visitors';
- $controller = 'UserCountry';
-
- WidgetsList::add($category, $widgetContinentLabel, $controller, 'getContinent');
- WidgetsList::add($category, $widgetCountryLabel, $controller, 'getCountry');
- WidgetsList::add($category, $widgetRegionLabel, $controller, 'getRegion');
- WidgetsList::add($category, $widgetCityLabel, $controller, 'getCity');
- }
-
-}
diff --git a/plugins/UserSettings/Columns/Browser.php b/plugins/UserSettings/Columns/Browser.php
new file mode 100644
index 0000000000..edb9b6f150
--- /dev/null
+++ b/plugins/UserSettings/Columns/Browser.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\UserSettings\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\DevicesDetection\Columns\BrowserName;
+use Piwik\Plugins\UserSettings\Segment;
+
+class Browser extends BrowserName
+{
+ protected $columnName = 'config_browser_name';
+ protected $columnType = 'VARCHAR(10) NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('browserCode');
+ $segment->setName('UserSettings_ColumnBrowser');
+ $segment->setAcceptedValues('FF, IE, CH, SF, OP, etc.');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_ColumnBrowser');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/BrowserFamily.php b/plugins/UserSettings/Columns/BrowserFamily.php
new file mode 100644
index 0000000000..1de0c4be8d
--- /dev/null
+++ b/plugins/UserSettings/Columns/BrowserFamily.php
@@ -0,0 +1,20 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class BrowserFamily extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_ColumnBrowserFamily');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/BrowserVersion.php b/plugins/UserSettings/Columns/BrowserVersion.php
new file mode 100644
index 0000000000..29c753ba60
--- /dev/null
+++ b/plugins/UserSettings/Columns/BrowserVersion.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\UserSettings\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\UserSettings\Segment;
+
+class BrowserVersion extends \Piwik\Plugins\DevicesDetection\Columns\BrowserVersion
+{
+ protected $columnName = 'config_browser_version';
+ protected $columnType = 'VARCHAR(20) NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('browserVersion');
+ $segment->setName('UserSettings_ColumnBrowserVersion');
+ $segment->setAcceptedValues('1.0, 8.0, etc.');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_ColumnBrowserVersion');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/Configuration.php b/plugins/UserSettings/Columns/Configuration.php
new file mode 100644
index 0000000000..c0b636d4cd
--- /dev/null
+++ b/plugins/UserSettings/Columns/Configuration.php
@@ -0,0 +1,20 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class Configuration extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_ColumnConfiguration');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/Language.php b/plugins/UserSettings/Columns/Language.php
new file mode 100644
index 0000000000..9c0bcadfd3
--- /dev/null
+++ b/plugins/UserSettings/Columns/Language.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class Language extends VisitDimension
+{
+ protected $columnName = 'location_browser_lang';
+ protected $columnType = 'VARCHAR(20) NOT NULL';
+
+ public function getName()
+ {
+ return Piwik::translate('General_Language');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return substr($request->getBrowserLanguage(), 0, 20);
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/MobilevsDesktop.php b/plugins/UserSettings/Columns/MobilevsDesktop.php
new file mode 100644
index 0000000000..98a0ad9799
--- /dev/null
+++ b/plugins/UserSettings/Columns/MobilevsDesktop.php
@@ -0,0 +1,20 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class MobilevsDesktop extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_MobileVsDesktop');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/Operatingsystem.php b/plugins/UserSettings/Columns/Operatingsystem.php
new file mode 100644
index 0000000000..0476fdf114
--- /dev/null
+++ b/plugins/UserSettings/Columns/Operatingsystem.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\UserSettings\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugins\DevicesDetection\Columns\Os;
+use Piwik\Plugins\UserSettings\Segment;
+
+class Operatingsystem extends Os
+{
+ protected $columnName = 'config_os';
+ protected $columnType = 'CHAR(3) NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('operatingSystemCode');
+ $segment->setName('UserSettings_ColumnOperatingSystem');
+ $segment->setAcceptedValues('WXP, WI7, MAC, LIN, AND, IPD, etc.');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_ColumnOperatingSystem');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/OperatingsystemFamily.php b/plugins/UserSettings/Columns/OperatingsystemFamily.php
new file mode 100644
index 0000000000..cdec387d19
--- /dev/null
+++ b/plugins/UserSettings/Columns/OperatingsystemFamily.php
@@ -0,0 +1,20 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class OperatingsystemFamily extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_OperatingSystemFamily');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/Plugin.php b/plugins/UserSettings/Columns/Plugin.php
new file mode 100644
index 0000000000..dd047f9479
--- /dev/null
+++ b/plugins/UserSettings/Columns/Plugin.php
@@ -0,0 +1,20 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class Plugin extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('General_Plugin');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginCookie.php b/plugins/UserSettings/Columns/PluginCookie.php
new file mode 100644
index 0000000000..427823c64b
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginCookie.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginCookie extends VisitDimension
+{
+ protected $columnName = 'config_cookie';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('cookie', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginDirector.php b/plugins/UserSettings/Columns/PluginDirector.php
new file mode 100644
index 0000000000..aab518109a
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginDirector.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginDirector extends VisitDimension
+{
+ protected $columnName = 'config_director';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('dir', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginFlash.php b/plugins/UserSettings/Columns/PluginFlash.php
new file mode 100644
index 0000000000..aa0a9e8c65
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginFlash.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginFlash extends VisitDimension
+{
+ protected $columnName = 'config_flash';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('fla', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginGears.php b/plugins/UserSettings/Columns/PluginGears.php
new file mode 100644
index 0000000000..9fc17e6307
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginGears.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginGears extends VisitDimension
+{
+ protected $columnName = 'config_gears';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('gears', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginJava.php b/plugins/UserSettings/Columns/PluginJava.php
new file mode 100644
index 0000000000..28542fa114
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginJava.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginJava extends VisitDimension
+{
+ protected $columnName = 'config_java';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('java', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginPdf.php b/plugins/UserSettings/Columns/PluginPdf.php
new file mode 100644
index 0000000000..3af3d159f0
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginPdf.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginPdf extends VisitDimension
+{
+ protected $columnName = 'config_pdf';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('pdf', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginQuickTime.php b/plugins/UserSettings/Columns/PluginQuickTime.php
new file mode 100644
index 0000000000..e55adabff4
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginQuickTime.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginQuickTime extends VisitDimension
+{
+ protected $columnName = 'config_quicktime';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('qt', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginRealPlayer.php b/plugins/UserSettings/Columns/PluginRealPlayer.php
new file mode 100644
index 0000000000..670ed70d35
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginRealPlayer.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginRealPlayer extends VisitDimension
+{
+ protected $columnName = 'config_realplayer';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('realp', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginSilverlight.php b/plugins/UserSettings/Columns/PluginSilverlight.php
new file mode 100644
index 0000000000..cc38b9aab9
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginSilverlight.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginSilverlight extends VisitDimension
+{
+ protected $columnName = 'config_silverlight';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('ag', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/PluginWindowsMedia.php b/plugins/UserSettings/Columns/PluginWindowsMedia.php
new file mode 100644
index 0000000000..b7826d123f
--- /dev/null
+++ b/plugins/UserSettings/Columns/PluginWindowsMedia.php
@@ -0,0 +1,37 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Common;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+use Piwik\Tracker\Action;
+
+class PluginWindowsMedia extends VisitDimension
+{
+ protected $columnName = 'config_windowsmedia';
+ protected $columnType = 'TINYINT(1) NOT NULL';
+
+ public function getName()
+ {
+ return '';
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return Common::getRequestVar('wma', 0, 'int', $request->getParams());
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/Resolution.php b/plugins/UserSettings/Columns/Resolution.php
new file mode 100644
index 0000000000..511c946186
--- /dev/null
+++ b/plugins/UserSettings/Columns/Resolution.php
@@ -0,0 +1,53 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\UserSettings\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class Resolution extends VisitDimension
+{
+ protected $columnName = 'config_resolution';
+ protected $columnType = 'VARCHAR(9) NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('resolution');
+ $segment->setName('UserSettings_ColumnResolution');
+ $segment->setAcceptedValues('1280x1024, 800x600, etc.');
+ $this->addSegment($segment);
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ $resolution = $request->getParam('res');
+
+ if (!empty($resolution)) {
+ return substr($resolution, 0, 9);
+ }
+
+ return $resolution;
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_ColumnResolution');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Columns/TypeOfScreen.php b/plugins/UserSettings/Columns/TypeOfScreen.php
new file mode 100644
index 0000000000..640eb35ea4
--- /dev/null
+++ b/plugins/UserSettings/Columns/TypeOfScreen.php
@@ -0,0 +1,20 @@
+<?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\UserSettings\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class TypeOfScreen extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('UserSettings_ColumnTypeOfScreen');
+ }
+} \ No newline at end of file
diff --git a/plugins/UserSettings/Controller.php b/plugins/UserSettings/Controller.php
index c2cf619b11..4f0e944672 100644
--- a/plugins/UserSettings/Controller.php
+++ b/plugins/UserSettings/Controller.php
@@ -8,6 +8,14 @@
*/
namespace Piwik\Plugins\UserSettings;
+use Piwik\Plugins\UserSettings\Reports\GetBrowser;
+use Piwik\Plugins\UserSettings\Reports\GetBrowserType;
+use Piwik\Plugins\UserSettings\Reports\GetConfiguration;
+use Piwik\Plugins\UserSettings\Reports\GetLanguage;
+use Piwik\Plugins\UserSettings\Reports\GetMobileVsDesktop;
+use Piwik\Plugins\UserSettings\Reports\GetOS;
+use Piwik\Plugins\UserSettings\Reports\GetPlugin;
+use Piwik\Plugins\UserSettings\Reports\GetResolution;
use Piwik\View;
/**
@@ -19,70 +27,15 @@ class Controller extends \Piwik\Plugin\Controller
{
$view = new View('@UserSettings/index');
- $view->dataTablePlugin = $this->getPlugin(true);
- $view->dataTableResolution = $this->getResolution(true);
- $view->dataTableConfiguration = $this->getConfiguration(true);
- $view->dataTableOS = $this->getOS(true);
- $view->dataTableBrowser = $this->getBrowser(true);
- $view->dataTableBrowserType = $this->getBrowserType(true);
- $view->dataTableMobileVsDesktop = $this->getMobileVsDesktop(true);
- $view->dataTableBrowserLanguage = $this->getLanguage(true);
+ $view->dataTablePlugin = $this->renderReport(new GetPlugin());
+ $view->dataTableResolution = $this->renderReport(new GetResolution());
+ $view->dataTableConfiguration = $this->renderReport(new GetConfiguration());
+ $view->dataTableOS = $this->renderReport(new GetOS());
+ $view->dataTableBrowser = $this->renderReport(new GetBrowser());
+ $view->dataTableBrowserType = $this->renderReport(new GetBrowserType());
+ $view->dataTableMobileVsDesktop = $this->renderReport(new GetMobileVsDesktop());
+ $view->dataTableBrowserLanguage = $this->renderReport(new GetLanguage());
return $view->render();
}
-
- public function getResolution()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getConfiguration()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getOS()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getOSFamily()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getMobileVsDesktop()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getBrowserVersion()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getBrowser()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getBrowserType()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getWideScreen()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getPlugin()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getLanguage()
- {
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/UserSettings/Reports/Base.php b/plugins/UserSettings/Reports/Base.php
new file mode 100644
index 0000000000..e802c9a3f1
--- /dev/null
+++ b/plugins/UserSettings/Reports/Base.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\UserSettings\Reports;
+
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'UserSettings_VisitorSettings';
+ }
+
+ protected function getBasicUserSettingsDisplayProperties(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->show_exclude_low_population = false;
+
+ $view->requestConfig->filter_limit = 5;
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->max_graph_elements = 5;
+ }
+ }
+}
diff --git a/plugins/UserSettings/Reports/GetBrowser.php b/plugins/UserSettings/Reports/GetBrowser.php
new file mode 100644
index 0000000000..47f262d2ef
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetBrowser.php
@@ -0,0 +1,46 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\UserSettings\Columns\Browser;
+
+class GetBrowser extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Browser();
+ $this->name = Piwik::translate('UserSettings_WidgetBrowsers');
+ $this->documentation = Piwik::translate('UserSettings_WidgetBrowsersDocumentation', '<br />');
+ $this->order = 1;
+ $this->widgetTitle = 'UserSettings_WidgetBrowsers';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->title = Piwik::translate('UserSettings_Browsers');
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->max_graph_elements = 7;
+ }
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetBrowserVersion()
+ );
+ }
+}
diff --git a/plugins/UserSettings/Reports/GetBrowserType.php b/plugins/UserSettings/Reports/GetBrowserType.php
new file mode 100644
index 0000000000..85852e8ba4
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetBrowserType.php
@@ -0,0 +1,43 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Pie;
+use Piwik\Plugins\UserSettings\Columns\BrowserFamily;
+
+class GetBrowserType extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new BrowserFamily();
+ $this->name = Piwik::translate('UserSettings_WidgetBrowserFamilies');
+ $this->documentation = Piwik::translate('UserSettings_WidgetBrowserFamiliesDocumentation', '<br />');
+ $this->order = 3;
+ $this->widgetTitle = 'UserSettings_WidgetBrowserFamilies';
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return Pie::ID;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->addTranslation('label', $this->dimension->getName());
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetBrowserVersion.php b/plugins/UserSettings/Reports/GetBrowserVersion.php
new file mode 100644
index 0000000000..aa1c39f042
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetBrowserVersion.php
@@ -0,0 +1,47 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\UserSettings\Columns\BrowserVersion;
+
+class GetBrowserVersion extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new BrowserVersion();
+ $this->name = Piwik::translate('UserSettings_WidgetBrowserVersion');
+ $this->documentation = ''; // TODO
+ $this->order = 2;
+ $this->widgetTitle = 'UserSettings_WidgetBrowserVersion';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->title = Piwik::translate('UserSettings_ColumnBrowserVersion');
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->max_graph_elements = 7;
+ }
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetBrowser()
+ );
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetConfiguration.php b/plugins/UserSettings/Reports/GetConfiguration.php
new file mode 100644
index 0000000000..67b00f8b7d
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetConfiguration.php
@@ -0,0 +1,36 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\Configuration;
+
+class GetConfiguration extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Configuration();
+ $this->name = Piwik::translate('UserSettings_WidgetGlobalVisitors');
+ $this->documentation = Piwik::translate('UserSettings_WidgetGlobalVisitorsDocumentation', '<br />');
+ $this->order = 7;
+ $this->widgetTitle = 'UserSettings_WidgetGlobalVisitors';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_limit = 3;
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetLanguage.php b/plugins/UserSettings/Reports/GetLanguage.php
new file mode 100644
index 0000000000..ed965f761b
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetLanguage.php
@@ -0,0 +1,38 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\Language;
+
+class GetLanguage extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Language();
+ $this->name = Piwik::translate('UserSettings_BrowserLanguage');
+ $this->documentation = ''; // TODO
+ $this->order = 10;
+ $this->widgetTitle = 'UserSettings_BrowserLanguage';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->config->show_search = false;
+ $view->config->columns_to_display = array('label', 'nb_visits');
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ $view->requestConfig->filter_sort_column = 'nb_visits';
+ $view->requestConfig->filter_sort_order = 'desc';
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetMobileVsDesktop.php b/plugins/UserSettings/Reports/GetMobileVsDesktop.php
new file mode 100644
index 0000000000..bbdfe90095
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetMobileVsDesktop.php
@@ -0,0 +1,43 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\MobilevsDesktop;
+
+class GetMobileVsDesktop extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new MobilevsDesktop();
+ $this->name = Piwik::translate('UserSettings_MobileVsDesktop');
+ $this->documentation = ''; // TODO
+ $this->constantRowsCount = true;
+ $this->order = 9;
+ $this->widgetTitle = 'UserSettings_MobileVsDesktop';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->title = Piwik::translate('UserSettings_MobileVsDesktop');
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetWideScreen()
+ );
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetOS.php b/plugins/UserSettings/Reports/GetOS.php
new file mode 100644
index 0000000000..f3b6c028a2
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetOS.php
@@ -0,0 +1,41 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\Operatingsystem;
+
+class GetOS extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Operatingsystem();
+ $this->name = Piwik::translate('UserSettings_WidgetOperatingSystems');
+ $this->documentation = ''; // TODO
+ $this->order = 6;
+ $this->widgetTitle = 'UserSettings_WidgetOperatingSystems';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->title = Piwik::translate('UserSettings_OperatingSystems');
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetOSFamily()
+ );
+ }
+}
diff --git a/plugins/UserSettings/Reports/GetOSFamily.php b/plugins/UserSettings/Reports/GetOSFamily.php
new file mode 100644
index 0000000000..5e12861b80
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetOSFamily.php
@@ -0,0 +1,42 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\OperatingsystemFamily;
+
+class GetOSFamily extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new OperatingsystemFamily();
+ $this->name = Piwik::translate('UserSettings_OperatingSystemFamily');
+ $this->documentation = ''; // TODO
+ $this->order = 8;
+ $this->widgetTitle = 'UserSettings_OperatingSystemFamily';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->title = $this->name;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetOS()
+ );
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetPlugin.php b/plugins/UserSettings/Reports/GetPlugin.php
new file mode 100644
index 0000000000..9b3890f1b3
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetPlugin.php
@@ -0,0 +1,53 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\Plugin;
+
+class GetPlugin extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Plugin();
+ $this->name = Piwik::translate('UserSettings_WidgetPlugins');
+ $this->documentation = Piwik::translate('UserSettings_WidgetPluginsDocumentation', '<br />');
+ $this->metrics = array('nb_visits', 'nb_visits_percentage');
+ $this->constantRowsCount = true;
+ $this->processedMetrics = array();
+ $this->order = 4;
+ $this->widgetTitle = 'UserSettings_WidgetPlugins';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->addTranslations(array(
+ 'label' => $this->dimension->getName(),
+ 'nb_visits_percentage' =>
+ str_replace(' ', '&nbsp;', Piwik::translate('General_ColumnPercentageVisits'))
+ ));
+
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->show_all_views_icons = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->columns_to_display = array('label', 'nb_visits_percentage', 'nb_visits');
+ $view->config->show_footer_message = Piwik::translate('UserSettings_PluginDetectionDoesNotWorkInIE');
+
+ $view->requestConfig->filter_sort_column = 'nb_visits_percentage';
+ $view->requestConfig->filter_sort_order = 'desc';
+ $view->requestConfig->filter_limit = 10;
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetResolution.php b/plugins/UserSettings/Reports/GetResolution.php
new file mode 100644
index 0000000000..2c8012a8d1
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetResolution.php
@@ -0,0 +1,34 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\Resolution;
+
+class GetResolution extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new Resolution();
+ $this->name = Piwik::translate('UserSettings_WidgetResolutions');
+ $this->documentation = ''; // TODO
+ $this->order = 0;
+ $this->widgetTitle = 'UserSettings_WidgetResolutions';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+}
diff --git a/plugins/UserSettings/Reports/GetWideScreen.php b/plugins/UserSettings/Reports/GetWideScreen.php
new file mode 100644
index 0000000000..92006d590c
--- /dev/null
+++ b/plugins/UserSettings/Reports/GetWideScreen.php
@@ -0,0 +1,44 @@
+<?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\UserSettings\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\UserSettings\Columns\TypeOfScreen;
+
+class GetWideScreen extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new TypeOfScreen();
+ $this->name = Piwik::translate('UserSettings_WidgetWidescreen');
+ $this->documentation = ''; // TODO
+ $this->order = 5;
+ $this->widgetTitle = 'UserSettings_WidgetWidescreen';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->getBasicUserSettingsDisplayProperties($view);
+
+ $view->config->title = Piwik::translate('UserSettings_ColumnTypeOfScreen');
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->addTranslation('label', $this->dimension->getName());
+ }
+
+ public function getRelatedReports()
+ {
+ return array(
+ new GetMobileVsDesktop()
+ );
+ }
+}
diff --git a/plugins/UserSettings/Segment.php b/plugins/UserSettings/Segment.php
new file mode 100644
index 0000000000..194ab6314a
--- /dev/null
+++ b/plugins/UserSettings/Segment.php
@@ -0,0 +1,21 @@
+<?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\UserSettings;
+
+/**
+ * UserSettings segment base class.
+ *
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+ protected function init()
+ {
+ $this->setCategory('General_Visit');
+ }
+}
diff --git a/plugins/UserSettings/UserSettings.php b/plugins/UserSettings/UserSettings.php
index 5da8af6c69..69f9b6519e 100644
--- a/plugins/UserSettings/UserSettings.php
+++ b/plugins/UserSettings/UserSettings.php
@@ -9,10 +9,8 @@
namespace Piwik\Plugins\UserSettings;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
-use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Pie;
/**
*
@@ -33,417 +31,22 @@ class UserSettings extends \Piwik\Plugin
);
/**
- * Defines API reports.
- * Also used to define Widgets.
- *
- * @type array
- *
- * Category, Report Name, API Module, API action, Translated column name,
- * $segment, $sqlSegment, $acceptedValues, $sqlFilter
- */
- protected $reportMetadata = array(
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetResolutions',
- 'UserSettings',
- 'getResolution',
- 'UserSettings_ColumnResolution',
- 'resolution',
- 'log_visit.config_resolution',
- '1280x1024, 800x600, etc.',
- null),
-
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetBrowsers',
- 'UserSettings',
- 'getBrowser',
- 'UserSettings_ColumnBrowser',
- 'browserCode',
- 'log_visit.config_browser_name',
- 'FF, IE, CH, SF, OP, etc.',
- null),
-
- // browser version
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetBrowserVersion',
- 'UserSettings',
- 'getBrowserVersion',
- 'UserSettings_ColumnBrowserVersion',
- 'browserVersion',
- 'log_visit.config_browser_version',
- '1.0, 8.0, etc.',
- null),
-
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetBrowserFamilies',
- 'UserSettings',
- 'getBrowserType',
- 'UserSettings_ColumnBrowserFamily',
- null,
- null,
- null,
- null),
-
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetPlugins',
- 'UserSettings',
- 'getPlugin',
- 'General_Plugin',
- null,
- null,
- null,
- null),
-
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetWidescreen',
- 'UserSettings',
- 'getWideScreen',
- 'UserSettings_ColumnTypeOfScreen',
- null,
- null,
- null,
- null),
-
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetOperatingSystems',
- 'UserSettings',
- 'getOS',
- 'UserSettings_ColumnOperatingSystem',
- 'operatingSystemCode',
- 'log_visit.config_os',
- 'WXP, WI7, MAC, LIN, AND, IPD, etc.',
- null),
-
- array('UserSettings_VisitorSettings',
- 'UserSettings_WidgetGlobalVisitors',
- 'UserSettings',
- 'getConfiguration',
- 'UserSettings_ColumnConfiguration',
- null,
- null,
- null,
- null),
-
- // operating system family
- array('UserSettings_VisitorSettings',
- 'UserSettings_OperatingSystemFamily',
- 'UserSettings',
- 'getOSFamily',
- 'UserSettings_OperatingSystemFamily',
- null,
- null,
- null,
- null),
-
- // device type
- array('UserSettings_VisitorSettings',
- 'UserSettings_MobileVsDesktop',
- 'UserSettings',
- 'getMobileVsDesktop',
- 'UserSettings_MobileVsDesktop',
- null,
- null,
- null,
- null),
-
- // Browser language
- array('UserSettings_VisitorSettings',
- 'UserSettings_BrowserLanguage',
- 'UserSettings',
- 'getLanguage',
- 'General_Language',
- null,
- null,
- null,
- null),
- );
-
- /**
* @see Piwik\Plugin::getListHooksRegistered
*/
public function getListHooksRegistered()
{
- $hooks = array(
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable',
- 'ViewDataTable.getDefaultType' => 'getDefaultTypeViewDataTable'
- );
- return $hooks;
- }
-
- public function getDefaultTypeViewDataTable(&$defaultViewTypes)
- {
- $defaultViewTypes['UserSettings.getBrowserType'] = Pie::ID;
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'UserSettings.getResolution':
- $this->configureViewForGetResolution($view);
- break;
- case 'UserSettings.getConfiguration':
- $this->configureViewForGetConfiguration($view);
- break;
- case 'UserSettings.getOS':
- $this->configureViewForGetOS($view);
- break;
- case 'UserSettings.getOSFamily':
- $this->configureViewForGetOSFamily($view);
- break;
- case 'UserSettings.getBrowserVersion':
- $this->configureViewForGetBrowserVersion($view);
- break;
- case 'UserSettings.getBrowser':
- $this->configureViewForGetBrowser($view);
- break;
- case 'UserSettings.getBrowserType':
- $this->configureViewForGetBrowserType($view);
- break;
- case 'UserSettings.getWideScreen':
- $this->configureViewForGetWideScreen($view);
- break;
- case 'UserSettings.getMobileVsDesktop':
- $this->configureViewForGetMobileVsDesktop($view);
- break;
- case 'UserSettings.getPlugin':
- $this->configureViewForGetPlugin($view);
- break;
- case 'UserSettings.getLanguage':
- $this->configureViewForGetLanguage($view);
- break;
- }
- }
-
- private function configureViewForGetResolution(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->addTranslation('label', Piwik::translate('UserSettings_ColumnResolution'));
- }
-
- private function configureViewForGetConfiguration(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->addTranslation('label', Piwik::translate('UserSettings_ColumnConfiguration'));
-
- $view->requestConfig->filter_limit = 3;
- }
-
- private function configureViewForGetOS(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->title = Piwik::translate('UserSettings_OperatingSystems');
- $view->config->addTranslation('label', Piwik::translate('UserSettings_ColumnOperatingSystem'));
- $view->config->addRelatedReports($this->getOsRelatedReports());
- }
-
- private function configureViewForGetOSFamily(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->title = Piwik::translate('UserSettings_OperatingSystemFamily');
- $view->config->addTranslation('label', Piwik::translate('UserSettings_OperatingSystemFamily'));
- $view->config->addRelatedReports($this->getOsRelatedReports());
- }
-
- private function configureViewForGetBrowserVersion(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->title = Piwik::translate('UserSettings_ColumnBrowserVersion');
- $view->config->addTranslation('label', Piwik::translate('UserSettings_ColumnBrowserVersion'));
- $view->config->addRelatedReports($this->getBrowserRelatedReports());
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->max_graph_elements = 7;
- }
- }
-
- private function configureViewForGetBrowser(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->title = Piwik::translate('UserSettings_Browsers');
- $view->config->addTranslation('label', Piwik::translate('UserSettings_ColumnBrowser'));
- $view->config->addRelatedReports($this->getBrowserRelatedReports());
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->max_graph_elements = 7;
- }
- }
-
- private function configureViewForGetBrowserType(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->addTranslation('label', Piwik::translate('UserSettings_ColumnBrowserFamily'));
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- }
-
- private function configureViewForGetWideScreen(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->title = Piwik::translate('UserSettings_ColumnTypeOfScreen');
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->addTranslation('label', Piwik::translate('UserSettings_ColumnTypeOfScreen'));
- $view->config->addRelatedReports($this->getWideScreenDeviceTypeRelatedReports());
- }
-
- private function configureViewForGetMobileVsDesktop(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->title = Piwik::translate('UserSettings_MobileVsDesktop');
- $view->config->addTranslation('label', Piwik::translate('UserSettings_MobileVsDesktop'));
- $view->config->addRelatedReports($this->getWideScreenDeviceTypeRelatedReports());
- }
-
- private function configureViewForGetPlugin(ViewDataTable $view)
- {
- $this->getBasicUserSettingsDisplayProperties($view);
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('General_Plugin'),
- 'nb_visits_percentage' =>
- str_replace(' ', '&nbsp;', Piwik::translate('General_ColumnPercentageVisits'))
- ));
-
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->show_all_views_icons = false;
- $view->config->show_table_all_columns = false;
- $view->config->columns_to_display = array('label', 'nb_visits_percentage', 'nb_visits');
- $view->config->show_footer_message = Piwik::translate('UserSettings_PluginDetectionDoesNotWorkInIE');
-
- $view->requestConfig->filter_sort_column = 'nb_visits_percentage';
- $view->requestConfig->filter_sort_order = 'desc';
- $view->requestConfig->filter_limit = 10;
- }
-
- private function configureViewForGetLanguage(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->columns_to_display = array('label', 'nb_visits');
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('General_Language'));
-
- $view->requestConfig->filter_sort_column = 'nb_visits';
- $view->requestConfig->filter_sort_order = 'desc';
- }
-
- private function getWideScreenDeviceTypeRelatedReports()
- {
- return array(
- 'UserSettings.getMobileVsDesktop' => Piwik::translate('UserSettings_MobileVsDesktop'),
- 'UserSettings.getWideScreen' => Piwik::translate('UserSettings_ColumnTypeOfScreen')
- );
- }
-
- private function getBrowserRelatedReports()
- {
return array(
- 'UserSettings.getBrowser' => Piwik::translate('UserSettings_Browsers'),
- 'UserSettings.getBrowserVersion' => Piwik::translate('UserSettings_ColumnBrowserVersion')
+ 'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations'
);
}
- private function getOsRelatedReports()
+ public function addMetricTranslations(&$translations)
{
- return array(
- 'UserSettings.getOSFamily' => Piwik::translate('UserSettings_OperatingSystemFamily'),
- 'UserSettings.getOS' => Piwik::translate('UserSettings_OperatingSystems')
+ $metrics = array(
+ 'nb_visits_percentage' => Piwik::translate('General_ColumnPercentageVisits')
);
- }
-
- private function getBasicUserSettingsDisplayProperties(ViewDataTable $view)
- {
- $view->config->show_search = false;
- $view->config->show_exclude_low_population = false;
-
- $view->requestConfig->filter_limit = 5;
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->max_graph_elements = 5;
- }
- }
-
- public function getRawReportMetadata()
- {
- return $this->reportMetadata;
- }
- /**
- * Registers reports metadata
- *
- * @param array $reports
- */
- public function getReportMetadata(&$reports)
- {
- $i = 0;
- foreach ($this->getRawReportMetadata() as $report) {
- list($category, $name, $apiModule, $apiAction, $columnName) = $report;
- if ($category == false) continue;
-
- $report = array(
- 'category' => Piwik::translate($category),
- 'name' => Piwik::translate($name),
- 'module' => $apiModule,
- 'action' => $apiAction,
- 'dimension' => Piwik::translate($columnName),
- 'order' => $i++
- );
-
- $translation = $name . 'Documentation';
- $translated = Piwik::translate($translation, '<br />');
- if ($translated != $translation) {
- $report['documentation'] = $translated;
- }
-
- if ($apiAction == 'getMobileVsDesktop') {
- $report['constantRowsCount'] = true;
- }
-
- // getPlugin returns only a subset of metrics
- if ($apiAction == 'getPlugin') {
- $report['metrics'] = array(
- 'nb_visits',
- 'nb_visits_percentage' => Piwik::translate('General_ColumnPercentageVisits')
- );
- // There is no processedMetrics for this report
- $report['processedMetrics'] = array();
- // Always has same number of rows, 1 per plugin
- $report['constantRowsCount'] = true;
- }
- $reports[] = $report;
- }
- }
-
- /**
- * Get segments meta data
- */
- public function getSegmentsMetadata(&$segments)
- {
- foreach ($this->reportMetadata as $report) {
- @list($category, $name, $apiModule, $apiAction, $columnName, $segment, $sqlSegment, $acceptedValues) = $report;
- if (empty($segment)) continue;
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => $columnName,
- 'segment' => $segment,
- 'acceptedValues' => $acceptedValues,
- 'sqlSegment' => $sqlSegment
- );
- }
+ $translations = array_merge($translations, $metrics);
}
}
diff --git a/plugins/UserSettings/Widgets.php b/plugins/UserSettings/Widgets.php
deleted file mode 100644
index 7d4278c163..0000000000
--- a/plugins/UserSettings/Widgets.php
+++ /dev/null
@@ -1,30 +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
- *
- */
-namespace Piwik\Plugins\UserSettings;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- $userSettings = new UserSettings();
-
- foreach ($userSettings->getRawReportMetadata() as $report) {
- list($category, $name, $controllerName, $controllerAction) = $report;
-
- if ($category == false) {
- continue;
- }
-
- $widgetsList->add($category, $name, $controllerName, $controllerAction);
- }
- }
-
-}
diff --git a/plugins/VisitFrequency/Reports/Get.php b/plugins/VisitFrequency/Reports/Get.php
new file mode 100644
index 0000000000..2c7d8fb21f
--- /dev/null
+++ b/plugins/VisitFrequency/Reports/Get.php
@@ -0,0 +1,25 @@
+<?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\VisitFrequency\Reports;
+
+use Piwik\Piwik;
+
+class Get extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ parent::init();
+ $this->category = 'General_Visitors';
+ $this->name = Piwik::translate('VisitFrequency_ColumnReturningVisits');
+ $this->documentation = ''; // TODO
+ $this->metrics = array('nb_visits_returning', 'nb_actions_returning', 'avg_time_on_site_returning', 'bounce_rate_returning', 'nb_actions_per_visit_returning', 'nb_uniq_visitors_returning');
+ $this->processedMetrics = false;
+ $this->order = 40;
+ }
+}
diff --git a/plugins/VisitFrequency/VisitFrequency.php b/plugins/VisitFrequency/VisitFrequency.php
index f3dcf598b6..1666edd0dc 100644
--- a/plugins/VisitFrequency/VisitFrequency.php
+++ b/plugins/VisitFrequency/VisitFrequency.php
@@ -9,10 +9,9 @@
namespace Piwik\Plugins\VisitFrequency;
use Piwik\Piwik;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
-/**
- *
- */
class VisitFrequency extends \Piwik\Plugin
{
/**
@@ -20,34 +19,23 @@ class VisitFrequency extends \Piwik\Plugin
*/
public function getListHooksRegistered()
{
- $hooks = array(
- 'API.getReportMetadata' => 'getReportMetadata',
+ return array(
+ 'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations'
);
- return $hooks;
}
- public function getReportMetadata(&$reports)
+ public function addMetricTranslations(&$translations)
{
- $reports[] = array(
- 'category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('VisitFrequency_ColumnReturningVisits'),
- 'module' => 'VisitFrequency',
- 'action' => 'get',
- 'metrics' => array(
- 'nb_visits_returning' => Piwik::translate('VisitFrequency_ColumnReturningVisits'),
- 'nb_actions_returning' => Piwik::translate('VisitFrequency_ColumnActionsByReturningVisits'),
- 'avg_time_on_site_returning' => Piwik::translate('VisitFrequency_ColumnAverageVisitDurationForReturningVisitors'),
- 'bounce_rate_returning' => Piwik::translate('VisitFrequency_ColumnBounceRateForReturningVisits'),
- 'nb_actions_per_visit_returning' => Piwik::translate('VisitFrequency_ColumnAvgActionsPerReturningVisit'),
- 'nb_uniq_visitors_returning' => Piwik::translate('VisitFrequency_ColumnUniqueReturningVisitors'),
-// Not displayed
-// 'nb_visits_converted_returning',
-// 'sum_visit_length_returning',
-// 'max_actions_returning',
-// 'bounce_count_returning',
- ),
- 'processedMetrics' => false,
- 'order' => 40
+ $metrics = array(
+ 'nb_visits_returning' => 'VisitFrequency_ColumnReturningVisits',
+ 'nb_actions_returning' => 'VisitFrequency_ColumnActionsByReturningVisits',
+ 'avg_time_on_site_returning' => 'VisitFrequency_ColumnAverageVisitDurationForReturningVisitors',
+ 'bounce_rate_returning' => 'VisitFrequency_ColumnBounceRateForReturningVisits',
+ 'nb_actions_per_visit_returning' => 'VisitFrequency_ColumnAvgActionsPerReturningVisit',
+ 'nb_uniq_visitors_returning' => 'VisitFrequency_ColumnUniqueReturningVisitors'
);
+
+ $translations = array_merge($translations, $metrics);
}
+
}
diff --git a/plugins/VisitFrequency/Widgets.php b/plugins/VisitFrequency/Widgets.php
index 1b132c9f45..53a5ddcd47 100644
--- a/plugins/VisitFrequency/Widgets.php
+++ b/plugins/VisitFrequency/Widgets.php
@@ -8,17 +8,15 @@
*/
namespace Piwik\Plugins\VisitFrequency;
-use Piwik\WidgetsList;
-
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'General_Visitors';
- $controller = 'VisitFrequency';
+ protected $category = 'General_Visitors';
- $widgetsList->add($category, 'VisitFrequency_WidgetOverview', $controller, 'getSparklines');
- $widgetsList->add($category, 'VisitFrequency_WidgetGraphReturning', $controller, 'getEvolutionGraph',
+ public function init()
+ {
+ $this->addWidget('VisitFrequency_WidgetOverview', 'getSparklines');
+ $this->addWidget('VisitFrequency_WidgetGraphReturning',
+ 'getEvolutionGraph',
array('columns' => array('nb_visits_returning')));
}
diff --git a/plugins/VisitTime/Columns/DayOfTheWeek.php b/plugins/VisitTime/Columns/DayOfTheWeek.php
new file mode 100644
index 0000000000..b6e39310ab
--- /dev/null
+++ b/plugins/VisitTime/Columns/DayOfTheWeek.php
@@ -0,0 +1,20 @@
+<?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\VisitTime\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class DayOfTheWeek extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('VisitTime_DayOfWeek');
+ }
+} \ No newline at end of file
diff --git a/plugins/VisitTime/Columns/LocalTime.php b/plugins/VisitTime/Columns/LocalTime.php
new file mode 100644
index 0000000000..ade984c1f1
--- /dev/null
+++ b/plugins/VisitTime/Columns/LocalTime.php
@@ -0,0 +1,48 @@
+<?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\VisitTime\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\VisitTime\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class LocalTime extends VisitDimension
+{
+ protected $columnName = 'visitor_localtime';
+ protected $columnType = 'TIME NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('visitLocalHour');
+ $segment->setName('VisitTime_ColumnLocalTime');
+ $segment->setSqlSegment('HOUR(log_visit.visitor_localtime)');
+ $segment->setAcceptedValues('0, 1, 2, 3, ..., 20, 21, 22, 23');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('VisitTime_ColumnLocalTime');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $request->getLocalTime();
+ }
+} \ No newline at end of file
diff --git a/plugins/VisitTime/Columns/ServerTime.php b/plugins/VisitTime/Columns/ServerTime.php
new file mode 100644
index 0000000000..f7c1c6c3d0
--- /dev/null
+++ b/plugins/VisitTime/Columns/ServerTime.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\VisitTime\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\VisitTime\Segment;
+
+class ServerTime extends VisitDimension
+{
+ protected $columnName = 'visit_last_action_time';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('visitServerHour');
+ $segment->setName('VisitTime_ColumnServerTime');
+ $segment->setSqlSegment('HOUR(log_visit.visit_last_action_time)');
+ $segment->setAcceptedValues('0, 1, 2, 3, ..., 20, 21, 22, 23');
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('VisitTime_ColumnServerTime');
+ }
+} \ No newline at end of file
diff --git a/plugins/VisitTime/Controller.php b/plugins/VisitTime/Controller.php
index c823bbf425..24bbf39a80 100644
--- a/plugins/VisitTime/Controller.php
+++ b/plugins/VisitTime/Controller.php
@@ -8,6 +8,8 @@
*/
namespace Piwik\Plugins\VisitTime;
+use Piwik\Plugins\VisitTime\Reports\GetVisitInformationPerLocalTime;
+use Piwik\Plugins\VisitTime\Reports\GetVisitInformationPerServerTime;
use Piwik\View;
/**
@@ -18,23 +20,8 @@ class Controller extends \Piwik\Plugin\Controller
public function index()
{
$view = new View('@VisitTime/index');
- $view->dataTableVisitInformationPerLocalTime = $this->getVisitInformationPerLocalTime(true);
- $view->dataTableVisitInformationPerServerTime = $this->getVisitInformationPerServerTime(true);
+ $view->dataTableVisitInformationPerLocalTime = $this->renderReport(new GetVisitInformationPerLocalTime());
+ $view->dataTableVisitInformationPerServerTime = $this->renderReport(new GetVisitInformationPerServerTime());
return $view->render();
}
-
- public function getVisitInformationPerServerTime()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getVisitInformationPerLocalTime()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getByDayOfWeek()
- {
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/VisitTime/Reports/Base.php b/plugins/VisitTime/Reports/Base.php
new file mode 100644
index 0000000000..886d51d963
--- /dev/null
+++ b/plugins/VisitTime/Reports/Base.php
@@ -0,0 +1,41 @@
+<?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\VisitTime\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Bar;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'VisitsSummary_VisitsSummary';
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return Bar::ID;
+ }
+
+ /**
+ * @param ViewDataTable $view
+ */
+ protected function setBasicConfigViewProperties(ViewDataTable $view)
+ {
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->requestConfig->addPropertiesThatShouldBeAvailableClientSide(array('filter_sort_column'));
+ $view->config->show_search = false;
+ $view->config->show_limit_control = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ }
+}
diff --git a/plugins/VisitTime/Reports/GetByDayOfWeek.php b/plugins/VisitTime/Reports/GetByDayOfWeek.php
new file mode 100644
index 0000000000..c720166cf5
--- /dev/null
+++ b/plugins/VisitTime/Reports/GetByDayOfWeek.php
@@ -0,0 +1,72 @@
+<?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\VisitTime\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\VisitTime\Columns\DayOfTheWeek;
+use Piwik\Period;
+use Piwik\Site;
+
+class GetByDayOfWeek extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new DayOfTheWeek();
+ $this->name = Piwik::translate('VisitTime_VisitsByDayOfWeek');
+ $this->documentation = Piwik::translate('VisitTime_WidgetByDayOfWeekDocumentation');
+ $this->constantRowsCount = true;
+ $this->order = 25;
+ $this->widgetTitle = 'VisitTime_VisitsByDayOfWeek';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->setBasicConfigViewProperties($view);
+
+ $view->requestConfig->filter_limit = 7;
+
+ $view->config->enable_sort = false;
+ $view->config->show_footer_message = Piwik::translate('General_ReportGeneratedFrom', $this->getDateRangeForFooterMessage());
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->max_graph_elements = false;
+ $view->config->show_all_ticks = true;
+ }
+ }
+
+ private function getDateRangeForFooterMessage()
+ {
+ // get query params
+ $idSite = Common::getRequestVar('idSite', false);
+ $date = Common::getRequestVar('date', false);
+ $period = Common::getRequestVar('period', false);
+
+ // create a period instance
+ try {
+ $oPeriod = Period\Factory::makePeriodFromQueryParams(Site::getTimezoneFor($idSite), $period, $date);
+ } catch (\Exception $ex) {
+ return ''; // if query params are incorrect, forget about the footer message
+ }
+
+ // set the footer message using the period start & end date
+ $start = $oPeriod->getDateStart()->toString();
+ $end = $oPeriod->getDateEnd()->toString();
+ if ($start == $end) {
+ $dateRange = $start;
+ } else {
+ $dateRange = $start . " &ndash; " . $end;
+ }
+ return $dateRange;
+ }
+}
diff --git a/plugins/VisitTime/Reports/GetVisitInformationPerLocalTime.php b/plugins/VisitTime/Reports/GetVisitInformationPerLocalTime.php
new file mode 100644
index 0000000000..bbc9aa5b1b
--- /dev/null
+++ b/plugins/VisitTime/Reports/GetVisitInformationPerLocalTime.php
@@ -0,0 +1,48 @@
+<?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\VisitTime\Reports;
+
+use Piwik\Common;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\VisitTime\Columns\LocalTime;
+
+class GetVisitInformationPerLocalTime extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new LocalTime();
+ $this->name = Piwik::translate('VisitTime_WidgetLocalTime');
+ $this->documentation = Piwik::translate('VisitTime_WidgetLocalTimeDocumentation', array('<strong>', '</strong>'));
+ $this->constantRowsCount = true;
+ $this->order = 20;
+ $this->widgetTitle = 'VisitTime_WidgetLocalTime';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->setBasicConfigViewProperties($view);
+
+ $view->requestConfig->filter_limit = 24;
+
+ $view->config->title = Piwik::translate('VisitTime_ColumnLocalTime');
+ $view->config->addTranslation('label', Piwik::translate('VisitTime_LocalTime'));
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->max_graph_elements = false;
+ }
+
+ // add the visits by day of week as a related report, if the current period is not 'day'
+ if (Common::getRequestVar('period', 'day') != 'day') {
+ $view->config->addRelatedReport('VisitTime.getByDayOfWeek', Piwik::translate('VisitTime_VisitsByDayOfWeek'));
+ }
+ }
+}
diff --git a/plugins/VisitTime/Reports/GetVisitInformationPerServerTime.php b/plugins/VisitTime/Reports/GetVisitInformationPerServerTime.php
new file mode 100644
index 0000000000..9f9e9170f3
--- /dev/null
+++ b/plugins/VisitTime/Reports/GetVisitInformationPerServerTime.php
@@ -0,0 +1,44 @@
+<?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\VisitTime\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\VisitTime\Columns\ServerTime;
+
+class GetVisitInformationPerServerTime extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new ServerTime();
+ $this->name = Piwik::translate('VisitTime_WidgetServerTime');
+ $this->documentation = Piwik::translate('VisitTime_WidgetServerTimeDocumentation', array('<strong>', '</strong>'));
+ $this->constantRowsCount = true;
+ $this->hasGoalMetrics = true;
+ $this->order = 15;
+ $this->widgetTitle = 'VisitTime_WidgetServerTime';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $this->setBasicConfigViewProperties($view);
+
+ $view->requestConfig->filter_limit = 24;
+ $view->requestConfig->request_parameters_to_modify['hideFutureHoursWhenToday'] = 1;
+
+ $view->config->show_goals = true;
+ $view->config->addTranslation('label', $this->dimension->getName());
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->max_graph_elements = false;
+ }
+ }
+}
diff --git a/plugins/VisitTime/Segment.php b/plugins/VisitTime/Segment.php
new file mode 100644
index 0000000000..30bc58f608
--- /dev/null
+++ b/plugins/VisitTime/Segment.php
@@ -0,0 +1,21 @@
+<?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\VisitTime;
+
+/**
+ * VisitTime segment base class.
+ *
+ */
+class Segment extends \Piwik\Plugin\Segment
+{
+ protected function init()
+ {
+ $this->setCategory('Visit');
+ }
+}
diff --git a/plugins/VisitTime/VisitTime.php b/plugins/VisitTime/VisitTime.php
index fbf115748c..39ac47d536 100644
--- a/plugins/VisitTime/VisitTime.php
+++ b/plugins/VisitTime/VisitTime.php
@@ -8,209 +8,7 @@
*/
namespace Piwik\Plugins\VisitTime;
-use Exception;
-use Piwik\ArchiveProcessor;
-use Piwik\Common;
-use Piwik\Period;
-use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
-use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
-use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Bar;
-use Piwik\Site;
-
-/**
- *
- */
+// empty plugin definition, otherwise plugin won't be installed during test run
class VisitTime extends \Piwik\Plugin
{
- /**
- * @see Piwik\Plugin::getListHooksRegistered
- */
- public function getListHooksRegistered()
- {
- $hooks = array(
- 'Goals.getReportsWithGoalMetrics' => 'getReportsWithGoalMetrics',
- 'API.getReportMetadata' => 'getReportMetadata',
- 'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable',
- 'ViewDataTable.getDefaultType' => 'getDefaultTypeViewDataTable'
- );
- return $hooks;
- }
-
- public function getReportMetadata(&$reports)
- {
- $reports[] = array(
- 'category' => Piwik::translate('VisitsSummary_VisitsSummary'),
- 'name' => Piwik::translate('VisitTime_WidgetLocalTime'),
- 'module' => 'VisitTime',
- 'action' => 'getVisitInformationPerLocalTime',
- 'dimension' => Piwik::translate('VisitTime_ColumnLocalTime'),
- 'documentation' => Piwik::translate('VisitTime_WidgetLocalTimeDocumentation', array('<strong>', '</strong>')),
- 'constantRowsCount' => true,
- 'order' => 20
- );
-
- $reports[] = array(
- 'category' => Piwik::translate('VisitsSummary_VisitsSummary'),
- 'name' => Piwik::translate('VisitTime_WidgetServerTime'),
- 'module' => 'VisitTime',
- 'action' => 'getVisitInformationPerServerTime',
- 'dimension' => Piwik::translate('VisitTime_ColumnServerTime'),
- 'documentation' => Piwik::translate('VisitTime_WidgetServerTimeDocumentation', array('<strong>', '</strong>')),
- 'constantRowsCount' => true,
- 'order' => 15,
- );
-
- $reports[] = array(
- 'category' => Piwik::translate('VisitsSummary_VisitsSummary'),
- 'name' => Piwik::translate('VisitTime_VisitsByDayOfWeek'),
- 'module' => 'VisitTime',
- 'action' => 'getByDayOfWeek',
- 'dimension' => Piwik::translate('VisitTime_DayOfWeek'),
- 'documentation' => Piwik::translate('VisitTime_WidgetByDayOfWeekDocumentation'),
- 'constantRowsCount' => true,
- 'order' => 25,
- );
- }
-
- public function getReportsWithGoalMetrics(&$dimensions)
- {
- $dimensions[] = array('category' => Piwik::translate('VisitTime_ColumnServerTime'),
- 'name' => Piwik::translate('VisitTime_ColumnServerTime'),
- 'module' => 'VisitTime',
- 'action' => 'getVisitInformationPerServerTime',
- );
- }
-
- public function getSegmentsMetadata(&$segments)
- {
- $acceptedValues = "0, 1, 2, 3, ..., 20, 21, 22, 23";
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => Piwik::translate('VisitTime_ColumnServerTime'),
- 'segment' => 'visitServerHour',
- 'sqlSegment' => 'HOUR(log_visit.visit_last_action_time)',
- 'acceptedValues' => $acceptedValues
- );
- $segments[] = array(
- 'type' => 'dimension',
- 'category' => Piwik::translate('General_Visit'),
- 'name' => Piwik::translate('VisitTime_ColumnLocalTime'),
- 'segment' => 'visitLocalHour',
- 'sqlSegment' => 'HOUR(log_visit.visitor_localtime)',
- 'acceptedValues' => $acceptedValues
- );
- }
-
- public function getDefaultTypeViewDataTable(&$defaultViewTypes)
- {
- $defaultViewTypes['VisitTime.getVisitInformationPerServerTime'] = Bar::ID;
- $defaultViewTypes['VisitTime.getVisitInformationPerLocalTime'] = Bar::ID;
- $defaultViewTypes['VisitTime.getByDayOfWeek'] = Bar::ID;
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'VisitTime.getVisitInformationPerServerTime':
- $this->setBasicConfigViewProperties($view);
- $this->configureViewForVisitInformationPerServerTime($view);
- break;
- case 'VisitTime.getVisitInformationPerLocalTime':
- $this->setBasicConfigViewProperties($view);
- $this->configureViewForVisitInformationPerLocalTime($view);
- break;
- case 'VisitTime.getByDayOfWeek':
- $this->setBasicConfigViewProperties($view);
- $this->configureViewForByDayOfWeek($view);
- break;
- }
- }
-
- protected function configureViewForVisitInformationPerServerTime(ViewDataTable $view)
- {
- $view->requestConfig->filter_limit = 24;
- $view->requestConfig->request_parameters_to_modify['hideFutureHoursWhenToday'] = 1;
-
- $view->config->show_goals = true;
- $view->config->addTranslation('label', Piwik::translate('VisitTime_ColumnServerTime'));
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->max_graph_elements = false;
- }
- }
-
- protected function configureViewForVisitInformationPerLocalTime(ViewDataTable $view)
- {
- $view->requestConfig->filter_limit = 24;
-
- $view->config->title = Piwik::translate('VisitTime_ColumnLocalTime');
- $view->config->addTranslation('label', Piwik::translate('VisitTime_LocalTime'));
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->max_graph_elements = false;
- }
-
- // add the visits by day of week as a related report, if the current period is not 'day'
- if (Common::getRequestVar('period', 'day') != 'day') {
- $view->config->addRelatedReport('VisitTime.getByDayOfWeek', Piwik::translate('VisitTime_VisitsByDayOfWeek'));
- }
-
- }
-
- protected function configureViewForByDayOfWeek(ViewDataTable $view)
- {
- $view->requestConfig->filter_limit = 7;
-
- $view->config->enable_sort = false;
- $view->config->show_footer_message = Piwik::translate('General_ReportGeneratedFrom', self::getDateRangeForFooterMessage());
- $view->config->addTranslation('label', Piwik::translate('VisitTime_DayOfWeek'));
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->max_graph_elements = false;
- $view->config->show_all_ticks = true;
- }
- }
-
- private static function getDateRangeForFooterMessage()
- {
- // get query params
- $idSite = Common::getRequestVar('idSite', false);
- $date = Common::getRequestVar('date', false);
- $period = Common::getRequestVar('period', false);
-
- // create a period instance
- try {
- $oPeriod = Period\Factory::makePeriodFromQueryParams(Site::getTimezoneFor($idSite), $period, $date);
- } catch (Exception $ex) {
- return ''; // if query params are incorrect, forget about the footer message
- }
-
- // set the footer message using the period start & end date
- $start = $oPeriod->getDateStart()->toString();
- $end = $oPeriod->getDateEnd()->toString();
- if ($start == $end) {
- $dateRange = $start;
- } else {
- $dateRange = $start . " &ndash; " . $end;
- }
- return $dateRange;
- }
-
- /**
- * @param ViewDataTable $view
- */
- private function setBasicConfigViewProperties(ViewDataTable $view)
- {
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'asc';
- $view->requestConfig->addPropertiesThatShouldBeAvailableClientSide(array('filter_sort_column'));
- $view->config->show_search = false;
- $view->config->show_limit_control = false;
- $view->config->show_exclude_low_population = false;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- }
}
diff --git a/plugins/VisitTime/Widgets.php b/plugins/VisitTime/Widgets.php
deleted file mode 100644
index 85801c7ab5..0000000000
--- a/plugins/VisitTime/Widgets.php
+++ /dev/null
@@ -1,25 +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
- *
- */
-namespace Piwik\Plugins\VisitTime;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'VisitsSummary_VisitsSummary';
- $controller = 'VisitTime';
-
- $widgetsList->add($category, 'VisitTime_WidgetLocalTime', $controller, 'getVisitInformationPerLocalTime');
- $widgetsList->add($category, 'VisitTime_WidgetServerTime', $controller, 'getVisitInformationPerServerTime');
- $widgetsList->add($category, 'VisitTime_VisitsByDayOfWeek', $controller, 'getByDayOfWeek');
- }
-
-}
diff --git a/plugins/VisitorInterest/Columns/PagesPerVisit.php b/plugins/VisitorInterest/Columns/PagesPerVisit.php
new file mode 100644
index 0000000000..a64e7e28fd
--- /dev/null
+++ b/plugins/VisitorInterest/Columns/PagesPerVisit.php
@@ -0,0 +1,20 @@
+<?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\VisitorInterest\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class PagesPerVisit extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('VisitorInterest_ColumnPagesPerVisit');
+ }
+} \ No newline at end of file
diff --git a/plugins/VisitorInterest/Columns/VisitDuration.php b/plugins/VisitorInterest/Columns/VisitDuration.php
new file mode 100644
index 0000000000..68311a013c
--- /dev/null
+++ b/plugins/VisitorInterest/Columns/VisitDuration.php
@@ -0,0 +1,20 @@
+<?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\VisitorInterest\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class VisitDuration extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('VisitorInterest_ColumnVisitDuration');
+ }
+} \ No newline at end of file
diff --git a/plugins/VisitorInterest/Columns/VisitsByDaysSinceLastVisit.php b/plugins/VisitorInterest/Columns/VisitsByDaysSinceLastVisit.php
new file mode 100644
index 0000000000..dfebfee708
--- /dev/null
+++ b/plugins/VisitorInterest/Columns/VisitsByDaysSinceLastVisit.php
@@ -0,0 +1,49 @@
+<?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\VisitorInterest\Columns;
+
+use Piwik\Piwik;
+use Piwik\Plugin\Dimension\VisitDimension;
+use Piwik\Plugins\CoreHome\Segment;
+use Piwik\Tracker\Action;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visitor;
+
+class VisitsByDaysSinceLastVisit extends VisitDimension
+{
+ protected $columnName = 'visitor_days_since_last';
+ protected $columnType = 'SMALLINT(5) UNSIGNED NOT NULL';
+
+ protected function configureSegments()
+ {
+ $segment = new Segment();
+ $segment->setSegment('daysSinceLastVisit');
+ $segment->setName('General_DaysSinceLastVisit');
+ $segment->setType(Segment::TYPE_METRIC);
+
+ $this->addSegment($segment);
+ }
+
+ public function getName()
+ {
+ return Piwik::translate('VisitorInterest_VisitsByDaysSinceLast');
+ }
+
+ /**
+ * @param Request $request
+ * @param Visitor $visitor
+ * @param Action|null $action
+ * @return mixed
+ */
+ public function onNewVisit(Request $request, Visitor $visitor, $action)
+ {
+ return $request->getDaysSinceLastVisit();
+ }
+
+} \ No newline at end of file
diff --git a/plugins/VisitorInterest/Columns/VisitsbyVisitNumber.php b/plugins/VisitorInterest/Columns/VisitsbyVisitNumber.php
new file mode 100644
index 0000000000..2d16fa5a5d
--- /dev/null
+++ b/plugins/VisitorInterest/Columns/VisitsbyVisitNumber.php
@@ -0,0 +1,20 @@
+<?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\VisitorInterest\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Piwik;
+
+class VisitsbyVisitNumber extends Dimension
+{
+ public function getName()
+ {
+ return Piwik::translate('VisitorInterest_visitsByVisitCount');
+ }
+} \ No newline at end of file
diff --git a/plugins/VisitorInterest/Controller.php b/plugins/VisitorInterest/Controller.php
index a2319d5c3e..54de697282 100644
--- a/plugins/VisitorInterest/Controller.php
+++ b/plugins/VisitorInterest/Controller.php
@@ -8,51 +8,21 @@
*/
namespace Piwik\Plugins\VisitorInterest;
+use Piwik\Plugins\VisitorInterest\Reports\GetNumberOfVisitsByDaysSinceLast;
+use Piwik\Plugins\VisitorInterest\Reports\GetNumberOfVisitsByVisitCount;
+use Piwik\Plugins\VisitorInterest\Reports\GetNumberOfVisitsPerPage;
+use Piwik\Plugins\VisitorInterest\Reports\GetNumberOfVisitsPerVisitDuration;
use Piwik\View;
-/**
- */
class Controller extends \Piwik\Plugin\Controller
{
public function index()
{
$view = new View('@VisitorInterest/index');
- $view->dataTableNumberOfVisitsPerVisitDuration = $this->getNumberOfVisitsPerVisitDuration(true);
- $view->dataTableNumberOfVisitsPerPage = $this->getNumberOfVisitsPerPage(true);
- $view->dataTableNumberOfVisitsByVisitNum = $this->getNumberOfVisitsByVisitCount(true);
- $view->dataTableNumberOfVisitsByDaysSinceLast = $this->getNumberOfVisitsByDaysSinceLast(true);
+ $view->dataTableNumberOfVisitsPerVisitDuration = $this->renderReport(new GetNumberOfVisitsPerVisitDuration());
+ $view->dataTableNumberOfVisitsPerPage = $this->renderReport(new GetNumberOfVisitsPerPage());
+ $view->dataTableNumberOfVisitsByVisitNum = $this->renderReport(new GetNumberOfVisitsByVisitCount());
+ $view->dataTableNumberOfVisitsByDaysSinceLast = $this->renderReport(new GetNumberOfVisitsByDaysSinceLast());
return $view->render();
}
-
- public function getNumberOfVisitsPerVisitDuration()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- public function getNumberOfVisitsPerPage()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Returns a report that lists the count of visits for different ranges of
- * a visitor's visit number.
- *
- * @return string The rendered report or nothing if $fetch is set to false.
- */
- public function getNumberOfVisitsByVisitCount()
- {
- return $this->renderReport(__FUNCTION__);
- }
-
- /**
- * Returns a rendered report that lists the count of visits for different ranges
- * of days since a visitor's last visit.
- *
- * @return string The rendered report or nothing if $fetch is set to false.
- */
- public function getNumberOfVisitsByDaysSinceLast()
- {
- return $this->renderReport(__FUNCTION__);
- }
}
diff --git a/plugins/VisitorInterest/Reports/Base.php b/plugins/VisitorInterest/Reports/Base.php
new file mode 100644
index 0000000000..fb3f0b4a42
--- /dev/null
+++ b/plugins/VisitorInterest/Reports/Base.php
@@ -0,0 +1,18 @@
+<?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\VisitorInterest\Reports;
+
+abstract class Base extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ $this->category = 'General_Visitors';
+ }
+
+}
diff --git a/plugins/VisitorInterest/Reports/GetNumberOfVisitsByDaysSinceLast.php b/plugins/VisitorInterest/Reports/GetNumberOfVisitsByDaysSinceLast.php
new file mode 100644
index 0000000000..c5a2aa471b
--- /dev/null
+++ b/plugins/VisitorInterest/Reports/GetNumberOfVisitsByDaysSinceLast.php
@@ -0,0 +1,47 @@
+<?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\VisitorInterest\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\VisitorInterest\Columns\VisitsByDaysSinceLastVisit;
+
+class GetNumberOfVisitsByDaysSinceLast extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new VisitsByDaysSinceLastVisit();
+ $this->name = Piwik::translate('VisitorInterest_VisitsByDaysSinceLast');
+ $this->documentation = Piwik::translate('VisitorInterest_WidgetVisitsByDaysSinceLastDocumentation');
+ $this->metrics = array('nb_visits');
+ $this->processedMetrics = false;
+ $this->constantRowsCount = true;
+ $this->order = 30;
+ $this->widgetTitle = 'VisitorInterest_WidgetVisitsByDaysSinceLast';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->requestConfig->filter_limit = 15;
+
+ $view->config->show_search = false;
+ $view->config->enable_sort = false;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->show_all_views_icons = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->addTranslation('label', Piwik::translate('General_DaysSinceLastVisit'));
+ }
+
+}
diff --git a/plugins/VisitorInterest/Reports/GetNumberOfVisitsByVisitCount.php b/plugins/VisitorInterest/Reports/GetNumberOfVisitsByVisitCount.php
new file mode 100644
index 0000000000..74cf975a4d
--- /dev/null
+++ b/plugins/VisitorInterest/Reports/GetNumberOfVisitsByVisitCount.php
@@ -0,0 +1,55 @@
+<?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\VisitorInterest\Reports;
+
+use Piwik\Metrics;
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\VisitorInterest\Columns\VisitsbyVisitNumber;
+
+class GetNumberOfVisitsByVisitCount extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new VisitsbyVisitNumber();
+ $this->name = Piwik::translate('VisitorInterest_visitsByVisitCount');
+ $this->documentation = Piwik::translate('VisitorInterest_WidgetVisitsByNumDocumentation')
+ . '<br />' . Piwik::translate('General_ChangeTagCloudView');
+ $this->metrics = array('nb_visits', 'nb_visits_percentage');
+ $this->processedMetrics = false;
+ $this->constantRowsCount = true;
+ $this->order = 25;
+ $this->widgetTitle = 'VisitorInterest_visitsByVisitCount';
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'asc';
+ $view->requestConfig->filter_limit = 15;
+
+ $view->config->addTranslations(array(
+ 'label' => Piwik::translate('VisitorInterest_VisitNum'),
+ 'nb_visits_percentage' => Metrics::getPercentVisitColumn())
+ );
+
+ $view->config->columns_to_display = array('label', 'nb_visits', 'nb_visits_percentage');
+ $view->config->show_exclude_low_population = false;
+
+ $view->config->enable_sort = false;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->show_search = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->show_all_views_icons = false;
+ }
+
+}
diff --git a/plugins/VisitorInterest/Reports/GetNumberOfVisitsPerPage.php b/plugins/VisitorInterest/Reports/GetNumberOfVisitsPerPage.php
new file mode 100644
index 0000000000..355b694406
--- /dev/null
+++ b/plugins/VisitorInterest/Reports/GetNumberOfVisitsPerPage.php
@@ -0,0 +1,60 @@
+<?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\VisitorInterest\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Cloud;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\VisitorInterest\Columns\PagesPerVisit;
+
+class GetNumberOfVisitsPerPage extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new PagesPerVisit();
+ $this->name = Piwik::translate('VisitorInterest_WidgetPages');
+ $this->documentation = Piwik::translate('VisitorInterest_WidgetPagesDocumentation')
+ . '<br />' . Piwik::translate('General_ChangeTagCloudView');
+ $this->metrics = array('nb_visits');
+ $this->processedMetrics = false;
+ $this->constantRowsCount = true;
+ $this->order = 20;
+ $this->widgetTitle = 'VisitorInterest_WidgetPages';
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return Cloud::ID;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'asc';
+
+ $view->config->addTranslation('label', Piwik::translate('VisitorInterest_ColumnVisitDuration'));
+ $view->config->enable_sort = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->show_search = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->columns_to_display = array('label', 'nb_visits');
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->show_series_picker = false;
+ $view->config->selectable_columns = array();
+ $view->config->max_graph_elements = 10;
+ }
+ }
+
+}
diff --git a/plugins/VisitorInterest/Reports/GetNumberOfVisitsPerVisitDuration.php b/plugins/VisitorInterest/Reports/GetNumberOfVisitsPerVisitDuration.php
new file mode 100644
index 0000000000..f518ce47c2
--- /dev/null
+++ b/plugins/VisitorInterest/Reports/GetNumberOfVisitsPerVisitDuration.php
@@ -0,0 +1,60 @@
+<?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\VisitorInterest\Reports;
+
+use Piwik\Piwik;
+use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Cloud;
+use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
+use Piwik\Plugins\VisitorInterest\Columns\VisitDuration;
+
+class GetNumberOfVisitsPerVisitDuration extends Base
+{
+ protected function init()
+ {
+ parent::init();
+ $this->dimension = new VisitDuration();
+ $this->name = Piwik::translate('VisitorInterest_WidgetLengths');
+ $this->documentation = Piwik::translate('VisitorInterest_WidgetLengthsDocumentation')
+ . '<br />' . Piwik::translate('General_ChangeTagCloudView');
+ $this->metrics = array('nb_visits');
+ $this->processedMetrics = false;
+ $this->constantRowsCount = true;
+ $this->order = 15;
+ $this->widgetTitle = 'VisitorInterest_WidgetLengths';
+ }
+
+ public function getDefaultTypeViewDataTable()
+ {
+ return Cloud::ID;
+ }
+
+ public function configureView(ViewDataTable $view)
+ {
+ $view->requestConfig->filter_sort_column = 'label';
+ $view->requestConfig->filter_sort_order = 'asc';
+
+ $view->config->addTranslation('label', $this->dimension->getName());
+ $view->config->enable_sort = false;
+ $view->config->show_exclude_low_population = false;
+ $view->config->show_offset_information = false;
+ $view->config->show_pagination_control = false;
+ $view->config->show_limit_control = false;
+ $view->config->show_search = false;
+ $view->config->show_table_all_columns = false;
+ $view->config->columns_to_display = array('label', 'nb_visits');
+
+ if ($view->isViewDataTableId(Graph::ID)) {
+ $view->config->show_series_picker = false;
+ $view->config->selectable_columns = array();
+ $view->config->max_graph_elements = 10;
+ }
+ }
+
+}
diff --git a/plugins/VisitorInterest/VisitorInterest.php b/plugins/VisitorInterest/VisitorInterest.php
index 0401883781..3a38f40c18 100644
--- a/plugins/VisitorInterest/VisitorInterest.php
+++ b/plugins/VisitorInterest/VisitorInterest.php
@@ -12,7 +12,6 @@ use Piwik\ArchiveProcessor;
use Piwik\FrontController;
use Piwik\Metrics;
use Piwik\Piwik;
-use Piwik\Plugin\ViewDataTable;
use Piwik\Plugins\CoreVisualizations\Visualizations\Cloud;
use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
@@ -21,79 +20,6 @@ use Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
*/
class VisitorInterest extends \Piwik\Plugin
{
- /**
- * @see Piwik\Plugin::getListHooksRegistered
- */
- public function getListHooksRegistered()
- {
- $hooks = array(
- 'API.getReportMetadata' => 'getReportMetadata',
- 'ViewDataTable.configure' => 'configureViewDataTable',
- 'ViewDataTable.getDefaultType' => 'getDefaultTypeViewDataTable'
- );
- return $hooks;
- }
-
- public function getReportMetadata(&$reports)
- {
- $reports[] = array(
- 'category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('VisitorInterest_WidgetLengths'),
- 'module' => 'VisitorInterest',
- 'action' => 'getNumberOfVisitsPerVisitDuration',
- 'dimension' => Piwik::translate('VisitorInterest_ColumnVisitDuration'),
- 'metrics' => array('nb_visits'),
- 'processedMetrics' => false,
- 'constantRowsCount' => true,
- 'documentation' => Piwik::translate('VisitorInterest_WidgetLengthsDocumentation')
- . '<br />' . Piwik::translate('General_ChangeTagCloudView'),
- 'order' => 15
- );
-
- $reports[] = array(
- 'category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('VisitorInterest_WidgetPages'),
- 'module' => 'VisitorInterest',
- 'action' => 'getNumberOfVisitsPerPage',
- 'dimension' => Piwik::translate('VisitorInterest_ColumnPagesPerVisit'),
- 'metrics' => array('nb_visits'),
- 'processedMetrics' => false,
- 'constantRowsCount' => true,
- 'documentation' => Piwik::translate('VisitorInterest_WidgetPagesDocumentation')
- . '<br />' . Piwik::translate('General_ChangeTagCloudView'),
- 'order' => 20
- );
-
- $reports[] = array(
- 'category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('VisitorInterest_visitsByVisitCount'),
- 'module' => 'VisitorInterest',
- 'action' => 'getNumberOfVisitsByVisitCount',
- 'dimension' => Piwik::translate('VisitorInterest_visitsByVisitCount'),
- 'metrics' => array(
- 'nb_visits',
- 'nb_visits_percentage' => Piwik::translate('General_ColumnPercentageVisits'),
- ),
- 'processedMetrics' => false,
- 'constantRowsCount' => true,
- 'documentation' => Piwik::translate('VisitorInterest_WidgetVisitsByNumDocumentation')
- . '<br />' . Piwik::translate('General_ChangeTagCloudView'),
- 'order' => 25
- );
-
- $reports[] = array(
- 'category' => Piwik::translate('General_Visitors'),
- 'name' => Piwik::translate('VisitorInterest_VisitsByDaysSinceLast'),
- 'module' => 'VisitorInterest',
- 'action' => 'getNumberOfVisitsByDaysSinceLast',
- 'dimension' => Piwik::translate('VisitorInterest_VisitsByDaysSinceLast'),
- 'metrics' => array('nb_visits'),
- 'processedMetrics' => false,
- 'constantRowsCount' => true,
- 'documentation' => Piwik::translate('VisitorInterest_WidgetVisitsByDaysSinceLastDocumentation'),
- 'order' => 30
- );
- }
function postLoad()
{
@@ -114,112 +40,4 @@ class VisitorInterest extends \Piwik\Plugin
$out .= FrontController::getInstance()->fetchDispatch('VisitorInterest', 'index');
$out .= '</div>';
}
-
- public function getDefaultTypeViewDataTable(&$defaultViewTypes)
- {
- $defaultViewTypes['VisitorInterest.getNumberOfVisitsPerVisitDuration'] = Cloud::ID;
- $defaultViewTypes['VisitorInterest.getNumberOfVisitsPerPage'] = Cloud::ID;
- }
-
- public function configureViewDataTable(ViewDataTable $view)
- {
- switch ($view->requestConfig->apiMethodToRequestDataTable) {
- case 'VisitorInterest.getNumberOfVisitsPerVisitDuration':
- $this->configureViewForGetNumberOfVisitsPerVisitDuration($view);
- break;
- case 'VisitorInterest.getNumberOfVisitsPerPage':
- $this->configureViewForGetNumberOfVisitsPerPage($view);
- break;
- case 'VisitorInterest.getNumberOfVisitsByVisitCount':
- $this->configureViewForGetNumberOfVisitsByVisitCount($view);
- break;
- case 'VisitorInterest.getNumberOfVisitsByDaysSinceLast':
- $this->configureViewForGetNumberOfVisitsByDaysSinceLast($view);
- break;
- }
- }
-
- private function configureViewForGetNumberOfVisitsPerVisitDuration(ViewDataTable $view)
- {
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'asc';
-
- $view->config->addTranslation('label', Piwik::translate('VisitorInterest_ColumnVisitDuration'));
- $view->config->enable_sort = false;
- $view->config->show_exclude_low_population = false;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->show_search = false;
- $view->config->show_table_all_columns = false;
- $view->config->columns_to_display = array('label', 'nb_visits');
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->show_series_picker = false;
- $view->config->selectable_columns = array();
- $view->config->max_graph_elements = 10;
- }
- }
-
- private function configureViewForGetNumberOfVisitsPerPage(ViewDataTable $view)
- {
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'asc';
-
- $view->config->addTranslation('label', Piwik::translate('VisitorInterest_ColumnVisitDuration'));
- $view->config->enable_sort = false;
- $view->config->show_exclude_low_population = false;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->show_search = false;
- $view->config->show_table_all_columns = false;
- $view->config->columns_to_display = array('label', 'nb_visits');
-
- if ($view->isViewDataTableId(Graph::ID)) {
- $view->config->show_series_picker = false;
- $view->config->selectable_columns = array();
- $view->config->max_graph_elements = 10;
- }
- }
-
- private function configureViewForGetNumberOfVisitsByVisitCount(ViewDataTable $view)
- {
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'asc';
- $view->requestConfig->filter_limit = 15;
-
- $view->config->addTranslations(array(
- 'label' => Piwik::translate('VisitorInterest_VisitNum'),
- 'nb_visits_percentage' => Metrics::getPercentVisitColumn())
- );
-
- $view->config->columns_to_display = array('label', 'nb_visits', 'nb_visits_percentage');
- $view->config->show_exclude_low_population = false;
-
- $view->config->enable_sort = false;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->show_search = false;
- $view->config->show_table_all_columns = false;
- $view->config->show_all_views_icons = false;
- }
-
- private function configureViewForGetNumberOfVisitsByDaysSinceLast(ViewDataTable $view)
- {
- $view->requestConfig->filter_sort_column = 'label';
- $view->requestConfig->filter_sort_order = 'asc';
- $view->requestConfig->filter_limit = 15;
-
- $view->config->show_search = false;
- $view->config->enable_sort = false;
- $view->config->show_offset_information = false;
- $view->config->show_pagination_control = false;
- $view->config->show_limit_control = false;
- $view->config->show_all_views_icons = false;
- $view->config->show_table_all_columns = false;
- $view->config->show_exclude_low_population = false;
- $view->config->addTranslation('label', Piwik::translate('General_DaysSinceLastVisit'));
- }
}
diff --git a/plugins/VisitorInterest/Widgets.php b/plugins/VisitorInterest/Widgets.php
deleted file mode 100644
index 3548840af2..0000000000
--- a/plugins/VisitorInterest/Widgets.php
+++ /dev/null
@@ -1,26 +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
- *
- */
-namespace Piwik\Plugins\VisitorInterest;
-
-use Piwik\WidgetsList;
-
-class Widgets extends \Piwik\Plugin\Widgets
-{
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'General_Visitors';
- $controller = 'VisitorInterest';
-
- $widgetsList->add($category, 'VisitorInterest_WidgetLengths', $controller, 'getNumberOfVisitsPerVisitDuration');
- $widgetsList->add($category, 'VisitorInterest_WidgetPages', $controller, 'getNumberOfVisitsPerPage');
- $widgetsList->add($category, 'VisitorInterest_visitsByVisitCount', $controller, 'getNumberOfVisitsByVisitCount');
- $widgetsList->add($category, 'VisitorInterest_WidgetVisitsByDaysSinceLast', $controller, 'getNumberOfVisitsByDaysSinceLast');
- }
-
-}
diff --git a/plugins/VisitsSummary/Reports/Get.php b/plugins/VisitsSummary/Reports/Get.php
new file mode 100644
index 0000000000..83b74d987d
--- /dev/null
+++ b/plugins/VisitsSummary/Reports/Get.php
@@ -0,0 +1,46 @@
+<?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\VisitsSummary\Reports;
+
+use Piwik\Piwik;
+
+class Get extends \Piwik\Plugin\Report
+{
+ protected function init()
+ {
+ parent::init();
+ $this->category = 'VisitsSummary_VisitsSummary';
+ $this->name = Piwik::translate('VisitsSummary_VisitsSummary');
+ $this->documentation = ''; // TODO
+ $this->processedMetrics = false;
+ $this->metrics = array(
+ 'nb_uniq_visitors',
+ 'nb_visits',
+ 'nb_actions',
+ 'nb_actions_per_visit',
+ 'bounce_rate',
+ 'avg_time_on_site',
+ 'max_actions'
+ );
+ // Used to process metrics, not displayed/used directly
+// 'sum_visit_length',
+// 'nb_visits_converted',
+ $this->order = 1;
+ }
+
+ public function getMetrics()
+ {
+ $metrics = parent::getMetrics();
+
+ $metrics['avg_time_on_site'] = Piwik::translate('General_VisitDuration');
+ $metrics['max_actions'] = Piwik::translate('General_ColumnMaxActions');
+
+ return $metrics;
+ }
+}
diff --git a/plugins/VisitsSummary/VisitsSummary.php b/plugins/VisitsSummary/VisitsSummary.php
index 3c3bcceda8..066a8e2e35 100644
--- a/plugins/VisitsSummary/VisitsSummary.php
+++ b/plugins/VisitsSummary/VisitsSummary.php
@@ -8,8 +8,6 @@
*/
namespace Piwik\Plugins\VisitsSummary;
-use Piwik\Piwik;
-
/**
* Note: This plugin does not hook on Daily and Period Archiving like other Plugins because it reports the
* very core metrics (visits, actions, visit duration, etc.) which are processed in the Core
@@ -25,32 +23,7 @@ class VisitsSummary extends \Piwik\Plugin
public function getListHooksRegistered()
{
return array(
- 'API.getReportMetadata' => 'getReportMetadata',
- 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
- );
- }
-
- public function getReportMetadata(&$reports)
- {
- $reports[] = array(
- 'category' => Piwik::translate('VisitsSummary_VisitsSummary'),
- 'name' => Piwik::translate('VisitsSummary_VisitsSummary'),
- 'module' => 'VisitsSummary',
- 'action' => 'get',
- 'metrics' => array(
- 'nb_uniq_visitors',
- 'nb_visits',
- 'nb_actions',
- 'nb_actions_per_visit',
- 'bounce_rate',
- 'avg_time_on_site' => Piwik::translate('General_VisitDuration'),
- 'max_actions' => Piwik::translate('General_ColumnMaxActions'),
-// Used to process metrics, not displayed/used directly
-// 'sum_visit_length',
-// 'nb_visits_converted',
- ),
- 'processedMetrics' => false,
- 'order' => 1
+ 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles'
);
}
diff --git a/plugins/VisitsSummary/Widgets.php b/plugins/VisitsSummary/Widgets.php
index 3e1b5cfbfe..5ec7eef56e 100644
--- a/plugins/VisitsSummary/Widgets.php
+++ b/plugins/VisitsSummary/Widgets.php
@@ -8,18 +8,15 @@
*/
namespace Piwik\Plugins\VisitsSummary;
-use Piwik\WidgetsList;
-
class Widgets extends \Piwik\Plugin\Widgets
{
- public function configure(WidgetsList $widgetsList)
- {
- $category = 'VisitsSummary_VisitsSummary';
- $controller = 'VisitsSummary';
+ protected $category = 'VisitsSummary_VisitsSummary';
- $widgetsList->add($category, 'VisitsSummary_WidgetLastVisits', $controller, 'getEvolutionGraph', array('columns' => array('nb_visits')));
- $widgetsList->add($category, 'VisitsSummary_WidgetVisits', $controller, 'getSparklines');
- $widgetsList->add($category, 'VisitsSummary_WidgetOverviewGraph', $controller, 'index');
+ public function init()
+ {
+ $this->addWidget('VisitsSummary_WidgetLastVisits', 'getEvolutionGraph', array('columns' => array('nb_visits')));
+ $this->addWidget('VisitsSummary_WidgetVisits', 'getSparklines');
+ $this->addWidget('VisitsSummary_WidgetOverviewGraph', 'index');
}
}
diff --git a/plugins/Widgetize/Controller.php b/plugins/Widgetize/Controller.php
index afdd38d42d..043ff8134d 100644
--- a/plugins/Widgetize/Controller.php
+++ b/plugins/Widgetize/Controller.php
@@ -48,17 +48,20 @@ class Controller extends \Piwik\Plugin\Controller
{
Request::reloadAuthUsingTokenAuth();
$this->init();
+
$controllerName = Common::getRequestVar('moduleToWidgetize');
- $actionName = Common::getRequestVar('actionToWidgetize');
- $outputDataTable = FrontController::getInstance()->fetchDispatch($controllerName, $actionName);
+ $actionName = Common::getRequestVar('actionToWidgetize');
+
if ($controllerName == 'Dashboard' && $actionName == 'index') {
$view = new View('@Widgetize/iframe_empty');
} else {
$view = new View('@Widgetize/iframe');
}
+
$this->setGeneralVariablesView($view);
$view->setXFrameOptions('allow');
- $view->content = $outputDataTable;
+ $view->content = FrontController::getInstance()->fetchDispatch($controllerName, $actionName);
+
return $view->render();
}
}
diff --git a/plugins/Widgetize/Widgetize.php b/plugins/Widgetize/Widgetize.php
index 992155a061..c01c8638be 100644
--- a/plugins/Widgetize/Widgetize.php
+++ b/plugins/Widgetize/Widgetize.php
@@ -9,12 +9,7 @@
*/
namespace Piwik\Plugins\Widgetize;
-use Piwik\Menu\MenuTop;
-use Piwik\Piwik;
-/**
- *
- */
class Widgetize extends \Piwik\Plugin
{
/**
diff --git a/tests/PHPUnit/Core/AssetManager/configs/merged-assets-disabled.ini.php b/tests/PHPUnit/Core/AssetManager/configs/merged-assets-disabled.ini.php
index 00887b8c52..610d020da1 100644
--- a/tests/PHPUnit/Core/AssetManager/configs/merged-assets-disabled.ini.php
+++ b/tests/PHPUnit/Core/AssetManager/configs/merged-assets-disabled.ini.php
@@ -1,2 +1,2 @@
-[Debug]
+[Development]
disable_merged_assets = 1
diff --git a/tests/PHPUnit/Core/AssetManager/configs/merged-assets-enabled.ini.php b/tests/PHPUnit/Core/AssetManager/configs/merged-assets-enabled.ini.php
index df10787203..69a1facd8a 100644
--- a/tests/PHPUnit/Core/AssetManager/configs/merged-assets-enabled.ini.php
+++ b/tests/PHPUnit/Core/AssetManager/configs/merged-assets-enabled.ini.php
@@ -1,2 +1,2 @@
-[Debug]
+[Development]
disable_merged_assets = 0
diff --git a/tests/PHPUnit/Fixture.php b/tests/PHPUnit/Fixture.php
index b94ffcc4e2..b12516136d 100644
--- a/tests/PHPUnit/Fixture.php
+++ b/tests/PHPUnit/Fixture.php
@@ -31,13 +31,13 @@ use Piwik\Site;
use Piwik\Tracker\Cache;
use Piwik\Translate;
use Piwik\Url;
-use Piwik\Plugins\CoreUpdater\CoreUpdater;
-use Piwik\Updater;
use PHPUnit_Framework_Assert;
use Piwik_TestingEnvironment;
use FakeAccess;
use PiwikTracker;
use Piwik_LocalTracker;
+use Piwik\Updater;
+use Piwik\Plugins\CoreUpdater\CoreUpdater;
/**
* Base type for all integration test fixtures. Integration test fixtures
@@ -159,9 +159,12 @@ class Fixture extends PHPUnit_Framework_Assert
Config::getInstance()->database['dbname'] = $this->dbName;
Db::createDatabaseObject();
+ Db::get()->query("SET wait_timeout=28800;");
+
DbHelper::createTables();
\Piwik\Plugin\Manager::getInstance()->unloadPlugins();
+
} catch (Exception $e) {
static::fail("TEST INITIALIZATION FAILED: " . $e->getMessage() . "\n" . $e->getTraceAsString());
}
@@ -187,6 +190,13 @@ class Fixture extends PHPUnit_Framework_Assert
static::loadAllPlugins($this->getTestEnvironment(), $this->testCaseClass, $this->extraPluginsToLoad);
+ $updater = new Updater();
+ $componentsWithUpdateFile = CoreUpdater::getComponentUpdates($updater);
+
+ if (!empty($componentsWithUpdateFile)) {
+ CoreUpdater::updateComponents($updater, $componentsWithUpdateFile);
+ }
+
$_GET = $_REQUEST = array();
$_SERVER['HTTP_REFERER'] = '';
@@ -325,7 +335,8 @@ class Fixture extends PHPUnit_Framework_Assert
public static function unloadAllPlugins()
{
try {
- $plugins = \Piwik\Plugin\Manager::getInstance()->getLoadedPlugins();
+ $manager = \Piwik\Plugin\Manager::getInstance();
+ $plugins = $manager->getLoadedPlugins();
foreach ($plugins AS $plugin) {
$plugin->uninstall();
}
diff --git a/tests/PHPUnit/Fixtures/OmniFixture.php b/tests/PHPUnit/Fixtures/OmniFixture.php
index ad1e6d8252..406deb77bc 100644
--- a/tests/PHPUnit/Fixtures/OmniFixture.php
+++ b/tests/PHPUnit/Fixtures/OmniFixture.php
@@ -90,7 +90,7 @@ class OmniFixture extends Fixture
public function setUp()
{
- foreach ($this->fixtures as $name => $fixture) {
+ foreach ($this->fixtures as $fixture) {
$fixture->setUp();
}
diff --git a/tests/PHPUnit/Fixtures/UITestFixture.php b/tests/PHPUnit/Fixtures/UITestFixture.php
index 50c49bade9..6afbfb2b6d 100644
--- a/tests/PHPUnit/Fixtures/UITestFixture.php
+++ b/tests/PHPUnit/Fixtures/UITestFixture.php
@@ -18,6 +18,8 @@ use Piwik\FrontController;
use Piwik\Option;
use Piwik\Plugins\SegmentEditor\API as APISegmentEditor;
use Piwik\Plugins\UsersManager\API as UsersManagerAPI;
+use Piwik\Plugins\VisitsSummary\API as VisitsSummaryAPI;
+use Piwik\Plugins\SitesManager\API as SitesManagerAPI;
use Piwik\WidgetsList;
use Piwik\Tests\Fixture;
use Piwik\Tests\OverrideLogin;
@@ -52,6 +54,7 @@ class UITestFixture extends SqlDump
DbHelper::createAnonymousUser();
UsersManagerAPI::getInstance()->setSuperUserAccess('superUserLogin', true);
+ SitesManagerAPI::getInstance()->updateSite(1, null, null, true);
}
public function performSetUp($setupEnvironmentOnly = false)
diff --git a/tests/PHPUnit/Integration/AutoSuggestAPITest.php b/tests/PHPUnit/Integration/AutoSuggestAPITest.php
index f415241dab..f893d258c6 100644
--- a/tests/PHPUnit/Integration/AutoSuggestAPITest.php
+++ b/tests/PHPUnit/Integration/AutoSuggestAPITest.php
@@ -134,8 +134,8 @@ class AutoSuggestAPITest extends IntegrationTestCase
*/
public function testCheckOtherTestsWereComplete()
{
- // Check that only a few haven't been tested specifically (these are all custom variables slots since we only test slot 1, 2, 5 (see the fixture))
- $maximumSegmentsToSkip = 11;
+ // Check that only a few haven't been tested specifically (these are all custom variables slots since we only test slot 1, 2, 5 (see the fixture) and example dimension slots)
+ $maximumSegmentsToSkip = 14;
$this->assertTrue(count(self::$skipped) <= $maximumSegmentsToSkip, 'SKIPPED ' . count(self::$skipped) . ' segments --> some segments had no "auto-suggested values"
but we should try and test the autosuggest for all new segments. Segments skipped were: ' . implode(', ', self::$skipped));
@@ -146,4 +146,4 @@ class AutoSuggestAPITest extends IntegrationTestCase
}
AutoSuggestAPITest::$fixture = new ManyVisitsWithGeoIP();
-AutoSuggestAPITest::$fixture->dateTime = Date::yesterday()->subDay(30)->getDatetime(); \ No newline at end of file
+AutoSuggestAPITest::$fixture->dateTime = Date::yesterday()->subDay(30)->getDatetime();
diff --git a/tests/PHPUnit/Core/JsProxyTest.php b/tests/PHPUnit/Integration/Core/JsProxyTest.php
index 91fe30dfae..91fe30dfae 100644
--- a/tests/PHPUnit/Core/JsProxyTest.php
+++ b/tests/PHPUnit/Integration/Core/JsProxyTest.php
diff --git a/tests/PHPUnit/Integration/PurgeDataTest.php b/tests/PHPUnit/Integration/PurgeDataTest.php
index 06e3e7595a..29d7ccc084 100755
--- a/tests/PHPUnit/Integration/PurgeDataTest.php
+++ b/tests/PHPUnit/Integration/PurgeDataTest.php
@@ -25,6 +25,15 @@ class PurgeDataTest extends IntegrationTestCase
{
public static $fixture = null; // initialized below class definition
+ public static function setUpBeforeClass()
+ {
+
+ }
+ public static function tearDownBeforeClass()
+ {
+
+ }
+
public function setUp()
{
parent::setUpBeforeClass();
@@ -182,4 +191,4 @@ class PurgeDataTest extends IntegrationTestCase
}
}
-PurgeDataTest::$fixture = new OneVisitorTwoVisits(); \ No newline at end of file
+PurgeDataTest::$fixture = new OneVisitorTwoVisits();
diff --git a/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_achievementPoints__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_achievementPoints__API.getSuggestedValuesForSegment.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_achievementPoints__API.getSuggestedValuesForSegment.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_keywords__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_keywords__API.getSuggestedValuesForSegment.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_keywords__API.getSuggestedValuesForSegment.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_myConversionSegmentName__API.getSuggestedValuesForSegment.xml b/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_myConversionSegmentName__API.getSuggestedValuesForSegment.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_AutoSuggestAPITest_myConversionSegmentName__API.getSuggestedValuesForSegment.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_ImportLogs__ExamplePlugin.getExampleReport.xml b/tests/PHPUnit/Integration/expected/test_ImportLogs__ExamplePlugin.getExampleReport.xml
new file mode 100644
index 0000000000..1b2fed39f9
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_ImportLogs__ExamplePlugin.getExampleReport.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <row>
+ <nb_visits>5</nb_visits>
+ </row>
+</result> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric__API.getProcessedReport_day.xml
index ad4b1d21f3..ea574a289f 100644
--- a/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageUrls</action>
<dimension>Page URL</dimension>
+ <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -22,7 +23,6 @@
<avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
- <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=day&amp;date=2010-01-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=day&amp;date=2009-12-05,2010-01-03</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric_constantRowsCountShouldKeepEmptyRows__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric_constantRowsCountShouldKeepEmptyRows__API.getProcessedReport_day.xml
index 44760dc087..5386b28232 100644
--- a/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric_constantRowsCountShouldKeepEmptyRows__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ManyVisitorsOneWebsiteTest_sortByProcessedMetric_constantRowsCountShouldKeepEmptyRows__API.getProcessedReport_day.xml
@@ -9,29 +9,22 @@
<action>getVisitInformationPerServerTime</action>
<dimension>Server time</dimension>
<documentation>This graph shows what time it was in the &lt;strong&gt; server's time zone &lt;/strong&gt; during the visits.</documentation>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__ExamplePlugin.getExampleReport.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__ExamplePlugin.getExampleReport.xml
new file mode 100644
index 0000000000..1b2fed39f9
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__ExamplePlugin.getExampleReport.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <row>
+ <nb_visits>5</nb_visits>
+ </row>
+</result> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__subtable__API.getProcessedReport_week.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__subtable__API.getProcessedReport_week.xml
index 1b53d25ac9..7279329235 100644
--- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__subtable__API.getProcessedReport_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__subtable__API.getProcessedReport_week.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageUrls</action>
<dimension>Page URL</dimension>
+ <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -24,7 +25,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=week&amp;date=2010-03-06&amp;idSubtable=</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=week&amp;date=2009-08-10,2010-03-07&amp;idSubtable=</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml
index 6b905f647f..fe3da65352 100644
--- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_hideColumns___API.getProcessedReport_day.xml
@@ -8,13 +8,13 @@
<module>Actions</module>
<action>getPageTitles</action>
<dimension>Page Name</dimension>
+ <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<metrics>
<exit_rate>Exit rate</exit_rate>
</metrics>
<metricsDocumentation>
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
- <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<actionToLoadSubTables>getPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2010-03-06</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2010-02-05,2010-03-06</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumnsWithProcessedMetrics___API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumnsWithProcessedMetrics___API.getProcessedReport_day.xml
index c204596614..1a1180bbff 100644
--- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumnsWithProcessedMetrics___API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumnsWithProcessedMetrics___API.getProcessedReport_day.xml
@@ -9,13 +9,13 @@
<action>getVisitInformationPerServerTime</action>
<dimension>Server time</dimension>
<documentation>This graph shows what time it was in the &lt;strong&gt; server's time zone &lt;/strong&gt; during the visits.</documentation>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_visits>Visits</nb_visits>
</metrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
</metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml
index d63a5ec71c..6c94a197f7 100644
--- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_showColumns___API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageTitles</action>
<dimension>Page Name</dimension>
+ <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<bounce_rate>Bounce Rate</bounce_rate>
@@ -16,7 +17,6 @@
<nb_hits>The number of times this page was visited.</nb_hits>
<bounce_rate>The percentage of visits that started on this page and left the website straight away.</bounce_rate>
</metricsDocumentation>
- <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<actionToLoadSubTables>getPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2010-03-06</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2010-02-05,2010-03-06</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_RowEvolution_entryPageTitles__API.getRowEvolution_day.xml b/tests/PHPUnit/Integration/expected/test_RowEvolution_entryPageTitles__API.getRowEvolution_day.xml
index 27eb97f81e..e73ba39d1d 100644
--- a/tests/PHPUnit/Integration/expected/test_RowEvolution_entryPageTitles__API.getRowEvolution_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_RowEvolution_entryPageTitles__API.getRowEvolution_day.xml
@@ -110,6 +110,6 @@
<max>100</max>
</bounce_rate>
</metrics>
- <dimension>Page Name</dimension>
+ <dimension>Entry Page title</dimension>
</metadata>
</result> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml
index 2257d15106..e1254c611b 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageTitlesFollowingSiteSearch</action>
<dimension>Destination Page</dimension>
+ <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits_following_search>Clicked in search results</nb_hits_following_search>
<nb_hits>Total Pageviews</nb_hits>
@@ -16,7 +17,6 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
- <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitlesFollowingSiteSearch&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitlesFollowingSiteSearch&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
<uniqueId>Actions_getPageTitlesFollowingSiteSearch</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml
index ba0cfd4ca6..358b09c180 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitlesFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageTitlesFollowingSiteSearch</action>
<dimension>Destination Page</dimension>
+ <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits_following_search>Clicked in search results</nb_hits_following_search>
<nb_hits>Total Pageviews</nb_hits>
@@ -16,7 +17,6 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
- <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitlesFollowingSiteSearch&amp;period=range&amp;date=2010-01-03,2010-07-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitlesFollowingSiteSearch&amp;period=month&amp;date=2010-01-03,2010-07-03</imageGraphEvolutionUrl>
<uniqueId>Actions_getPageTitlesFollowingSiteSearch</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml
index 4fddcb23fb..c1f7037343 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageTitles</action>
<dimension>Page Name</dimension>
+ <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -24,7 +25,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<actionToLoadSubTables>getPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_month.xml
index fc5ea10e47..33516984c8 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_month.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageTitles</action>
<dimension>Page Name</dimension>
+ <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -24,7 +25,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<actionToLoadSubTables>getPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=range&amp;date=2010-01-03,2010-07-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=month&amp;date=2010-01-03,2010-07-03</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml
index 267fc71a02..a139b8c186 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageUrlsFollowingSiteSearch</action>
<dimension>Destination Page</dimension>
+ <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits_following_search>Clicked in search results</nb_hits_following_search>
<nb_hits>Total Pageviews</nb_hits>
@@ -16,7 +17,6 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
- <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrlsFollowingSiteSearch&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrlsFollowingSiteSearch&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
<uniqueId>Actions_getPageUrlsFollowingSiteSearch</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml
index 891b6485a6..ddbfc27323 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrlsFollowingSiteSearch_firstSite_lastN__API.getProcessedReport_month.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageUrlsFollowingSiteSearch</action>
<dimension>Destination Page</dimension>
+ <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits_following_search>Clicked in search results</nb_hits_following_search>
<nb_hits>Total Pageviews</nb_hits>
@@ -16,7 +17,6 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
- <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrlsFollowingSiteSearch&amp;period=range&amp;date=2010-01-03,2010-07-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrlsFollowingSiteSearch&amp;period=month&amp;date=2010-01-03,2010-07-03</imageGraphEvolutionUrl>
<uniqueId>Actions_getPageUrlsFollowingSiteSearch</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml
index afc1d09316..3778066188 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageUrls</action>
<dimension>Page URL</dimension>
+ <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -24,7 +25,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_month.xml
index 2e1f0405ff..c4d5795571 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_month.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageUrls</action>
<dimension>Page URL</dimension>
+ <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -24,7 +25,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=range&amp;date=2010-01-03,2010-07-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=month&amp;date=2010-01-03,2010-07-03</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_day.xml
index 9f2dac1197..48dec5534c 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getSiteSearchCategories</action>
<dimension>Search Category</dimension>
+ <documentation>This report lists the Categories that visitors selected when they made a Search on your website.&lt;br/&gt;For example, Ecommerce websites typically have a &quot;Category&quot; selector so that visitors can restrict their searches to all products in a specific Category.</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<nb_pages_per_search>Search Results pages</nb_pages_per_search>
@@ -18,7 +19,6 @@
<nb_pages_per_search>Visitors will search on your website, and sometimes click &quot;next&quot; to view more results. This is the average number of search results pages viewed for this keyword.</nb_pages_per_search>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>This report lists the Categories that visitors selected when they made a Search on your website.&lt;br/&gt;For example, Ecommerce websites typically have a &quot;Category&quot; selector so that visitors can restrict their searches to all products in a specific Category.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchCategories&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchCategories&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchCategories</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_month.xml
index 76f0c59e99..cb33390062 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchCategories_firstSite_lastN__API.getProcessedReport_month.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getSiteSearchCategories</action>
<dimension>Search Category</dimension>
+ <documentation>This report lists the Categories that visitors selected when they made a Search on your website.&lt;br/&gt;For example, Ecommerce websites typically have a &quot;Category&quot; selector so that visitors can restrict their searches to all products in a specific Category.</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<nb_pages_per_search>Search Results pages</nb_pages_per_search>
@@ -18,7 +19,6 @@
<nb_pages_per_search>Visitors will search on your website, and sometimes click &quot;next&quot; to view more results. This is the average number of search results pages viewed for this keyword.</nb_pages_per_search>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>This report lists the Categories that visitors selected when they made a Search on your website.&lt;br/&gt;For example, Ecommerce websites typically have a &quot;Category&quot; selector so that visitors can restrict their searches to all products in a specific Category.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchCategories&amp;period=range&amp;date=2010-01-03,2010-07-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchCategories&amp;period=month&amp;date=2010-01-03,2010-07-03</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchCategories</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_day.xml
index f54f55fa27..84b4b19ea1 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getSiteSearchKeywords</action>
<dimension>Keyword</dimension>
+ <documentation>This report lists the Search Keywords that visitors searched for on your internal Search Engine.&lt;br/&gt;&lt;br/&gt;Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;http://piwik.org/docs/site-search/&quot; target=&quot;_blank&quot;&gt;Learn more about Tracking how your visitors use your Search engine.&lt;/a&gt;</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<nb_pages_per_search>Search Results pages</nb_pages_per_search>
@@ -18,7 +19,6 @@
<nb_pages_per_search>Visitors will search on your website, and sometimes click &quot;next&quot; to view more results. This is the average number of search results pages viewed for this keyword.</nb_pages_per_search>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>This report lists the Search Keywords that visitors searched for on your internal Search Engine.&lt;br/&gt;&lt;br/&gt;Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;http://piwik.org/docs/site-search/&quot; target=&quot;_blank&quot;&gt;Learn more about Tracking how your visitors use your Search engine.&lt;/a&gt;</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchKeywords&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchKeywords&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchKeywords</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_month.xml
index 224ae8f903..133ef2f538 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchKeywords_firstSite_lastN__API.getProcessedReport_month.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getSiteSearchKeywords</action>
<dimension>Keyword</dimension>
+ <documentation>This report lists the Search Keywords that visitors searched for on your internal Search Engine.&lt;br/&gt;&lt;br/&gt;Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;http://piwik.org/docs/site-search/&quot; target=&quot;_blank&quot;&gt;Learn more about Tracking how your visitors use your Search engine.&lt;/a&gt;</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<nb_pages_per_search>Search Results pages</nb_pages_per_search>
@@ -18,7 +19,6 @@
<nb_pages_per_search>Visitors will search on your website, and sometimes click &quot;next&quot; to view more results. This is the average number of search results pages viewed for this keyword.</nb_pages_per_search>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>This report lists the Search Keywords that visitors searched for on your internal Search Engine.&lt;br/&gt;&lt;br/&gt;Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;http://piwik.org/docs/site-search/&quot; target=&quot;_blank&quot;&gt;Learn more about Tracking how your visitors use your Search engine.&lt;/a&gt;</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchKeywords&amp;period=range&amp;date=2010-01-03,2010-07-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchKeywords&amp;period=month&amp;date=2010-01-03,2010-07-03</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchKeywords</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_day.xml
index c470b54e87..e52d6cd8f3 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getSiteSearchNoResultKeywords</action>
<dimension>Keyword with No Search Result</dimension>
+ <documentation>Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br /&gt;&lt;br /&gt;This report lists the Search Keywords that did not return any Search result: maybe the search engine algorithm can be improved, or maybe your visitors are looking for content that is not (yet) on your website?</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<exit_rate>% Search Exits</exit_rate>
@@ -16,7 +17,6 @@
<nb_visits>The number of visits that searched for this keyword on your website's search engine.</nb_visits>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br /&gt;&lt;br /&gt;This report lists the Search Keywords that did not return any Search result: maybe the search engine algorithm can be improved, or maybe your visitors are looking for content that is not (yet) on your website?</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchNoResultKeywords&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchNoResultKeywords&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchNoResultKeywords</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_month.xml
index e24254261c..63ba94eaf9 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.getSiteSearchNoResultKeywords_firstSite_lastN__API.getProcessedReport_month.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getSiteSearchNoResultKeywords</action>
<dimension>Keyword with No Search Result</dimension>
+ <documentation>Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br /&gt;&lt;br /&gt;This report lists the Search Keywords that did not return any Search result: maybe the search engine algorithm can be improved, or maybe your visitors are looking for content that is not (yet) on your website?</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<exit_rate>% Search Exits</exit_rate>
@@ -16,7 +17,6 @@
<nb_visits>The number of visits that searched for this keyword on your website's search engine.</nb_visits>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br /&gt;&lt;br /&gt;This report lists the Search Keywords that did not return any Search result: maybe the search engine algorithm can be improved, or maybe your visitors are looking for content that is not (yet) on your website?</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchNoResultKeywords&amp;period=range&amp;date=2010-01-03,2010-07-03</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchNoResultKeywords&amp;period=month&amp;date=2010-01-03,2010-07-03</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchNoResultKeywords</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml
index 2091e19992..1e7e2b8d0c 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_day.xml
@@ -7,7 +7,6 @@
<name>Custom Variables</name>
<module>CustomVariables</module>
<action>getCustomVariables</action>
- <actionToLoadSubTables>getCustomVariablesValuesFromNameId</actionToLoadSubTables>
<dimension>Custom Variable name</dimension>
<documentation>This report contains information about your Custom Variables. Click on a variable name to see the distribution of the values. &lt;br /&gt; For more information about Custom Variables in general, read the &lt;a href=&quot;http://piwik.org/docs/custom-variables/&quot; target=&quot;_blank&quot;&gt;Custom Variables documentation on piwik.org&lt;/a&gt;</documentation>
<metrics>
@@ -15,23 +14,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getCustomVariablesValuesFromNameId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml
index 8b0c92adf2..a34a4ccc8f 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_CustomVariables.getCustomVariables_firstSite_lastN__API.getProcessedReport_month.xml
@@ -7,30 +7,23 @@
<name>Custom Variables</name>
<module>CustomVariables</module>
<action>getCustomVariables</action>
- <actionToLoadSubTables>getCustomVariablesValuesFromNameId</actionToLoadSubTables>
<dimension>Custom Variable name</dimension>
<documentation>This report contains information about your Custom Variables. Click on a variable name to see the distribution of the values. &lt;br /&gt; For more information about Custom Variables in general, read the &lt;a href=&quot;http://piwik.org/docs/custom-variables/&quot; target=&quot;_blank&quot;&gt;Custom Variables documentation on piwik.org&lt;/a&gt;</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getCustomVariablesValuesFromNameId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml
index f6fbe6a31a..85885d4462 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getOutlinks</action>
<dimension>Clicked URL</dimension>
+ <documentation>This report shows a hierarchical list of outlink URLs that were clicked by your visitors. An outlink is a link that leads the visitor away from your website (to another domain).&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_visits>Unique Clicks</nb_visits>
<nb_hits>Clicks</nb_hits>
@@ -16,7 +17,6 @@
<nb_visits>The number of visits that involved a click on this link. If a link was clicked multiple times during one visit, it is only counted once.</nb_visits>
<nb_hits>The number of times this link was clicked.</nb_hits>
</metricsDocumentation>
- <documentation>This report shows a hierarchical list of outlink URLs that were clicked by your visitors. An outlink is a link that leads the visitor away from your website (to another domain).&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getOutlinks</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getOutlinks&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getOutlinks&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml
index 3fdf8404b4..7d8be22272 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageTitles</action>
<dimension>Page Name</dimension>
+ <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -24,7 +25,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<actionToLoadSubTables>getPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml
index 08ce9a57b0..dfccc81659 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,6 +8,7 @@
<module>Actions</module>
<action>getPageUrls</action>
<dimension>Page URL</dimension>
+ <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -24,7 +25,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml
index 07b29ed772..5518322f9d 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,10 +8,10 @@
<module>Goals</module>
<action>getDaysToConversion</action>
<dimension>Days to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml
index ccdae6dd68..31f9f11927 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml
@@ -26,15 +26,8 @@
</metrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
+ <nb_pageviews>The number of times this page was visited.</nb_pageviews>
</metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=MultiSites&amp;apiAction=getAll&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=MultiSites&amp;apiAction=getAll&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referrers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referrers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml
index 04bde10b70..59aea854d4 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referrers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referrers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml
@@ -9,29 +9,22 @@
<action>getWebsites</action>
<dimension>Website</dimension>
<documentation>In this table, you can see which websites referred visitors to your site. &lt;br /&gt; By clicking on a row in the table, you can see which URLs the links to your website were on.</documentation>
- <actionToLoadSubTables>getUrlsFromWebsiteId</actionToLoadSubTables>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getUrlsFromWebsiteId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml
index 8e79d6b766..fa28a54c25 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml
@@ -15,18 +15,6 @@
<nb_actions_per_visit_returning>Avg. Actions per Returning Visit</nb_actions_per_visit_returning>
<nb_uniq_visitors_returning>Unique returning visitors</nb_uniq_visitors_returning>
</metrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitFrequency&amp;apiAction=get&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitFrequency&amp;apiAction=get&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
<uniqueId>VisitFrequency_get</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml
index 0c7dae5507..0cfdf60b49 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml
@@ -8,23 +8,14 @@
<module>VisitorInterest</module>
<action>getNumberOfVisitsByDaysSinceLast</action>
<dimension>Visits by days since last visit</dimension>
+ <documentation>In this report, you can see how many visits were from visitors whose last visit was a certain number of days ago.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
</metrics>
- <constantRowsCount>1</constantRowsCount>
- <documentation>In this report, you can see how many visits were from visitors whose last visit was a certain number of days ago.</documentation>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitorInterest&amp;apiAction=getNumberOfVisitsByDaysSinceLast&amp;period=range&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<uniqueId>VisitorInterest_getNumberOfVisitsByDaysSinceLast</uniqueId>
</metadata>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml
index 358f9e9937..ea77225478 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml
@@ -17,16 +17,12 @@
<max_actions>Maximum actions in one visit</max_actions>
</metrics>
<metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
<nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
<bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
+ <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
</metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitsSummary&amp;apiAction=get&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitsSummary&amp;apiAction=get&amp;period=day&amp;date=2010-01-03,2010-01-09</imageGraphEvolutionUrl>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_csv__ScheduledReports.generateReport_month.original.csv b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_csv__ScheduledReports.generateReport_month.original.csv
index ba5dafe722..e662112861 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_csv__ScheduledReports.generateReport_month.original.csv
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_csv__ScheduledReports.generateReport_month.original.csv
@@ -1,3 +1,7 @@
+ExampleReportName
+nb_visits,conversion_rate,nb_actions_per_visit,avg_time_on_site,bounce_rate,label,nb_actions
+5,0%,0,00:00:00,0%,0,0
+
All Websites dashboard
label,nb_visits,nb_actions,nb_pageviews,revenue,nb_conversions,visits_evolution,actions_evolution,pageviews_evolution,revenue_evolution,nb_conversions_evolution,orders,orders_evolution,ecommerce_revenue,ecommerce_revenue_evolution
Site 1,10,43,43,$ 0,0,100%,100%,100%,0%,0%,0,0,$ 0,0
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html
index 6b1e064fde..8837c3277c 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_month.original.html
@@ -20,6 +20,11 @@
</h2>
<ul>
<li>
+ <a href="#ExamplePlugin_getExampleReport" style="text-decoration:none; color: rgb(68,68,68);">
+ ExampleReportName
+ </a>
+ </li>
+ <li>
<a href="#MultiSites_getAll" style="text-decoration:none; color: rgb(68,68,68);">
All Websites dashboard
</a>
@@ -300,6 +305,66 @@
</a>
</li>
</ul>
+<h2 id="ExamplePlugin_getExampleReport" style="color: rgb(126,115,99); font-size: 11pt;">
+ ExampleReportName
+</h2>
+
+
+
+ <table style="border-collapse:collapse; margin-left: 5px;">
+ <thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
+ <th style="padding: 6px 0;">
+ &nbsp;Exit Page URL&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Visits&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Actions&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Actions per Visit&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Avg. Time on Website&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Bounce Rate&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Conversion Rate&nbsp;&nbsp;
+ </th>
+ </thead>
+ <tbody>
+
+ <tr style="">
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0 </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 5
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 00:00:00
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0%
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0%
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <br/>
+ <a style="text-decoration:none; color: rgb(126,115,99); font-size: 9pt;" href="#reportTop">
+ Back to top
+ </a>
<h2 id="MultiSites_getAll" style="color: rgb(126,115,99); font-size: 11pt;">
All Websites dashboard
</h2>
@@ -3216,7 +3281,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page URL&nbsp;&nbsp;
+ &nbsp;Entry Page URL&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Entrances&nbsp;&nbsp;
@@ -3276,7 +3341,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page URL&nbsp;&nbsp;
+ &nbsp;Exit Page URL&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Exits&nbsp;&nbsp;
@@ -3465,7 +3530,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page Name&nbsp;&nbsp;
+ &nbsp;Entry Page title&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Entrances&nbsp;&nbsp;
@@ -3521,7 +3586,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page Name&nbsp;&nbsp;
+ &nbsp;Exit Page Title&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Exits&nbsp;&nbsp;
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getDefaultMetricTranslations.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getDefaultMetricTranslations.xml
index 8bbfb4595d..e8c2be194d 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getDefaultMetricTranslations.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getDefaultMetricTranslations.xml
@@ -35,11 +35,47 @@
<sum_daily_exit_nb_uniq_visitors>Unique exits (daily sum)</sum_daily_exit_nb_uniq_visitors>
<entry_nb_actions>Actions after entering here</entry_nb_actions>
<entry_sum_visit_length>Total time spent by visitors (in seconds) after entering here</entry_sum_visit_length>
+ <nb_pageviews>Pageviews</nb_pageviews>
+ <nb_uniq_pageviews>Unique Pageviews</nb_uniq_pageviews>
+ <nb_downloads>Downloads</nb_downloads>
+ <nb_uniq_downloads>Unique Downloads</nb_uniq_downloads>
+ <nb_outlinks>Outlinks</nb_outlinks>
+ <nb_uniq_outlinks>Unique Outlinks</nb_uniq_outlinks>
+ <nb_searches>Searches</nb_searches>
+ <nb_keywords>Unique Keywords</nb_keywords>
+ <avg_time_generation>Avg. generation time</avg_time_generation>
+ <nb_pages_per_search>Search Results pages</nb_pages_per_search>
+ <nb_hits_following_search>Clicked in search results</nb_hits_following_search>
<nb_events>Total events</nb_events>
<sum_event_value>Total value</sum_event_value>
<min_event_value>Minimum value</min_event_value>
<max_event_value>Maximum value</max_event_value>
<avg_event_value>Average value</avg_event_value>
<nb_events_with_value>Events with a value</nb_events_with_value>
+ <orders>Ecommerce Orders</orders>
+ <ecommerce_revenue>Product Revenue</ecommerce_revenue>
+ <revenue_per_visit>Revenue per Visit</revenue_per_visit>
+ <quantity>Quantity</quantity>
+ <avg_price>Average Price</avg_price>
+ <avg_quantity>Average Quantity</avg_quantity>
+ <revenue_subtotal>Subtotal</revenue_subtotal>
+ <revenue_tax>Tax</revenue_tax>
+ <revenue_shipping>Shipping</revenue_shipping>
+ <revenue_discount>Discount</revenue_discount>
+ <avg_order_revenue>Average Order Value</avg_order_revenue>
+ <visits_evolution>Visits Evolution</visits_evolution>
+ <actions_evolution>Actions Evolution</actions_evolution>
+ <pageviews_evolution>Pageviews Evolution</pageviews_evolution>
+ <revenue_evolution>Revenue Evolution</revenue_evolution>
+ <nb_conversions_evolution>Conversions Evolution</nb_conversions_evolution>
+ <orders_evolution>Ecommerce Orders Evolution</orders_evolution>
+ <ecommerce_revenue_evolution>Product Revenue Evolution</ecommerce_revenue_evolution>
+ <nb_visits_percentage>% Visits</nb_visits_percentage>
+ <nb_visits_returning>Returning Visits</nb_visits_returning>
+ <nb_actions_returning>Actions by Returning Visits</nb_actions_returning>
+ <avg_time_on_site_returning>Avg. Duration of a Returning Visit (in sec)</avg_time_on_site_returning>
+ <bounce_rate_returning>Bounce Rate for Returning Visits</bounce_rate_returning>
+ <nb_actions_per_visit_returning>Avg. Actions per Returning Visit</nb_actions_per_visit_returning>
+ <nb_uniq_visitors_returning>Unique returning visitors</nb_uniq_visitors_returning>
</row>
</result> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getMetadata_day.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getMetadata_day.xml
index 799f4d89e4..c495e00070 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getMetadata_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getMetadata_day.xml
@@ -6,28 +6,22 @@
<module>UserCountry</module>
<action>getCountry</action>
<dimension>Country</dimension>
+ <documentation>This report shows which country your visitors were in when they accessed your website.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getProcessedReport_day.xml
index 8673e95066..f08e134ae6 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getProcessedReport_day.xml
@@ -8,28 +8,22 @@
<module>UserCountry</module>
<action>getCountry</action>
<dimension>Country</dimension>
+ <documentation>This report shows which country your visitors were in when they accessed your website.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml
index 63e903114b..62ed8fedd7 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml
@@ -1,6 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<result>
<row>
+ <category>ExampleCategory</category>
+ <name>ExampleReportName</name>
+ <module>ExamplePlugin</module>
+ <action>getExampleReport</action>
+ <dimension>Exit Page URL</dimension>
+ <documentation>ExampleReportDocumentation</documentation>
+ <metrics>
+ <nb_visits>Visits</nb_visits>
+ <nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
+ <nb_actions>Actions</nb_actions>
+ </metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ <conversion_rate>Conversion Rate</conversion_rate>
+ </processedMetrics>
+ <imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=ExamplePlugin&amp;apiAction=getExampleReport&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
+ <imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=ExamplePlugin&amp;apiAction=getExampleReport&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
+ <uniqueId>ExamplePlugin_getExampleReport</uniqueId>
+ </row>
+ <row>
<category>All Websites</category>
<name>All Websites dashboard</name>
<module>MultiSites</module>
@@ -24,15 +51,8 @@
</metrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
+ <nb_pageviews>The number of times this page was visited.</nb_pageviews>
</metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=MultiSites&amp;apiAction=getAll&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=MultiSites&amp;apiAction=getAll&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -62,15 +82,8 @@
</metrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
+ <nb_pageviews>The number of times this page was visited.</nb_pageviews>
</metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=MultiSites&amp;apiAction=getOne&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=MultiSites&amp;apiAction=getOne&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -91,16 +104,12 @@
<max_actions>Maximum actions in one visit</max_actions>
</metrics>
<metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
<nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
<bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
+ <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
</metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitsSummary&amp;apiAction=get&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitsSummary&amp;apiAction=get&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -113,29 +122,22 @@
<action>getVisitInformationPerServerTime</action>
<dimension>Server time</dimension>
<documentation>This graph shows what time it was in the &lt;strong&gt; server's time zone &lt;/strong&gt; during the visits.</documentation>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -153,30 +155,23 @@
<action>getVisitInformationPerLocalTime</action>
<dimension>Local time</dimension>
<documentation>This graph shows what time it was in the &lt;strong&gt; visitors' time zones &lt;/strong&gt; during their visits.</documentation>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitTime&amp;apiAction=getVisitInformationPerLocalTime&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>VisitTime_getVisitInformationPerLocalTime</uniqueId>
</row>
@@ -187,30 +182,23 @@
<action>getByDayOfWeek</action>
<dimension>Day of the week</dimension>
<documentation>This graph shows the number of visits your website received on each day of the week.</documentation>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitTime&amp;apiAction=getByDayOfWeek&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>VisitTime_getByDayOfWeek</uniqueId>
</row>
@@ -225,24 +213,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getResolution&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getResolution&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getResolution</uniqueId>
@@ -259,24 +240,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getBrowser&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getBrowser&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getBrowser</uniqueId>
@@ -292,24 +266,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getBrowserVersion&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getBrowserVersion&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getBrowserVersion</uniqueId>
@@ -326,24 +293,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getBrowserType&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getBrowserType&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getBrowserType</uniqueId>
@@ -359,19 +319,10 @@
<nb_visits>Visits</nb_visits>
<nb_visits_percentage>% Visits</nb_visits_percentage>
</metrics>
- <constantRowsCount>1</constantRowsCount>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getPlugin&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>UserSettings_getPlugin</uniqueId>
</row>
@@ -386,24 +337,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getWideScreen&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getWideScreen&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getWideScreen</uniqueId>
@@ -419,24 +363,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getOS&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getOS&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getOS</uniqueId>
@@ -453,24 +390,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getConfiguration&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getConfiguration&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getConfiguration</uniqueId>
@@ -486,24 +416,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getOSFamily&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getOSFamily&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getOSFamily</uniqueId>
@@ -514,30 +437,23 @@
<module>UserSettings</module>
<action>getMobileVsDesktop</action>
<dimension>Mobile vs Desktop</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getMobileVsDesktop&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>UserSettings_getMobileVsDesktop</uniqueId>
</row>
@@ -552,24 +468,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getLanguage&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserSettings&amp;apiAction=getLanguage&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserSettings_getLanguage</uniqueId>
@@ -594,6 +503,9 @@
<items>Purchased Products</items>
<avg_order_revenue>Average Order Value</avg_order_revenue>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceOrder&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceOrder&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--ecommerceOrder</uniqueId>
@@ -603,14 +515,14 @@
<name>Ecommerce Orders - Visits to Conversion</name>
<module>Goals</module>
<action>getVisitsUntilConversion</action>
+ <parameters>
+ <idGoal>ecommerceOrder</idGoal>
+ </parameters>
<dimension>Visits to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
- <parameters>
- <idGoal>ecommerceOrder</idGoal>
- </parameters>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getVisitsUntilConversion&amp;idGoal=ecommerceOrder&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getVisitsUntilConversion_idGoal--ecommerceOrder</uniqueId>
</row>
@@ -619,14 +531,14 @@
<name>Ecommerce Orders - Days to Conversion</name>
<module>Goals</module>
<action>getDaysToConversion</action>
+ <parameters>
+ <idGoal>ecommerceOrder</idGoal>
+ </parameters>
<dimension>Days to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
- <parameters>
- <idGoal>ecommerceOrder</idGoal>
- </parameters>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getDaysToConversion&amp;idGoal=ecommerceOrder&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getDaysToConversion_idGoal--ecommerceOrder</uniqueId>
</row>
@@ -644,6 +556,9 @@
<revenue>Revenue left in cart</revenue>
<items>Products left in cart</items>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceAbandonedCart&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceAbandonedCart&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--ecommerceAbandonedCart</uniqueId>
@@ -653,14 +568,14 @@
<name>Abandoned Carts - Visits to Conversion</name>
<module>Goals</module>
<action>getVisitsUntilConversion</action>
+ <parameters>
+ <idGoal>ecommerceAbandonedCart</idGoal>
+ </parameters>
<dimension>Visits to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
- <parameters>
- <idGoal>ecommerceAbandonedCart</idGoal>
- </parameters>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getVisitsUntilConversion&amp;idGoal=ecommerceAbandonedCart&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getVisitsUntilConversion_idGoal--ecommerceAbandonedCart</uniqueId>
</row>
@@ -669,14 +584,14 @@
<name>Abandoned Carts - Days to Conversion</name>
<module>Goals</module>
<action>getDaysToConversion</action>
+ <parameters>
+ <idGoal>ecommerceAbandonedCart</idGoal>
+ </parameters>
<dimension>Days to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
- <parameters>
- <idGoal>ecommerceAbandonedCart</idGoal>
- </parameters>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getDaysToConversion&amp;idGoal=ecommerceAbandonedCart&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getDaysToConversion_idGoal--ecommerceAbandonedCart</uniqueId>
</row>
@@ -773,6 +688,7 @@
<module>Actions</module>
<action>getPageUrls</action>
<dimension>Page URL</dimension>
+ <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -789,7 +705,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the page URLs that have been visited. &lt;br /&gt; The table is organized hierarchically, the URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrls&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -800,7 +715,8 @@
<name>Entry pages</name>
<module>Actions</module>
<action>getEntryPageUrls</action>
- <dimension>Page URL</dimension>
+ <dimension>Entry Page URL</dimension>
+ <documentation>This report contains information about the entry pages that were used during the specified period. An entry page is the first page that a user views during his visit. &lt;br /&gt; The entry URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<entry_nb_visits>Entrances</entry_nb_visits>
<entry_bounce_count>Bounces</entry_bounce_count>
@@ -811,7 +727,6 @@
<entry_bounce_count>Number of visits that started and ended on this page. This means that the visitor left the website after viewing only this page.</entry_bounce_count>
<bounce_rate>Percentage of visits that started and ended on this page.</bounce_rate>
</metricsDocumentation>
- <documentation>This report contains information about the entry pages that were used during the specified period. An entry page is the first page that a user views during his visit. &lt;br /&gt; The entry URLs are displayed as a folder structure. Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getEntryPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getEntryPageUrls&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getEntryPageUrls&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -822,7 +737,8 @@
<name>Exit pages</name>
<module>Actions</module>
<action>getExitPageUrls</action>
- <dimension>Page URL</dimension>
+ <dimension>Exit Page URL</dimension>
+ <documentation>This report contains information about the exit pages that occurred during the specified period. An exit page is the last page that a user views during his visit. &lt;br /&gt; The exit URLs are displayed as a folder structure.&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<exit_nb_visits>Exits</exit_nb_visits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -833,7 +749,6 @@
<nb_visits>The number of visits that included this page. If a page was viewed multiple times during one visit, it is only counted once.</nb_visits>
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
- <documentation>This report contains information about the exit pages that occurred during the specified period. An exit page is the last page that a user views during his visit. &lt;br /&gt; The exit URLs are displayed as a folder structure. Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getExitPageUrls</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getExitPageUrls&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getExitPageUrls&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -845,6 +760,7 @@
<module>Actions</module>
<action>getPageTitles</action>
<dimension>Page Name</dimension>
+ <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<metrics>
<nb_hits>Pageviews</nb_hits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -861,7 +777,6 @@
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<avg_time_generation>The average time it took to generate the page. This metric includes the time it took the server to generate the web page, plus the time it took for the visitor to download the response from the server. A lower 'Avg. generation time' means a faster website for your visitors!</avg_time_generation>
</metricsDocumentation>
- <documentation>This report contains information about the titles of the pages that have been visited. &lt;br /&gt; The page title is the HTML &lt;title&gt; Tag that most browsers show in their window title.</documentation>
<actionToLoadSubTables>getPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitles&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -872,7 +787,8 @@
<name>Entry page titles</name>
<module>Actions</module>
<action>getEntryPageTitles</action>
- <dimension>Page Name</dimension>
+ <dimension>Entry Page title</dimension>
+ <documentation>This report contains information about the titles of exit pages that occurred during the specified period. Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<entry_nb_visits>Entrances</entry_nb_visits>
<entry_bounce_count>Bounces</entry_bounce_count>
@@ -883,7 +799,6 @@
<entry_bounce_count>Number of visits that started and ended on this page. This means that the visitor left the website after viewing only this page.</entry_bounce_count>
<bounce_rate>Percentage of visits that started and ended on this page.</bounce_rate>
</metricsDocumentation>
- <documentation>This report contains information about the titles of exit pages that occurred during the specified period. Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getEntryPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getEntryPageTitles&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getEntryPageTitles&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -894,7 +809,8 @@
<name>Exit page titles</name>
<module>Actions</module>
<action>getExitPageTitles</action>
- <dimension>Page Name</dimension>
+ <dimension>Exit Page Title</dimension>
+ <documentation>This report contains information about the titles of entry pages that were used during the specified period. Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<exit_nb_visits>Exits</exit_nb_visits>
<nb_visits>Unique Pageviews</nb_visits>
@@ -905,7 +821,6 @@
<nb_visits>The number of visits that included this page. If a page was viewed multiple times during one visit, it is only counted once.</nb_visits>
<exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
- <documentation>This report contains information about the titles of entry pages that were used during the specified period. Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getExitPageTitles</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getExitPageTitles&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getExitPageTitles&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -917,6 +832,7 @@
<module>Actions</module>
<action>getOutlinks</action>
<dimension>Clicked URL</dimension>
+ <documentation>This report shows a hierarchical list of outlink URLs that were clicked by your visitors. An outlink is a link that leads the visitor away from your website (to another domain).&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_visits>Unique Clicks</nb_visits>
<nb_hits>Clicks</nb_hits>
@@ -925,7 +841,6 @@
<nb_visits>The number of visits that involved a click on this link. If a link was clicked multiple times during one visit, it is only counted once.</nb_visits>
<nb_hits>The number of times this link was clicked.</nb_hits>
</metricsDocumentation>
- <documentation>This report shows a hierarchical list of outlink URLs that were clicked by your visitors. An outlink is a link that leads the visitor away from your website (to another domain).&lt;br /&gt;Use the plus and minus icons on the left to navigate.</documentation>
<actionToLoadSubTables>getOutlinks</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getOutlinks&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getOutlinks&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -937,6 +852,7 @@
<module>Actions</module>
<action>getDownloads</action>
<dimension>Download URL</dimension>
+ <documentation>In this report, you can see which files your visitors have downloaded. &lt;br /&gt; What Piwik counts as a download is the click on a download link. Whether the download was completed or not isn't known to Piwik.</documentation>
<metrics>
<nb_visits>Unique Downloads</nb_visits>
<nb_hits>Downloads</nb_hits>
@@ -945,7 +861,6 @@
<nb_visits>The number of visits that involved a click on this link. If a link was clicked multiple times during one visit, it is only counted once.</nb_visits>
<nb_hits>The number of times this link was clicked.</nb_hits>
</metricsDocumentation>
- <documentation>In this report, you can see which files your visitors have downloaded. &lt;br /&gt; What Piwik counts as a download is the click on a download link. Whether the download was completed or not isn't known to Piwik.</documentation>
<actionToLoadSubTables>getDownloads</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getDownloads&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getDownloads&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
@@ -1038,6 +953,7 @@
<module>Actions</module>
<action>getSiteSearchKeywords</action>
<dimension>Keyword</dimension>
+ <documentation>This report lists the Search Keywords that visitors searched for on your internal Search Engine.&lt;br/&gt;&lt;br/&gt;Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;http://piwik.org/docs/site-search/&quot; target=&quot;_blank&quot;&gt;Learn more about Tracking how your visitors use your Search engine.&lt;/a&gt;</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<nb_pages_per_search>Search Results pages</nb_pages_per_search>
@@ -1048,7 +964,6 @@
<nb_pages_per_search>Visitors will search on your website, and sometimes click &quot;next&quot; to view more results. This is the average number of search results pages viewed for this keyword.</nb_pages_per_search>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>This report lists the Search Keywords that visitors searched for on your internal Search Engine.&lt;br/&gt;&lt;br/&gt;Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;http://piwik.org/docs/site-search/&quot; target=&quot;_blank&quot;&gt;Learn more about Tracking how your visitors use your Search engine.&lt;/a&gt;</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchKeywords&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchKeywords&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchKeywords</uniqueId>
@@ -1059,6 +974,7 @@
<module>Actions</module>
<action>getSiteSearchNoResultKeywords</action>
<dimension>Keyword with No Search Result</dimension>
+ <documentation>Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br /&gt;&lt;br /&gt;This report lists the Search Keywords that did not return any Search result: maybe the search engine algorithm can be improved, or maybe your visitors are looking for content that is not (yet) on your website?</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<exit_rate>% Search Exits</exit_rate>
@@ -1067,7 +983,6 @@
<nb_visits>The number of visits that searched for this keyword on your website's search engine.</nb_visits>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>Tracking searches that visitors make on your website is a very effective way to learn more about what your audience is looking for, it can help find ideas for new content, new Ecommerce products that potential customers might be searching for, and generally improve the visitors' experience on your website.&lt;br /&gt;&lt;br /&gt;This report lists the Search Keywords that did not return any Search result: maybe the search engine algorithm can be improved, or maybe your visitors are looking for content that is not (yet) on your website?</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchNoResultKeywords&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchNoResultKeywords&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchNoResultKeywords</uniqueId>
@@ -1078,6 +993,7 @@
<module>Actions</module>
<action>getSiteSearchCategories</action>
<dimension>Search Category</dimension>
+ <documentation>This report lists the Categories that visitors selected when they made a Search on your website.&lt;br/&gt;For example, Ecommerce websites typically have a &quot;Category&quot; selector so that visitors can restrict their searches to all products in a specific Category.</documentation>
<metrics>
<nb_visits>Searches</nb_visits>
<nb_pages_per_search>Search Results pages</nb_pages_per_search>
@@ -1088,7 +1004,6 @@
<nb_pages_per_search>Visitors will search on your website, and sometimes click &quot;next&quot; to view more results. This is the average number of search results pages viewed for this keyword.</nb_pages_per_search>
<exit_rate>The percentage of visits that left the website after searching for this Keyword on your Site Search engine.</exit_rate>
</metricsDocumentation>
- <documentation>This report lists the Categories that visitors selected when they made a Search on your website.&lt;br/&gt;For example, Ecommerce websites typically have a &quot;Category&quot; selector so that visitors can restrict their searches to all products in a specific Category.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchCategories&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getSiteSearchCategories&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Actions_getSiteSearchCategories</uniqueId>
@@ -1099,6 +1014,7 @@
<module>Actions</module>
<action>getPageUrlsFollowingSiteSearch</action>
<dimension>Destination Page</dimension>
+ <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits_following_search>Clicked in search results</nb_hits_following_search>
<nb_hits>Total Pageviews</nb_hits>
@@ -1107,7 +1023,6 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
- <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrlsFollowingSiteSearch&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageUrlsFollowingSiteSearch&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Actions_getPageUrlsFollowingSiteSearch</uniqueId>
@@ -1118,6 +1033,7 @@
<module>Actions</module>
<action>getPageTitlesFollowingSiteSearch</action>
<dimension>Destination Page</dimension>
+ <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<metrics>
<nb_hits_following_search>Clicked in search results</nb_hits_following_search>
<nb_hits>Total Pageviews</nb_hits>
@@ -1126,7 +1042,6 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
- <documentation>When visitors search on your website, they are looking for a particular page, content, product, or service. This report lists the pages that were clicked the most after an internal search. In other words, the list of pages the most searched for by visitors already on your website.&lt;br/&gt;Use the plus and minus icons on the left to navigate.</documentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitlesFollowingSiteSearch&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Actions&amp;apiAction=getPageTitlesFollowingSiteSearch&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Actions_getPageTitlesFollowingSiteSearch</uniqueId>
@@ -1137,30 +1052,23 @@
<module>Referrers</module>
<action>getReferrerType</action>
<dimension>Referrer Type</dimension>
- <constantRowsCount>1</constantRowsCount>
<documentation>This table contains information about the distribution of the referrer types.&lt;br /&gt;&lt;b&gt;Direct Entry:&lt;/b&gt; A visitor has entered the URL in his browser and started browsing on your website - he entered the website directly.&lt;br /&gt;&lt;b&gt;Search Engines:&lt;/b&gt; A visitor was referred to your website by a search engine. &lt;br /&gt; See the &quot;Search Engines &amp; Keywords&quot; report for more details.&lt;br /&gt;&lt;b&gt;Websites:&lt;/b&gt; The visitor followed a link on antoher website that led to your site. &lt;br /&gt; See the &quot;Websites &amp; Social&quot; report for more details.&lt;br /&gt;&lt;b&gt;Campaigns:&lt;/b&gt; Visitors that came to your website as the result of a campaign. &lt;br /&gt; See the &quot;Campaigns&quot; report for more details.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1184,24 +1092,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Referrers&amp;apiAction=getAll&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Referrers_getAll</uniqueId>
</row>
@@ -1210,7 +1111,6 @@
<name>Keywords</name>
<module>Referrers</module>
<action>getKeywords</action>
- <actionToLoadSubTables>getSearchEnginesFromKeywordId</actionToLoadSubTables>
<dimension>Keyword</dimension>
<documentation>This report shows which keywords users were searching for before they were referred to your website. &lt;br /&gt; By clicking on a row in the table, you can see the distribution of search engines that were queried for the keyword.</documentation>
<metrics>
@@ -1218,23 +1118,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getSearchEnginesFromKeywordId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1253,29 +1147,22 @@
<action>getWebsites</action>
<dimension>Website</dimension>
<documentation>In this table, you can see which websites referred visitors to your site. &lt;br /&gt; By clicking on a row in the table, you can see which URLs the links to your website were on.</documentation>
- <actionToLoadSubTables>getUrlsFromWebsiteId</actionToLoadSubTables>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getUrlsFromWebsiteId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1294,29 +1181,22 @@
<action>getSearchEngines</action>
<dimension>Search Engine</dimension>
<documentation>This report shows which search engines referred users to your website. &lt;br /&gt; By clicking on a row in the table, you can see what users were searching for using a specific search engine.</documentation>
- <actionToLoadSubTables>getKeywordsFromSearchEngineId</actionToLoadSubTables>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getKeywordsFromSearchEngineId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1335,29 +1215,22 @@
<action>getCampaigns</action>
<dimension>Campaign</dimension>
<documentation>This report shows which campaigns led visitors to your website. &lt;br /&gt; For more information about tracking campaigns, read the &lt;a href=&quot;http://piwik.org/docs/tracking-campaigns/&quot; target=&quot;_blank&quot;&gt;campaigns documentation on piwik.org&lt;/a&gt;</documentation>
- <actionToLoadSubTables>getKeywordsFromCampaignId</actionToLoadSubTables>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getKeywordsFromCampaignId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1374,7 +1247,6 @@
<name>Social Networks</name>
<module>Referrers</module>
<action>getSocials</action>
- <actionToLoadSubTables>getUrlsForSocial</actionToLoadSubTables>
<dimension>Social network</dimension>
<documentation>In this table, you can see which websites referred visitors to your site. &lt;br /&gt; By clicking on a row in the table, you can see which URLs the links to your website were on.</documentation>
<metrics>
@@ -1382,24 +1254,18 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
+ <actionToLoadSubTables>getUrlsForSocial</actionToLoadSubTables>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Referrers&amp;apiAction=getSocials&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Referrers&amp;apiAction=getSocials&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Referrers_getSocials</uniqueId>
@@ -1415,6 +1281,9 @@
<conversion_rate>Conversion Rate</conversion_rate>
<revenue>Revenue</revenue>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Goals_get</uniqueId>
@@ -1425,10 +1294,10 @@
<module>Goals</module>
<action>getVisitsUntilConversion</action>
<dimension>Visits to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1445,10 +1314,10 @@
<module>Goals</module>
<action>getDaysToConversion</action>
<dimension>Days to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1473,6 +1342,9 @@
<conversion_rate>Conversion Rate</conversion_rate>
<revenue>Revenue</revenue>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=1&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=1&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--1</uniqueId>
@@ -1482,14 +1354,14 @@
<name>Goal 1 - Thank you - Visits to Conversion</name>
<module>Goals</module>
<action>getVisitsUntilConversion</action>
- <dimension>Visits to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<parameters>
<idGoal>1</idGoal>
</parameters>
+ <dimension>Visits to Conversion</dimension>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getVisitsUntilConversion&amp;idGoal=1&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getVisitsUntilConversion_idGoal--1</uniqueId>
</row>
@@ -1498,14 +1370,14 @@
<name>Goal 1 - Thank you - Days to Conversion</name>
<module>Goals</module>
<action>getDaysToConversion</action>
- <dimension>Days to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<parameters>
<idGoal>1</idGoal>
</parameters>
+ <dimension>Days to Conversion</dimension>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getDaysToConversion&amp;idGoal=1&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getDaysToConversion_idGoal--1</uniqueId>
</row>
@@ -1523,6 +1395,9 @@
<conversion_rate>Conversion Rate</conversion_rate>
<revenue>Revenue</revenue>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=2&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=2&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--2</uniqueId>
@@ -1532,14 +1407,14 @@
<name>Goal 2 - Hello - Visits to Conversion</name>
<module>Goals</module>
<action>getVisitsUntilConversion</action>
- <dimension>Visits to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<parameters>
<idGoal>2</idGoal>
</parameters>
+ <dimension>Visits to Conversion</dimension>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getVisitsUntilConversion&amp;idGoal=2&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getVisitsUntilConversion_idGoal--2</uniqueId>
</row>
@@ -1548,14 +1423,14 @@
<name>Goal 2 - Hello - Days to Conversion</name>
<module>Goals</module>
<action>getDaysToConversion</action>
- <dimension>Days to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<parameters>
<idGoal>2</idGoal>
</parameters>
+ <dimension>Days to Conversion</dimension>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getDaysToConversion&amp;idGoal=2&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getDaysToConversion_idGoal--2</uniqueId>
</row>
@@ -1573,6 +1448,9 @@
<conversion_rate>Conversion Rate</conversion_rate>
<revenue>Revenue</revenue>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=3&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=3&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--3</uniqueId>
@@ -1582,14 +1460,14 @@
<name>triggered js - Visits to Conversion</name>
<module>Goals</module>
<action>getVisitsUntilConversion</action>
- <dimension>Visits to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<parameters>
<idGoal>3</idGoal>
</parameters>
+ <dimension>Visits to Conversion</dimension>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getVisitsUntilConversion&amp;idGoal=3&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getVisitsUntilConversion_idGoal--3</uniqueId>
</row>
@@ -1598,14 +1476,14 @@
<name>triggered js - Days to Conversion</name>
<module>Goals</module>
<action>getDaysToConversion</action>
- <dimension>Days to Conversion</dimension>
- <constantRowsCount>1</constantRowsCount>
<parameters>
<idGoal>3</idGoal>
</parameters>
+ <dimension>Days to Conversion</dimension>
<metrics>
<nb_conversions>Conversions</nb_conversions>
</metrics>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=getDaysToConversion&amp;idGoal=3&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>Goals_getDaysToConversion_idGoal--3</uniqueId>
</row>
@@ -1615,28 +1493,22 @@
<module>UserCountry</module>
<action>getCountry</action>
<dimension>Country</dimension>
+ <documentation>This report shows which country your visitors were in when they accessed your website.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1654,28 +1526,22 @@
<module>UserCountry</module>
<action>getContinent</action>
<dimension>Continent</dimension>
+ <documentation>This report shows which continent your visitors were in when they accessed your website.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1693,28 +1559,22 @@
<module>UserCountry</module>
<action>getRegion</action>
<dimension>Region</dimension>
+ <documentation>This report shows which region your visitors were in when they accessed your website.&lt;br/&gt;In order to see data for this report, you must setup GeoIP in the Geolocation admin tab. The commercial &lt;a target=&quot;_blank&quot; href=&quot;http://www.maxmind.com/?rId=piwik&quot;&gt;Maxmind&lt;/a&gt; GeoIP databases are more accurate than the free ones. To see how accurate they are, click &lt;a target=&quot;_blank&quot; href=&quot;http://www.maxmind.com/en/city_accuracy?rId=piwik&quot;&gt;here&lt;/a&gt;.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1732,28 +1592,22 @@
<module>UserCountry</module>
<action>getCity</action>
<dimension>City</dimension>
+ <documentation>This report shows the cities your visitors were in when they accessed your website.&lt;br/&gt;In order to see data for this report, you must setup GeoIP in the Geolocation admin tab. The commercial &lt;a target=&quot;_blank&quot; href=&quot;http://www.maxmind.com/?rId=piwik&quot;&gt;Maxmind&lt;/a&gt; GeoIP databases are more accurate than the free ones. To see how accurate they are, click &lt;a target=&quot;_blank&quot; href=&quot;http://www.maxmind.com/en/city_accuracy?rId=piwik&quot;&gt;here&lt;/a&gt;.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1770,7 +1624,6 @@
<name>Custom Variables</name>
<module>CustomVariables</module>
<action>getCustomVariables</action>
- <actionToLoadSubTables>getCustomVariablesValuesFromNameId</actionToLoadSubTables>
<dimension>Custom Variable name</dimension>
<documentation>This report contains information about your Custom Variables. Click on a variable name to see the distribution of the values. &lt;br /&gt; For more information about Custom Variables in general, read the &lt;a href=&quot;http://piwik.org/docs/custom-variables/&quot; target=&quot;_blank&quot;&gt;Custom Variables documentation on piwik.org&lt;/a&gt;</documentation>
<metrics>
@@ -1778,23 +1631,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <actionToLoadSubTables>getCustomVariablesValuesFromNameId</actionToLoadSubTables>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
@@ -1812,23 +1659,14 @@
<module>VisitorInterest</module>
<action>getNumberOfVisitsPerVisitDuration</action>
<dimension>Visit duration</dimension>
+ <documentation>In this report, you can see how many visits had a certain total duration. Initially, the report is shown as a tag cloud, more common durations are displayed in a larger font.&lt;br /&gt;Please note, that you can view the report in other ways than as a tag cloud. Use the controls at the bottom of the report to do so.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
</metrics>
- <constantRowsCount>1</constantRowsCount>
- <documentation>In this report, you can see how many visits had a certain total duration. Initially, the report is shown as a tag cloud, more common durations are displayed in a larger font.&lt;br /&gt;Please note, that you can view the report in other ways than as a tag cloud. Use the controls at the bottom of the report to do so.</documentation>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitorInterest&amp;apiAction=getNumberOfVisitsPerVisitDuration&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>VisitorInterest_getNumberOfVisitsPerVisitDuration</uniqueId>
</row>
@@ -1838,23 +1676,14 @@
<module>VisitorInterest</module>
<action>getNumberOfVisitsPerPage</action>
<dimension>Pages per visit</dimension>
+ <documentation>In this report, you can see how many visits involved a certain number of pageviews. Initially, the report is shown as a tag cloud, more common numbers of pages are displayed in a larger font.&lt;br /&gt;Please note, that you can view the report in other ways than as a tag cloud. Use the controls at the bottom of the report to do so.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
</metrics>
- <constantRowsCount>1</constantRowsCount>
- <documentation>In this report, you can see how many visits involved a certain number of pageviews. Initially, the report is shown as a tag cloud, more common numbers of pages are displayed in a larger font.&lt;br /&gt;Please note, that you can view the report in other ways than as a tag cloud. Use the controls at the bottom of the report to do so.</documentation>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitorInterest&amp;apiAction=getNumberOfVisitsPerPage&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>VisitorInterest_getNumberOfVisitsPerPage</uniqueId>
</row>
@@ -1864,24 +1693,15 @@
<module>VisitorInterest</module>
<action>getNumberOfVisitsByVisitCount</action>
<dimension>Visits by Visit Number</dimension>
+ <documentation>In this report, you can see the number of visits who were the Nth visit, ie. visitors who visited your website at least N times.&lt;br /&gt;Please note, that you can view the report in other ways than as a tag cloud. Use the controls at the bottom of the report to do so.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_visits_percentage>% Visits</nb_visits_percentage>
</metrics>
- <constantRowsCount>1</constantRowsCount>
- <documentation>In this report, you can see the number of visits who were the Nth visit, ie. visitors who visited your website at least N times.&lt;br /&gt;Please note, that you can view the report in other ways than as a tag cloud. Use the controls at the bottom of the report to do so.</documentation>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitorInterest&amp;apiAction=getNumberOfVisitsByVisitCount&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>VisitorInterest_getNumberOfVisitsByVisitCount</uniqueId>
</row>
@@ -1891,23 +1711,14 @@
<module>VisitorInterest</module>
<action>getNumberOfVisitsByDaysSinceLast</action>
<dimension>Visits by days since last visit</dimension>
+ <documentation>In this report, you can see how many visits were from visitors whose last visit was a certain number of days ago.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
</metrics>
- <constantRowsCount>1</constantRowsCount>
- <documentation>In this report, you can see how many visits were from visitors whose last visit was a certain number of days ago.</documentation>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <constantRowsCount>1</constantRowsCount>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitorInterest&amp;apiAction=getNumberOfVisitsByDaysSinceLast&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<uniqueId>VisitorInterest_getNumberOfVisitsByDaysSinceLast</uniqueId>
</row>
@@ -1924,18 +1735,6 @@
<nb_actions_per_visit_returning>Avg. Actions per Returning Visit</nb_actions_per_visit_returning>
<nb_uniq_visitors_returning>Unique returning visitors</nb_uniq_visitors_returning>
</metrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitFrequency&amp;apiAction=get&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=VisitFrequency&amp;apiAction=get&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>VisitFrequency_get</uniqueId>
@@ -1952,24 +1751,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Provider&amp;apiAction=getProvider&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Provider&amp;apiAction=getProvider&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>Provider_getProvider</uniqueId>
@@ -1985,24 +1777,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getType&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getType&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>DevicesDetection_getType</uniqueId>
@@ -2018,24 +1803,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getBrand&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getBrand&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>DevicesDetection_getBrand</uniqueId>
@@ -2051,24 +1829,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getModel&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getModel&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>DevicesDetection_getModel</uniqueId>
@@ -2084,24 +1855,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getOsFamilies&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getOsFamilies&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>DevicesDetection_getOsFamilies</uniqueId>
@@ -2117,24 +1881,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getOsVersions&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getOsVersions&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>DevicesDetection_getOsVersions</uniqueId>
@@ -2150,24 +1907,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getBrowserFamilies&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getBrowserFamilies&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>DevicesDetection_getBrowserFamilies</uniqueId>
@@ -2183,24 +1933,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getBrowserVersions&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=DevicesDetection&amp;apiAction=getBrowserVersions&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>DevicesDetection_getBrowserVersions</uniqueId>
@@ -2245,16 +1988,13 @@
<nb_uniq_visitors_returning>Unique returning visitors</nb_uniq_visitors_returning>
</metrics>
<metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
<nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
<bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
+ <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
<conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
<nb_pageviews>The number of times this page was visited.</nb_pageviews>
<nb_uniq_pageviews>The number of visits that included this page. If a page was viewed multiple times during one visit, it is only counted once.</nb_uniq_pageviews>
<nb_downloads>The number of times this link was clicked.</nb_downloads>
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
index c3f602ca1e..cfcf4e9a0b 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
@@ -131,6 +131,20 @@
<row>
<type>dimension</type>
<category>Visit</category>
+ <name>Example Dimension</name>
+ <segment>myConversionSegmentName</segment>
+ <acceptedValues>Here you should explain which values are accepted/useful: Any number, for instance 1, 2, 3 , 99</acceptedValues>
+ </row>
+ <row>
+ <type>dimension</type>
+ <category>Visit</category>
+ <name>Example Dimension</name>
+ <segment>achievementPoints</segment>
+ <acceptedValues>Here you should explain which values are accepted/useful: Any number, for instance 1, 2, 3 , 99</acceptedValues>
+ </row>
+ <row>
+ <type>dimension</type>
+ <category>Visit</category>
<name>Local time</name>
<segment>visitLocalHour</segment>
<acceptedValues>0, 1, 2, 3, ..., 20, 21, 22, 23</acceptedValues>
@@ -225,8 +239,8 @@
<type>dimension</type>
<category>Referrers</category>
<name>Referrer URL</name>
- <acceptedValues>http%3A%2F%2Fwww.example.org%2Freferer-page.htm</acceptedValues>
<segment>referrerUrl</segment>
+ <acceptedValues>http%3A%2F%2Fwww.example.org%2Freferer-page.htm</acceptedValues>
</row>
<row>
<type>dimension</type>
@@ -381,6 +395,13 @@
<row>
<type>dimension</type>
<category>Actions</category>
+ <name>Example Dimension</name>
+ <segment>keywords</segment>
+ <acceptedValues>Here you should explain which values are accepted/useful: Any word, for instance MyKeyword1, MyKeyword2</acceptedValues>
+ </row>
+ <row>
+ <type>dimension</type>
+ <category>Actions</category>
<name>Exit Page Title</name>
<segment>exitPageTitle</segment>
</row>
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_phpRenderer__API.getDefaultMetricTranslations.php b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_phpRenderer__API.getDefaultMetricTranslations.php
index 0905e86f31..ec25ddae75 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_phpRenderer__API.getDefaultMetricTranslations.php
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_phpRenderer__API.getDefaultMetricTranslations.php
@@ -1 +1 @@
-a:1:{i:0;a:40:{s:9:"nb_visits";s:6:"Visits";s:16:"nb_uniq_visitors";s:15:"Unique visitors";s:10:"nb_actions";s:7:"Actions";s:20:"nb_actions_per_visit";s:17:"Actions per Visit";s:16:"avg_time_on_site";s:20:"Avg. Time on Website";s:11:"bounce_rate";s:11:"Bounce Rate";s:15:"conversion_rate";s:15:"Conversion Rate";s:5:"label";s:5:"Label";s:4:"date";s:4:"Date";s:16:"avg_time_on_page";s:17:"Avg. time on page";s:14:"sum_time_spent";s:41:"Total time spent by visitors (in seconds)";s:16:"sum_visit_length";s:41:"Total time spent by visitors (in seconds)";s:12:"bounce_count";s:7:"Bounces";s:22:"bounce_count_returning";s:33:"Bounce Count for Returning Visits";s:11:"max_actions";s:28:"Maximum actions in one visit";s:21:"max_actions_returning";s:38:"Maximum actions in one returning visit";s:29:"nb_visits_converted_returning";s:36:"Number of converted returning visits";s:26:"sum_visit_length_returning";s:51:"Total time spent by returning visitors (in seconds)";s:19:"nb_visits_converted";s:23:"Visits with Conversions";s:14:"nb_conversions";s:11:"Conversions";s:7:"revenue";s:7:"Revenue";s:7:"nb_hits";s:9:"Pageviews";s:15:"entry_nb_visits";s:9:"Entrances";s:22:"entry_nb_uniq_visitors";s:16:"Unique entrances";s:14:"exit_nb_visits";s:5:"Exits";s:21:"exit_nb_uniq_visitors";s:12:"Unique exits";s:18:"entry_bounce_count";s:7:"Bounces";s:17:"exit_bounce_count";s:7:"Bounces";s:9:"exit_rate";s:9:"Exit rate";s:26:"sum_daily_nb_uniq_visitors";s:27:"Unique visitors (daily sum)";s:32:"sum_daily_entry_nb_uniq_visitors";s:28:"Unique entrances (daily sum)";s:31:"sum_daily_exit_nb_uniq_visitors";s:24:"Unique exits (daily sum)";s:16:"entry_nb_actions";s:27:"Actions after entering here";s:22:"entry_sum_visit_length";s:61:"Total time spent by visitors (in seconds) after entering here";s:9:"nb_events";s:12:"Total events";s:15:"sum_event_value";s:11:"Total value";s:15:"min_event_value";s:13:"Minimum value";s:15:"max_event_value";s:13:"Maximum value";s:15:"avg_event_value";s:13:"Average value";s:20:"nb_events_with_value";s:19:"Events with a value";}} \ No newline at end of file
+a:1:{i:0;a:76:{s:9:"nb_visits";s:6:"Visits";s:16:"nb_uniq_visitors";s:15:"Unique visitors";s:10:"nb_actions";s:7:"Actions";s:20:"nb_actions_per_visit";s:17:"Actions per Visit";s:16:"avg_time_on_site";s:20:"Avg. Time on Website";s:11:"bounce_rate";s:11:"Bounce Rate";s:15:"conversion_rate";s:15:"Conversion Rate";s:5:"label";s:5:"Label";s:4:"date";s:4:"Date";s:16:"avg_time_on_page";s:17:"Avg. time on page";s:14:"sum_time_spent";s:41:"Total time spent by visitors (in seconds)";s:16:"sum_visit_length";s:41:"Total time spent by visitors (in seconds)";s:12:"bounce_count";s:7:"Bounces";s:22:"bounce_count_returning";s:33:"Bounce Count for Returning Visits";s:11:"max_actions";s:28:"Maximum actions in one visit";s:21:"max_actions_returning";s:38:"Maximum actions in one returning visit";s:29:"nb_visits_converted_returning";s:36:"Number of converted returning visits";s:26:"sum_visit_length_returning";s:51:"Total time spent by returning visitors (in seconds)";s:19:"nb_visits_converted";s:23:"Visits with Conversions";s:14:"nb_conversions";s:11:"Conversions";s:7:"revenue";s:7:"Revenue";s:7:"nb_hits";s:9:"Pageviews";s:15:"entry_nb_visits";s:9:"Entrances";s:22:"entry_nb_uniq_visitors";s:16:"Unique entrances";s:14:"exit_nb_visits";s:5:"Exits";s:21:"exit_nb_uniq_visitors";s:12:"Unique exits";s:18:"entry_bounce_count";s:7:"Bounces";s:17:"exit_bounce_count";s:7:"Bounces";s:9:"exit_rate";s:9:"Exit rate";s:26:"sum_daily_nb_uniq_visitors";s:27:"Unique visitors (daily sum)";s:32:"sum_daily_entry_nb_uniq_visitors";s:28:"Unique entrances (daily sum)";s:31:"sum_daily_exit_nb_uniq_visitors";s:24:"Unique exits (daily sum)";s:16:"entry_nb_actions";s:27:"Actions after entering here";s:22:"entry_sum_visit_length";s:61:"Total time spent by visitors (in seconds) after entering here";s:12:"nb_pageviews";s:9:"Pageviews";s:17:"nb_uniq_pageviews";s:16:"Unique Pageviews";s:12:"nb_downloads";s:9:"Downloads";s:17:"nb_uniq_downloads";s:16:"Unique Downloads";s:11:"nb_outlinks";s:8:"Outlinks";s:16:"nb_uniq_outlinks";s:15:"Unique Outlinks";s:11:"nb_searches";s:8:"Searches";s:11:"nb_keywords";s:15:"Unique Keywords";s:19:"avg_time_generation";s:20:"Avg. generation time";s:19:"nb_pages_per_search";s:20:"Search Results pages";s:24:"nb_hits_following_search";s:25:"Clicked in search results";s:9:"nb_events";s:12:"Total events";s:15:"sum_event_value";s:11:"Total value";s:15:"min_event_value";s:13:"Minimum value";s:15:"max_event_value";s:13:"Maximum value";s:15:"avg_event_value";s:13:"Average value";s:20:"nb_events_with_value";s:19:"Events with a value";s:6:"orders";s:16:"Ecommerce Orders";s:17:"ecommerce_revenue";s:15:"Product Revenue";s:17:"revenue_per_visit";s:17:"Revenue per Visit";s:8:"quantity";s:8:"Quantity";s:9:"avg_price";s:13:"Average Price";s:12:"avg_quantity";s:16:"Average Quantity";s:16:"revenue_subtotal";s:8:"Subtotal";s:11:"revenue_tax";s:3:"Tax";s:16:"revenue_shipping";s:8:"Shipping";s:16:"revenue_discount";s:8:"Discount";s:17:"avg_order_revenue";s:19:"Average Order Value";s:16:"visits_evolution";s:16:"Visits Evolution";s:17:"actions_evolution";s:17:"Actions Evolution";s:19:"pageviews_evolution";s:19:"Pageviews Evolution";s:17:"revenue_evolution";s:17:"Revenue Evolution";s:24:"nb_conversions_evolution";s:21:"Conversions Evolution";s:16:"orders_evolution";s:26:"Ecommerce Orders Evolution";s:27:"ecommerce_revenue_evolution";s:25:"Product Revenue Evolution";s:20:"nb_visits_percentage";s:8:"% Visits";s:19:"nb_visits_returning";s:16:"Returning Visits";s:20:"nb_actions_returning";s:27:"Actions by Returning Visits";s:26:"avg_time_on_site_returning";s:43:"Avg. Duration of a Returning Visit (in sec)";s:21:"bounce_rate_returning";s:32:"Bounce Rate for Returning Visits";s:30:"nb_actions_per_visit_returning";s:32:"Avg. Actions per Returning Visit";s:26:"nb_uniq_visitors_returning";s:25:"Unique returning visitors";}} \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_showRawMetrics__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_showRawMetrics__API.getProcessedReport_day.xml
index 6fdba43d1e..ec3e001105 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_showRawMetrics__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_showRawMetrics__API.getProcessedReport_day.xml
@@ -8,28 +8,22 @@
<module>UserCountry</module>
<action>getCountry</action>
<dimension>Country</dimension>
+ <documentation>This report shows which country your visitors were in when they accessed your website.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_year__API.getProcessedReport_year.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_year__API.getProcessedReport_year.xml
index 6713a65b92..f371029f1b 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_year__API.getProcessedReport_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata_year__API.getProcessedReport_year.xml
@@ -8,27 +8,21 @@
<module>UserCountry</module>
<action>getCountry</action>
<dimension>Pays</dimension>
+ <documentation>Ce rapport montre dans quel pays vos visiteurs étaient quand ils ont accédé à votre site web.</documentation>
<metrics>
<nb_visits>Visites</nb_visits>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions par visite</nb_actions_per_visit>
- <avg_time_on_site>Temps moyen sur le site</avg_time_on_site>
- <bounce_rate>Taux de rebond</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>Si un visiteur se rend sur votre site web pour la première fois ou s'il visite une page plus de 30 minutes après sa dernière page, il sera enregistré en tant que nouvelle visite.</nb_visits>
<nb_uniq_visitors>Nombre de visiteurs uniques visitant votre site web. Chaque utilisateur n'est compté qu'une seule fois, même s'il visite le site plusieurs fois dans la journée.</nb_uniq_visitors>
<nb_actions>Nombre d'actions effectuées par vos visiteurs. Les actions peuvent être des visites de pages, téléchargements, liens sortants.</nb_actions>
- <nb_actions_per_visit>Nombre moyen d'actions (affichages de page, téléchargements ou liens sortants) qui ont été effectuées durant les visites.</nb_actions_per_visit>
- <avg_time_on_site>Durée moyenne d'une visite</avg_time_on_site>
- <bounce_rate>Pourcentage de visites qui ont eu un affichage unique de page. Cela signifie que le visiteur a quitté le site directement depuis la page d'entrée.</bounce_rate>
- <conversion_rate>Pourcentage de visites qui ont déclenché une conversion en Objectif.</conversion_rate>
- <avg_time_on_page>Temps moyen que les visiteurs ont passé sur cette page (seulement la page, pas le site entier).</avg_time_on_page>
- <nb_hits>Le nombre de fois que cette page a été visitée.</nb_hits>
- <exit_rate>Pourcentage de visites qui ont quitté le site web après avoir visualisé cette page (affichages uniques divisés par sorties)</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions par visite</nb_actions_per_visit>
+ <avg_time_on_site>Temps moyen sur le site</avg_time_on_site>
+ <bounce_rate>Taux de rebond</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenu</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_AbandonedCart__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_AbandonedCart__API.getProcessedReport_day.xml
index 0c400e2b2f..65e862ccc6 100644
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_AbandonedCart__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_AbandonedCart__API.getProcessedReport_day.xml
@@ -16,6 +16,9 @@
<revenue>Revenue left in cart</revenue>
<items>Products left in cart</items>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceAbandonedCart&amp;period=day&amp;date=2011-03-07,2011-04-05</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceAbandonedCart&amp;period=day&amp;date=2011-03-07,2011-04-05</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--ecommerceAbandonedCart</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_NormalGoal__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_NormalGoal__API.getProcessedReport_day.xml
index ba7c4224ca..358467f45e 100644
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_NormalGoal__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_NormalGoal__API.getProcessedReport_day.xml
@@ -16,6 +16,9 @@
<conversion_rate>Conversion Rate</conversion_rate>
<revenue>Revenue</revenue>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=1&amp;period=day&amp;date=2011-03-07,2011-04-05</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=1&amp;period=day&amp;date=2011-03-07,2011-04-05</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--1</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_Order__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_Order__API.getProcessedReport_day.xml
index 34b087f2a9..795e631e81 100644
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_Order__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_Goals.Get_Order__API.getProcessedReport_day.xml
@@ -22,6 +22,9 @@
<items>Purchased Products</items>
<avg_order_revenue>Average Order Value</avg_order_revenue>
</metrics>
+ <metricsDocumentation>
+ <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
+ </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceOrder&amp;period=day&amp;date=2011-03-07,2011-04-05</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=Goals&amp;apiAction=get&amp;idGoal=ecommerceOrder&amp;period=day&amp;date=2011-03-07,2011-04-05</imageGraphEvolutionUrl>
<uniqueId>Goals_get_idGoal--ecommerceOrder</uniqueId>
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_VisitTime.getVisitInformationPerServerTime__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_VisitTime.getVisitInformationPerServerTime__API.getProcessedReport_day.xml
index fb55b9b273..12740b0394 100644
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_VisitTime.getVisitInformationPerServerTime__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_Metadata_VisitTime.getVisitInformationPerServerTime__API.getProcessedReport_day.xml
@@ -9,29 +9,22 @@
<action>getVisitInformationPerServerTime</action>
<dimension>Server time</dimension>
<documentation>This graph shows what time it was in the &lt;strong&gt; server's time zone &lt;/strong&gt; during the visits.</documentation>
- <constantRowsCount>1</constantRowsCount>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
+ <constantRowsCount>1</constantRowsCount>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml
index b41761c345..79289ce2d7 100644
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml
@@ -8,28 +8,22 @@
<module>UserCountry</module>
<action>getCountry</action>
<dimension>Country</dimension>
+ <documentation>This report shows which country your visitors were in when they accessed your website.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_csv__ScheduledReports.generateReport_week.original.csv b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_csv__ScheduledReports.generateReport_week.original.csv
index 478590155c..29fef7ec11 100644
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_csv__ScheduledReports.generateReport_week.original.csv
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_csv__ScheduledReports.generateReport_week.original.csv
@@ -1,3 +1,7 @@
+ExampleReportName
+nb_visits,conversion_rate,nb_actions_per_visit,avg_time_on_site,bounce_rate,label,nb_actions
+5,0%,0,00:00:00,0%,0,0
+
All Websites dashboard
label,nb_visits,nb_actions,nb_pageviews,revenue,nb_conversions,orders,ecommerce_revenue,visits_evolution,actions_evolution,pageviews_evolution,revenue_evolution,nb_conversions_evolution,orders_evolution,ecommerce_revenue_evolution
Piwik test,5,16,16,$ 13361.11,5,4,$ 13351.11,100%,100%,100%,100%,100%,100%,100%
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html
index 0ea0e0b3cd..8cdec86451 100644
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems_scheduled_report_in_html_tables_only__ScheduledReports.generateReport_week.original.html
@@ -20,6 +20,11 @@
</h2>
<ul>
<li>
+ <a href="#ExamplePlugin_getExampleReport" style="text-decoration:none; color: rgb(68,68,68);">
+ ExampleReportName
+ </a>
+ </li>
+ <li>
<a href="#MultiSites_getAll" style="text-decoration:none; color: rgb(68,68,68);">
All Websites dashboard
</a>
@@ -360,6 +365,66 @@
</a>
</li>
</ul>
+<h2 id="ExamplePlugin_getExampleReport" style="color: rgb(126,115,99); font-size: 11pt;">
+ ExampleReportName
+</h2>
+
+
+
+ <table style="border-collapse:collapse; margin-left: 5px;">
+ <thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
+ <th style="padding: 6px 0;">
+ &nbsp;Exit Page URL&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Visits&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Actions&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Actions per Visit&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Avg. Time on Website&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Bounce Rate&nbsp;&nbsp;
+ </th>
+ <th style="padding: 6px 0;">
+ &nbsp;Conversion Rate&nbsp;&nbsp;
+ </th>
+ </thead>
+ <tbody>
+
+ <tr style="">
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0 </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 5
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 00:00:00
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0%
+ </td>
+ <td style="font-size: 11pt; border-bottom: 1px solid rgb(231,231,231); padding: 5px 0 5px 5px;">
+ 0%
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <br/>
+ <a style="text-decoration:none; color: rgb(126,115,99); font-size: 9pt;" href="#reportTop">
+ Back to top
+ </a>
<h2 id="MultiSites_getAll" style="color: rgb(126,115,99); font-size: 11pt;">
All Websites dashboard
</h2>
@@ -4170,7 +4235,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page URL&nbsp;&nbsp;
+ &nbsp;Entry Page URL&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Entrances&nbsp;&nbsp;
@@ -4214,7 +4279,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page URL&nbsp;&nbsp;
+ &nbsp;Exit Page URL&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Exits&nbsp;&nbsp;
@@ -4452,7 +4517,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page Name&nbsp;&nbsp;
+ &nbsp;Entry Page title&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Entrances&nbsp;&nbsp;
@@ -4522,7 +4587,7 @@
<table style="border-collapse:collapse; margin-left: 5px;">
<thead style="background-color: rgb(228,226,215); color: rgb(37,87,146); font-size: 11pt;">
<th style="padding: 6px 0;">
- &nbsp;Page Name&nbsp;&nbsp;
+ &nbsp;Exit Page Title&nbsp;&nbsp;
</th>
<th style="padding: 6px 0;">
&nbsp;Exits&nbsp;&nbsp;
diff --git a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__ExamplePlugin.getExampleReport.xml b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__ExamplePlugin.getExampleReport.xml
new file mode 100644
index 0000000000..1b2fed39f9
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__ExamplePlugin.getExampleReport.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <row>
+ <nb_visits>5</nb_visits>
+ </row>
+</result> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_noVisit__ExamplePlugin.getExampleReport.xml b/tests/PHPUnit/Integration/expected/test_noVisit__ExamplePlugin.getExampleReport.xml
new file mode 100644
index 0000000000..1b2fed39f9
--- /dev/null
+++ b/tests/PHPUnit/Integration/expected/test_noVisit__ExamplePlugin.getExampleReport.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <row>
+ <nb_visits>5</nb_visits>
+ </row>
+</result> \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__API.getProcessedReport_range.xml b/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__API.getProcessedReport_range.xml
index 9c53a29fad..9efeb67c66 100644
--- a/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__API.getProcessedReport_range.xml
+++ b/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__API.getProcessedReport_range.xml
@@ -8,27 +8,21 @@
<module>UserCountry</module>
<action>getCountry</action>
<dimension>Country</dimension>
+ <documentation>This report shows which country your visitors were in when they accessed your website.</documentation>
<metrics>
<nb_visits>Visits</nb_visits>
<nb_actions>Actions</nb_actions>
</metrics>
- <processedMetrics>
- <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
- <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
- <bounce_rate>Bounce Rate</bounce_rate>
- </processedMetrics>
<metricsDocumentation>
<nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
<nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
<nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
</metricsDocumentation>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ </processedMetrics>
<metricsGoal>
<nb_conversions>Conversions</nb_conversions>
<revenue>Revenue</revenue>
diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__subtable__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__subtable__API.getProcessedReport_day.xml
index 4144bf99c5..9b072bf91e 100644
--- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__subtable__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__subtable__API.getProcessedReport_day.xml
@@ -15,24 +15,17 @@
<nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
<nb_actions>Actions</nb_actions>
</metrics>
+ <metricsDocumentation>
+ <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
+ <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
+ <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
+ </metricsDocumentation>
<processedMetrics>
<nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
- <metricsDocumentation>
- <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits>
- <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors>
- <nb_actions>The number of actions performed by your visitors. Actions can be page views, internal site searches, downloads or outlinks.</nb_actions>
- <nb_actions_per_visit>The average number of actions (page views, site searches, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit>
- <avg_time_on_site>The average duration of a visit.</avg_time_on_site>
- <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate>
- <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate>
- <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page>
- <nb_hits>The number of times this page was visited.</nb_hits>
- <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate>
- </metricsDocumentation>
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=CustomVariables&amp;apiAction=getCustomVariablesValuesFromNameId&amp;period=day&amp;date=2010-01-03&amp;idSubtable=</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=CustomVariables&amp;apiAction=getCustomVariablesValuesFromNameId&amp;period=day&amp;date=2009-12-05,2010-01-03&amp;idSubtable=</imageGraphEvolutionUrl>
<uniqueId>CustomVariables_getCustomVariablesValuesFromNameId</uniqueId>
diff --git a/tests/PHPUnit/UI b/tests/PHPUnit/UI
-Subproject 08a9738e7211373da4784541c1cc3434eecb180
+Subproject ea850260f162f2c167fdf3bd6782e838e09f67d
diff --git a/tests/PHPUnit/proxy/includes.php b/tests/PHPUnit/proxy/includes.php
index ab272378c9..6e3acc8af5 100644
--- a/tests/PHPUnit/proxy/includes.php
+++ b/tests/PHPUnit/proxy/includes.php
@@ -18,6 +18,14 @@ require_once PIWIK_INCLUDE_PATH . '/core/EventDispatcher.php';
require_once PIWIK_INCLUDE_PATH . '/core/Piwik.php';
require_once PIWIK_INCLUDE_PATH . '/libs/upgradephp/upgrade.php';
require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/TestingEnvironment.php';
+if (file_exists(PIWIK_INCLUDE_PATH . '/vendor/autoload.php')) {
+ $vendorDirectory = PIWIK_INCLUDE_PATH . '/vendor';
+} else {
+ $vendorDirectory = PIWIK_INCLUDE_PATH . '/../..';
+}
+require_once $vendorDirectory . '/autoload.php';
+require_once $vendorDirectory . '/mustangostang/spyc/Spyc.php';
+require_once $vendorDirectory . '/piwik/device-detector/DeviceDetector.php';
\Piwik\SettingsServer::setMaxExecutionTime(0);
diff --git a/tests/PHPUnit/travis.sh b/tests/PHPUnit/travis.sh
index 6ad7d07c79..331b59f4e4 100755
--- a/tests/PHPUnit/travis.sh
+++ b/tests/PHPUnit/travis.sh
@@ -36,7 +36,7 @@ then
then
artifacts_folder="protected/ui-tests.master.$PLUGIN_NAME"
else
- artifacts_folder="ui-tests.master"
+ artifacts_folder="ui-tests.$TRAVIS_BRANCH"
fi
echo ""
diff --git a/tests/travis/initiate_ui_tests.sh b/tests/travis/initiate_ui_tests.sh
index 3278e51724..233fd74ae0 100755
--- a/tests/travis/initiate_ui_tests.sh
+++ b/tests/travis/initiate_ui_tests.sh
@@ -11,27 +11,29 @@ if [ "$PIWIK_AUTOMATION" = "" ]; then
exit
fi
+git checkout "$TRAVIS_BRANCH"
+
git submodule update
-git checkout "$TRAVIS_BRANCH"
COMMIT_MESSAGE=$(git log "$TRAVIS_COMMIT" -1 --pretty=%B)
cd tests/PHPUnit/UI
-git checkout master
-git pull --rebase origin master
+git config --global user.email "hello@piwik.org"
+git config --global user.name "Piwik Automation"
+
+UI_BRANCH="report_and_dimension_refactoring"
+git checkout $UI_BRANCH
+git pull --rebase origin $UI_BRANCH
echo "$TRAVIS_COMMIT
$TRAVIS_BRANCH" > piwik_commit.txt
-git config --global user.email "hello@piwik.org"
-git config --global user.name "Piwik Automation"
-
git add ./piwik_commit.txt
git commit -m "Travis: Initiating build for commit '$TRAVIS_COMMIT' on branch '$TRAVIS_BRANCH': $COMMIT_MESSAGE"
git remote set-url origin "https://piwik-auto-commit-bot:$PIWIK_AUTOMATION@github.com/piwik/piwik-ui-tests.git"
-if ! git push origin master 2> /dev/null; then
+if ! git push origin $UI_BRANCH 2> /dev/null; then
echo "Failed to push!"
exit 1
fi \ No newline at end of file