This is a self contained module that enables you to track and display 'view counter' on content types in your Yii based website
- Attach-able to any content type on your site.
- Self contained widget provides all you need to integrate a 'views count widget' in existing pages.
- Widget can be called in 'view-only' mode, which means it won't advance the counter but just display it. This is good for showing 'views count' in a tabular presentation of data. For example, when you want to show a table view (=CGridView) of posts, along with data of views count in each row (=on each post).
- Works in AJAX after the page has been loaded. This has two great benefits:
- It minimizes the performance impact on the site.
- It skip false counts for search engine which, to the best of my knowledge, don't issue AJAX requests and thus no count will be accounted on visits from search engines/other-crawlers.
- Count views for both guest and authenticated users.
- Tracks users based on user_id (if logged in), cookie and IP address (supports tracking on both IPv4 and IPv6).
- Counts both unique and non-unique impressions. Each instantiation of the included widget can be asked to run in unique or non-unique mode and they can be combined on the same page.
- Requires a 'users' table with primary key column named "id" (it uses this to record impressions made by logged in users).
- Uses and therefore requires PcBaseArModel extension (it uses it for "safe" updates of records, using optimistic locking).
- Requires 'cache' application component. Be sure to either have it working or rewrite ViewsCountWidget._setPersistentCounterConfig() and ViewsCountWidget._getPersistentCounterConfig(). See those methods for more information.
- The provided widget records the IP address of the user. You'll need to provide it with the IP address. See recommended package below, in the 'Usage/Installation' section.
- Unpack this extension under /protected/modules
- In Yii's main.php config file:
'import' => array( //... // Views counter module 'application.modules.PcViewsCounter.*', 'application.modules.PcViewsCounter.models.*', 'application.modules.PcViewsCounter.controllers.*', 'application.modules.PcViewsCounter.components.*', 'application.modules.PcViewsCounter.extensions.ViewsCountWidget.*', //... ), //... 'modules' => array( //... 'contentViewsCounter' => array( 'class' => 'application.modules.PcViewsCounter.PcViewsCounterModule', ), //... ),
- Setup a new encryption key in ViewsCountWidget::COOKIE_ENCRYPT_KEY (or your user's viewing history could be hijacked by a third party). This key is used to encrypt the views counter cookie value.
- Install the schema file located in /data directory in this package tree. You might need to alter it a bit. The schema file is for MySQL v5.1.
- Since the widget will try to store the IP address of the user, it needs to be able to tell it somehow. I recommend using another extension that I've written: PcMaxmindGeoIP that has a powerful method for retriving the remote IP address. In fact, the code already includes a usage of this extension so you need to either download and install it, or update the line of code. This is line 51 (as of writing these documentation lines):
$this->_clientIpAddress = Yii::app()->geoip->getRemoteIpAddress();
Configurable parameters passed to the widget instance: ¶
- modelClassName: string. the model class name this widget instance refers to
- modelId: integer. the model object id this widget instance refers to
- uniqueMode: boolean. Whether this widget instance should run, count and display unique or non-unique views. Defaults to true, meaning works in unique mode.
- dontCount: boolean. Whether this widget should run in 'read only' mode, meaning no impression count would be performed - just showing existing views count is done.
In the view file ¶
$this->widget("ViewsCountWidget", array('modelId' => $model->id, 'modelClassName' => get_class($model)));
API Methods ¶
- int PcViewsCounterModule::getViewsCount($model_name, $model_id, $unique = true) : Static method that is used to retrieve the views counter of a certain model, programmatically on server side. This is useful if other components of your application needs to make decisions based on the views count. Note that unique/non-unique count is easily distinguished by the $unique boolean parameter.
Design Notes ¶
- Some information is saved in a cookie. Due to cookies limitations on client side (i.e. browsers), we save this info in a single cookie. This cookie data structure is as follows: (serialized and encrypted) array('modelname-modelId' => UTC_timestamp_when_viewed)
- More? That's my kind of attitude! Use the force - read the source! The code is full with useful (hopefully) documentation notes.
- The following is the algorithm for impression request handling (the AJAX request). Notice that the check for an impression cookie is performed for BOTH guest and authenticated users:
if impression-cookie exists (this is for guest) do nothing. else if authenticated search PageViewBookeeping record for this user (based on user_id, PageViewsStat->id (which is an FK in the former class/table)) if not found search for PageViewBookeeping record based on ip address. if found in either of the 2 checks above add this information into the impression cookie. return else add impression record for this user. add this information into the impression cookie. else (this is guest user) add cookie for this guest user unique impression search for PageViewBookeeping record based on ip address. if NOT found add impression record for guest (record his ip address) else return existing counter add +1 to unique stats counter for this model name + id.
- The following is a drawing of the schema used in this extension:
Change Log ¶
- 26 March 2014 v1.3: Added getViewsCount(), a static method in the module class for getting stats on server side, no rendering etc. This can be utilized by other components that can read the stats and act accordingly (for example, render stuff differently if above certain views count). Also, a few modifications for PHP v5.4
- 10 Jan 2013 v1.2 : Bugfix. Now supports rendering multiple instances of widget on the same page.
- 6 July 2012 v1.1 : Attached missing schema file.