From 8214d4aaa47a3a5dce1214c752951b66933fda2f Mon Sep 17 00:00:00 2001 From: Robert Gruendler Date: Fri, 11 May 2012 02:34:01 +0200 Subject: [PATCH 1/7] added dashboard api base --- Analytics.php | 63 +- DependencyInjection/GoogleExtension.php | 3 + Helper/AnalyticsHelper.php | 15 + Resources/config/analytics.xml | 1 + Resources/public/js/gdash-1.0.js | 578 ++++++++++++++++++ Resources/views/Analytics/dashboard.html.twig | 56 ++ 6 files changed, 704 insertions(+), 12 deletions(-) create mode 100644 Resources/public/js/gdash-1.0.js create mode 100644 Resources/views/Analytics/dashboard.html.twig diff --git a/Analytics.php b/Analytics.php index a6258ed..ea884b4 100644 --- a/Analytics.php +++ b/Analytics.php @@ -1,7 +1,6 @@ container = $container; $this->trackers = $trackers; $this->whitelist = $whitelist; + $this->api_key = isset($dashboard['api_key']) ? $dashboard['api_key'] : ''; + $this->client_id = isset($dashboard['client_id']) ? $dashboard['client_id'] : ''; + $this->table_id = isset($dashboard['table_id']) ? $dashboard['table_id'] : ''; } public function excludeBaseUrl() @@ -128,7 +134,8 @@ public function getTrackPageLoadTime($trackerKey) */ public function getCustomPageView() { - $customPageView = $this->container->get('session')->get(self::CUSTOM_PAGE_VIEW_KEY); + $customPageView = $this->container->get('session') + ->get(self::CUSTOM_PAGE_VIEW_KEY); $this->container->get('session')->remove(self::CUSTOM_PAGE_VIEW_KEY); return $customPageView; } @@ -146,7 +153,8 @@ public function hasCustomPageView() */ public function setCustomPageView($customPageView) { - $this->container->get('session')->set(self::CUSTOM_PAGE_VIEW_KEY, $customPageView); + $this->container->get('session') + ->set(self::CUSTOM_PAGE_VIEW_KEY, $customPageView); } /** @@ -303,7 +311,7 @@ public function getRequestUri() $query = http_build_query($params); if (isset($query) && '' != trim($query)) { - $requestUri .= '?'. $query; + $requestUri .= '?' . $query; } return $requestUri; } @@ -331,13 +339,17 @@ public function getTrackers(array $trackers = array()) */ public function isTransactionValid() { - if (!$this->hasTransaction() || (null === $this->getTransactionFromSession()->getOrderNumber())) { + if (!$this->hasTransaction() + || (null + === $this->getTransactionFromSession() + ->getOrderNumber())) { return false; } if ($this->hasItems()) { $items = $this->getItemsFromSession(); foreach ($items as $item) { - if (!$item->getOrderNumber() || !$item->getSku() || !$item->getPrice() || !$item->getQuantity()) { + if (!$item->getOrderNumber() || !$item->getSku() + || !$item->getPrice() || !$item->getQuantity()) { return false; } } @@ -368,7 +380,8 @@ public function hasTransaction() */ public function setTransaction(Transaction $transaction) { - $this->container->get('session')->set(self::TRANSACTION_KEY, $transaction); + $this->container->get('session') + ->set(self::TRANSACTION_KEY, $transaction); } /** @@ -427,4 +440,30 @@ private function getTransactionFromSession() { return $this->container->get('session')->get(self::TRANSACTION_KEY); } + + /** + * + * @return string + */ + public function getApiKey() + { + return $this->api_key; + } + + /** + * + * @return string + */ + public function getClientId() + { + return $this->client_id; + } + + /** + * @return string + */ + public function getTableId() + { + return $this->table_id; + } } diff --git a/DependencyInjection/GoogleExtension.php b/DependencyInjection/GoogleExtension.php index 3cf8e4b..bb891b3 100755 --- a/DependencyInjection/GoogleExtension.php +++ b/DependencyInjection/GoogleExtension.php @@ -65,6 +65,9 @@ private function analyticsLoad(array $configs, ContainerBuilder $container) if (isset($config['trackers'])) { $container->setParameter('google.analytics.trackers', $config['trackers']); } + if (isset($config['dashboard'])) { + $container->setParameter('google.analytics.dashboard', $config['dashboard']); + } if (isset($config['whitelist'])) { $container->setParameter('google.analytics.whitelist', $config['whitelist']); } diff --git a/Helper/AnalyticsHelper.php b/Helper/AnalyticsHelper.php index e8f4e28..3691dcb 100644 --- a/Helper/AnalyticsHelper.php +++ b/Helper/AnalyticsHelper.php @@ -110,6 +110,21 @@ public function getTrackers(array $trackers = array()) { return $this->analytics->getTrackers($trackers); } + + public function getApiKey() + { + return $this->analytics->getApiKey(); + } + + public function getClientId() + { + return $this->analytics->getClientId(); + } + + public function getTableId() + { + return $this->analytics->getTableId(); + } public function isTransactionValid() { diff --git a/Resources/config/analytics.xml b/Resources/config/analytics.xml index a43a196..4597ce4 100644 --- a/Resources/config/analytics.xml +++ b/Resources/config/analytics.xml @@ -15,6 +15,7 @@ %google.analytics.trackers% %google.analytics.whitelist% + %google.analytics.dashboard% diff --git a/Resources/public/js/gdash-1.0.js b/Resources/public/js/gdash-1.0.js new file mode 100644 index 0000000..4d5c263 --- /dev/null +++ b/Resources/public/js/gdash-1.0.js @@ -0,0 +1,578 @@ +// Copyright 2012 Google Inc. All Rights Reserved. + +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author + * Shan Aminzadeh, shan.aminzadeh@gmail.com + * Arya Bondarian, aryabond@gmail.com + * Albert Gau, agau@uci.edu + * Travis Lai, travisrlai@gmail.com + * Daniel Nguyen, danielnuwin@gmail.com + * Nick Mihailovski, api.nickm@gmail.com + * + * @fileoverview + * This library is designed to create an easier way to build a custom + * Google Analytics Dashboard by visualizing data from Google Analytics + * API with the Google Chart Tools. + */ + + +// Loads the core chart and table from the Google Visualization. +google.load('visualization', '1', {'packages': ['corechart', 'table']}); + + +// Create namespace for this library if not already created. +var gadash = gadash || {}; + + +// Namespace for util object. Contains lots of library utilities. +gadash.util = gadash.util || {}; + + +/** + * Refers to the Google Analytics API scope that the user will need + * authentication for. + * @const {String} + */ +gadash.SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'; + + +/** + * List of functions that are queued for execution. This is only used + * until all the libraries have fully loaded. + * @type {Array} + */ +gadash.commandQueue = []; + + +/** + * Callback executed once the Google APIs Javascript client library has loaded. + * The function name is specified in the onload query parameter of URL to load + * this library. After 1 millisecond, checkAuth is called. + */ +window.gadashInit = function() { + gapi.client.setApiKey(gadash.apiKey); + window.setTimeout(gadash.checkAuth, 1); + renderGraph(); +}; + + +/** + * Sets the API key and Client ID passed by the user. + * This information can be found in your Google API Console. + * @param {Object} settings - Contains the API Key and Client ID variables. + */ +gadash.configKeys = function(settings) { + gadash.apiKey = settings.apiKey; + gadash.clientId = settings.clientId; +}; + + +/** + * Uses the OAuth2.0 clientId to query the Google Accounts service + * to see if the user has authorized. Once complete, handleAuthResults is + * called. + */ +gadash.checkAuth = function() { + gapi.auth.authorize({ + client_id: gadash.clientId, + scope: gadash.SCOPE, + immediate: true}, gadash.handleAuthResult); +}; + + +/** + * Handler that is called once the script has checked to see if the user has + * authorized access to their Google Analytics data. If the user has authorized + * access, the analytics api library is loaded and the handleAuthorized + * function is executed. If the user has not authorized access to their data, + * the handleUnauthorized function is executed. + * @param {Object} authResult The result object returned form the authorization + * service that determine whether the user has currently authorized access + * to their data. If it exists, the user has authorized access. + */ +gadash.handleAuthResult = function(authResult) { + if (authResult) { + gapi.client.setApiVersions({'analytics': 'v3'}); + gapi.client.load('analytics', 'v3', gadash.handleAuthorized); + } else { + gadash.handleUnAuthorized(); + } +}; + + +/** + * Updates the UI once the user has authorized this script to access their + * data by hiding the authorize button. Also, runs executeCommandQueue + * function to render all charts in the commandQueue. The execution of the + * command queue only happens once. + */ +gadash.handleAuthorized = function() { + var authorizeButton = document.getElementById('authorize-button'); + authorizeButton.style.visibility = 'hidden'; + + gadash.executeCommandQueue(); +}; + + +/** + * Updates the UI if a user has not yet authorized this script to access + * their Google Analytics data. This function changes the visibility of + * some elements on the screen. It also adds the handleAuthClick + * click handler to the authorize-button. + */ +gadash.handleUnAuthorized = function() { + var authorizeButton = document.getElementById('authorize-button'); + authorizeButton.style.visibility = ''; + authorizeButton.onclick = gadash.handleAuthClick; +}; + + +/** + * Checks to see if user is authenticated, calls handleAuthResult + * @return {boolean} false. + * @param {Object} event - event when button is clicked. + */ +gadash.handleAuthClick = function(event) { + gapi.auth.authorize({ + client_id: gadash.clientId, + scope: gadash.SCOPE, + immediate: false}, gadash.handleAuthResult); + return false; +}; + + +/** + * Iterates through all commands on the commandQueue and executes them. + */ +gadash.executeCommandQueue = function() { + for (var i = 0, command; command = gadash.commandQueue[i]; ++i) { + command(); + } +}; + + +/** + * A Chart object is the primary object in this library. + * A Chart accepts an optional configuration object that contains all the + * parameters of the chart. Also changes start and end date of + * the query, if last-n-days is set in the config. + * @param {?Object} config - Contains all configuration variables + * of a Chart object. This parameter is passed by value, and a deep + * copy is made. Once set, the original object can be modified and + * it will not affect this object. + * @return {Object} this Returns a reference to the newly instantiated + * Chart instance. Useful for chaining methods together. + * @constructor + */ +gadash.Chart = function(opt_config) { + /** + * The main configuration object. + * @type {Object} + */ + this.config = {}; + + if (opt_config) { + gadash.util.extend(opt_config, this.config); + } + + return this; +}; + + +/** + * Extends the values in the chart's config object with the keys in + * the config parameters. If a key in config already exists in the chart, + * and the value is not an object, the new value overwrites the old. + * @param {Object} config The config object to set inside this object. + * @return {Object} The current instance of the Chart object. Useful + * for chaining methods. + */ +gadash.Chart.prototype.set = function(config) { + gadash.util.extend(config, this.config); + return this; +}; + + +/** + * First checks to see if the GA library is loaded. If it is then the + * chart can be rendered right away. Otherwise, other operations are queued, + * so the render command is pushed to the command queue to be executed in + * the same order as originally called. + * @this Points to the current chart instance. + * @return {Object} The current instance of this chart object. Useful for + * chaining methods. + */ +gadash.Chart.prototype.render = function() { + + // If the client library has loaded. + if (gapi.client.analytics) { + this.renderFunction(); + } else { + var renderFunction = gadash.util.bindMethod(this, this.renderFunction); + gadash.commandQueue.push(renderFunction); + } + + return this; +}; + + +/** + * Makes a request to the Google Analytics API. + * Updates the start and end date if last-n-days + * has been set. The function also creates and executes a Google Analytics + * API request using the Chart objects callback method. The callback + * is bound to the Chart instance so a reference back to this chart is + * maintained within the callback. + */ +gadash.Chart.prototype.renderFunction = function() { + + // Update the start and end dates based on last n days. + if (this.config['last-n-days']) { + this.config.query['end-date'] = gadash.util.lastNdays(0); + this.config.query['start-date'] = + gadash.util.lastNdays(this.config['last-n-days']); + } + var request = gapi.client.analytics.data.ga.get(this.config.query); + request.execute(gadash.util.bindMethod(this, this.callback)); +} + + + +/** + * Callback function that is called after a GA query is executed. + * First, the function checks to see if there are any errors on the + * response. Then check to see if a onSuccess function was declared + * in the config. If present, call onSuccess by first binding it to + * this (ie this chart object instance). If not defined, just use + * the default callback. The entire JSON response from the API + * is passed to either defined or default callback. + * @param {Object} response - Google Analytics API JSON response. + */ +gadash.Chart.prototype.callback = function(response) { + if (response.error) { + this.defaultOnError(response.error.code + ' ' + response.error.message); + } else { + + if (this.config.onSuccess) { + gadash.util.bindMethod(this, this.config.onSuccess)(response); + } else { + this.defaultOnSuccess(response); + } + } +}; + + +/** + * Checks to see if onError parameter is set in config. If it is, + * use the user defined error function else check to see if an error + * div is created. If not, create an error div. Print error message + * to the error div. + * @param {String} message - error message to print. + */ +gadash.Chart.prototype.defaultOnError = function(message) { + + // If onError param exists, use that as error handling function. + if (this.config.onError) { + this.config.onError(message); + } else { + + var errorDiv = document.getElementById('errors'); + + // Create error div if not already made. + if (!errorDiv) { + errorDiv = document.createElement('div'); + errorDiv.style.color = 'red'; + errorDiv.setAttribute('id', 'errors'); + errorDiv.innerHTML = 'ERRORS:' + '
'; + document.body.appendChild(errorDiv); + } + + // Prints chart divContainer and message to error div. + errorDiv.innerHTML += this.config.divContainer + ' error: ' + + message + '
'; + } +}; + + +/** + * Default callback for creating Google Charts with a response. First, the + * response is put into a DataTable object Second, the corresponding chart + * is returned. The two are then combined to draw a chart that is populated + * with the GA data. + * @param {Object} resp - A Google Analytics API JSON response. + */ +gadash.Chart.prototype.defaultOnSuccess = function(resp) { + var dataTable = gadash.util.getDataTable(resp); + var chart = gadash.util.getChart(this.config.divContainer, this.config.type); + gadash.util.draw(chart, dataTable, this.config.chartOptions); +}; + + +/** + * Creates a DataTable object using a GA response. + * @param {Object} resp - A Google Analytics response. + * @param {?String} opt_chartType - The chart type. Provides a hint on + * how to parse the API results into a data table. + * @return {Object} data - A Google DataTable object populated + * with the GA response data. + */ +gadash.util.getDataTable = function(resp, opt_chartType) { + + var chartType = opt_chartType || false; + + var data = new google.visualization.DataTable(); + var numOfColumns = resp.columnHeaders.length; + var numOfRows; + + // Throw an error if there are no rows returned. + if (resp.rows && resp.rows.length) { + numOfRows = resp.rows.length; + } else { + this.defaultOnError('No rows returned for that query.'); + } + + /* + * Looks at the resp column headers to set names and types for each column. + * Since bar and column chart don't support date object, set type as string + * rather than a Date. + */ + for (var i = 0; i < numOfColumns; i++) { + var dataType = resp.columnHeaders[i].dataType; + var name = resp.columnHeaders[i].name; + + if (name == 'ga:date' && + !(chartType == 'ColumnChart' || chartType == 'BarChart')) { + + dataType = 'date'; + } else if (dataType == 'STRING') { + dataType = 'string'; + } else { + dataType = 'number'; + } + data.addColumn(dataType, gadash.util.formatGAString(name)); + } + + /* + * Populates the rows by using the resp.rows array. If the type + * is an int then parse the INT. If it is a percent, then round + * to last two decimal places and store as INT. + */ + for (var i = 0; i < numOfRows; i++) { + var arrayMetrics = []; + for (var j = 0; j < numOfColumns; j++) { + var name = resp.columnHeaders[j].name; + var dataType = resp.columnHeaders[j].dataType; + + if (name == 'ga:date' && + !(chartType == 'ColumnChart' || chartType == 'BarChart')) { + + arrayMetrics.push(gadash.util.stringToDate(resp.rows[i][j])); + } else if (dataType == 'INTEGER') { + arrayMetrics.push(parseInt(resp.rows[i][j])); + } else if (dataType == 'PERCENT' || dataType == 'TIME' || + dataType == 'FLOAT') { + arrayMetrics.push(Math.round((resp.rows[i][j]) * 100) / 100); + } else { + arrayMetrics.push(resp.rows[i][j]); + } + } + data.addRow(arrayMetrics); + } + + return data; +}; + + +/** + * Checks to see if the type of chart in the config is valid. + * If it is, get its chart instance, else return a Table instance. + * @param {String} id The ID of the HTML element in which to render + * the chart. + * @param {String} chartType The type of the Chart to render. + * @return {Object} visualization - returns the Chart instance. + */ +gadash.util.getChart = function(id, chartType) { + var elem = document.getElementById(id); + + if (google.visualization[chartType]) { + return new google.visualization[chartType](elem); + } + + return new google.visualization.Table(elem); +}; + + +/** + * Draws a chart to its declared div using a DataTable. + * @param {Object} chart - The Chart instance you wish to draw the data into. + * @param {Object} dataTable - The Google DataTable object holding + * the response data. + * @param {Object} options - The optional configuration parameters to pass + * into the chart. + */ +gadash.util.draw = function(chart, dataTable, chartOptions) { + chart.draw(dataTable, chartOptions); +}; + + +/** + * Binds a method to its object. + * @param {Object} object The main object to bind to. + * @param {Object} method The method to bind to the object. + * @return {function} the function passed in boound to the object parameter. + */ +gadash.util.bindMethod = function(object, method) { + return function() { + return method.apply(object, arguments); + }; +}; + + +/** + * Utility method to return the lastNdays from today in the format yyyy-MM-dd. + * @param {Number} n The number of days in the past from tpday that we should + * return a date. Value of 0 returns today. + * @return {String} date - The adjusted date value represented as a String. + */ +gadash.util.lastNdays = function(n) { + var today = new Date(); + var before = new Date(); + before.setDate(today.getDate() - n); + + var year = before.getFullYear(); + + var month = before.getMonth() + 1; + if (month < 10) { + month = '0' + month; + } + + var day = before.getDate(); + if (day < 10) { + day = '0' + day; + } + + return [year, month, day].join('-'); +}; + + +/** + * Utility method to return Date from a String in the format yyyy-MM-dd. + * This function is used for a Chart that has a Time Series. + * @param {String} date - The String representation of the date. + * @return {Date} date - Corresponding JS Date object. + */ +gadash.util.stringToDate = function(date) { + var year = date.substring(0, 4); + var month = date.substring(4, 6); + var day = date.substring(6, 8); + + if (month < 10) { + month = month.substring(1, 2); + } + + month = month - 1; + + if (day < 10) { + day = day.substring(1, 2); + } + + var dateObj = new Date(year, month, day); + return dateObj; +}; + + +/** + * Formats the Google Metrics and Dimensions into readable strings + * Strips away the 'ga' and capitalizes first letter. Also puts a space + * between any lowercase and capital letters. + * ie: "ga:percentNewVisits" ---> "Percent New Visits" + * @param {String} gaString - the String name of Metric/Dimension from GA. + * @return {String} newString - Metric/Dimension formatted nicely. + */ +gadash.util.formatGAString = function(gaString) { + var newString = gaString.substring(3); + newString = newString.charAt(0).toUpperCase() + newString.slice(1); + + // Check for a capital letter in the string. If found, + // put a space between that char and the char before it. + for (var i = 1; i < newString.length; i++) { + if (newString.charAt(i) == newString.charAt(i).toUpperCase()) { + var left = newString.substring(0, i); + var right = newString.substring(i, newString.length); + newString = [left, right].join(' '); + i++; + } + } + + return newString; +}; + + +/** + * Recursively copies the values in the from object into the to object. + * If a key in from object already exists, and has child values, + * the child values are copied over. So: + * extend({'a': {'b': 2}}, {'a': {'c': 1}}) will result in: + * {'a': {'b': 2, 'c': 1}} + * Once run, modifying the from object will not impact the to object. + * NOTE: Arrays will write over each other. + * NOTE: This is unsafe in that circular references are not checked. Calling + * this method with a circular reference could cause an infinite loop. + * @param {Object} from The object to copy values from. + * @param {Object} to The object to copy values into. + */ +gadash.util.extend = function(from, to) { + for (var key in from) { + var type = gadash.util.getType(from[key]); + if (type == 'object') { + to[key] = to[key] || {}; + gadash.util.extend(from[key], to[key]); + } else { + to[key] = from[key]; + } + } +} + + +/** + * Returns the native type (class property) of this object. + * General idea grabbed from here: http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ + * Per ECMA-262: + * + * 15.2.4.2 Object.prototype.toString ( ) + * When the toString method is called, the following steps are taken: + * 1. Get the [[Class]] property of this object. + * 2. Compute a string value by concatenating the three + * strings "[object ", | Result(1), and "]". + * 3. Return Result(2). + * + * @param {Object} value Any type. + * @returns {String} The lower class property of the object. Undefined if value + * is undefined or null. + */ +gadash.util.getType = function(value) { + var classStringName = Object.prototype.toString.call(value); + return ({ + '[object Boolean]': 'boolean', + '[object Number]': 'number', + '[object String]': 'string', + '[object Array]': 'array', + '[object Date]': 'date', + '[object RegExp]': 'regex', + '[object Object]' : 'object', + })[classStringName]; +} + diff --git a/Resources/views/Analytics/dashboard.html.twig b/Resources/views/Analytics/dashboard.html.twig new file mode 100644 index 0000000..5d52d08 --- /dev/null +++ b/Resources/views/Analytics/dashboard.html.twig @@ -0,0 +1,56 @@ + + + + + \ No newline at end of file From db4d136d731ec2f4084dc353143542cf28ece00a Mon Sep 17 00:00:00 2001 From: Robert Gruendler Date: Fri, 11 May 2012 09:02:35 +0200 Subject: [PATCH 2/7] removed drawing code, added callbacks --- Resources/public/js/gdash-1.0.js | 33 +++++++++++- Resources/views/Analytics/dashboard.html.twig | 51 ++----------------- 2 files changed, 36 insertions(+), 48 deletions(-) diff --git a/Resources/public/js/gdash-1.0.js b/Resources/public/js/gdash-1.0.js index 4d5c263..ee561da 100644 --- a/Resources/public/js/gdash-1.0.js +++ b/Resources/public/js/gdash-1.0.js @@ -65,10 +65,15 @@ gadash.commandQueue = []; window.gadashInit = function() { gapi.client.setApiKey(gadash.apiKey); window.setTimeout(gadash.checkAuth, 1); - renderGraph(); + gadash.initCallback(); }; +gadash.initCallback = function() { + + +} + /** * Sets the API key and Client ID passed by the user. * This information can be found in your Google API Console. @@ -77,6 +82,7 @@ window.gadashInit = function() { gadash.configKeys = function(settings) { gadash.apiKey = settings.apiKey; gadash.clientId = settings.clientId; + gadash.tableId = settings.tableId; }; @@ -124,8 +130,17 @@ gadash.handleAuthorized = function() { authorizeButton.style.visibility = 'hidden'; gadash.executeCommandQueue(); + gadash.onAuthorized(); + }; +/** + * Callback when the user is authorized + */ +gadash.onAuthorized = function() { + + +} /** * Updates the UI if a user has not yet authorized this script to access @@ -137,8 +152,16 @@ gadash.handleUnAuthorized = function() { var authorizeButton = document.getElementById('authorize-button'); authorizeButton.style.visibility = ''; authorizeButton.onclick = gadash.handleAuthClick; + gadash.onUnauthorized(); }; +/** + * Callback when the user is not authorized + */ +gadash.onUnauthorized = function() { + + +} /** * Checks to see if user is authenticated, calls handleAuthResult @@ -318,8 +341,16 @@ gadash.Chart.prototype.defaultOnSuccess = function(resp) { var dataTable = gadash.util.getDataTable(resp); var chart = gadash.util.getChart(this.config.divContainer, this.config.type); gadash.util.draw(chart, dataTable, this.config.chartOptions); + gadash.onSuccess(); }; +/** + * Callback when a chart has been rendered + */ +gadash.onSuccess = function() +{ + +} /** * Creates a DataTable object using a GA response. diff --git a/Resources/views/Analytics/dashboard.html.twig b/Resources/views/Analytics/dashboard.html.twig index 5d52d08..e2785c9 100644 --- a/Resources/views/Analytics/dashboard.html.twig +++ b/Resources/views/Analytics/dashboard.html.twig @@ -1,56 +1,13 @@ - + \ No newline at end of file From ce08493085d4f756d0634ee0d81bc97222545491 Mon Sep 17 00:00:00 2001 From: Robert Gruendler Date: Fri, 11 May 2012 09:07:37 +0200 Subject: [PATCH 3/7] fixed formatting --- Analytics.php | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/Analytics.php b/Analytics.php index ea884b4..c4accab 100644 --- a/Analytics.php +++ b/Analytics.php @@ -9,11 +9,11 @@ class Analytics { - const EVENT_QUEUE_KEY = 'google_analytics/event/queue'; + const EVENT_QUEUE_KEY = 'google_analytics/event/queue'; const CUSTOM_PAGE_VIEW_KEY = 'google_analytics/page_view'; - const PAGE_VIEW_QUEUE_KEY = 'google_analytics/page_view/queue'; - const TRANSACTION_KEY = 'google_analytics/transaction'; - const ITEMS_KEY = 'google_analytics/items'; + const PAGE_VIEW_QUEUE_KEY = 'google_analytics/page_view/queue'; + const TRANSACTION_KEY = 'google_analytics/transaction'; + const ITEMS_KEY = 'google_analytics/items'; private $container; private $customVariables = array(); @@ -134,8 +134,7 @@ public function getTrackPageLoadTime($trackerKey) */ public function getCustomPageView() { - $customPageView = $this->container->get('session') - ->get(self::CUSTOM_PAGE_VIEW_KEY); + $customPageView = $this->container->get('session')->get(self::CUSTOM_PAGE_VIEW_KEY); $this->container->get('session')->remove(self::CUSTOM_PAGE_VIEW_KEY); return $customPageView; } @@ -153,8 +152,7 @@ public function hasCustomPageView() */ public function setCustomPageView($customPageView) { - $this->container->get('session') - ->set(self::CUSTOM_PAGE_VIEW_KEY, $customPageView); + $this->container->get('session')->set(self::CUSTOM_PAGE_VIEW_KEY, $customPageView); } /** @@ -311,7 +309,7 @@ public function getRequestUri() $query = http_build_query($params); if (isset($query) && '' != trim($query)) { - $requestUri .= '?' . $query; + $requestUri .= '?'. $query; } return $requestUri; } @@ -339,17 +337,13 @@ public function getTrackers(array $trackers = array()) */ public function isTransactionValid() { - if (!$this->hasTransaction() - || (null - === $this->getTransactionFromSession() - ->getOrderNumber())) { + if (!$this->hasTransaction() || (null === $this->getTransactionFromSession()->getOrderNumber())) { return false; } if ($this->hasItems()) { $items = $this->getItemsFromSession(); foreach ($items as $item) { - if (!$item->getOrderNumber() || !$item->getSku() - || !$item->getPrice() || !$item->getQuantity()) { + if (!$item->getOrderNumber() || !$item->getSku() || !$item->getPrice() || !$item->getQuantity()) { return false; } } @@ -380,8 +374,7 @@ public function hasTransaction() */ public function setTransaction(Transaction $transaction) { - $this->container->get('session') - ->set(self::TRANSACTION_KEY, $transaction); + $this->container->get('session')->set(self::TRANSACTION_KEY, $transaction); } /** From d43050ff5914cef555e38772c3fb940ebdde8d8a Mon Sep 17 00:00:00 2001 From: Robert Gruendler Date: Fri, 11 May 2012 09:08:22 +0200 Subject: [PATCH 4/7] fixed newline --- Analytics.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Analytics.php b/Analytics.php index c4accab..b53632a 100644 --- a/Analytics.php +++ b/Analytics.php @@ -1,6 +1,7 @@ Date: Fri, 11 May 2012 09:10:18 +0200 Subject: [PATCH 5/7] made initCallback optional --- Resources/views/Analytics/dashboard.html.twig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Resources/views/Analytics/dashboard.html.twig b/Resources/views/Analytics/dashboard.html.twig index e2785c9..95d9f7f 100644 --- a/Resources/views/Analytics/dashboard.html.twig +++ b/Resources/views/Analytics/dashboard.html.twig @@ -8,6 +8,8 @@ 'clientId':'{{ google_analytics.clientId }}', 'tableId': '{{ google_analytics.tableId }}' }); - - gadash.initCallback = {{ initCallback }}; + + {% if initCallback is defined %} + gadash.initCallback = {{ initCallback }}; + {% endif %} \ No newline at end of file From 6c39ee49365cd3b89042c03872d4ee7a096bdfed Mon Sep 17 00:00:00 2001 From: Robert Gruendler Date: Fri, 11 May 2012 09:23:02 +0200 Subject: [PATCH 6/7] made authorize button configurable --- Resources/public/js/gdash-1.0.js | 5 +++-- Resources/views/Analytics/dashboard.html.twig | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Resources/public/js/gdash-1.0.js b/Resources/public/js/gdash-1.0.js index ee561da..a2701f3 100644 --- a/Resources/public/js/gdash-1.0.js +++ b/Resources/public/js/gdash-1.0.js @@ -83,6 +83,7 @@ gadash.configKeys = function(settings) { gadash.apiKey = settings.apiKey; gadash.clientId = settings.clientId; gadash.tableId = settings.tableId; + gadash.authorizeButton = settings.authorizeButton || 'authorize-button'; }; @@ -126,7 +127,7 @@ gadash.handleAuthResult = function(authResult) { * command queue only happens once. */ gadash.handleAuthorized = function() { - var authorizeButton = document.getElementById('authorize-button'); + var authorizeButton = document.getElementById(gadash.authorizeButton); authorizeButton.style.visibility = 'hidden'; gadash.executeCommandQueue(); @@ -149,7 +150,7 @@ gadash.onAuthorized = function() { * click handler to the authorize-button. */ gadash.handleUnAuthorized = function() { - var authorizeButton = document.getElementById('authorize-button'); + var authorizeButton = document.getElementById(gadash.authorizeButton); authorizeButton.style.visibility = ''; authorizeButton.onclick = gadash.handleAuthClick; gadash.onUnauthorized(); diff --git a/Resources/views/Analytics/dashboard.html.twig b/Resources/views/Analytics/dashboard.html.twig index 95d9f7f..672062b 100644 --- a/Resources/views/Analytics/dashboard.html.twig +++ b/Resources/views/Analytics/dashboard.html.twig @@ -3,13 +3,21 @@ \ No newline at end of file From eda53a7137ccd1ef77dc5e7685f8295afc5e0683 Mon Sep 17 00:00:00 2001 From: Robert Gruendler Date: Tue, 15 May 2012 17:30:53 +0200 Subject: [PATCH 7/7] fixed leading slash, added literal escaping, added docs for dashboard lib --- Resources/docs/dashboard.md | 88 +++++++++++++++++++ Resources/views/Analytics/dashboard.html.twig | 8 +- 2 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 Resources/docs/dashboard.md diff --git a/Resources/docs/dashboard.md b/Resources/docs/dashboard.md new file mode 100644 index 0000000..906b6f3 --- /dev/null +++ b/Resources/docs/dashboard.md @@ -0,0 +1,88 @@ +Google Dashboard API +==================== + +The bundle adds support for the [google dashboard library](http://googledevelopers.blogspot.com/2012/05/new-google-analytics-easy-dashboard.html). + +## Usage + + +### Configuration + +Add your google api credentials in your configuration (see the above link how to set it up): + +``` yml +google: + analytics: + # .... other settings + dashboard: + api_key: your-api-key + client_id: your-client-id + table_id: your-table-id +``` + +### Initializtation + +In your dashboard, simply include the `dashboard.html.twig` template with an optional `initCallback` parameter: + +``` jinja + {% include "GoogleBundle:Analytics:dashboard.html.twig" with { 'initCallback' : 'myDashCallback' } %} +``` + +The `myDashCallback` is a name of a javascript function which is being called after the google dashboard library has been initialized. + + +### Authorization + +The dashboard library needs a button to initialize the google authorization, this defaults to the id `authorize-button`: + +``` html + +``` + +The id of the element can be configured by passing a `authorizeButton` parameter to the dashboard twig template. + +### Drawing charts + +Once the user is authorized at google, you can start drawing your analytics charts in your templates: + +``` html + +
+

Visits

+
+
+ + +``` + +Note that you need to pass the `gadash.tableId` in each chart, otherwise you'll get an api error. + + + diff --git a/Resources/views/Analytics/dashboard.html.twig b/Resources/views/Analytics/dashboard.html.twig index 672062b..a9da83f 100644 --- a/Resources/views/Analytics/dashboard.html.twig +++ b/Resources/views/Analytics/dashboard.html.twig @@ -1,13 +1,13 @@ - +