Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of github.com:antimattr/GoogleBundle

  • Loading branch information...
commit 8de3f84822acde05b45832294955ece2bf92f05c 2 parents 635c590 + 8cadb31
@matthewfitz matthewfitz authored
View
35 Analytics.php
@@ -21,12 +21,19 @@ class Analytics
private $pageViewsWithBaseUrl = true;
private $trackers;
private $whitelist;
+ private $api_key;
+ private $client_id;
+ private $table_id;
- public function __construct(ContainerInterface $container, array $trackers = array(), array $whitelist = array())
+ public function __construct(ContainerInterface $container,
+ array $trackers = array(), array $whitelist = array(), array $dashboard = array())
{
$this->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()
@@ -427,4 +434,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;
+ }
}
View
3  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']);
}
View
15 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()
{
View
1  Resources/config/analytics.xml
@@ -15,6 +15,7 @@
<argument type="service" id="service_container" />
<argument>%google.analytics.trackers%</argument>
<argument>%google.analytics.whitelist%</argument>
+ <argument>%google.analytics.dashboard%</argument>
</service>
<service id="templating.helper.google_analytics" class="AntiMattr\GoogleBundle\Helper\AnalyticsHelper">
View
88 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
+<button id="authorize-button" style="visibility:hidden">Authorize Google Analytics</button>
+```
+
+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
+
+<div class="gadash-container">
+ <h3>Visits</h3>
+ <div id='dataOverTimeConfig'></div>
+<div>
+
+<script type="text/javascript">
+
+function adminInit() {
+
+ // Create new Chart.
+ var dataOverTime = new gadash.Chart({
+ 'last-n-days': 30,
+ 'chartOptions': {
+ width: 700
+ },
+ 'divContainer': 'dataOverTimeConfig',
+ 'type': 'LineChart',
+ 'query': {
+ 'dimensions': 'ga:date',
+ 'sort': 'ga:date',
+ 'metrics': 'ga:visitors, ga:visits, ga:pageviews',
+ 'ids' : gadash.tableId
+ },
+ 'chartOptions': {
+ height: 300,
+ legend: {position: 'bottom'},
+ hAxis: {title:'Date'},
+ curveType: 'function'
+ }
+ }).render();
+}
+
+</script>
+```
+
+Note that you need to pass the `gadash.tableId` in each chart, otherwise you'll get an api error.
+
+
+
View
610 Resources/public/js/gdash-1.0.js
@@ -0,0 +1,610 @@
+// 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);
+ 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.
+ * @param {Object} settings - Contains the API Key and Client ID variables.
+ */
+gadash.configKeys = function(settings) {
+ gadash.apiKey = settings.apiKey;
+ gadash.clientId = settings.clientId;
+ gadash.tableId = settings.tableId;
+ gadash.authorizeButton = settings.authorizeButton || 'authorize-button';
+};
+
+
+/**
+ * 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(gadash.authorizeButton);
+ 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
+ * 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(gadash.authorizeButton);
+ 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
+ * @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:' + '<br />';
+ document.body.appendChild(errorDiv);
+ }
+
+ // Prints chart divContainer and message to error div.
+ errorDiv.innerHTML += this.config.divContainer + ' error: ' +
+ message + '<br />';
+ }
+};
+
+
+/**
+ * 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);
+ gadash.onSuccess();
+};
+
+/**
+ * Callback when a chart has been rendered
+ */
+gadash.onSuccess = function()
+{
+
+}
+
+/**
+ * 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];
+}
+
View
23 Resources/views/Analytics/dashboard.html.twig
@@ -0,0 +1,23 @@
+<script src="https://www.google.com/jsapi"></script>
+<script src="{{ asset('bundles/google/js/gdash-1.0.js') }}"></script>
+<script src="https://apis.google.com/js/client.js?onload=gadashInit"></script>
+
+<script>
+
+ var config = {
+ 'apiKey' : '{{ google_analytics.apiKey|e('js') }}',
+ 'clientId' : '{{ google_analytics.clientId|e('js') }}',
+ 'tableId' : '{{ google_analytics.tableId|e('js') }}'
+ };
+
+ {% if authorizeButton is defined %}
+ config.authorizeButton = '{{ authorizeButton }}';
+ {% endif %}
+
+ gadash.configKeys(config);
+
+ {% if initCallback is defined %}
+ gadash.initCallback = {{ initCallback }};
+ {% endif %}
+
+</script>
Please sign in to comment.
Something went wrong with that request. Please try again.