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.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

Need advice designing classes


Go to End


6 Posts   1704 Views

Avatar
JoshuaLewis

Community Member, 81 Posts

22 August 2009 at 10:59pm

Edited: 22/08/2009 11:04pm

I would like to get some input on how I plan to setup the classes and relationships for a particular site . I'll start with an description of the site and follow that with the explanation of how I plan to implement it in Silverstripe. My apologies if it runs a little long.

Most of the site will be simple pages with text and no advanced functionality. The exception is the 'Products' section which is outlined in the site tree below.

Product Line 1 : info page, just text and an image.
----Customer Type : group label to organize sub-menus, not a link or page
--------Type 1 : ProductHolder - lists products defined in a many-many relationship, product detail page provided by class method
--------Type 2 : ProductHolder
--------Type 3 : ProductHolder
----Product Category : group label
--------Category 1 : ProductHolder
--------Category 2 : ProductHolder
--------more categories
Product Line 2 : info page
----Product Category : group label
--------Category 1 : ProductHolder
--------Category 2 : ProductHolder
--------more categories
Product Line 3 : info page
----Related Service : info page
----Product Category : group label
--------Category 1 : ProductHolder
--------Category 2 : ProductHolder
--------more categories

What makes this tricky (to me at least) is that the product catalog for each product line is separate from the others but the behavior needed in each product line is otherwise identical as are the requirements for the product dataobjects.
What I take this to means is that I need to define different ProductHolder page types and dataobjects for each product line to manage the relationships properly. But I also don't want to be repeating myself and make maintenance more difficult than it needs to be.

So here are the classes I plan to create to make this work.

  • *Overview extends Page : adds an image to $db and the CMSFields, has it's own layout.
  • *Label extends Page : removes Content from CMSFields, sub-menu include has if control to test ClassName and print title without link.
  • *ProductHolder extends Page : abstract class, defines common logic, $db/CMSFields, etc in one place. Not to be used to actually create pages in the cms.
  • *ProductObject extends DataObject : abstract class, defines the dataobjects fields, sets up method to assign template used to display objects, setsup getCMSFields_forPopup.
  • *Line1Holder extends ProductHolder : at this point it only sets up the many_many relationship with the appropriate child of ProductObject. Same goes for Line2Holder, Line3Holder, etc.
  • *Line1Object extends ProductObject : same as Line1Holder this should only need to setup the relatioship.

If this is a good setup then I'm particularly interested in whether ProductHolder and ProductObject can be explicitly defined as abstract or not and how to prevent database tables from being created from them since they won't be used.

Any advice or feedback is appreciated.

Avatar
bummzack

Community Member, 904 Posts

23 August 2009 at 10:09pm

Edited: 23/08/2009 10:09pm

Hi

I don't think you can have abstract classes inherit from Page. Technically it would probably work, but I think SilverStripe won't like it.
Classes that don't define additional DB fields or relations will not create a new Table in the DB. They will simply be added to the ClassName enum.

Do your so called "Product Lines" have different DataObject fields? Like Line 1 has "Title" and "Text", whereas Line 2 has "Title" and "Image"?
If not, all you need is just a single ProductHolder and a ProductObject class. You can then create several "ProductHolder" Pages and simply add the wanted ProductObjects to that page... I suggest you use the DataObjectManager for this purpose.

Avatar
JoshuaLewis

Community Member, 81 Posts

24 August 2009 at 1:01am

All products will have fields that extend the default set but I don't expect that line1 will need a different set of fields from lines 2 or 3, it is a possibility though. Because of that possibility I think that using sub-classes for each line should give me the flexibility to handle any possible differences while still having all of the shared fields and behaviors defined in a single parent class so I'm not having to keep several copies in sync.

A second problem that I see with only having a single set of page type and dataobject classes is that a ProductHolder page in the Line1 section would have the same ProductObjects listed in the ComplexTableField used to set relationships as ProductHolder pages under Lines 2 and 3. This would make working with those lists and managing the objects in them more difficult and I would like to avoid that problem by restricting products that belong to line1 only to ProductHolder pages within that section.

Unless I'm misunderstanding something I don't see how I can keep those dataobject lists separate from each other and retain the flexibility to handle potential differences in the requirements for each sections products without hurting maintainability unless I setup a series of sub-classes like I described in my first post. I've looked at the DataObjectManager module and while it should certainly improve the interface I don't see anything about it that would solve the problems I've listed.

Of course I don't have much practical experience working with OOP or anything above basic PHP programing so the prospect of me having misunderstood something doesn't sound too unlikely.

Avatar
JoshuaLewis

Community Member, 81 Posts

28 August 2009 at 1:27am

Sorry to bump the thread but I would really like some input on this.

Am I looking at the problem the problem the right way?

I'm confident this solution will work but could it be better and are there alternatives I haven't thought of?

Avatar
bummzack

Community Member, 904 Posts

28 August 2009 at 2:59am

Yes, the DataObjectManager allows separate DataObjects per Page-Instance. DataObjects belonging to other Pages won't be displayed. So, that's obviously an advantage when compared to the TableField Classes.

If your DataObjects won't defer from line to line, you're already set with a Holder and a DataObject. Otherwise, creating a base DataObject from which other DataObjects inherit seems like the way to go. You'll also have to create a different holder Page for all the desired "lines". These Holder-Pages could also inherit from a Base-Page. Since a real abstract page won't work, you could solve the issue by using the canCreate method to prevent creation of the "abstract/base" page.

Avatar
JoshuaLewis

Community Member, 81 Posts

1 September 2009 at 10:03am

Edited: 01/09/2009 10:06am

Thanks again Banal.

I haven't seen DataObjectManager separate the DataObjects like that but I'm working with many_many relationships so I don't see how it could know how to split the objects up.

I've been able to test this setup and it seems to be working fine. I went with a setup using child classes so that I will have more flexibility and used canCreate() like you suggested. I've also decided that not having the abstract pages be truly abstract is a good thing since it means multiple database tables aren't being created that, for the time being, would be structurally identical.

I've attached a copy of the classes I created in mysite/code for anyone who might be interested.
Edit - This was created using Silverstripe version 2.3.3, DataObjectManager version 1.0 r244, and SWFUpload version 0.6 r216.

Attached Files