Configure Concrete5 to show Google Analytics data in the dashboard

Warning! This tutorial is for deprecated Concrete5 versions 5.6 and below. Many of the examples and methods are no longer relevant to modern Concrete5.

If you are like me, you have taken the advantage of the new full page caching features of version 5.4.1 and disabled the concrete5 default statistics in an effort to minimize calls to the database and maximize Concrete5 performance. Typically, turning off the statistics is no big loss because I run Google Analytics on all of my websites. But, you do end up with a dismal graph showing 0 pageviews whenever you access the dashboard. This tutorial will show you how to import Google Analytics data into the default chart.

Step 1. Import the Google Analytics PHP Interface

I am going to use the established GAPI - Google Analytics API PHP Interface to connect with Google Analytics. Go over to their web page and download the latest version. Create the following directory structure in your C5 install /libraries/3rdparty and Upload thegapi.class.php file in the new directory.

Step 2. Override the chart_handler.php file

The default Concrete5 statistics chart uses a 3rd party library called Open Flash Chart to draw the statistics. The flash looks to a user provided file to define the chart data and formatting. Concrete5 is already setup to use the /concrete/tools/dashboard/chart_handler.php file to provide that data and formatting. We are going to override this core file with our own modified copy that interfaces with Google Analytics instead of the default Concrete5 statistics. Create the following directory structure /tools/dashboard and then create a newchart_handler.php file with the following contents:

defined('C5_EXECUTE') or die("Access Denied.");
define('ga_email',''); //email address for Google Analytics Account
define('ga_password','password'); //Password for Google Analytics Account
define('ga_report_id','5555555'); //Report ID for Website
define('report_period','10'); //Number of Days in the Report
define('x_axis_label_frequency','2'); //Number of Labels to skip 
define('cache_life','5'); //How long between queries to Google in minutes 
$ch = Page::getByPath("/dashboard");
$chp = new Permissions($ch);
if (!$chp->canRead()) {
	die(_("Access Denied."));
$cached_stats = Cache::get('dash_stats', 'current', time()-(cache_life * 60)); //check the cache for current stats
if (!$cached_stats) { //run the google report if a valid cache doesnt exist
	Loader::library('3rdparty/gapi.class' );
	Loader::library('3rdparty/open_flash_chart' );
	$ga = new gapi(ga_email,ga_password);
	$report_seconds = (report_period - 1) * 86400;
	$today = date("Y-m-d"); //todays date in YYYY-MM-DD format
	$start_date = date("Y-m-d", time()-$report_seconds); // YYYY-MM-DD Five days ago (345600 seconds)
	$ga->requestReportData(ga_report_id,array('date'),array('visits','pageviews'),'','',$start_date ,$today); //Fetch the Data
	$googlestats = array();
	foreach($ga->getResults() as $result) {
		$googlestats[$result->getDate()]['visits'] = $result->getVisits();
		$googlestats[$result->getDate()]['pageviews'] = $result->getPageviews();
	ksort($googlestats, SORT_NUMERIC);
	$daysRow = array();
	$visitsArray = array();
	$pageviewsArray = array();
	$max = 0;
	foreach ($googlestats as $key => $day_stats) {
		$daysRow[] = date("n/j",strtotime($key));
		$visitsArray[] = $day_stats['visits'];
		$pageviewsArray[] = $day_stats['pageviews'];
		if ($day_stats['pageviews'] > $max) {
		$max = $day_stats['pageviews'];
	$g = new graph();
	$g->set_title(' ', '{color: #ffffff}');
	$g->bg_colour = '#ffffff';
	$g->set_inner_background('#ffffff', "#cccccc", 90);
	// we add the 2 line types and key labels
	$g->line_dot( 3, 5, '#4C85BB', 'Visits', 10);
	$g->line( 1, '#B34F2E', 'Page Views', 10 );
	$g->set_x_labels( $daysRow );
	$g->set_x_label_style( 10, '#ababab', 0, x_axis_label_frequency );
	$g->x_axis_colour( '#333333', '#bebebe' );
	$g->y_axis_colour( '#333333', '#bebebe' );
	$g->set_y_max( $max );
	$g->num_decimals = 0;
	$g->is_fixed_num_decimals_forced = true;
	$g->y_label_steps( 5 );
	$rendered_stats = $g->render();
	$stats_expire = time() + (cache_life * 60); // builds unix timestamp for cache expiration
	Cache::set('dash_stats', 'current', $rendered_stats, $stats_expire);
	echo $g->render();
} else {
	echo $cached_stats;

Step 3. Enter the appropriate variables

Finally, you are going to need to provide the Google Analytics login credentials and report id for the website. If you plan to deploy this on a customers website you may want to create a throwaway google account and link it to the profile in Google Analytics instead of providing your own credentials. The report ID can be found in the google analytics URL when viewing the report. It is provided as the id= parameter. You will also find it as your Web Property ID in the following format UA-XXXXXXXX-1, with the X's representing the number to enter into the script.

Step 4. Customize

I hardcoded a simple "visits" and "pageviews" metric in the new chart_handler, but you can perform all kinds of queries using the API. Take a look at the metrics and dimensions page of the analytics API to get an idea of the other statistics you can display.

Too Lazy to Create Your Own?

You can download my GoogChart package if you would like the above features rolled into a ready to install block. Just unzip the file into your /packages directory and install.

This is all at your own risk though, as the block WAS NOT accepted into the Concrete5 Martketplace for various reasons, some having to due with the way your Google Email and Password are stored and transmitted. It also failed to copy the approrpriate files on certain webhosts.