Jump to content

Assigning a group in a registration hook


Recommended Posts

Posted

I have a customized signup form where the user can enter a unique key that will give them to access to certain parts of the site. I intend to implement this through the primary member group as the distinction between the various access levels should be immediately obvious in the forum.

In order to achieve this I have added a hook to \IPS\core\modules\front\system\register, extending the _createMember() method. My method looks vaguely like this:

public static function _createMember($values, $profileFields)
{
  $member = parent::_createMember($values, $profileFields);
  $accessData = SomeClass::checkAccessCode($values['access_code']);

  switch ($accessData->type)
  {
    case 'foo':
      $member->member_group_id = \IPS\Settings::i()->member_group_foo;
      break;
    case 'bar':
      $member->member_group_id = \IPS\Settings::i()->member_group_bar;
      break;
    default:
      $member->member_group_id = \IPS\Settings::i()->member_group_baz;
      break;
  }

  $member->save();
}

It actually works... until the "Email activation required" page is loaded. Then the member group is reset to "Member". The stack trace for that save looks like this:

  1. /ips4/system/Session/Session.php:210 (IPS\_Member->save)
  2. /ips4/system/Session/Session.php:93 (IPS\_Session->init)
  3. /ips4/system/Member/Member.php:145 (IPS\_Session::i)
  4. /ips4/system/Dispatcher/Front.php:643 (IPS\_Member::loggedIn)
  5. /ips4/system/Dispatcher/Front.php:63 (IPS\Dispatcher\_Front::baseCss)
  6. /ips4/system/Dispatcher/Dispatcher.php:103 (IPS\Dispatcher\_Front->init)
  7. /ips4/index.php:12 (IPS\_Dispatcher::i)

From what I can tell the dispatcher asks for the currently logged in member, whoch comes from the session. The session still has the old member object (with member group "Member") and saves that to the database before returning it.

Attempts to overwrite the session's member object in my hook have failed, as have attempts to destroy the session in the hook. What are my options for setting the member group during registration without the session undoing my changes?

Posted
44 minutes ago, Adriano Faria said:

IPS\core\modules\front\system\register::_createMember().

I already hook that method. The session schenanigans happen later.

 

43 minutes ago, newbie LAC said:

If you make an app 

 

I already use a MemberSync extension to set up a few things. As far as I can tell onCreateAccount() runs far too early (as soon as the member is first written to the DB) and onValidate() runs too late – I don't want unvalidated members to be in the default group.

Posted
/**
     * Call after completed registration to send email for validation if required or flag for admin validation
     *
     * @param    bool    $noEmailValidationRequired    If the user's email is implicitly trusted (for example, provided by a third party), set this to TRUE to bypass email validation
     * @param    bool    $doNotDelete                If TRUE, the account will not be deleted in the normal cleanup of unvalidated accounts. Used for accounts created in Commerce checkout.
     * @return    void
     */
    public function \IPS\Member::postRegistration( $noEmailValidationRequired=false, $doNotDelete=false )

check also it

    /**
     * Member account has been created
     *
     * @param    $member    \IPS\Member    New member account
     * @return    void
     */
    public function onCreateAccount( $member )
    {
        if( !$this->_checkStatus() )
        {
            return;
        }
        if ( $member->email AND !$member->members_bitoptions['bw_is_spammer'] AND \IPS\Settings::i()->reg_auth_type == 'none')
        {
	//member is approved and there are not any auth required
	}
	}

 

/**
     * Member has validated
     *
     * @param    \IPS\Member    $member        Member validated
     * @return    void
     */
    public function onValidate( $member )
    {
        if( !$this->_checkStatus() )
        {
            return;
        }
	//member is validated do something here
	}

Posted

That does sound good... Unfortunately, \IPS\Member::postRegistration() still seems to run before the session overwrites the member.

Perhaps my code works correctly and I should rather investigate what causes the session to write obsolete data to the database... Time to hit the source code again.

Posted

Okay, I finally managed to resolve the problem. Two of them, actually.

Basically, I had some problem I can't reconstruct right now. While trying out various things I waved a few dead chickens around. One of those dead chickens involved messing around with how exactly the member groups were set – instead of using the magic member_group_id property I now called set_member_group_id(). I then proceeded to somehow fix the first problem, although by now the member group ID would outwardly change but would never be propagated to the database. The resulting behavior looked exactly as before, although the underlying problem was now a different one. That's why I couldn't get your suggestions to work – the problem was technically solved very early on.

After I noticed that set_member_group_id() does not actually do what I thought it does I changed my code back to using the property and it suddenly worked just fine.

Perhaps the IPS code documentation could be a bit clearer in situations like this – set_member_group_id() is not there to set the member group ID but is instead a helper method called by the magic property setter defined by the ActiveRecord pattern. While there is a @see reference to ActiveRecord::_set in the doc block the title of "Set group" makes it look like the method can be used to set the group, while it really shouldn't be called directly.

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...