Jump to:

3460 Posts in 1064 Topics by 739 members

Data Model Questions

SilverStripe Forums » Data Model Questions » Inheritance and has_many (SiteTree)

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

Page: 1
Go to End
Author Topic: 1028 Views
  • cake
    Avatar
    Community Member
    19 Posts

    Inheritance and has_many (SiteTree) Link to this post

    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?

  • cake
    Avatar
    Community Member
    19 Posts

    Re: Inheritance and has_many (SiteTree) Link to this post

    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

  • martimiz
    Avatar
    Forum Moderator
    1085 Posts

    Re: Inheritance and has_many (SiteTree) Link to this post

    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

  • cake
    Avatar
    Community Member
    19 Posts

    Re: Inheritance and has_many (SiteTree) Link to this post

    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().

  • martimiz
    Avatar
    Forum Moderator
    1085 Posts

    Re: Inheritance and has_many (SiteTree) Link to this post

    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...

  • cake
    Avatar
    Community Member
    19 Posts

    Re: Inheritance and has_many (SiteTree) Link to this post

    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.

  • martimiz
    Avatar
    Forum Moderator
    1085 Posts

    Re: Inheritance and has_many (SiteTree) Link to this post

    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...

    1028 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.