by Kevin Schroeder | 12:00 am

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).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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.

1
2
3
4
5
6
google.username = "[email protected]"
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.

Comments

mturillo

The profileId is not the ID in the query string but this one:
For example:
https://www.google.com/analytics/web/#report/visitors-overview/a38121w432122p123456/
The profile id is 123456. After the letter “p”.
Best Regards

Jan 29.2013 | 12:59 am

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.