Jump to:

3373 Posts in 998 Topics by 712 members

Data Model Questions

SilverStripe Forums » Data Model Questions » Duplicate page should duplicate and link dataobjects

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

Page: 1 2
Go to End
Author Topic: 2453 Views
  • Nobrainer Web
    Avatar
    Community Member
    134 Posts

    Duplicate page should duplicate and link dataobjects Link to this post

    Hi,

    I constantly keep running in to this issue.

    I like to use DataObjects for lists of items on my pgaes, like images or links.
    This works fine, no need for the DataObject Manger Module, just a DO.

    Problem is when i duplicate a page (context menu in the CMS), the DataObject "references" gets lost and i'm left with adding all DataObjects manually to my page.

    Can someone tell me how to get the DataObjects duplicated aswell? I think this most be something that some of you are using in your projects and i hope you will share some code or help me get it working.

    I think it should be a matter of overloading the duplicate() method of the SiteTree class, but i dont know how this is done.
    I've read all the threads i could find regarding this matter, closest thing i could find is this post: http://www.silverstripe.org/customising-the-cms/show/11571

    Hope that someone can help!

  • Nobrainer Web
    Avatar
    Community Member
    134 Posts

    Re: Duplicate page should duplicate and link dataobjects Link to this post

    Ok willr answerede this question for me in the irq channel.

    Adding the following code to the Page class (or what class you need it in) will duplicate page and the specified Dataobjects, and set the relation to the duplicated page.

    (This method overloads the duplicate method from SiteTree.php - it's this function that is called when you right click a menu item in the CMS and choose duplicate this page)

       /**
       * Duplicate this page, and its DataObjects.
       *
       * @return Page
       */
       public function duplicate() {
          $page = parent::duplicate();
          
          // the PageImages (name of the has many relation)
          if($this->PageImages()) {
             foreach($this->PageImages() as $image) {
                $newField = $image->duplicate();
                $newField->PageID = $page->ID; // Important that this is the ID of the relation to the DO's parent page!
                                         // Can be ParentID, PageID atc. - It's the current class name
                $newField->write();
             }
          }
          
          return $page;
       }

    Hope this will help someone else to :o)

    Thanks for helping willr

  • mco
    Avatar
    Community Member
    14 Posts

    Re: Duplicate page should duplicate and link dataobjects Link to this post

    Thanks for the input. I had an issue with updating a many_many relation. But then instead of doing a copy of the original items linked to the current page, you need to re-link them to the new object. Here is the modified code:

       /**
        * Duplicate this page and update it's many_many relations
        *
        * @return Page
        */
       public function duplicate() {
          $page = parent::duplicate();

          if($this->Tags()) {
             $page->Tags()->addMany($this->Tags()->getIdList());
          }

          return $page;
       }

    where Tags is defined as

       static $many_many = array(
          'Tags' => 'Tag'
       );

  • dendeffe
    Avatar
    Community Member
    135 Posts

    Re: Duplicate page should duplicate and link dataobjects Link to this post

    This looks great. I was trying to use it on translations, which doesn't use duplicate (as I was thinking). Any idea where I should get started on that?

  • joelg
    Avatar
    Community Member
    129 Posts

    Re: Duplicate page should duplicate and link dataobjects Link to this post

    Wonderful informations about duplicating relations. Thanks everybody.

  • max5k
    Avatar
    Community Member
    8 Posts

    Re: Duplicate page should duplicate and link dataobjects Link to this post

    great, thanks for that one.

    this is what i ended up with:

    duplicate all has_many and many_many relationships of a page dynamically...:

    public function duplicate() {

    $page = parent::duplicate();

    //duplicate has many items
    foreach ($this->has_many() as $key => $className) {
    foreach ($this->{$key}() as $item) {
    $newField = $item->duplicate();
    $id = get_class($this) . 'ID';
    $newField->{$id} = $page->ID;
    $newField->write();
    }
    }

    //duplicate many_many items
    foreach( $this->many_many() as $key => $className ){
    $page->{$key}()->addMany($this->{$key}()->getIdList());
    }

    return $page;
    }

    cheers

  • Nobrainer Web
    Avatar
    Community Member
    134 Posts

    Re: Duplicate page should duplicate and link dataobjects Link to this post

    Thank you so much for posting this max5k, this has gone in to my SilverStripe package that i put on all new sites.
    So usefull!

  • max5k
    Avatar
    Community Member
    8 Posts

    Re: Duplicate page should duplicate and link dataobjects Link to this post

    you might want to add a filter, which relations to duplicate
    the above version does a little too much in some cases...

    public function duplicate() {

    $items_to_duplicate = array(
    'Images' //anything you want to duplicate
    );

    $page = parent::duplicate();

    //duplicate has many items
    foreach ($this->has_many() as $key => $className) {
    if (in_array($key, $items_to_duplicate)) {
    foreach ($this->{$key}() as $item) {
    $newField = $item->duplicate();
    $id = get_class($this) . 'ID';
    $newField->{$id} = $page->ID;
    $newField->write();
    }
    }
    }

    //duplicate many_many items
    foreach ($this->many_many() as $key => $className) {
    if (in_array($key, $items_to_duplicate)) {
    $page->{$key}()->addMany($this->{$key}()->getIdList());
    }
    }

    return $page;
    }

    2453 Views
Page: 1 2
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.