Jump to:

7938 Posts in 1541 Topics by 945 members

DataObjectManager Module

SilverStripe Forums » DataObjectManager Module » Sort By Category

Discuss the DataObjectManager module, and the related ImageGallery module.

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

Page: 1 2 3
Go to End
Author Topic: 4052 Views
  • UncleCheese
    Avatar
    4085 Posts

    Re: Sort By Category Link to this post

    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.

  • Matty Balaam
    Avatar
    Community Member
    69 Posts

    Re: Sort By Category Link to this post

    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/

  • UncleCheese
    Avatar
    4085 Posts

    Re: Sort By Category Link to this post

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

  • Matty Balaam
    Avatar
    Community Member
    69 Posts

    Re: Sort By Category Link to this post

    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?

  • Matty Balaam
    Avatar
    Community Member
    69 Posts

    Re: Sort By Category Link to this post

    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;

    }

  • UncleCheese
    Avatar
    4085 Posts

    Re: Sort By Category Link to this post

    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'")

  • Matty Balaam
    Avatar
    Community Member
    69 Posts

    Re: Sort By Category Link to this post

    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.

  • UncleCheese
    Avatar
    4085 Posts

    Re: Sort By Category Link to this post

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

    4052 Views
Page: 1 2 3
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.