2

I'm looking to add some additional functionality to the user registration process. Basically, we will be creating "access codes" that can be used N number of times during registration. Once N users have signed up using that code, the plugin that I'm writing will prevent additional users from registering on the site.

Right now, I'm having trouble determining how to add errors to the users.onBeforeSaveUser event. My plugin checks availability of the access code that was submitted during the registration process, and I'd like to prevent Craft from saving the user if the code isn't valid/enabled. Here's what the code looks like:

<?php

namespace Craft;

class GatekeeperPlugin extends BasePlugin
{

  ...

  function init()
  {

    craft()->on('users.onBeforeSaveUser', function(Event $event) {

      // The user that's about to be saved
      $user = $event->params['user'];

      // Determine if an access code was submitted
      $accessCodeUsed = isset($user->contentFromPost['accessCodeUsed']) ? $user->contentFromPost['accessCodeUsed'] : false ;

      // If there was an access code submitted...
      if ($accessCodeUsed)
      {

        // Look for it in the database
        $queryAccessCode = craft()->db->createCommand()
          ->select('id, field_code, field_limit, field_timesUsed')
          ->from('content')
          ->where(array('field_code' => $accessCodeUsed))
          ->limit('1')
          ->queryRow();

        // If the code was found...
        if($queryAccessCode)
        {

          ...Do some stuff

        }

        // If the code wasn't found...
        else
        {

          // Prevent Craft from saving the user
          // Add error "Sorry, that code is not valid."


        }

      }

    });

  }

}

It appears that error messages can only be added to models, but I'm working with an event here. The event has a user model within it, but trying to add errors to it (e.g. $event->params['user']->addErrors([array of errors])) hasn't worked for me. Any pointers, here?

1 Answer 1

2

Events are generally not capable of having an effect on the calling code; they’re just notifications.

You would probably be better off disabling public user registration (Settings > Users > Settings), and creating a custom controller that registers users instead. Your controller would be the one to determine if there are still any slots left, and if so, call craft()->users->saveUser() itself.

4
  • I'm in a similar situation of needing to do additional validation onBeforeSaveEntry and would like to stop the action gracefully. Is this something that you have considered adding? Or would this be considered bad form in general to allow events to interfere with an action? Commented Oct 8, 2014 at 16:17
  • @DouglasMcDonald I’m generally of the opinion that events should just be notifications. If you want to add additional validation, that can be handled with a custom controller. Commented Oct 8, 2014 at 16:23
  • I agree in principle 100%. Just trying to figure out a workaround? Is it possible to re-route default actions (i.e. action/saveEntry) to a custom plugin controller using registerCPRoutes? If so, that would definitely solve the problem. Commented Oct 9, 2014 at 4:09
  • 1
    @DouglasMcDonald Sorry I didn’t realize you meant within the CP. That may be a case where it would make sense to give the event a little more power. I’ll put it on the list to think about. Commented Oct 9, 2014 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.