Kevin Schroeder, Technology Evangelist for Zend Technologies, is well versed in a wide variety of technologies pertinent to both small and large scale application deployments. He has developed production software using a wide variety of languages including PHP, Java (standalone and web-based applications), Javascript, HTML, SQL, Perl, Visual Basic, ASP and occasionally C. His software development experience is accompanied with extensive experience as a system administrator on platforms including Linux, Solaris and Windows on scales of a single server up to several hundred servers on installations that range from a few to millions of users. He has spoken at several conferences and has written two books; co-author of “The IBM i Programmer’s Guide to PHP” and author of the upcoming “You want to do WHAT with PHP?” and in his spare time races Ferraris. His Honda has a dismal win record. Kevin has posted 1 posts at DZone. View Full User Profile

Google Analytics feed handling in Zend Framework

07.09.2010
| 8750 views |
  • submit to reddit

(This article was originally published on eschrade.com)

So there I was, looking at some other websites out there (because I think my site design sucks.  Thanks, me).  One of the things that virtually no blogs do is promote specific content.  In other words, highlight content that is most popular over a certain time frame.  So I was thinking to myself, how would I do that?  One option would be to have a database table that could record each click.  That, however, is boring and requires changes to my DB schema (evil!).  What I want to do is take my most popular pages of the last week and highlight them at the top of the web site. 

Then I realized that I'm already doing it, with Google Analytics.

But how would I do it?  Turns out there's already a proposal in the Zend Framework wiki for a Google Analytics GData service.  It's not in the main line but it's in good working order and you can git it from GetHub (bad joke intentional).  So I downloaded it from there and placed it in my Blog /library directory, breaking the coding standard that states that only things in the Zend Framework may have the Zend_ pseudo namespace.  Oh well, it works.

The way I have implemented this is to set it up as a precache.  What that means is that I use the Zend Server Job Queue to run it at period intervals, like once a day, and then take the results and cache them in a non-expiring cache.

This code makes use of the Task class that I had built out earlier on (go down to the "Doing it Cool-ly" section).

class Admin_Task_GoogleAnalyticsPopular extends Esc_Queue_TaskAbstract
{
protected $_count;

protected function _execute(Zend_Application $app)
{
$this->_count = 0;
$options = $app->getOption('google');
$client = Zend_Gdata_ClientLogin::getHttpClient(
$options['username'],
$options['password'],
Zend_Gdata_Analytics::AUTH_SERVICE_NAME
);

$service = new Zend_Gdata_Analytics($client);

$query = $service->newDataQuery()
->setProfileId($options['analytics']['profileId'])
->addDimension(Zend_Gdata_Analytics_DataQuery::DIMENSION_PAGE_PATH)
->addMetric(Zend_Gdata_Analytics_DataQuery::METRIC_VISITS)
->setStartDate(date('Y-m-d', strtotime($options['analytics']['start'])))
->setEndDate(date('Y-m-d', strtotime($options['analytics']['end'])))
->setSort(Zend_Gdata_Analytics_DataQuery::METRIC_VISITS, true)
->setMaxResults($options['analytics']['count']);

$result = $service->getDataFeed($query);
$pages = array();
$manager = $app->getBootstrap()->getResource('cachemanager');

$pages = $manager->getCache('preview')->load('previewCacheArray');

if (is_array($pages)) {
foreach (array_keys($pages) as $key) {
if (strpos($key, 'analytics') == 0) {
unset($pages[$key]);
}
}
} else {
$pages = array();
}
$contentTbl = new Model_DbTable_Content();
foreach($result as $row){
$this->_count++;
$page = (string)$row->title;
$pre = Zend_Gdata_Analytics_DataQuery::DIMENSION_PAGE_PATH.'=/page/';
$id = substr($page, strlen($pre));
$content = $contentTbl->getContentByPage($id);
/* @var $content Model_Content */
if (!$content) continue;
$pages['analytics'.$this->_count] = array(
'title' => 'Popular: ' . $content->getTitle(),
'content' => $content->getContentSnip()
);

}

$manager->getCache('preview')->save($pages, 'previewCacheArray');

}
}

 

You might notice a few things.  First is that I have several options that I retrieve from my Zend_Application class.  Here is a copy of those options.

google.username = "xxxxx@gmail.com"
google.password = "password"
google.analytics.profileId = xxxxxxxx
google.analytics.count = 2
google.analytics.start = "-1 week"
google.analytics.end = "now"

 

The count is the number of items to retrieve.  Start and end are set for strtotime().  However, the interesting one that I have x'ed out (because I don't know if it's a security risk) is profileId.  That is the individual website profile identifier that uniquely identifies an individual site for you.  This is different from the tracker number, such as UA-13220492-1.  To find out what the profile ID number is log in to Analytics, go to your website and hover over "View Report".  In the URL you will see a query string value for the key "id".  That is your profile number.

So what does this code do?  First of all it logs in to Google using the credentials you supplied.  After that we create a new service class and create a query.  In the query I need to set at least the profile ID.  But what I can also do is state the type of results I want, the metrics, start and end time and a few other things.  After I've done that I retrieve the data feed.

The code after that is simply code that I use to match up the URL that Google reports back to me with pages I have in the database.  I remove all of the data from the array that was built by Analytics (the foreach followed by strpos) I iterate over the Google results and add the content I want to highlight into the array.  Sweet.  Done.

Please note that the code for this may change as it is not part of Zend Framework (yet).  Or it might be declined.  Who knows?  Not me.  But until then, this seems to work pretty well for when you want to make content available based off of Google Analytics data.

Published at DZone with permission of its author, Kevin Schroeder.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)