7913 Posts in 1355 Topics by 930 members
DataObjectManager Module
SilverStripe Forums » DataObjectManager Module » ManyManyDataObjectManager to manage two subclasses of DataObject
Discuss the DataObjectManager module, and the related ImageGallery module.
Moderators: martimiz, UncleCheese, Howard, Sean, Ryan M., biapar, Willr, Ingo, swaiba, simon_w
| Go to End | Next > | |
| Author | Topic: | 1295 Views |
-
ManyManyDataObjectManager to manage two subclasses of DataObject

22 December 2010 at 1:26pm
I'm new to SilverStripe (and OO PHP) and am hoping someone can pick out what's wrong with or what I need to do to the code I currently have.
Requirements:
A parts list.
A bundles list.
Recording which bundles contain which parts.I've got so far as successfully creating the CMS fields for the two lists, but am stuck on controlling which parts are in which bundles.
After a /dev/build, I get this in the admin:
[User Warning] I could not find the relation PartsBundles in PartsHolder or any of its ancestors.
GET /admin
Line 54 in /data/htdocs/ac/dataobject_manager/code/ManyManyDataObjectManager.phpI think I may need to change '$this' in the '$manager_parts_bundles' DOM subclass in PartsHolder.php to something else to let SilverStripe know that it needs to look into one of the other two files to establish the relationship, but I'm not sure how to go about this.
Here are my files:
PartsHolder.php
class PartsHolder extends Page {
static $has_many = array(
'Parts' => 'Part',
'Bundles' => 'PartsBundle'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$manager_parts = new DataObjectManager(
$this,
'Parts',
'Part'
);
$fields->addFieldToTab('Root.Content.Parts', $manager_parts);
$manager_bundles = new DataObjectManager(
$this,
'Bundles',
'PartsBundle'
);
$fields->addFieldToTab('Root.Content.Bundles', $manager_bundles);
$manager_parts_bundles = new ManyManyDataObjectManager(
$this,
'PartsBundles',
'PartsBundle'
);
$fields->addFieldToTab('Root.Content.Bundles', $manager_parts_bundles);
return $fields;
}
}class PartsHolder_Controller extends Page_Controller {
}Part.php
class Part extends DataObject {
static $db = array(
'PartNumber' => 'Varchar',
'Description' => 'Text',
'PurchasePrice' => 'Varchar',
'SupplierPartNumber' => 'Varchar',
'SupplierDescription' => 'Text',
'SupplierTerms' => 'Text',
'SalesPrice' => 'Varchar'
);
static $has_one = array(
'PartsHolder' => 'PartsHolder',
'Image' => 'Image'
);
static $belongs_many_many = array(
'Bundles' => 'PartsBundle'
);
static $summary_fields = array(
'PartNumber' => 'PartNumber',
'Description' => 'Description',
'PurchasePrice' => 'PurchasePrice',
'SalesPrice' => 'SalesPrice'
);
function getCMSFields() {
return new FieldSet(
new TextField('PartNumber'),
new TextAreaField('Description'),
new NumericField('PurchasePrice'),
new TextField('SupplierPartNumber'),
new TextAreaField('SupplierDescription'),
new TextAreaField('SupplierTerms'),
new NumericField('SalesPrice'),
new ImageField('Image')
);
}}
PartsBundle.php
class PartsBundle extends DataObject {
static $db = array(
'Description' => 'Text',
'SalesPrice' => 'Varchar'
);
static $has_one = array(
'PartsHolder' => 'PartsHolder'
);
static $many_many = array(
'Parts' => 'Part'
);
static $summary_fields = array(
'Description' => 'Description',
'SalesPrice' => 'SalesPrice'
);
function getCMSFields() {
return new FieldSet(
new TextAreaField('Description'),
new NumericField('SalesPrice')
);
}
}Many thanks!
-
Re: ManyManyDataObjectManager to manage two subclasses of DataObject

1 January 2011 at 12:45am
Friendly bump as I still haven't sorted this.
Let me know if I need to clarify anything. Thanks. -
Re: ManyManyDataObjectManager to manage two subclasses of DataObject

9 January 2011 at 2:06am
Any pointers on this still appreciated.
-
Re: ManyManyDataObjectManager to manage two subclasses of DataObject

9 February 2011 at 8:19am
I am having a similar problem using ModelAdmin to show editable relations between Organisations and Persons.
Organisation.php
class Organisation extends DataObject {
static $db = array(
"Name" => "Varchar",
"Type" => "Enum('Registered Business, Freelancer, Sole Trader, Charity, Public Sector')",
"RegNum" => "Varchar(100)",
"Website" => "Varchar",
"Phone" => "Varchar",
'Email' => 'Varchar',
'Address' => 'Varchar',
'Postcode' => 'Varchar(10)'
);
static $has_one = array(
);
static $belongs_many_many = array(
"Persons" => "Person"
);
static $summary_fields = array(
'Name' => 'Name',
'Phone' => 'Phone',
'Email' => 'Email'
);
static $searchable_fields = array (
'Name',
'Type'
);
function getCMSFields() {
$fields = new Fieldset();
$fields->push(new TextField('Name', 'Name'));
$fields->push(new DropdownField("Type", "Type of Organisation", $this->dbObject('Type')->enumValues()));
$fields->push(new TextField('RegNum', 'Company/Charity Number'));
$fields->push(new TextField('Email', 'Email'));
$fields->push(new TextField('Phone', 'Phone'));
$fields->push(new TextField('Website', 'Website'));
$fields->push(new TextareaField('Address', 'Address'));
$fields->push(new TextField('Postcode', 'Postcode'));
return $fields;
}Person.php
class Person extends DataObject {
static $db = array(
"Title" => "Enum('Mr, Mrs, Ms, Dr')",
"FirstName" => "Varchar",
"Surname" => "Varchar",
"FullName" => "Varchar",
'Email' => 'Varchar',
'Phone' => 'Varchar',
'Mobile' => 'Varchar',
'Address' => 'Varchar',
'Postcode' => 'Varchar(10)'
);
static $has_one = array(
"User" => "Member"
);
static $many_many = array(
"Organisations" => "Organisation"
);
static $defaults = array(
);
static $summary_fields = array(
'FullName' => 'Full Name',
'Member' => 'Member',
'Phone' => 'Phone',
'Email' => 'Email'
);
static $searchable_fields = array (
'FullName',
'Surname',
'FirstName'
);
function getCMSFields() {
$userManager = new HasOneDataObjectManager($this, 'User', 'Member');
$userManager->setPermissions(
array(
"show",
"edit"
));
$organisation = new ManyManyDataObjectManager($this, 'Organisation', 'Organisation');
$fields = parent::getCMSFields();
$fields->addFieldToTab("Root.Main", new ReadonlyField('FullName', 'Full Name'));$fields->addFieldToTab("Root.Main", new DropdownField("Title", "Title", $this->dbObject('Title')->enumValues()));
$fields->addFieldToTab("Root.Main", new TextField('FirstName', 'First Name'));
$fields->addFieldToTab("Root.Main", new TextField('Surname', 'Surname'));$fields->addFieldToTab("Root.Main", new TextField('Email', 'Email'));
$fields->addFieldToTab("Root.Main", new TextField('Phone', 'Phone'));
$fields->addFieldToTab("Root.Main", new TextField('Mobile', 'Mobile'));$fields->addFieldToTab("Root.Main", new TextareaField('Address', 'Address'));
$fields->addFieldToTab("Root.Main", new TextField('Postcode', 'Postcode'));$fields->addFieldToTab("Root.UserAccount", $userManager);
$fields->addFieldToTab("Root.Organisations", $organisation);
return $fields;
}Looking into, have you found anything else?
-
Re: ManyManyDataObjectManager to manage two subclasses of DataObject

10 February 2011 at 6:37am Last edited: 10 February 2011 6:38am
Hi,
didnt see the flaw per ce, but heres an alternative way to do this,
for the PartsBundle change the getCMSFields to inlcude the ManyManyDataObjectManager for the parts
eg
function getCMSFields() {
return new FieldSet(
new TextAreaField('Description'),
new NumericField('SalesPrice'),
new ManyManyDataObjectManager(
$this,
'Parts',
'Part'
)
);
}and for the PartsHolder comment out the two other editors and just leave the one for the bundles,
$manager_bundles = new DataObjectManager(
$this,
'Bundles',
'PartsBundle'
);
$fields->addFieldToTab('Root.Content.Bundles', $manager_bundles);this way youll get one tab for bundles and when adding creating a bundle you can select existing to it or add new ones.
Cheers,
BoWa -
Re: ManyManyDataObjectManager to manage two subclasses of DataObject

10 February 2011 at 7:22am
Thanks Bowa,
Funnily enough, this is about what I have now after I chatted to you on IRC (it was you, wasn't it?), but now I've come across the issue where Parts that are ticked are not saved by the ManyManyComplexTableField because it's in a pop-up which is something many are finding (seemingly for about a year or more).
I'm now trying to figure out how to get the ManyManyComplexTableField not to be in a pop-up so that it works.
-
Re: ManyManyDataObjectManager to manage two subclasses of DataObject

10 February 2011 at 10:02am
Cheers,
And im a fraid it was me
, selection at the admin end seemed to work for the inner "manymanyeditor" for me at least.
But if you have an issue with it theres a nifty workaround, instead of the inner editor use the CheckboxSetField to manage the selections.
Below a snipped of a working idea, wont copy the whole thing here ;P
$doTravellerTag = DataObject::get("TravellerTag");
$mapTravellerTag = $doTravellerTag ? $mapTravellerTag = $doTravellerTag->toDropdownMap('ID','Name') : array();
$fields->push(new CheckboxSetField('TravellerTags','TravellerTags', $mapTravellerTag));TravellerTag is a many_many relation for that Data Object. Off course with this you need one tab were you "build" the bundles packages but the relations are managed with a simple checkboxlist.
Or just crate a site tree with pages to hide the underliying "datamodel" it really depents how "politically correct" you want to be with your relations ;)
Cheers,
Olli -
Re: ManyManyDataObjectManager to manage two subclasses of DataObject

10 February 2011 at 10:08am
Got this sorted now. I made another Holder class for the bundles and separated them out. Not what I was hoping for, but it works.
I think the issue may be that DOM is not supposed to handle relationships between DataObjects and DataObjects (only Pages and DataObjects)?
| 1295 Views | ||
| Go to Top | Next > |


