Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

DataObjectManager Module /

Discuss the DataObjectManager module, and the related ImageGallery module.

Moderators: martimiz, UncleCheese, Sean, Ed, biapar, Willr, Ingo, swaiba

Sort By Category


Go to End


22 Posts   7823 Views

Avatar
UncleCheese

Forum Moderator, 4102 Posts

12 June 2009 at 8:46am

Oh, duh.. it's in your controller, not your model.. that's why $this->class didn't work!

If by re-ordering you're talking about the drag-and-drop, that has to be done with a global view of your records, without pagination. I haven't figured out any other way to do it. Think about it -- you need to send a serialized list of the objects to the controller. If some are missing, how can you get an accurate sort? If you replace the 3rd one in the list, for instance, what about the 3rd one on the list when the records are not filtered?

If resources could only be viewed in a category, it would make sense, but since there is a global view of resources, unfortunately, sorting has to take place on that global view.

Although.. I'm open to ideas.

Avatar
Matty Balaam

Community Member, 74 Posts

26 June 2010 at 3:41am

Edited: 26/06/2010 3:51am

The code above works great, but I would like to amend it to generate a heading for each year (e.g. "2010"), with most recent documents listed at the top.

'Publication' is the class, and 'Date' is a 'Datetime' value.

	public function PublicationYears()
	{
	$pubyears = new DataObjectSet();
	foreach(singleton('Publication')->dbObject('Date')->date('Y') as $date) {
	$pubyears->push(new ArrayData(array(
	'Title' => $date,
	'Publications' => $this->Publications("Date = '$date'")
	)));
	}
	return $pubyears; 

Unfortunately I get the error: Invalid argument supplied for foreach()

I'm assuming I need to do something more complex than date'Y', but as a bit of a coding novice I am unsure what I need to do. Any help very much appreciated.

Here is the page in case anyone is interested: http://www.madelinebalaam.co.uk/publications/

Avatar
UncleCheese

Forum Moderator, 4102 Posts

26 June 2010 at 4:34am

1) Never enter a loop without first testing if you have something to loop through!

2), dbObject() is not going to return what you're looking for. It's not even going to connect to the database. You need to run a query.

$result = DB::query("SELECT DISTINCT YEAR(Date) as Year FROM `Publication`");
$years = array();
if($result) }
while($r = $result->nextRecord()) $years[] = $r['Year'];
}

echo "unique years"; var_dump($years);

Avatar
Matty Balaam

Community Member, 74 Posts

26 June 2010 at 5:18am

Thanks for the quick reply. A lot of that has gone *whoosh* over my head, but from what I understand, the code you've posted is to find out which years are in the database, and then I need to amend the other code after that to query the database based on the results?

Avatar
Matty Balaam

Community Member, 74 Posts

1 July 2010 at 4:58am

Many thanks again for your help. It's taken me a few days of trial and error and as far as my limited understanding goes, I think I'm almost there, but not quite.

At the moment I have this line:

'Publications' => $this->Publications("Date='$date'")

If I take out the content from the brackets, it shows every result under each year heading, so I think everything else works. I assume therefore that I need a way of just pulling the year from the database entry 'Date' and matching that to $date.

Here is my full Controller code, if I'm doing anything wrong, or over-complicated it would be good to get any pointers also, thanks.

	public function PublicationYears()
	{
		
	$result = DB::query("SELECT DISTINCT YEAR(Date) as Year FROM `Publication`"); 
	$years = array(); 
	if($result) {
	while($r = $result->nextRecord()) $years[] = $r['Year']; 
	}
	
	$pubyears = new DataObjectSet();
	foreach ($years as $date) {
	$pubyears->push(new ArrayData(array(
	'Title' => $date,
	'Publications' => $this->Publications("Date='$date'")
	)));
	}
	return $pubyears;

}

Avatar
UncleCheese

Forum Moderator, 4102 Posts

1 July 2010 at 5:18am

Don't forget, $date only represents a year, not a date. Probably a misnomer in your foreach loop to call it "$date" when a typical value is something like "2009".

'Publications' => $this->Publications("YEAR(Date)='$date'")

Avatar
Matty Balaam

Community Member, 74 Posts

1 July 2010 at 5:26am

Edited: 01/07/2010 5:29am

Thank so much, works perfectly! I hear you about naming things clearly, will change that right away too.

Edit: I now spot I should have realised I could have worked out it would be YEAR(Date) from the DB::query code you provided before. Silly me.

Avatar
UncleCheese

Forum Moderator, 4102 Posts

1 July 2010 at 5:36am

This is actually a really ugly way to do this, because you're running a query at every iteration of the loop. Change:

   $pubyears = new DataObjectSet(); 
   foreach ($years as $date) { 
   $pubyears->push(new ArrayData(array( 
   'Title' => $date, 
   'Publications' => $this->Publications("Date='$date'") 
   ))); 
   } 
   return $pubyears;

to

return $this->Publications("YEAR(Date) IN (".implode(",",$years).")");