7913 Posts in 1355 Topics by 930 members
DataObjectManager Module
SilverStripe Forums » DataObjectManager Module » Using ManyManyDataObjectManager on the belongs_many_many side
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: | 4570 Views |
-
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 2:16am
Ok the function that's causing the error is getRawDetailFields(). Currently it kills my Apache server after loading for awhile. Trying to figure out why.
-
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 2:33am
Can one of you guys post the code you're using so I can set up a test case?
-
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 2:44am Last edited: 5 September 2009 2:46am
It seems like the culprit is getCMSFields() in the related class. If the related class also has a ManyManyDataObjectManager then it kills my script.
Using the code I posted before the DataObjectManager works on the belongs_many_many side as long as you don't have a ManyManyDataObjectManager on the many_many side as well.
The reason for why it doesn't work is because you end up in an infinite loop. When getCMSFields() gets called on the other class then that in turn calls getCMSFields() on its related class and so on and so on ad infinitum. The way around this is that you HAVE TO define a getCMSFields_forPopup() method which passes in another fieldset than the one with the ManyManyDataObjectManager.
So in summary:
In the latest SVN version of ManyManyDataObjectManager replace this (line 31 to 35):
if( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
$this->manyManyParentClass = $class;
$manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $this->name;
break;
}
with thisif( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
$newSingleton = singleton($belongsManyManyRelations[$this->name]);
$relationships = $newSingleton->uninherited('many_many', true);
$tie = array_search($controller->ClassName, $relationships);
$this->manyManyParentClass = $class;
$manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $tie;
break;
}
Then make sure to define popup getter methods in your dataobjectmanagers to avoid infinite loops. This is working great for me, let me know if it works. -
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 2:53am
Hello Uncle Cheese.
I am running a very basic test case for this with the latest trunk version of Silverstripe and and the latest SVN trunk version of your DataObjectManager. I have just two classes that extend the basic page class with a many many relationship between them.
Do you want me to setup a test case somewhere public where you can have a look at it?
-
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 4:22am Last edited: 5 September 2009 4:23am
No, because I'd like to be able to make the edits to the DOM code to test the results. I know for some reason this forum doesn't have file attachments, but could you just dump your page and dataobject classes?
Careful, Smurkas, you don't want to rely on the popupfields method. It's not required by DOM or CTF that you define such a method. You can pass a Fieldset as the fifth argument to either, in which case the DataObject becomes fieldset agnostic.
-
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 4:29am
Yeah I went looking for an attach file button so I could attach the classes.
Anyway repeating them here shouldn't be a problem.
So the first class looks like this
class ProductPage extends Page {
static $db = array(
);
static $many_many = array(
"Software" => "SoftwarePage",
);
static $has_one = array(
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$products = new ManyManyDataObjectManager(
$this,
'Software',
'SoftwarePage',
array(
'Title' => 'Software Name',
)
);
$products->setPermissions(array('edit', 'delete'));
$products->setAddTitle('Related Software');
$fields->addFieldToTab('Root.Content.Software', $products);
return $fields;
}
}class ProductPage_Controller extends Page_Controller {
} -
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 4:31am
And the other one looks like this
class SoftwarePage extends Page {
static $db = array(
);static $belongs_many_many = array(
"Products" => "ProductPage",
);
static $has_one = array(
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$products = new ManyManyDataObjectManager(
$this,
'Products',
'ProductPage',
array(
'Title' => 'Product Name',
));
$products->setPermissions(array('edit', 'delete'));
$products->setAddTitle('Related Products');
$fields->addFieldToTab('Root.Content.Products', $products);
return $fields;
return $fields;
}
}class SoftwarePage_Controller extends Page_Controller {
} -
Re: Using ManyManyDataObjectManager on the belongs_many_many side

5 September 2009 at 4:39am
These are the only classes I have in the test system. If I remember correctly I first created a software page before actually putting the ManyManyDataObjectManager in there.
Like I said before, trying to create any of those two classes will fail since they will get stuck in an infinite loops when DataObjectManager calls getCMSFields() on the related object. The solution to this is either to define a custom field getter for the classes and pass the getters as an argument or pass in a fieldset like you suggested.
Like you said that isn't really a satisfactory solution since the $detailFormFields is supposed to be volountary.
| 4570 Views | ||
| Go to Top | Next > |

