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

Sharing a DataObjectManager with multiple classes


Go to End


7 Posts   2738 Views

Avatar
Xurk

Community Member, 50 Posts

12 October 2011 at 3:40am

Edited: 12/10/2011 3:41am

At the moment we're developing a website which consists of pages which are to be entirely populated by "blocks" of content. The content author should be able to add as few as one block of content to a page, but also be allowed to add as many blocks of content as he wants to, in any order. All the blocks will be floated next to one another in the template and overflow to the next "line" when necessary (or when the content author decides a new line of blocks should start).

These blocks can be thought of as widgets. In fact, we've developed a similar website before using SilverStripe's Widget functionality to make the above description possible. However, we found that while Widget sounds like the most plausible approach, in practice it is lacking due to not being very organized (visually) and due to the fact that much hacking is needed to get certain FormField types to work in widgets.

Therefore, we are now trying a new approach with the current website, by developing the blocks of content as DataObjects and managing their order in a DataObjectManager. I've set up a "master" DataObject class which has a few DB fields which are shared among all the different content blocks (e.g. TextBlock, ImageBlock, VideoBlock, FormBlock, etc.) and a few other DataObject classes which have their own unique DB fields.

My question (finally ;-)) is whether or not there is any way to get a DataObjectManager to display all of the different classes representing blocks of content in a single DOM? When creating a DOM, one of the arguments is the source class and I've used the master class there. The $has_one and $has_many relationships between the classes are set up correctly. What I would like, is to be able to use the DOM's "Add" button to add any one of the block types (influencing the fields shown in the DOM popup) and also see the different block types listed in the same DOM instance.

Is any of this possible or are we marching in the wrong direction entirely by trying to use the DataObjectManager for this scenario? I've actually managed to get about halfway there today by "abusing" DataObjectManager a bit through JavaScript and using onAfterWrite(), but so far I'm not sure that is the way to go as I feel that is making the whole thing too complicated...

Avatar
Xurk

Community Member, 50 Posts

13 October 2011 at 1:41am

An update: I've managed to get the DataObjectManager display the subclasses in it by using onAfterWrite() to retrieve the saved DataObject and implement newClassInstance() on it to duplicate it into the subclass table. Because of this, the ClassName field of the master class convienently is altered to contain the ClassName of the subclass it has been duplicated to.

The next step is saving the subclass data in its new record (in its own table), as upon creating an object of the master class, there was nowhere to put the data from the specific form fields during creation - but afterwards, there is. So I've saved the relevant form data into a Session variable (using onBeforeWrite()) and in onAfterWrite() I've added an update() to the subclass instance created with newClassInstance() to add the subclass data values to the DataObject. This does the job in terms of saving the DataObject to the database with a complete set of data, but there are still some problems at the moment.

1. Using the update() method in onAfterWrite() on the subclass instance causes SilverStripe to get stuck for a while and then display an error saying that memory has run out (this also happens if I try to set any random property of the subclass instance manually (e.g. $oSubInstance->RandomProperty = $randomVar); this occurs even though the records are successfully saved in the database.

2. Seeing as the master class' getCMSFields() function also retrieves the getCMSFields from the subclass which is being created at the time and adds them into the form, errors arise for form fields such as ImageUploadField. I think what's happening is the ImageUploadField tries to use URLs which point towards the master class' Form and seeing as the ImageUploadField isn't actually part of that Form, the actions aren't supported. Therefore, it's impossible to upload an image.

Avatar
jumprock

Community Member, 8 Posts

8 December 2011 at 2:48am

Hi, any chance on sharing your progress? I'm looking to do the exact same thing but not sure how to go about. I was thinking of using sub pages on the Site Tree to achieve the same functionality (these wouldn't appear in the menu but I would use the children control to get the sub content for each parent page and display accordingly).

Avatar
Xurk

Community Member, 50 Posts

14 December 2011 at 3:19am

Hi jumprock :-)

Unfortunately, we abandoned this approach shortly after my last post in this thread, due to the problems I described in that post and seeing as no one else here seemed to have any ideas ;-) We ended up going with a single class which has an Enum database variable holding the names of all of the (previously available as) subclasses.

Following that, we limited the getCMSFields_forPopup() method to only allow setting of the generic properties when creating a new instance of the class. If the method is fired on an existing record, the Enum variable is checked and the designated FormFields are displayed for that CustomBlock type.

Hopefully this will give you some inspiration on how to deal with your problem?

Avatar
DNA

Community Member, 24 Posts

14 January 2012 at 5:57pm

Avatar
Juanitou

Community Member, 323 Posts

14 January 2012 at 10:30pm

Hi DNA!

Your solution seems very promising, you should maybe make a module of it!

By the way, I’d like to congratulate you for your website, really nice posts there.

Best regards,
Juan

Avatar
Xurk

Community Member, 50 Posts

17 January 2012 at 2:05am

Hey DNA,

Thanks a lot for sharing your solution in this thread, it looks very promising :-) I'll be sure to give it a shot next time we need this functionality in a project!