So, you finished that CodeIgniter Website last month. It was a tedious project and you’re glad it’s over! But wait! Now, your client informs you that you’re missing all the tracking code! The client also mentions he wants to use the popular, free Analytics tools from Google. This is gonna require inserting some javascript into all of your Web pages. Not a problem if you used a global footer in your views. A potentially huge pain otherwise. Either way, if you’re looking for a very simple way to globally implement Analytics code in your application, CodeIgniter hooks can make your life much easier. I’m going to show you how to take advantage of the ‘display_override’ hook point in CodeIgniter to get the job done fast!
To pull this off, you’ll need to slightly modify two configuration files (config.php and hooks.php) and then create another with a “hook” function (google_analytics.php.)
First, create a file named google_analytics.php and place it inside your application/hooks folder. We’ll reference this file later when we do our hooks configuration from within application/config/hooks.php.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( !function_exists('insert_ga_script') ) {
function insert_ga_script($account_id) {
/***NOTE: This hook replaces the _display
* method in the Output Class. I have
* not made provisions for caching nor compression!
*/
$CI =& get_instance();
$output = $CI->output->get_output();
//keep performance templates in...
$elapsed = $CI->benchmark->elapsed_time('total_execution_time_start', 'total_execution_time_end');
$output = str_replace('{elapsed_time}', $elapsed, $output);
$memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
$output = str_replace('{memory_usage}', $memory, $output);
// keep profiler working
if ($CI->output->enable_profiler == TRUE) {
$CI->load->library('profiler');
// If the output data contains closing </body> and </html> tags
// we will remove them and add them back after we insert the profile data
if (preg_match("|</body>.*?</html>|is", $output)){
$output = preg_replace("|</body>.*?</html>|is", '', $output);
$output .= $CI->profiler->run();
$output .= '</body></html>';
} else {
$output .= $CI->profiler->run();
}
}
// if no account information just return the output
if ( empty ($account_id) ) {
// keep _output methods working...
if (method_exists($CI, '_output')) {
$CI->_output($output);
} else {
echo $output; // Send it to the browser!
}
return ;
}
ob_start();
?>
<!--Begin Google Analytics Site Code-->
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("<?=$account_id?>");
pageTracker._initData();
pageTracker._trackPageview();
} catch(err) {}
</script>
<!--End Google Analytics Site Code-->
<?php
$script = ob_get_clean();
//insert the script
$output = str_replace('</html>', $script . "\n</html>", $output);
// keep _output methods working...
if (method_exists($CI, '_output')) {
$CI->_output($output);
} else {
echo $output; // Send it to the browser!
}
}
}
?>The function above slips Analytics javsacript code into the CodeIgniter output buffer. It finds the closing html tag in CodeIgniter’s output and replaces it with our script. It then puts the closing html tag back into the output string. Simple and effective; because your views generally output html, and this method will only insert Analytics code if a closing html tag is found (your rss feeds, etc. are safe.)
Now, how do we intercept CodeIgniter’s output before rendering it to the browser? This is where hooks come into play. CodeIgniter hooks provide a way to extend the framework without messing with the CodeIgniter core code (which has many advantages I won’t go into during this post.) CodeIgniter defines “hook points” to allow you to specify where you want to throw your “monkey wrench.” Our “gilded wrench” is going to be thrown into CodeIgniter’s display or output proccess.
To demonstrate, let’s edit our application/config/hooks.php file. We leave ‘class’ empty because we only need a function (in case you wondered.) We specify ‘googlea.php’ under ‘filename.’ We specify our ‘function’ (in our case ‘insert_track_js.’) Finally, we have one parameter to send to our function: the value of the google analytics account number (yours will vary of course.) We hook into the ‘display_override’ hook point to override CodeIgniter’s default output (display) process. When you are done, your application/config/hooks.php should look similar to:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------------
| Hooks
| -------------------------------------------------------------------------
| This file lets you define "hooks" to extend CI without hacking the core
| files. Please see the user guide for info:
|
| http://codeigniter.com/user_guide/general/hooks.html
|
*/
// google analytics insertion
$hook['display_override'] = array(
'class' => '',
'function' => 'insert_ga_script',
'filename' => 'google_analytics.php',
'filepath' => 'hooks',
'params' => 'UA-*******-**'
);
/* End of file hooks.php */
/* Location: ./system/application/config/hooks.php */Finally, we just need to enable hooks in application/config/config.php. Look for the ‘enable_hooks’ line:
$config['enable_hooks'] = TRUE;Set the value to TRUE as shown above. You’re done!
For more information on hooks, see the CodeIgniter Manual or this recent tutorial from Net Tuts.



Hi nice article …. i was looking for this ..let me try if it works for me thanks
Hi i am getting this error please help me i am using version 2
Fatal error: Cannot access protected property CI_Output::$enable_profiler in C:\xampp\htdocs*****application\hooks\google_analytics.php on line 21
thanks
It would seem that the enable_profiler property is now protected in the output class (FYI…protected just means that it’s private except for child classes.)
You might need to look for an alternate public property or method that indicates whether or not profiling is turned on. If I get some time in the next few days, I’ll take a look and update my code.
This was written over a year ago for pre-2.x code.
Thanks for your reply