Jump to:

7935 Posts in 1536 Topics by 943 members

DataObjectManager Module

SilverStripe Forums » DataObjectManager Module » Using ManyManyDataObjectManager on the belongs_many_many side

Discuss the DataObjectManager module, and the related ImageGallery module.

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

Page: 1 2 3 4
Go to End
Author Topic: 5286 Views
  • MarcusDalgren
    Avatar
    Community Member
    288 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    Ok the function that's causing the error is getRawDetailFields(). Currently it kills my Apache server after loading for awhile. Trying to figure out why.

  • UncleCheese
    Avatar
    4085 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    Can one of you guys post the code you're using so I can set up a test case?

  • MarcusDalgren
    Avatar
    Community Member
    288 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    It seems like the culprit is getCMSFields() in the related class. If the related class also has a ManyManyDataObjectManager then it kills my script.

    Using the code I posted before the DataObjectManager works on the belongs_many_many side as long as you don't have a ManyManyDataObjectManager on the many_many side as well.

    The reason for why it doesn't work is because you end up in an infinite loop. When getCMSFields() gets called on the other class then that in turn calls getCMSFields() on its related class and so on and so on ad infinitum. The way around this is that you HAVE TO define a getCMSFields_forPopup() method which passes in another fieldset than the one with the ManyManyDataObjectManager.

    So in summary:

    In the latest SVN version of ManyManyDataObjectManager replace this (line 31 to 35):

    if( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
       $this->manyManyParentClass = $class;
       $manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $this->name;
       break;
    }


    with this

    if( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
       $newSingleton = singleton($belongsManyManyRelations[$this->name]);
       $relationships = $newSingleton->uninherited('many_many', true);
       $tie = array_search($controller->ClassName, $relationships);
       $this->manyManyParentClass = $class;
       $manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $tie;
       break;
    }


    Then make sure to define popup getter methods in your dataobjectmanagers to avoid infinite loops. This is working great for me, let me know if it works.

  • MarcusDalgren
    Avatar
    Community Member
    288 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    Hello Uncle Cheese.

    I am running a very basic test case for this with the latest trunk version of Silverstripe and and the latest SVN trunk version of your DataObjectManager. I have just two classes that extend the basic page class with a many many relationship between them.

    Do you want me to setup a test case somewhere public where you can have a look at it?

  • UncleCheese
    Avatar
    4085 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    No, because I'd like to be able to make the edits to the DOM code to test the results. I know for some reason this forum doesn't have file attachments, but could you just dump your page and dataobject classes?

    Careful, Smurkas, you don't want to rely on the popupfields method. It's not required by DOM or CTF that you define such a method. You can pass a Fieldset as the fifth argument to either, in which case the DataObject becomes fieldset agnostic.

  • MarcusDalgren
    Avatar
    Community Member
    288 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    Yeah I went looking for an attach file button so I could attach the classes.

    Anyway repeating them here shouldn't be a problem.

    So the first class looks like this

    class ProductPage extends Page {
       
       static $db = array(
       );
       
       static $many_many = array(
          "Software"   => "SoftwarePage",
       );
       
       static $has_one = array(
       );
       
       public function getCMSFields() {
          $fields = parent::getCMSFields();
          $products = new ManyManyDataObjectManager(
        $this,
        'Software',
        'SoftwarePage',
        array(
           'Title' => 'Software Name',
        )
          );
    $products->setPermissions(array('edit', 'delete'));
    $products->setAddTitle('Related Software');
          $fields->addFieldToTab('Root.Content.Software', $products);
          return $fields;
       }
    }

    class ProductPage_Controller extends Page_Controller {
    }

  • MarcusDalgren
    Avatar
    Community Member
    288 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    And the other one looks like this

    class SoftwarePage extends Page {
       
       static $db = array(
       );

       static $belongs_many_many = array(
          "Products"       => "ProductPage",
       );
       
       static $has_one = array(
       );
       
       public function getCMSFields() {
          $fields = parent::getCMSFields();
       
          $products = new ManyManyDataObjectManager(
    $this,
    'Products',
    'ProductPage',
    array(
           'Title' => 'Product Name',
    ));
    $products->setPermissions(array('edit', 'delete'));
    $products->setAddTitle('Related Products');
          $fields->addFieldToTab('Root.Content.Products', $products);
          return $fields;
                
          return $fields;
       }
    }

    class SoftwarePage_Controller extends Page_Controller {
    }

  • MarcusDalgren
    Avatar
    Community Member
    288 Posts

    Re: Using ManyManyDataObjectManager on the belongs_many_many side Link to this post

    These are the only classes I have in the test system. If I remember correctly I first created a software page before actually putting the ManyManyDataObjectManager in there.

    Like I said before, trying to create any of those two classes will fail since they will get stuck in an infinite loops when DataObjectManager calls getCMSFields() on the related object. The solution to this is either to define a custom field getter for the classes and pass the getters as an argument or pass in a fieldset like you suggested.

    Like you said that isn't really a satisfactory solution since the $detailFormFields is supposed to be volountary.

    5286 Views
Page: 1 2 3 4
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.