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.

Template Questions /

Data model question - access one of has_many properties in class


Reply


2 Posts   1522 Views

Avatar
KINKCreative

Community Member, 56 Posts

2 January 2010 at 4:06pm

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!! :)

Avatar
zenmonkey

Community Member, 528 Posts

3 January 2010 at 8:08am

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