Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #2 from shashig/master

Winning CloudSpokes challenge submission - Mavens Force.com Toolkit for Google Analytics Admin App
  • Loading branch information...
commit 6ffbe480b1cba6df498261b0183e6bd2b602637a 2 parents 7cbad77 + 026a2f5
@mbotos mbotos authored
Showing with 912 additions and 18 deletions.
  1. +129 −0 src/classes/AnalyticSettingsController.cls
  2. +5 −0 src/classes/AnalyticSettingsController.cls-meta.xml
  3. +86 −0 src/classes/AnalyticSettingsController_Test.cls
  4. +5 −0 src/classes/AnalyticSettingsController_Test.cls-meta.xml
  5. +188 −0 src/classes/DataImportWorker.cls
  6. +5 −0 src/classes/DataImportWorker.cls-meta.xml
  7. +20 −0 src/classes/DataImportWorker_Test.cls
  8. +5 −0 src/classes/DataImportWorker_Test.cls-meta.xml
  9. +37 −0 src/classes/GoogleAnalytics.cls
  10. +8 −0 src/classes/GoogleAnalyticsImporter.cls
  11. +5 −0 src/classes/GoogleAnalyticsImporter.cls-meta.xml
  12. +13 −0 src/classes/GoogleAnalyticsImporter_Test.cls
  13. +5 −0 src/classes/GoogleAnalyticsImporter_Test.cls-meta.xml
  14. +19 −0 src/classes/GoogleAnalyticsTest.cls
  15. +7 −3 src/classes/ImportGoogleAnalytics.cls
  16. +1 −1  src/classes/ImportGoogleAnalytics_Test.cls
  17. +33 −0 src/classes/MetricsData.cls
  18. +5 −0 src/classes/MetricsData.cls-meta.xml
  19. +92 −0 src/classes/MetricsData_Test.cls
  20. +5 −0 src/classes/MetricsData_Test.cls-meta.xml
  21. +11 −0 src/classes/UtilityClass.cls
  22. +5 −0 src/classes/UtilityClass.cls-meta.xml
  23. +5 −0 src/objects/Site_Event__c.object
  24. +13 −1 src/objects/Site_Metric_Date__c.object
  25. +80 −0 src/objects/Site_Metric_Settings__c.object
  26. +6 −1 src/objects/Site_Metric__c.object
  27. +21 −12 src/package.xml
  28. +64 −0 src/pages/analyticsSettings.page
  29. +5 −0 src/pages/analyticsSettings.page-meta.xml
  30. +24 −0 src/pages/editsite.page
  31. +5 −0 src/pages/editsite.page-meta.xml
View
129 src/classes/AnalyticSettingsController.cls
@@ -0,0 +1,129 @@
+public with sharing class AnalyticSettingsController {
+ public PageReference cancel() {
+ PageReference pageRef = Page.analyticsSettings;
+
+ pageRef.setRedirect(true);
+
+ return (pageRef);
+ }
+
+
+ public String siteName {get; set;}
+
+ public Site_Metric_Settings__c settings {get; set;}
+
+ public List<Site_Metric_Settings__c> sites {get; set;}
+
+
+ public PageReference save() {
+ PageReference pageRef = null;
+
+ //Update tracking status to turn off tracking based on any instructions to track off a metric.
+ //Turning on tracking status would be done in the daily job.
+ if (settings.Track_Visitors__c == false && settings.Tracking_Visitors__c == true) {
+ settings.Tracking_Visitors__c = false;
+ }
+ if (settings.Track_New_Visits__c == false && settings.Tracking_New_Visits__c == true) {
+ settings.Tracking_New_Visits__c = false;
+ }
+ if (settings.Track_Page_Views_Per_Visit__c == false && settings.Tracking_Page_Views_Per_Visit__c == true) {
+ settings.Tracking_Page_Views_Per_Visit__c = false;
+ }
+ if (settings.Track_Visit_Bounce_Rate__c == false && settings.Tracking_Visit_Bounce_Rate__c == true) {
+ settings.Tracking_Visit_Bounce_Rate__c = false;
+ }
+ if (settings.Average_Time_on_Site__c == false && settings.Tracking_Average_Time_on_Site__c == true) {
+ settings.Tracking_Average_Time_on_Site__c = false;
+ }
+
+ try {
+ upsert(settings);
+ } catch(System.DMLException e) {
+ ApexPages.addMessages(e);
+ return null;
+ }
+
+ pageRef = Page.analyticsSettings;
+ pageRef.getParameters().put('siteName', settings.Name);
+
+ return (pageRef);
+ }
+
+ public PageReference editSite() {
+ PageReference pageRef = null;
+
+ settings = null;
+ try {
+ settings = [Select s.Name, s.Table_Id__c, s.Password__c,
+ s.Email__c, s.Track_Visitors__c, s.Track_New_Visits__c, s.Track_Page_Views_Per_Visit__c,
+ s.Track_Visit_Bounce_Rate__c, s.Average_Time_on_Site__c,
+ s.Tracking_Visitors__c, s.Tracking_New_Visits__c,
+ s.Tracking_Page_Views_Per_Visit__c,
+ s.Tracking_Visit_Bounce_Rate__c, s.Tracking_Average_Time_on_Site__c
+ From Site_Metric_Settings__c s where s.Name = :siteName];
+ } catch (QueryException ex) {
+ }
+
+ if (settings == null) {
+ settings = new Site_Metric_Settings__c();
+ settings.Name = siteName;
+ }
+
+ pageRef = Page.editsite;
+ pageRef.getParameters().put('siteName', siteName);
+
+ return (pageRef);
+ }
+
+ public PageReference getSiteInfo() {
+ settings = null;
+ if (siteName != null && siteName != '') {
+ try {
+ settings = [Select s.Name, s.Table_Id__c, s.Password__c,
+ s.Email__c, s.Track_Visitors__c, s.Track_New_Visits__c, s.Track_Page_Views_Per_Visit__c,
+ s.Track_Visit_Bounce_Rate__c, s.Average_Time_on_Site__c,
+ s.Tracking_Visitors__c, s.Tracking_New_Visits__c,
+ s.Tracking_Page_Views_Per_Visit__c,
+ s.Tracking_Visit_Bounce_Rate__c, s.Tracking_Average_Time_on_Site__c
+ From Site_Metric_Settings__c s where s.Name = :siteName];
+ } catch (QueryException ex) {
+ ApexPages.Message pageMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'No Site Metric Settings with Name = ' + siteName);
+ ApexPages.addMessage(pageMsg);
+ }
+ } else {
+ ApexPages.Message pageMsg = new ApexPages.Message(ApexPages.Severity.WARNING, 'Site Name is asd required');
+ ApexPages.addMessage(pageMsg);
+ }
+ return null;
+ }
+
+ public PageReference searchSites() {
+ sites = null;
+ settings = null;
+ if (siteName == null || siteName == '') {
+ try {
+ sites = [Select s.Name
+ From Site_Metric_Settings__c s];
+ } catch (QueryException ex) {
+ ApexPages.Message pageMsg = new ApexPages.Message(ApexPages.Severity.WARNING, 'No Site setup with Name = ' + siteName);
+ ApexPages.addMessage(pageMsg);
+ }
+ } else {
+ try {
+ sites = [Select s.Name
+ From Site_Metric_Settings__c s where s.Name = :siteName];
+ } catch (QueryException ex) {
+ ApexPages.Message pageMsg = new ApexPages.Message(ApexPages.Severity.WARNING, 'No Site setup with Name = ' + siteName);
+ ApexPages.addMessage(pageMsg);
+ }
+ }
+ if (sites == null || sites.size() == 0) {
+ ApexPages.Message pageMsg = new ApexPages.Message(ApexPages.Severity.WARNING, 'No sites for the entered criteria.');
+ ApexPages.addMessage(pageMsg);
+ }
+ return null;
+ }
+
+ public AnalyticSettingsController () {
+ }
+}
View
5 src/classes/AnalyticSettingsController.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>22.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
86 src/classes/AnalyticSettingsController_Test.cls
@@ -0,0 +1,86 @@
+@isTest
+private class AnalyticSettingsController_Test {
+ static testMethod void testCancel() {
+ AnalyticSettingsController asController = new AnalyticSettingsController();
+ PageReference returnedPageRef = asController.cancel();
+ System.assertEquals(returnedPageRef.getUrl(), Page.analyticsSettings.getUrl());
+ }
+
+ static testMethod void testSave() {
+ AnalyticSettingsController asController = new AnalyticSettingsController();
+ String siteName = 'MySite';
+
+ asController.settings = new Site_Metric_Settings__c(Name = siteName, Email__c = 'as@as.com', Password__c = '123', Table_Id__c = 'ga:123456');
+ asController.settings.Track_Visitors__c = false;
+ asController.settings.Tracking_Visitors__c = true;
+ asController.settings.Track_New_Visits__c = false;
+ asController.settings.Tracking_New_Visits__c = true;
+ asController.settings.Track_Page_Views_Per_Visit__c = false;
+ asController.settings.Tracking_Page_Views_Per_Visit__c = true;
+ asController.settings.Track_Visit_Bounce_Rate__c = false;
+ asController.settings.Tracking_Visit_Bounce_Rate__c = true;
+ asController.settings.Average_Time_on_Site__c = false;
+ asController.settings.Tracking_Average_Time_on_Site__c = true;
+
+ PageReference returnedPageRef = asController.save();
+
+ Site_Metric_Settings__c settings = [Select s.Name, s.Table_Id__c, s.Password__c,
+ s.Email__c, s.Track_Visitors__c, s.Track_New_Visits__c, s.Track_Page_Views_Per_Visit__c,
+ s.Track_Visit_Bounce_Rate__c, s.Average_Time_on_Site__c,
+ s.Tracking_Visitors__c, s.Tracking_New_Visits__c,
+ s.Tracking_Page_Views_Per_Visit__c,
+ s.Tracking_Visit_Bounce_Rate__c, s.Tracking_Average_Time_on_Site__c
+ From Site_Metric_Settings__c s where s.Name = :siteName];
+
+ System.assertEquals(settings.Tracking_Visitors__c, false);
+ System.assertEquals(settings.Tracking_New_Visits__c, false);
+ System.assertEquals(settings.Tracking_Page_Views_Per_Visit__c, false);
+ System.assertEquals(settings.Tracking_Visit_Bounce_Rate__c, false);
+ System.assertEquals(settings.Tracking_Average_Time_on_Site__c, false);
+ System.assertEquals(returnedPageRef.getUrl().contains('/apex/analyticssettings'), true);
+ }
+ static testMethod void testEditSite() {
+ AnalyticSettingsController asController = new AnalyticSettingsController();
+ asController.siteName = 'JunkSite';
+
+ PageReference returnedPageRef = asController.editSite();
+
+ System.assertEquals(asController.settings.Name, 'JunkSite');
+ System.assertEquals(returnedPageRef.getUrl().contains('/apex/editsite'), true);
+ }
+
+ static testMethod void testGetSiteInfo() {
+ AnalyticSettingsController asController = new AnalyticSettingsController();
+
+ asController.siteName = '';
+ PageReference returnedPageRef = asController.getSiteInfo();
+ System.assertEquals(asController.settings, null);
+
+ asController.siteName = 'AnotherJunkSite';
+ returnedPageRef = asController.getSiteInfo();
+ System.assertEquals(asController.settings, null);
+
+ asController.siteName = 'MyBlog';
+ returnedPageRef = asController.getSiteInfo();
+ System.assertNotEquals(asController.settings, null);
+ }
+
+ static testMethod void testSearchSites() {
+ AnalyticSettingsController asController = new AnalyticSettingsController();
+
+ //zero value with wrong criteria
+ asController.siteName = 'JunkSite';
+ PageReference returnedPageRef = asController.searchSites();
+ System.assertEquals(0, asController.sites.size());
+
+ //One value with no criteria (as there is only one site defined in the database)
+ asController.siteName = '';
+ returnedPageRef = asController.searchSites();
+ System.assertEquals(1, asController.sites.size());
+
+ //One value with correct criteria
+ asController.siteName = 'MyBlog';
+ returnedPageRef = asController.searchSites();
+ System.assertEquals(1, asController.sites.size());
+ }
+}
View
5 src/classes/AnalyticSettingsController_Test.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
188 src/classes/DataImportWorker.cls
@@ -0,0 +1,188 @@
+/*
+This class queries the custom settings: Site_Metric_Settings__c to determine
+the metrics to be pulled from Google Analytics as well as the dates for which the
+metrics need to be pulled.
+
+The detailed logic is as follows:
+1. Query Site_Metric_Settings__c to retrieve the metrics to be pulled.
+*/
+public with sharing class DataImportWorker {
+ private static MetricsData metricsData = new MetricsData();
+ private static Site_Metric_Settings__c settings {get; set;}
+
+ /* Currently data can be imported only for one site */
+ private static List<Site_Metric_Settings__c> sites = [Select s.Name From Site_Metric_Settings__c s];
+ private static String siteName = sites[0].Name;
+
+ public static GoogleAnalytics ga;
+
+ private static List<String> regularMetrics = new list<String>();
+ private static Date regularImportDate = Date.Today() - 2; //Data available after 2 days so pick up data for 2 days before.
+ private static Integer firstTimeDaysToBeImported = 30;
+
+ public DataImportWorker() {
+ System.debug('Beginning Google Analytics data import. Date being imported: ' + regularImportDate);
+ }
+
+ @future(callout=true)
+ public static void importData() {
+ System.debug('Starting Import. Date being imported: ' + regularImportDate);
+ try {
+ settings = [Select s.Name, s.Table_Id__c, s.Password__c, s.Email__c,
+ s.Track_Visitors__c, s.Track_New_Visits__c,
+ s.Track_Page_Views_Per_Visit__c,
+ s.Track_Visit_Bounce_Rate__c, s.Average_Time_on_Site__c,
+ s.Tracking_Visitors__c, s.Tracking_New_Visits__c,
+ s.Tracking_Page_Views_Per_Visit__c,
+ s.Tracking_Visit_Bounce_Rate__c, s.Tracking_Average_Time_on_Site__c
+ From Site_Metric_Settings__c s where s.Name = :siteName];
+ } catch (QueryException ex) {
+ System.debug('Error getting settings' + ex);
+ }
+
+ //Get data into local variables
+ String name = settings.Name;
+ Boolean trackVisitors = settings.Track_Visitors__c;
+ Boolean trackNewVisits = settings.Track_New_Visits__c;
+ Boolean trackPageViewsPerVisit = settings.Track_Page_Views_Per_Visit__c;
+ Boolean trackAverageTimeOnSite = settings.Average_Time_on_Site__c;
+ Boolean trackVisitBounceRate = settings.Track_Visit_Bounce_Rate__c;
+ Boolean trackingVisitors = settings.Tracking_Visitors__c;
+ Boolean trackingNewVisits = settings.Tracking_New_Visits__c;
+ Boolean trackingPageViewsPerVisit = settings.Tracking_Page_Views_Per_Visit__c;
+ Boolean trackingAverageTimeOnSite = settings.Tracking_Average_Time_on_Site__c;
+ Boolean trackingVisitBounceRate = settings.Tracking_Visit_Bounce_Rate__c;
+
+ // Initialize & setup connection to Google Analytics
+ ga = new GoogleAnalytics(settings);
+
+ //Manage Visitors Metric
+ if (trackVisitors == true) {
+ if (trackingVisitors == false) {
+ //First time tracking so need to get 30 days worth of data
+ MetricsData md = ga.getMetrics(regularImportDate - firstTimeDaysToBeImported + 1, regularImportDate,
+ new list<String>{GoogleAnalytics.VisitorsMetric});
+
+ //Accumalate metrics data for later database save
+ metricsData.accumulateData(md);
+
+ //Update site metric settings to indicate we have started tracking this metric
+ settings.Tracking_Visitors__c = true;
+ } else {
+ // We will just do a regular import of one day's data for this metric so just add this metric to the list.
+ regularMetrics.add(GoogleAnalytics.VisitorsMetric);
+ }
+ }
+
+ //Manage New Visits % Metric
+ if (trackNewVisits == true) {
+ if (trackingNewVisits == false) {
+ //First time tracking so need to get 30 days worth of data
+ MetricsData md = ga.getMetrics(regularImportDate - firstTimeDaysToBeImported, regularImportDate,
+ new list<String>{GoogleAnalytics.PercentNewVisitsMetric});
+
+ //Accumalate metrics data for later database save
+ metricsData.accumulateData(md);
+
+ //Update site metric settings to indicate we have started tracking this metric
+ settings.Tracking_New_Visits__c = true;
+ } else {
+ // We will just do a regular import of one day's data for this metric so just add this metric to the list.
+ regularMetrics.add(GoogleAnalytics.PercentNewVisitsMetric);
+ }
+ }
+
+ //Manage Page Views per Visit Metric
+ if (trackPageViewsPerVisit == true) {
+ if (trackingPageViewsPerVisit == false) {
+ //First time tracking so need to get 30 days worth of data
+ MetricsData md = ga.getMetrics(regularImportDate - firstTimeDaysToBeImported, regularImportDate,
+ new list<String>{GoogleAnalytics.PageViewsPerVisitMetric});
+
+ //Accumalate metrics data for later database save
+ metricsData.accumulateData(md);
+
+ //Update site metric settings to indicate we have started tracking this metric
+ settings.Tracking_Page_Views_Per_Visit__c = true;
+ } else {
+ // We will just do a regular import of one day's data for this metric so just add this metric to the list.
+ regularMetrics.add(GoogleAnalytics.PageViewsPerVisitMetric);
+ }
+ }
+
+ //Manage Average Time on Site Metric
+ if (trackAverageTimeOnSite == true) {
+ if (trackingAverageTimeOnSite == false) {
+ //First time tracking so need to get 30 days worth of data
+ MetricsData md = ga.getMetrics(regularImportDate - firstTimeDaysToBeImported, regularImportDate,
+ new list<String>{GoogleAnalytics.AverageTimeOnSiteMetric});
+
+ //Accumalate metrics data for later database save
+ metricsData.accumulateData(md);
+
+ //Update site metric settings to indicate we have started tracking this metric
+ settings.Tracking_Average_Time_on_Site__c = true;
+ } else {
+ // We will just do a regular import of one day's data for this metric so just add this metric to the list.
+ regularMetrics.add(GoogleAnalytics.AverageTimeOnSiteMetric);
+ }
+ }
+
+ //Manage Visit Bounce Rate Metric
+ if (trackVisitBounceRate == true) {
+ if (trackingVisitBounceRate == false) {
+ //First time tracking so need to get 30 days worth of data
+ MetricsData md = ga.getMetrics(regularImportDate - firstTimeDaysToBeImported, regularImportDate,
+ new list<String>{GoogleAnalytics.VisitBounceRateMetric});
+
+ //Accumalate metrics data for later database save
+ metricsData.accumulateData(md);
+
+ //Update site metric settings to indicate we have started tracking this metric
+ settings.Tracking_Visit_Bounce_Rate__c = true;
+ } else {
+ // We will just do a regular import of one day's data for this metric so just add this metric to the list.
+ regularMetrics.add(GoogleAnalytics.VisitBounceRateMetric);
+ }
+ }
+
+ if (regularMetrics.size() > 0) {
+ System.debug('Importing single day data for: ' + regularMetrics + ', Date: ' + regularImportDate);
+ // Now that we have handled the individual exceptions to the regular daily import, let's get the regulars
+ MetricsData md = ga.getMetrics(regularImportDate, regularImportDate, regularMetrics);
+
+ //Accumalate metrics data for later database save
+ metricsData.accumulateData(md);
+ }
+
+ //Now save the metrics data to the database
+ map<Date, Site_Metric_Date__c> metricDates = metricsData.metricDates;
+ map<Date, list<Site_Metric__c>> metricsMap = metricsData.metricsMap;
+
+ System.debug('inserting ' + metricsMap);
+
+ if (metricsMap != null) {
+ insert metricDates.values();
+
+ list<Site_Metric__c> metricList = new list<Site_Metric__c>();
+
+ for (Site_Metric_Date__c metricDate : metricDates.values()) {
+ System.debug('assigning date ' + metricDate + ' to ' + metricsMap.get(metricDate.Start_Date__c));
+
+ for (Site_Metric__c metric : metricsMap.get(metricDate.Start_Date__c)) {
+ metric.Site_Metric_Date__c = metricDate.Id;
+ metricList.add(metric);
+ }
+ }
+
+ insert metricList;
+ }
+
+ //Update metrics tracking settings
+ try {
+ update(settings);
+ } catch (DMLException dmle) {
+ System.debug('Error updating settings' + dmle);
+ }
+ }
+}
View
5 src/classes/DataImportWorker.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
20 src/classes/DataImportWorker_Test.cls
@@ -0,0 +1,20 @@
+@isTest
+private class DataImportWorker_Test {
+ /* Since database update cannot be done before a callout, the testing for each metric will need to be done step by step */
+ static testMethod void testImportData() {
+ String siteName = 'MyBlog';
+
+ DataImportWorker.importData();
+
+ Site_Metric_Settings__c settings = [Select s.Name, s.Table_Id__c, s.Password__c, s.Email__c,
+ s.Track_Visitors__c, s.Track_New_Visits__c,
+ s.Track_Page_Views_Per_Visit__c,
+ s.Track_Visit_Bounce_Rate__c, s.Average_Time_on_Site__c,
+ s.Tracking_Visitors__c, s.Tracking_New_Visits__c,
+ s.Tracking_Page_Views_Per_Visit__c,
+ s.Tracking_Visit_Bounce_Rate__c, s.Tracking_Average_Time_on_Site__c
+ From Site_Metric_Settings__c s where s.Name = :siteName];
+
+ System.assertEquals(true, settings.Tracking_Visitors__c);
+ }
+}
View
5 src/classes/DataImportWorker_Test.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
37 src/classes/GoogleAnalytics.cls
@@ -373,6 +373,43 @@ public with sharing class GoogleAnalytics {
}
}
+ /* This method returns metrics which will be accumulated in the client for insertion
+ */
+ public MetricsData getMetrics(Date startDate, Date endDate, list<string> metrics) {
+ MetricsData metricsData;
+ list<GoogleAnalytics.Entry> entries = getEntries(
+ startDate,
+ endDate,
+ new list<string>{DateDimension},
+ metrics
+ );
+
+ map<Date, Site_Metric_Date__c> metricDates = new map<Date, Site_Metric_Date__c>();
+ map<Date, list<Site_Metric__c>> metricsMap = new map<Date, list<Site_Metric__c>>();
+
+ for (GoogleAnalytics.Entry entry : entries) {
+ Date metricDate = GoogleAnalytics.parseDate(entry.getDimension(DateDimension));
+ metricDates.put(metricDate, new Site_Metric_Date__c(Start_Date__c = metricDate));
+
+ if (!metricsMap.containsKey(metricDate)) {
+ metricsMap.put(metricDate, new list<Site_Metric__c>());
+ }
+
+ for (string gaMetric : metrics) {
+ Site_Metric__c metric = new Site_Metric__c(Name = gaMetric, Metric__c = gaMetric, Value__c = decimal.ValueOf(entry.getMetric(gaMetric)));
+ metricsMap.get(metricDate).add(metric);
+ }
+ }
+
+ if (metricsMap != null) {
+ metricsData = new MetricsData();
+ metricsData.metricDates = metricDates;
+ metricsData.metricsMap = metricsMap;
+ }
+
+ return (metricsData);
+ }
+
public static Date parseDate(string dt) {
if(dt != null && dt.length() == 8){
return Date.newInstance(
View
8 src/classes/GoogleAnalyticsImporter.cls
@@ -0,0 +1,8 @@
+global with sharing class GoogleAnalyticsImporter implements Schedulable {
+ global void execute(SchedulableContext SC) {
+ System.debug('Starting Scheduled job @ ' + Date.today());
+ DataImportWorker diw = new DataImportWorker();
+ DataImportWorker.importData();
+ System.debug('Finished Scheduled job @ ' + Date.today());
+ }
+}
View
5 src/classes/GoogleAnalyticsImporter.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
13 src/classes/GoogleAnalyticsImporter_Test.cls
@@ -0,0 +1,13 @@
+@isTest
+private class GoogleAnalyticsImporter_Test {
+ static testMethod void testShceduledJob()
+ {
+ Test.startTest();
+ GoogleAnalyticsImporter gai = new GoogleAnalyticsImporter();
+ Datetime dt = Datetime.now().addMinutes(1);
+ String sch = '0 '+dt.minute()+' * '+dt.day()+' '+dt.month()+' '+' ? '+dt.year();
+
+ System.schedule('Schedule', sch, gai);
+ test.stoptest();
+ }
+}
View
5 src/classes/GoogleAnalyticsImporter_Test.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
19 src/classes/GoogleAnalyticsTest.cls
@@ -77,4 +77,23 @@ private class GoogleAnalyticsTest {
System.assertEquals('/hcpHome', entries[0].getDimension('ga:pagePath'));
System.assertEquals('6', entries[0].getMetric('ga:pageviews'));
}
+
+ static testMethod void testParseDate() {
+ Date dt = GoogleAnalytics.parseDate('20110824');
+ System.assertEquals(2011, dt.year());
+ System.assertEquals(8, dt.month());
+ System.assertEquals(24, dt.day());
+ }
+
+ static testMethod void testGetMetrics() {
+ List<String> metrics = new List<String>();
+ metrics.add('ga:Visitors');
+ MetricsData md = ga.getMetrics(Date.today() - 100, Date.today()-99, metrics);
+ }
+
+ static testMethod void insertDailyMetrics() {
+ List<String> metrics = new List<String>();
+ metrics.add('ga:Visitors');
+ ga.insertDailyMetrics(Date.today() - 100, Date.today()-99, metrics);
+ }
}
View
10 src/classes/ImportGoogleAnalytics.cls
@@ -38,10 +38,14 @@ public with sharing class ImportGoogleAnalytics {
public static void importDailyMetrics(string siteMetricSettingsName) {
if(initialize(siteMetricSettingsName)) {
- Date startDate = Date.newInstance(2011, 2, 1);
- Date endDate = Date.newInstance(2011, 2, 28);
+ Date startDate = Date.newInstance(2011, 8, 19);
+ Date endDate = Date.newInstance(2011, 8, 19);
- ga.insertDailyMetrics(startDate, endDate, new list<String>{GoogleAnalytics.VisitorsMetric});
+ ga.insertDailyMetrics(startDate, endDate, new list<String>{GoogleAnalytics.VisitorsMetric,
+ GoogleAnalytics.PageViewsPerVisitMetric,
+ GoogleAnalytics.PercentNewVisitsMetric,
+ GoogleAnalytics.VisitBounceRateMetric,
+ GoogleAnalytics.AverageTimeOnSiteMetric});
}
}
View
2  src/classes/ImportGoogleAnalytics_Test.cls
@@ -16,7 +16,7 @@
@isTest
private class ImportGoogleAnalytics_Test {
- static string siteMetricSettingsName = 'Test';
+ static string siteMetricSettingsName = 'MyBlog';
static {
insert new Site_Metric_Settings__c(Name='Test', Email__c='test@test.com', Password__c='test', Table_Id__c='test');
View
33 src/classes/MetricsData.cls
@@ -0,0 +1,33 @@
+public with sharing class MetricsData {
+ public map<Date, Site_Metric_Date__c> metricDates {get; set;}
+ public map<Date, list<Site_Metric__c>> metricsMap {get; set;}
+
+ public MetricsData() {
+ metricDates = new map<Date, Site_Metric_Date__c>();
+ metricsMap = new map<Date, list<Site_Metric__c>>();
+ }
+
+ public void accumulateData(MetricsData metricsData) {
+ for (Date metricsDate : metricsData.metricDates.keySet()) {
+ System.debug('Date in MetricsData.accumulateData - metricDates: ' + metricsDate);
+ metricDates.put(metricsDate, metricsData.metricDates.get(metricsDate));
+ }
+ for (Date metricsDate : metricsData.metricsMap.keySet()) {
+ System.debug('Date in MetricsData.accumulateData - metricsMap: ' + metricsDate);
+
+ list<Site_Metric__c> allMetrics = metricsMap.get(metricsDate);
+ list<Site_Metric__c> metricsToBeAdded = metricsData.metricsMap.get(metricsDate);
+
+ if (allMetrics != null) {
+ //Metrics exist so add to the metrics
+ for (Site_Metric__c siteMetric : metricsToBeAdded) {
+ allMetrics.add(siteMetric);
+ }
+ metricsMap.put(metricsDate, allMetrics);
+ } else {
+ //Adding metrics for the first time
+ metricsMap.put(metricsDate, metricsToBeAdded);
+ }
+ }
+ }
+}
View
5 src/classes/MetricsData.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
92 src/classes/MetricsData_Test.cls
@@ -0,0 +1,92 @@
+@isTest
+private class MetricsData_Test {
+ static Date yesterdayDate = Date.TODAY() - 1;
+ static Date todayDate = Date.TODAY();
+
+ static Site_Metric_Date__c metricDateYesterday = new Site_Metric_Date__c(Name = 'Yesterday', Start_Date__c = yesterdayDate);
+ static Site_Metric_Date__c metricDateToday = new Site_Metric_Date__c(Name = 'Today', Start_Date__c = todayDate);
+
+ static testMethod void testEmptyMapsCreated() {
+ MetricsData md = new MetricsData();
+ System.assert(md.metricDates.size() == 0);
+ System.assert(md.metricsMap.size() == 0);
+ }
+
+ static testMethod void testMetricDatesAccumulation() {
+ MetricsData mdMaster = new MetricsData();
+ MetricsData dataToBeAdded = new MetricsData();
+
+ //Add one date record
+ dataToBeAdded.metricDates.put(yesterdayDate, metricDateYesterday);
+ mdMaster.accumulateData(dataToBeAdded);
+ System.assert(mdMaster.metricDates.size() == 1);
+
+ //Add one more date record with same date - size should not increase
+ mdMaster.accumulateData(dataToBeAdded);
+ System.assert(mdMaster.metricDates.size() == 1);
+
+ //Add one more date record with different date - size should increase by 1
+ dataToBeAdded = new MetricsData();
+ dataToBeAdded.metricDates.put(todayDate, metricDateToday);
+ mdMaster.accumulateData(dataToBeAdded);
+ System.assert(mdMaster.metricDates.size() == 2);
+
+ }
+ static testMethod void testMetricsAccumulation() {
+ MetricsData mdMaster = new MetricsData();
+ MetricsData dataToBeAdded = new MetricsData();
+
+ Site_Metric__c siteMetricYesterdayVisitors = new Site_Metric__c(Name = 'Yesterday-visitors',
+ value__c = 4);
+ Site_Metric__c siteMetricTodayVisitors = new Site_Metric__c(Name = 'Today-visitors',
+ value__c = 2);
+ Site_Metric__c siteMetricYesterdayPageViews = new Site_Metric__c(Name = 'Yesterday-pageViews',
+ value__c = 10);
+ Site_Metric__c siteMetricTodayPageViews = new Site_Metric__c(Name = 'Today-pageViews',
+ value__c = 8);
+
+ //Add one date record & one metric record for the same date
+ dataToBeAdded.metricDates.put(yesterdayDate, metricDateYesterday);
+ dataToBeAdded.metricsMap.put(yesterdayDate, new List<Site_Metric__c>{siteMetricYesterdayVisitors});
+ mdMaster.accumulateData(dataToBeAdded);
+
+ //Assert only one record in metricsMap and only one record in the list for the single metricsMap Record
+ System.assert(mdMaster.metricsMap.size() == 1);
+ System.assert(mdMaster.metricsMap.get(yesterdayDate).size() == 1);
+
+ //Add another metric record for the same date
+ dataToBeAdded = new MetricsData();
+ dataToBeAdded.metricDates.put(yesterdayDate, metricDateYesterday);
+ dataToBeAdded.metricsMap.put(yesterdayDate, new List<Site_Metric__c>{siteMetricYesterdayPageViews});
+ mdMaster.accumulateData(dataToBeAdded);
+
+ //Assert only one record in metricsMap and two records in the list for the single metricsMap Record
+ System.assert(mdMaster.metricsMap.size() == 1);
+ System.assert(mdMaster.metricsMap.get(yesterdayDate).size() == 2);
+
+
+ //Add another date record & one metric record for the new date
+ dataToBeAdded = new MetricsData();
+ dataToBeAdded.metricDates.put(todayDate, metricDateToday);
+ dataToBeAdded.metricsMap.put(todayDate, new List<Site_Metric__c>{siteMetricTodayVisitors});
+ mdMaster.accumulateData(dataToBeAdded);
+
+ //Assert two records in metricsMap and only one record in the list for the newly inserted metricsMap Record.
+ //The old metricsMap record will have 2 records in the list as per before
+ System.assert(mdMaster.metricsMap.size() == 2);
+ System.assert(mdMaster.metricsMap.get(todayDate).size() == 1);
+ System.assert(mdMaster.metricsMap.get(yesterdayDate).size() == 2);
+
+ //Add another metric record for the same date
+ dataToBeAdded = new MetricsData();
+ dataToBeAdded.metricDates.put(todayDate, metricDateToday);
+ dataToBeAdded.metricsMap.put(todayDate, new List<Site_Metric__c>{siteMetricTodayPageViews});
+ mdMaster.accumulateData(dataToBeAdded);
+
+ //Assert two records in metricsMap and two records in the list for the new metricsMap Record
+ //The old metricsMap record will have 2 records in the list as per before
+ System.assert(mdMaster.metricsMap.size() == 2);
+ System.assert(mdMaster.metricsMap.get(todayDate).size() == 2);
+ System.assert(mdMaster.metricsMap.get(yesterdayDate).size() == 2);
+ }
+}
View
5 src/classes/MetricsData_Test.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
11 src/classes/UtilityClass.cls
@@ -0,0 +1,11 @@
+public with sharing class UtilityClass {
+ public static void deleteSiteMetricDates() {
+ List<Site_Metric_Date__c> dates = [select name from Site_Metric_Date__c];
+ delete dates;
+ }
+ public static void getOneSiteSetting() {
+ List<Site_Metric_Settings__c> sites = [Select s.Name From Site_Metric_Settings__c s];
+ String siteName = sites[0].Name;
+ System.debug('Site Name: ' + siteName);
+ }
+}
View
5 src/classes/UtilityClass.cls-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>20.0</apiVersion>
+ <status>Active</status>
+</ApexClass>
View
5 src/objects/Site_Event__c.object
@@ -105,6 +105,11 @@
<label>All</label>
<language>en_US</language>
</listViews>
+ <listViews>
+ <fullName>All1</fullName>
+ <filterScope>Everything</filterScope>
+ <label>All</label>
+ </listViews>
<nameField>
<label>Product</label>
<type>Text</type>
View
14 src/objects/Site_Metric_Date__c.object
@@ -59,6 +59,10 @@
<label>Site Metric Date</label>
<listViews>
<fullName>All</fullName>
+ <columns>NAME</columns>
+ <columns>Start_Date__c</columns>
+ <columns>CREATED_DATE</columns>
+ <columns>LAST_UPDATE</columns>
<filterScope>Everything</filterScope>
<label>All</label>
</listViews>
@@ -67,7 +71,15 @@
<type>Text</type>
</nameField>
<pluralLabel>Site Metric Dates</pluralLabel>
- <searchLayouts/>
+ <searchLayouts>
+ <customTabListAdditionalFields>Start_Date__c</customTabListAdditionalFields>
+ <customTabListAdditionalFields>End_Date__c</customTabListAdditionalFields>
+ <lookupDialogsAdditionalFields>Start_Date__c</lookupDialogsAdditionalFields>
+ <lookupDialogsAdditionalFields>End_Date__c</lookupDialogsAdditionalFields>
+ <lookupPhoneDialogsAdditionalFields>Start_Date__c</lookupPhoneDialogsAdditionalFields>
+ <lookupPhoneDialogsAdditionalFields>End_Date__c</lookupPhoneDialogsAdditionalFields>
+ <searchResultsAdditionalFields>Start_Date__c</searchResultsAdditionalFields>
+ </searchLayouts>
<sharingModel>ReadWrite</sharingModel>
<validationRules>
<fullName>End_Date_After_Start_Date</fullName>
View
80 src/objects/Site_Metric_Settings__c.object
@@ -6,6 +6,14 @@
<enableEnhancedLookup>false</enableEnhancedLookup>
<enableFeeds>false</enableFeeds>
<fields>
+ <fullName>Average_Time_on_Site__c</fullName>
+ <defaultValue>false</defaultValue>
+ <externalId>false</externalId>
+ <inlineHelpText>Select if you want to track average time spent on the site per visit.</inlineHelpText>
+ <label>Track Average Time on Site</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
<fullName>Email__c</fullName>
<description>Email username for Google Analytics</description>
<externalId>false</externalId>
@@ -37,5 +45,77 @@
<type>Text</type>
<unique>false</unique>
</fields>
+ <fields>
+ <fullName>Track_New_Visits__c</fullName>
+ <defaultValue>false</defaultValue>
+ <externalId>false</externalId>
+ <inlineHelpText>Select if you want to track percentage of new visits.</inlineHelpText>
+ <label>Track New Visits %</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Track_Page_Views_Per_Visit__c</fullName>
+ <defaultValue>false</defaultValue>
+ <externalId>false</externalId>
+ <inlineHelpText>Select if you want to track page views per visit.</inlineHelpText>
+ <label>Track Page Views Per Visit</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Track_Visit_Bounce_Rate__c</fullName>
+ <defaultValue>false</defaultValue>
+ <externalId>false</externalId>
+ <inlineHelpText>Select if you want to track visit bounce rate.</inlineHelpText>
+ <label>Track Visit Bounce Rate</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Track_Visitors__c</fullName>
+ <defaultValue>false</defaultValue>
+ <externalId>false</externalId>
+ <inlineHelpText>Select if you want to track visitors to your site.</inlineHelpText>
+ <label>Track Visitors</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Tracking_Average_Time_on_Site__c</fullName>
+ <defaultValue>false</defaultValue>
+ <description>This is an internal field to determine if we need to pull just the day&apos;s Google Analytics data or last 30 day&apos;s worth Google Analytics data.</description>
+ <externalId>false</externalId>
+ <label>Tracking Average Time on Site</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Tracking_New_Visits__c</fullName>
+ <defaultValue>false</defaultValue>
+ <description>This is an internal field to determine if we need to pull just the day&apos;s Google Analytics data or last 30 day&apos;s worth Google Analytics data.</description>
+ <externalId>false</externalId>
+ <label>Tracking New Visits %</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Tracking_Page_Views_Per_Visit__c</fullName>
+ <defaultValue>false</defaultValue>
+ <description>This is an internal field to determine if we need to pull just the day&apos;s Google Analytics data or last 30 day&apos;s worth Google Analytics data.</description>
+ <externalId>false</externalId>
+ <label>Tracking Page Views Per Visit</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Tracking_Visit_Bounce_Rate__c</fullName>
+ <defaultValue>false</defaultValue>
+ <description>This is an internal field to determine if we need to pull just the day&apos;s Google Analytics data or last 30 day&apos;s worth Google Analytics data.</description>
+ <externalId>false</externalId>
+ <label>Tracking Visit Bounce Rate</label>
+ <type>Checkbox</type>
+ </fields>
+ <fields>
+ <fullName>Tracking_Visitors__c</fullName>
+ <defaultValue>false</defaultValue>
+ <description>This is an internal field to determine if we need to pull just the day&apos;s Google Analytics data or last 30 day&apos;s worth Google Analytics data.</description>
+ <externalId>false</externalId>
+ <label>Tracking Visitors</label>
+ <type>Checkbox</type>
+ </fields>
<label>Site Metric Settings</label>
</CustomObject>
View
7 src/objects/Site_Metric__c.object
@@ -154,7 +154,12 @@
<type>Text</type>
</nameField>
<pluralLabel>Site Metrics</pluralLabel>
- <searchLayouts/>
+ <searchLayouts>
+ <lookupDialogsAdditionalFields>Display_Value__c</lookupDialogsAdditionalFields>
+ <lookupDialogsAdditionalFields>Value__c</lookupDialogsAdditionalFields>
+ <lookupPhoneDialogsAdditionalFields>Display_Value__c</lookupPhoneDialogsAdditionalFields>
+ <lookupPhoneDialogsAdditionalFields>Value__c</lookupPhoneDialogsAdditionalFields>
+ </searchLayouts>
<sharingModel>ControlledByParent</sharingModel>
<validationRules>
<fullName>Time_Format</fullName>
View
33 src/package.xml
@@ -1,28 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
- <members>*</members>
+ <members>AnalyticSettingsController</members>
+ <members>AnalyticSettingsController_Test</members>
+ <members>DataImportWorker</members>
+ <members>DataImportWorker_Test</members>
+ <members>GoogleAnalytics</members>
+ <members>GoogleAnalyticsImporter</members>
+ <members>GoogleAnalyticsImporter_Test</members>
+ <members>GoogleAnalyticsTest</members>
+ <members>ImportGoogleAnalytics</members>
+ <members>ImportGoogleAnalytics_Test</members>
+ <members>MetricsData</members>
+ <members>MetricsData_Test</members>
+ <members>SiteMetricTime_Test</members>
+ <members>UtilityClass</members>
<name>ApexClass</name>
</types>
<types>
- <members>*</members>
- <name>ApexComponent</name>
- </types>
- <types>
- <members>*</members>
+ <members>analyticsSettings</members>
+ <members>editsite</members>
<name>ApexPage</name>
</types>
<types>
- <members>*</members>
+ <members>SiteMetric_Time</members>
<name>ApexTrigger</name>
</types>
<types>
- <members>*</members>
+ <members>Site_Event__c</members>
+ <members>Site_Metric_Date__c</members>
+ <members>Site_Metric_Settings__c</members>
+ <members>Site_Metric__c</members>
<name>CustomObject</name>
</types>
- <types>
- <members>*</members>
- <name>StaticResource</name>
- </types>
<version>20.0</version>
</Package>
View
64 src/pages/analyticsSettings.page
@@ -0,0 +1,64 @@
+<apex:page controller="AnalyticSettingsController">
+ <apex:form >
+ <apex:pageBlock mode="edit" id="block">
+ <apex:pageMessages />
+ <apex:pageBlockSection title="Manage Sites">
+ <apex:pageBlockSectionItem >
+ <apex:panelGroup >
+ <apex:outputLabel for="siteName">Site Name</apex:outputLabel>
+ <apex:inputText id="siteName" value="{!siteName}"/>
+ <br/>
+ <apex:commandButton value="Search" action="{!searchSites}"
+ rerender="block" status="searchStatus"/>
+ <apex:commandButton value="View" action="{!getSiteInfo}"
+ rerender="block" status="status"/>
+ <apex:commandButton value="Edit / New" action="{!editSite}" />
+ </apex:panelGroup>
+ </apex:pageBlockSectionItem>
+ </apex:pageBlockSection>
+ <apex:actionStatus id="searchStatus" startText="searching..."/>
+ <apex:pageBlockSection title="Available Sites" id="availableSites" columns="1">
+ <apex:pageBlockTable value="{!sites}" var="site"
+ rendered="{!NOT(ISNULL(sites))}">
+ <apex:column headerValue="Site Name">
+ <apex:commandLink value="{!site.Name}" action="{!getSiteInfo}">
+ <apex:param name="siteName" value="{!site.Name}" assignTo="{!siteName}"/>
+ </apex:commandLink>
+ </apex:column>
+ </apex:pageBlockTable>
+ </apex:pageBlockSection>
+ <apex:actionStatus id="status" startText="requesting..."/>
+ <apex:pageBlockSection title="Site Info" id="siteInfo" columns="1">
+
+ <apex:pageBlockTable value="{!settings}" var="siteSetting"
+ rendered="{!NOT(ISNULL(settings))}">
+ <apex:column value="{!siteSetting.Name}"/>
+ <apex:column value="{!siteSetting.Email__c}"/>
+ <apex:column value="{!siteSetting.Password__c}"/>
+ <apex:column value="{!siteSetting.Table_Id__c}"/>
+ </apex:pageBlockTable>
+ </apex:pageBlockSection>
+ <apex:pageBlockSection title="Site Metrics" id="siteMetrics" columns="1">
+ <apex:pageBlockTable value="{!settings}" var="siteMetrics"
+ rendered="{!NOT(ISNULL(settings))}">
+ <apex:column value="{!siteMetrics.Track_Visitors__c}"/>
+ <apex:column value="{!siteMetrics.Track_New_Visits__c}"/>
+ <apex:column value="{!siteMetrics.Track_Page_Views_Per_Visit__c}"/>
+ <apex:column value="{!siteMetrics.Average_Time_on_Site__c}"/>
+ <apex:column value="{!siteMetrics.Track_Visit_Bounce_Rate__c}"/>
+ </apex:pageBlockTable>
+ </apex:pageBlockSection>
+ <apex:pageBlockSection title="Tracking Status" id="siteTrackingStatus" columns="1">
+ <apex:pageBlockTable value="{!settings}" var="siteTrackingStatus"
+ rendered="{!NOT(ISNULL(settings))}">
+ <apex:column value="{!siteTrackingStatus.Tracking_Visitors__c}"/>
+ <apex:column value="{!siteTrackingStatus.Tracking_New_Visits__c}"/>
+ <apex:column value="{!siteTrackingStatus.Tracking_Page_Views_Per_Visit__c}"/>
+ <apex:column value="{!siteTrackingStatus.Tracking_Average_Time_on_Site__c}"/>
+ <apex:column value="{!siteTrackingStatus.Tracking_Visit_Bounce_Rate__c}"/>
+ </apex:pageBlockTable>
+ </apex:pageBlockSection>
+
+ </apex:pageBlock>
+ </apex:form>
+</apex:page>
View
5 src/pages/analyticsSettings.page-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>22.0</apiVersion>
+ <label>analyticsSettings</label>
+</ApexPage>
View
24 src/pages/editsite.page
@@ -0,0 +1,24 @@
+<apex:page controller="AnalyticSettingsController">
+ <apex:form >
+ <apex:pageBlock title="Edit Site Info" mode="edit" id="block">
+ <apex:pageMessages />
+ <apex:pageBlockButtons >
+ <apex:commandButton value="Save" action="{!save}" />
+ <apex:commandButton immediate="true" value="Cancel" action="{!cancel}" />
+ </apex:pageBlockButtons>
+ <apex:pageBlockSection columns="2" title="Site Info">
+ <apex:inputField value="{!settings.Name}"/>
+ <apex:inputField value="{!settings.Email__c}"/>
+ <apex:inputField value="{!settings.Password__c}"/>
+ <apex:inputField value="{!settings.Table_Id__c}"/>
+ </apex:pageBlockSection>
+ <apex:pageBlockSection columns="2" title="Site Metrics">
+ <apex:inputField value="{!settings.Track_Visitors__c}"/>
+ <apex:inputField value="{!settings.Track_New_Visits__c}"/>
+ <apex:inputField value="{!settings.Track_Page_Views_Per_Visit__c}"/>
+ <apex:inputField value="{!settings.Average_Time_on_Site__c}"/>
+ <apex:inputField value="{!settings.Track_Visit_Bounce_Rate__c}"/>
+ </apex:pageBlockSection>
+ </apex:pageBlock>
+ </apex:form>
+</apex:page>
View
5 src/pages/editsite.page-meta.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
+ <apiVersion>22.0</apiVersion>
+ <label>editsite</label>
+</ApexPage>
Please sign in to comment.
Something went wrong with that request. Please try again.