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.

Customising the CMS /

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

Many to many relationship between two set of pages


Go to End


3 Posts   1729 Views

Avatar
Ben_W

Community Member, 80 Posts

13 March 2009 at 6:20pm

I have ServicePageHolder, ServicePages and LocationPageHolder, LocationPage, each location will have a number of service available to the public, and each service can belong to multiple locations. What I need is to create a interface in the cms where I can manage this many to many relationship. I.E. I would like to create a new tab in the location page where user may select number of services. In the front end where I display the location details, I may also list a number of services which has link to each service page.

Could someone point me to the right direction. I have read the tutorial 5 which gives a example of module - project. However the module extends the DataObject, not Page.

class ServicePage extends Page {
static $db = array(
'Headline' => 'Text'
);
static $has_one = array(
);

function getCMSFields() {
$fields = parent::getCMSFields();

$fields->addFieldToTab('Root.Content.Main', new TextField('Headline'), 'Content');

return $fields;
}
}

class ServicePage_Controller extends Page_Controller {

}

###########################################

class ServicePageHolder extends Page {
static $db = array(
);
static $has_one = array(
);

static $allowed_children = array('ServicePage');
}

class ServicePageHolder_Controller extends Page_Controller {
function FirstService($num=1) {
$service = DataObject::get_one("ServicePageHolder");
return ($news) ? DataObject::get("ServicePage", "ParentID = $service->ID", "Headline DESC", "", $num) : false;
}

}

###########################################

class LocationPage extends Page {
static $db = array(
'Headline' => 'Varchar',
'Phone' => 'Varchar',
'Facsimile' => 'Varchar',
'Email' => 'Varchar',
'Monday' => 'Varchar',
'Tuesday' => 'Varchar',
'Wednesday' => 'Varchar',
'Thursday' => 'Varchar',
'Friday' => 'Varchar',
'Saturday' => 'Varchar',
'Sunday' => 'Varchar',
'Street' => 'Varchar',
'Suburb' => 'Varchar',
'State' => 'Varchar',
'Postcode' => 'Varchar'

);
static $has_one = array(
'Photo' => 'Image'
);

function getCMSFields() {
$fields = parent::getCMSFields();

$fields->addFieldToTab('Root.Content.Main', new TextField('Headline'), 'Content');
$fields->addFieldToTab('Root.Content.Main', new TextField('Phone'), 'Content');
$fields->addFieldToTab('Root.Content.Main', new TextField('Facsimile'), 'Content');
$fields->addFieldToTab('Root.Content.Main', new TextField('Email'), 'Content');

$fields->addFieldToTab("Root.Content.Images", new ImageField('Photo'));

$fields->addFieldToTab('Root.Content.OpenHours', new TextField('Monday'));
$fields->addFieldToTab('Root.Content.OpenHours', new TextField('Tuesday'));
$fields->addFieldToTab('Root.Content.OpenHours', new TextField('Wednesday'));
$fields->addFieldToTab('Root.Content.OpenHours', new TextField('Thursday'));
$fields->addFieldToTab('Root.Content.OpenHours', new TextField('Friday'));
$fields->addFieldToTab('Root.Content.OpenHours', new TextField('Saturday'));
$fields->addFieldToTab('Root.Content.OpenHours', new TextField('Sunday'));

$fields->addFieldToTab('Root.Content.Location', new TextField('Street'));
$fields->addFieldToTab('Root.Content.Location', new TextField('Suburb'));
$fields->addFieldToTab('Root.Content.Location', new TextField('State'));
$fields->addFieldToTab('Root.Content.Location', new TextField('Postcode'));

return $fields;
}
}

class LocationPage_Controller extends Page_Controller {

}

###########################################

class LocationPageHolder extends Page {
static $db = array(
'Headline' => 'Varchar'
);
static $has_one = array(
);

static $allowed_children = array('LocationPage');

function getCMSFields() {
$fields = parent::getCMSFields();

$fields->addFieldToTab('Root.Content.Main', new TextField('Headline'), 'Content');

return $fields;
}
}

class LocationPageHolder_Controller extends Page_Controller {

}

Thanks.

Avatar
Benedikt

Community Member, 16 Posts

3 September 2009 at 3:57am

I encountered the same problem. I want to create news articles which will be categorized by countries. Every news article can have one or more countries to be associated with. On the other hand the country pages shall have their own HTML content which will be edited via the CMS.

Have you (or someone else) found a solution for the problem?

Avatar
Ben_W

Community Member, 80 Posts

3 September 2009 at 12:49pm

I manage to create this relationship as following. The key is that I need to add $belongs_many_many in ServicePage.php, then add $many_many in LocationPage.php as well as the tab field.

class ServicePage extends Page {
static $db = array(
'Headline' => 'Text'
);
static $has_one = array(
);

static $belongs_many_many = array(
'MyLocations' => 'LocationPage'
);

function getCMSFields() {
$fields = parent::getCMSFields();

$fields->addFieldToTab('Root.Content.Main', new TextField('Headline'), 'Content');

return $fields;
}
}

##############################################################
class LocationPage extends Page {
static $db = array(
#code omitted
);
static $has_one = array(
'Photo' => 'Image'
);

static $many_many = array(
'MyServices' => 'ServicePage'
);

function getCMSFields() {
$fields = parent::getCMSFields();

#code omitted

$myServicesTablefield = new ManyManyComplexTableField(
$this,
'MyServices',
'ServicePage',
array(
'Headline' => 'Headline'
),
'getCMSFields_forPopup'
);
$myServicesTablefield->setAddTitle( 'A Service' );

$fields->addFieldToTab( 'Root.Content.Services', $myServicesTablefield );

return $fields;
}
}

#######################################################

I have removed some code, but you should have all the code you need to solve this relationship problem. Good Luck.