3214 Posts in 848 Topics by 810 members
| Go to End | ||
| Author | Topic: | 2688 Views |
-
Re: Counting hits

30 October 2009 at 4:07am
You can't address the DataObject inside the Controller using $this. You should try something like the following:
class RadioStation_Controller extends RadioOverzichtNL_Controller {
public function init() {
parent::init();
$data = DataObject::get_one( 'RadioStation', "URLSegment='{$this->URLSegment}'" ); // select the data object for the current page
$data->RadioHits++;
$data->write();
}
} -
Re: Counting hits

30 October 2009 at 4:55am
Hi Martin thanks for your reply and help.
I've changed URLSegment to ID instead. My final code is below which works perfectly:
public function init()
{
parent::init();
$data = DataObject::get_by_id( 'RadioStation', $this->ID);
$data->RadioHits++;
$data->write();
}Thanks to all who helped me out on this one!
-
Re: Counting hits

30 October 2009 at 9:19am
That's certainly odd, as you can indeed address a DataObject from within a ContentController. However, since that's not working you should access it using $this->data() rather than re-getting the object, which creates an unnecessary query and object.
-
Re: Counting hits

30 October 2009 at 10:10am
$this->data()
It's never too late to learn! Thanks! I'll keep that in mind next time!
-
Re: Counting hits

11 January 2011 at 2:21am
I've recently been asked to do this for a client, so I just thought I'd explicitly post how it was achieved and why, perhaps, other ways are flawed.
Firstly, working code:
function init() {
parent::init();
$pageData = $this->data();
++$pageData->PageViews;
$pageData->write();
}Now, that seems to work and write the data to all relevant stages.
Going and looking up a DataObject by ID or URLSegment (as ajshort points out) results in an un-required amount of work (querying the DB, making an object). This is partly why I suggested the SQL query (DB::query("UPDATE `RadioStation_Live` SET RadioHits=RadioHits+1 WHERE ID=$this->ID");) in IRC. This is the least intensive way to do it, but it only tracks one type of page and also isn't using the framework to its full effect. Yes, it also only alters data on the _Live table which can lead to inconsistencies, but in my opinion we are only tracking views of the Live site but, not the best solution.
doPublish() is also a bad idea as it will publish draft changes without the admin's approval and will be very intensive.
So hopefully that will help some people out.
-
Re: Counting hits

18 March 2012 at 9:25am Last edited: 18 March 2012 9:29am
Hi guys.
Sorry to tell you this, but you're all wrong
Do not EVER try to write anything that is versionable inside your controller.
If you try to do $this->write() inside init() function, you operate only on current stage. So if you increment your page views on live version, only live version is being updated in the database, but your draft version counter is still 0.
This way every time you publish your page, PageViews field value is being rewritten from draft to live, so the counter resets to 0 every time you make changes to the page. And whatsmore - each time you call DataObject::write(), its LastEdited value changes and there's no point to update it every time user visits a page.I've just found a nice solution to do this. You should store your PageViews inside a separate DataObject, because DataObjects are not versionable:
class PageStat extends DataObject {
public static $db = array(
'PageID' => 'Int',
'Views' => 'Decimal(16,0)', // i am an optimist
);
}and the init() function:
public function init() {
parent::init();
$do = DataObject::get_one('PageStat','PageID = '.$this->ID);
if(!$do) {
$do = new PageStat();
$do->PageID = $this->ID;
$do->Views = 0;
$do->write();
}
$do->Views += 1;
$do->write();
} -
Re: Counting hits

18 March 2012 at 9:49am
Of course, for getting this to work like, for example, Most Popular Pages, you need to use JOIN clause:
public function MostPopularChildren() {
return DataObject::get('Page','ParentID = '.$this->ID,'Views DESC','INNER JOIN PageStat ON PageStat.PageID = SiteTree_Live.ID');
}And for example a list of the most popular articles throughout the whole site:
DataObject::get('Page',"ClassName LIKE 'ArticlePage'",'Views DESC','INNER JOIN PageStat ON PageStat.PageID = SiteTree_Live.ID');
| 2688 Views | ||
| Go to Top |




