Jump to:

7939 Posts in 1472 Topics by 944 members

DataObjectManager Module

SilverStripe Forums » DataObjectManager Module » How/Where to Do Something when altering manymany relation

Discuss the DataObjectManager module, and the related ImageGallery module.

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

Page: 1
Go to End
Author Topic: 1465 Views
  • silk
    Avatar
    Community Member
    18 Posts

    How/Where to Do Something when altering manymany relation Link to this post

    Hello,

    I want to make a module for configuring majordomo mailing list. Configuring, like adding and removing members is done via mail.
    I keep track who is currently in the list in a database table. Inserting and removing from the database works. But where do I put the code for sending the mail to the majordomo server?

    Example:
    For each member new to the database table I have to send a line like
    subscribe...

    A similar line has to be send when a member has to be removed.
    Where to put it? onBeforeWrite()?
    My code right now is:

    class MailinglistePage extends Page {

    static $db = array(
    'Description'=>'Text',
    'EMail'=>'Text'
    );
    static $has_one = array('Admin'=>'Member'
    );

    static $many_many = array('MailUser'=>'Member'
    );

    public function getCMSFields()
       {
          $f = parent::getCMSFields();
          $f->addFieldToTab('Root.Content.Main', new TextField('Description', 'Description'));
          $f->addFieldToTab('Root.Content.Main', new EmailField('Description', 'Description'));
          $f->addFieldToTab("Root.Content.Mitglieder", new ManyManyDataObjectManager(
             $this,
             'MailUser',
             'Member',
             array('Surname' => 'Surname',
             'Firstname'=>'Firstname',
             'Email'=>'Email'         
             ),
             'getCMSFields'
          ));
          return $f;
       }

    function onBeforeWrite() {

    // CAUTION: You are required to call the parent-function, otherwise sapphire will not execute the request.
    parent::onBeforeWrite();
    }
    }

  • UncleCheese
    Avatar
    4085 Posts

    Re: How/Where to Do Something when altering manymany relation Link to this post

    onBeforeWrite() should work fine, but maybe onAfterWrite() is a safer bet because you know at that point that the record has been written.

  • silk
    Avatar
    Community Member
    18 Posts

    Re: How/Where to Do Something when altering manymany relation Link to this post

    Which is the best way to obtain which Members are in my list?
    Is there a way to get only the new members?

  • UncleCheese
    Avatar
    4085 Posts

    Re: How/Where to Do Something when altering manymany relation Link to this post

    I'm not sure what you mean by "new".. what would make someone new? Created in the last day? Week?

    You can get all the user records associated with that page by running the relation as a function..

    $yourMalinglistePage->MailUser();

    Generally you should name your has_many and many_many relations in the plural, since they can return multiple records, but in your case you've named it MailUser, so you have to use that..

  • silk
    Avatar
    Community Member
    18 Posts

    Re: How/Where to Do Something when altering manymany relation Link to this post

    Sorry for being so unclear, you understood correctly.

    Now I have a problem you also have dealt with according to the forums.

    My new code is as follows:

    (...)

    function onBeforeWrite() {
    parent::onBeforeWrite();

    $this->oldUsers=$this->MailUsers()->getIdList();
    foreach ($this->oldUsers as $user){
    print '// +++++++++++++++++ '.$user.' +++++++++++++ \n';
    }
    }

    function onAfterWrite() {
    parent::onAfterWrite();

    $nowUsers=$this->MailUsers()->getIdList();
    foreach ($nowUsers as $user){
    print '// ################# '.$user.' ############# \n';
    }
    }


    In my test I have three Members with Id's 5, 6, 7 and I remove two of them. Then I press Save.
    Debugging Output is:

    // +++++++++++++++++ 6 +++++++++++++
    // +++++++++++++++++ 5 +++++++++++++
    // +++++++++++++++++ 7 +++++++++++++

    // ################# 6 #############
    // ################# 5 #############
    // ################# 7 #############

    // +++++++++++++++++ 7 +++++++++++++

    // ################# 7 #############


    This shows:
    1. onBefore- and onAfterWrite is called twice. In your old posts about this issue you said it might depend on the number of relations. Same here: Two relations (1 has_one, 1 manymany). Did you find anything out to deal with this?
    2. Even more severe: The table seems to change *between* calling onAfterWrite() and the second onBeforeWrite()!
    Shouldn't be the point for having those two functions to make clear this does not happen?

  • UncleCheese
    Avatar
    4085 Posts

    Re: How/Where to Do Something when altering manymany relation Link to this post

    A lot of times what I do when you have a really specific onBeforeWrite() handler is to set a static class property to count the number of times onBeforeWrite() has been run. If it is the number that you want, you can run your code, but otherwise save it until everything is the way you want it.

    static $write_count = 0;

    public function onBeforeWrite() {
    self::$write_count++;
    parent::onBeforeWrite();
    if($write_count == 3)
    // do stuff

    }

  • silk
    Avatar
    Community Member
    18 Posts

    Re: How/Where to Do Something when altering manymany relation Link to this post

    I thought about something like this, but what is with the second point?

    The changes to the database table do not seem to happen between OnBeforeWrite and OnAfterWrite, but before OnBeforeWrite!

    I have removed all but my manymany relation. With newly created database table OnBeforeWrite and OnAfterWrite are executed only once and the database table has already entries in OnBeforeWrite. Next time when hitting 'Save' they are executed twice. Now the changes to the database table happen between the first OnAfterWrite and the second OnBeforeWrite.
    This is bad for me, because I want to find out which entries have been added and removed (by comparing before state and after state).

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