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

Using Same DOM PageTypes Template for Multiple Pages


Go to End


2 Posts   2053 Views

Avatar
Hello_electro

Community Member, 80 Posts

9 October 2010 at 7:58am

Not sure if the title is overly confusing or makes no sense at all so let me explain.

I have to build donation pages that each have a set of 6 donation buttons. Each donation button has two options. "one time donation" and "recurring" donation. I then need to have this occur accross different supported projects. Each donation button is uniquely identified by its code because I have to be able to identify what people are donating to. Setting up the buttons is not a problem, i have all of the code ready for this.

I was trying to set up a DOM that allows me to create each object and in the popup include: donation value, donation category, 2 sets of donation code for the buttons and image to display on the front end

I accomplished this using DOM no problem. BUT, if I create a page in the CMS, using the donatePage type and title it Project 1, i can add each donation value and subsequent field.

When I go to create Project 2, using the same DOM pagetype, the items from the previous Project are there as well.

What I am trying to avoid is every time I have to create a new project I have to then set up a new DOM pagetype (i.e. pageType2.php)

I assume there is a much easier way to do this that I am just not familiar with. If anyone can make a suggestion I would greatly appreciate it.

For ease, I am pasting the code I was working off of from ssbits.com http://www.ssbits.com/tutorials/2010/dataobjects-as-pages-part-1-keeping-it-simple/

See below and thanks for your help!!

StaffMember.php

<?php
class StaffMember extends DataObject
{
    //db fields
    static $db = array (
        'Name' => 'Varchar(255)',
        'Role' => 'Varchar(100)',
        'Description' => 'Text'
    );
     
    //Relations
    static $has_one = array (
        'StaffPage' => 'StaffPage',
        'Photo' => 'Image'
    );
     
    //Fields to show in the DOM table
    static $summary_fields = array(
        'Thumb' => 'Photo', 
        'Name' => 'Name',
        'Role' => 'Role'
    );
     
    //Fields for the DOM Popup
    public function getCMSFields()
    {
        return new FieldSet(
            new TextField('Name'),
            new TextField('Role'),
            new TextareaField('Description', 'Description'),
            new ImageField('Photo', 'Photo', Null, Null, Null, 'Uploads/staff-photos/')
        );
    }
 
    //Generate our thumbnail for the DOM
    public function getThumb()
    {
        if($this->PhotoID)
            return $this->Photo()->CMSThumbnail();
        else   
            return '(No Image)';
    }
}

StaffPage.php


<?php
 
class StaffPage extends Page {
     
    static $has_many = array(
        'StaffMembers' => 'StaffMember'
    );
     
    public function getCMSFields()
    {
        $fields = parent::getCMSFields();
         
        $manager = new DataObjectManager(
            $this,
            'StaffMembers',
            'StaffMember'
        ); 
        $fields->addFieldToTab("Root.Content.StaffMembers", $manager);
         
        return $fields;
    }
 
}
 
class StaffPage_Controller extends Page_Controller {
     
 
}

Avatar
s!m

Community Member, 9 Posts

12 October 2010 at 6:15am

Edited: 12/10/2010 6:22am

Hi Hello_electro,

I once had a similar problem, as I wanted to have unique datasets for each page for the DataObjectManager to display. If you just want to display the datasets without the possibility to enable/disable them, then you can just use a filter on the DOM to just display the items linked to the specific page, the code would be something like this:

...
$filter = $this->class . 'ID = ' . $this->ID;

$Manager= new HasManyDataObjectManager(
   $this, // Controller
   'Items', // Source name
   'Item', // Source class
   array(), // Headings
   'getCMSFields_forPopup', // Detail fields function or FieldSet
   $filter // Filter clause
   // Sort clause
   // Join clause
);
...//add to CMS-Fields, etc.

Note, that once you disable an item in a DOM with that filter, it gets "lost" (it's still there, but it's not possible to re-enable this item).

If you still want to be able to enable/disable items, I found no elegant solution. I still got something for you that works, it's just a bit more code:
This one goes into the class with the DOM:

...
$filter = 'Ref_ID_orig = ' . $this->ID;

$Manager= new HasManyDataObjectManager(
   $this, // Controller
   'Items', // Source name
   'Item', // Source class
   array(), // Headings
   'getCMSFields_forPopup', // Detail fields function or FieldSet
   $filter // Filter clause
   // Sort clause
   // Join clause
);
...//add to CMS-Fields, etc.

Note that there's just a slight difference in the filter.
Thats all for your DOM-displaying class, now go to your Item-Class and add/change:
public static $db = array(
   ...
   'Ref_ID_orig' => 'Int',
);
...
function onAfterWrite()
{
   if (isset($_REQUEST['ctf']) && !isset($_REQUEST['ctf']['childID']))
   {
      // new record!
      $ID = (int) $this->record['ctf[sourceID]'];
      DB::query("UPDATE `Item` SET Ref_ID_orig = " . $ID . " WHERE ID = " . $this->ID);
   }
   parent::onAfterWrite();
}
...

You still have to adjust the table to match your database-scheme.
The reason why I use a pure DB-query rather than updating through changing the objectproperty and then calling write() is, that a call to write() also calls onAfterWrite() and therefore leads to an infinite loop.

I think thats all, if I missed something, or something is not clear enough, feel free to ask... :-)

Best regards,
s!m