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.

Data Model Questions /

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

Inheritance and has_many (SiteTree)


Go to End


7 Posts   1996 Views

Avatar
cake

Community Member, 19 Posts

12 January 2011 at 4:53am

Hi all,

I run into a problem with inheritance. It's quite simple but perhaps this isn't possible - I'll try to explain it:

I've got one class "BackgroundPage" which extends Page and has a has_many relation to a data object.

I've got another class "TilePageCategory" which extends "BackgroundPage" with it's own has_many relationship to a SiteTree class.


class BackgroundPage extends Page {

	static $has_many = array(
			'Backgrounds' => 'Background'
	);
}

class TilePageCategory extends BackgroundPage {

    static $allowed_children = array( 'TilePageHolder' );

    static $has_many = array (
        'TilePageHolders' => 'TilePageHolder'
    );


}

So an instance of TilePageCategory should be able to call

$this->Backgrounds()
and
$this->TilePageHolders()

But it isn't. The resulting componentSet instances are empty (I just get the instance's skeleton):

print_r($this->TilePageHolders()) gives me:

ComponentSet Object
(
    [type:protected] => 1-to-many
    [ownerObj:protected] => TilePageCategory Object
        (
            [destroyed] => 
            [record:protected] => Array
                (
                    [ClassName] => TilePageCategory
                    [Created] => 2010-12-06 10:56:56
                    [LastEdited] => 2011-01-11 14:18:10
                    [URLSegment] => projekte
                    [Title] => PROJEKTE
                    [MetaTitle] => Bauten
                    [ShowInMenus] => 1
                    [ShowInSearch] => 1
                    [ProvideComments] => 0
                    [Sort] => 2
                    [HasBrokenFile] => 0
                    [HasBrokenLink] => 0
                    [Status] => Published
                    [CanViewType] => Inherit
                    [CanEditType] => Inherit
                    [Version] => 7
                    [Priority] => 1.0
                    [ParentID] => 0
                    [ID] => 6
                    [RecordClassName] => TilePageCategory
                )

            [changed:DataObject:private] => Array
                (
                )

            [original:protected] => Array
                (
                    [ClassName] => TilePageCategory
                    [Created] => 2010-12-06 10:56:56
                    [LastEdited] => 2011-01-11 14:18:10
                    [URLSegment] => projekte
                    [Title] => PROJEKTE
                    [MetaTitle] => Bauten
                    [ShowInMenus] => 1
                    [ShowInSearch] => 1
                    [ProvideComments] => 0
                    [Sort] => 2
                    [HasBrokenFile] => 0
                    [HasBrokenLink] => 0
                    [Status] => Published
                    [CanViewType] => Inherit
                    [CanEditType] => Inherit
                    [Version] => 7
                    [Priority] => 1.0
                    [ParentID] => 0
                    [ID] => 6
                    [RecordClassName] => TilePageCategory
                )

            [components:protected] => 
            [brokenOnDelete:protected] => 
            [brokenOnWrite:protected] => 
            [componentCache:protected] => Array
                (
                    [Backgrounds_948a13f1eb402f8ff16472e217608fb6] => ComponentSet Object
                        (
                            [type:protected] => 1-to-many
                            [ownerObj:protected] => TilePageCategory Object
 *RECURSION*
                            [ownerClass:protected] => TilePageCategory
                            [tableName:protected] => 
                            [childClass:protected] => Background
                            [joinField:protected] => BackgroundPageID
                            [items:protected] => Array
                                (
                                )

                            [odd:protected] => 0
                            [first:protected] => 1
                            [last:protected] => 
                            [current:protected] => 
                            [pageStart:protected] => 
                            [pageLength:protected] => 
                            [totalSize:protected] => 
                            [paginationGetVar:protected] => start
                            [iteratorPos:protected] => 
                            [iteratorTotalItems:protected] => 
                            [failover:protected] => 
                            [customisedObject:protected] => 
                            [objCache:ViewableData:private] => Array
                                (
                                )

                            [class] => ComponentSet
                            [extension_instances:protected] => Array
                                (
                                )

                        )

                    [TilePageHolders_948a13f1eb402f8ff16472e217608fb6] => ComponentSet Object
 *RECURSION*
                )

            [iteratorPos:protected] => 
            [iteratorTotalItems:protected] => 
            [failover:protected] => 
            [customisedObject:protected] => 
            [objCache:ViewableData:private] => Array
                (
                )

            [class] => TilePageCategory
            [extension_instances:protected] => Array
                (
                    [GoogleSitemapDecorator] => GoogleSitemapDecorator Object
                        (
                            [owner:protected] => 
                            [ownerBaseClass:protected] => SiteTree
                            [ownerRefs:Extension:private] => 0
                            [class] => GoogleSitemapDecorator
                        )

                    [Hierarchy] => Hierarchy Object
                        (
                            [markedNodes:protected] => 
                            [markingFilter:protected] => 
                            [_cache_numChildren:protected] => 
                            [owner:protected] => 
                            [ownerBaseClass:protected] => SiteTree
                            [ownerRefs:Extension:private] => 0
                            [class] => Hierarchy
                        )

                    [Versioned] => Versioned Object
                        (
                            [stages:protected] => Array
                                (
                                    [0] => Stage
                                    [1] => Live
                                )

                            [defaultStage:protected] => Stage
                            [liveStage:protected] => Live
                            [migratingVersion] => 
                            [owner:protected] => 
                            [ownerBaseClass:protected] => SiteTree
                            [ownerRefs:Extension:private] => 0
                            [class] => Versioned
                        )

                )

        )

    [ownerClass:protected] => TilePageCategory
    [tableName:protected] => 
    [childClass:protected] => TilePageHolder
    [joinField:protected] => TilePageCategoryID
    [items:protected] => Array
        (
        )

    [odd:protected] => 0
    [first:protected] => 1
    [last:protected] => 
    [current:protected] => 
    [pageStart:protected] => 
    [pageLength:protected] => 
    [totalSize:protected] => 
    [paginationGetVar:protected] => start
    [iteratorPos:protected] => 
    [iteratorTotalItems:protected] => 
    [failover:protected] => 
    [customisedObject:protected] => 
    [objCache:ViewableData:private] => Array
        (
        )

    [class] => ComponentSet
    [extension_instances:protected] => Array
        (
        )

)

Any ideas?

Avatar
cake

Community Member, 19 Posts

12 January 2011 at 4:56am

Okay, I found out that I am able to call

$this->AllChildren()

or

$this->Children()

But what if I just want to have childs of Type TilePageHolder?? I.e I can call $this->Backgrounds() in BackgroundPage_Controller but not in the inherited TileHolder_Controller

Avatar
martimiz

Forum Moderator, 1391 Posts

12 January 2011 at 6:04am

I'm a bit confused about what you are trying to do...

By inheritance you mean class inheritance? Because subpages can inherit certain settings from their parentpages, but they don't have access to their parents class methods unless they are of or extend the same class...

Are TilePageHolder objects in fact pages? And do they extend the BackgroundPage class?

If TilePageHolders are subpages of TilePageCategory, then a relation already exists between parent and children so you don't need to create an extra has_many relation for them and the (All)Children() methods provide one way to retrieve them. The allowed_children setting you added, should make sure that subpages of a TilePageCategory can only ever be of the type TilePageHolder, so that should take care of that. If you don't trust these settings, you can allways check the subpages ClassName property.

If the TilePageHolder class indeed extends the BackgroundPage class, it should have access to all its methods and properties (unless they are declared private). So if there are any Background objects added to a page, $this->Backgrounds() should get them I suppose...

Hope this helps

Avatar
cake

Community Member, 19 Posts

12 January 2011 at 10:55pm

Hi martimiz,

thanks for your response.

Indeed i meant class inheritance. TilePageHolders are special BackgroundPages (they extend BackgroundPage).

Calling $this->TilePageHolders() should work but it doesn't.

If TilePageHolders are subpages of TilePageCategory, then a relation already exists between parent and children so you don't need to create an extra has_many relation for them

I'll try to remove the has_many relation to the TilePageHolders. Perhaps this might be a problem. Nevertheless I should be able to call $this->Backgrounds().

Avatar
martimiz

Forum Moderator, 1391 Posts

13 January 2011 at 12:34am

Edited: 13/01/2011 12:35am

If you created your Background object like this:

class Background extends DataObject{
static $has_one = array('BackgroundPage' => 'BackgroundPage');
...
}

And if you successfully added one or more of these objects to one of your pages of the type TilePageHolder in the CMS, and if you then call $this->Backgrounds() from your TilePageHolder_Controller, it should return a DataObjectSet of Background objects. On TilePageHolder pages where no Background objects were added, the method will return empty.

If this is not how you did it, well...

Avatar
cake

Community Member, 19 Posts

13 January 2011 at 1:30am

This is exactly how my Background class looks like.
I removed the has_many relation to TilePageHolder without luck. I get an empty component set.

Avatar
martimiz

Forum Moderator, 1391 Posts

13 January 2011 at 6:08am

Alas - this is a far as I can help you. Maybe something in your code is still not quite right, but I wouldn't know what, from a distance... :-(