Jump to:

3447 Posts in 1031 Topics by 872 members

Template Questions

SilverStripe Forums » Template Questions » Data model question - access one of has_many properties in class

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

Page: 1
Go to End
Author Topic: 1513 Views
  • KINKCreative
    Avatar
    Community Member
    56 Posts

    Data model question - access one of has_many properties in class Link to this post

    Hey, I'm pretty new with SS, so I'm still trying to figure out the data model and how best to put it work. So far I've worked with pages which I understand as objects quite okay, but the moment I need to work with DataObject classes, I get a bit stuck.

    Here's what I'd like to do:

    I have a ProjectPage that uses DataObjectManager for two has_many properties: Reviews (Review class)and Media (for images etc).

    The ProjectPage:

    class ProjectPage extends Page
    {
       static $db = array(
          'Category' => "Enum('Broadway, Off-Broadway, Regional, International')"
       );
       static $has_one = array(
       );
       static $has_many = array (
          'Resources' => 'Resource',
          'Reviews' => 'Review'
       );
       
       static $defaults = array(
          'ShowInMenus' => 0,
          'ShowInSearch' => 0
       );
       
       public function getCMSFields()
       {
          $f = parent::getCMSFields();
          $photoManager = new ImageDataObjectManager(
             $this, // Controller
             'Resources', // Source name
             'Resource', // Source class
             'File', // File name on DataObject
             array(
                'Name' => 'Name',
                'Description' => 'Description',
             ), // Headings
             'getCMSFields_forPopup' // Detail fields (function name or FieldSet object)
             // Filter clause
             // Sort clause
             // Join clause
          );

          $reviewManager = new DataObjectManager(
             $this, // Controller
             'Reviews', // Source name
             'Review', // Source class
             array(
                'Date' => 'Date',
                'Author' => 'Author',
                'Link' => 'Link',
                'Quote' => 'Quote',
                'Image' => 'Image'
             ), // Headings
             'getCMSFields_forPopup' // Detail fields (function name or FieldSet object)
             // Filter clause
             // Sort clause
             // Join clause
          );

          $f->addFieldToTab("Root.Content.Reviews",$reviewManager);      
          $f->addFieldToTab("Root.Content.Media",$photoManager);      
          $f->addFieldToTab("Root.Content.Main",
             new DropdownField('Category','Pick a category',singleton('ProjectPage')->dbObject('Category')->enumValues())
          );
          
          $f->renameField("Content", "Project Description");
          $f->renameField("Title", "Project Name");
          $f->removeFieldFromTab('Root', 'Behaviour');
          return $f;
       }   
    }   

    ...and here is the Review class:

    class Review extends DataObject
    {
       static $db = array (
          'Date' => 'Date',
          'Author' => 'Text',
          'Link' => 'Text',
          'Quote' => 'HTMLText'
       );
       
       static $has_one = array (
          'Image' => 'File',
          'ProjectPage' => 'ProjectPage'
       );
          
       public function getCMSFields_forPopup()
       {
          return new FieldSet(
             new CalendarDateField('Date'),
             new TextField('Author'),
             new TextField('Link'),
             new TextareaField('Quote'),
             new FileIFrameField('Image')
          );
       }
    }

    Questions:

    1. I would like to create a ReviewPage that will, upon clicking just display the content of a Review (I guess based on some kind of ID?). I don't know how to access a particular Review instance from the DB, especially if I'm not on a ProjectPage.

    2. On the ProjectPage, I need to cycle through the Reviews and also Resources that apply to the particular ProjectPage and display them. Can I just use Control for that? How would I do that?

    3. This is the biggie. I will need a ReviewHolder that will display a list of all Reviews that I've added to ProjectPages, but this time grouped by the ProjectPage Category. I'm totally in the dark here for that

    4. Just generally. There is a particular methodology that I'm not getting quite yet - e.g. creating a custom data class that's not part of the SiteTree, and then a particular Page type that will somehow display the info (I'm guessing through the controller?) If you have any tips on the whole approach or if there's a good book / tutorial that builds a similar site like this, please let me know.

    Thanks a lot for any help - and a happy new year!!

  • zenmonkey
    Avatar
    Community Member
    528 Posts

    Re: Data model question - access one of has_many properties in class Link to this post

    Well for your first question look at this post

    http://silverstripe.org/data-model-questions/show/257660

    For question 2 using a <% control Reviews %> and <% control Resources %> will give you access to those data object

    3rd question: You'll need to create your ReviewHolder page and add function to get all the Project Pages

    Something like:

    function Projects() {
    return DataObject::get("ProjectPage");
    }

    Then in the ReviewHolder template you just need to do

    <% control Projects %>
    $Title
    <% control Reviews %>
    ...
    <% end_control %>
    <% end_control %>

    I'd suggest picking up the SilverStripe book, I've found it really helpful in learning SS especially for a PHP newbie

    1513 Views
Page: 1
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.