Background
In Drupal 6, we had the option to use 'Access Rules', which allowed us to create rules to restrict user registration based on email patterns. For example, we could deny users with the following pattern %@yahoo.com from registering on the site. However, with Drupal 7, there is no such 'Access Rules'. For this reason, I attempted to write my own module to replace this functionality.

Problem
Though my module seems to be correct, it doesn't quite work just yet. If I attempt to register with an invalid email (bonesaw@yahoo.com), I get the 'E-mail address' fieldbox highlighted in red with no error messages; if I attempt to register with a valid email (bonesaw@unh.edu), clicking submit does nothing - when I login with the admin account, i see no such account was created.

My Code

<?php

/**
 * @file
 * Specifies rules for restricting user registration based on email domains.
 */
 
  function registration_restriction_form_alter(&$form, &$form_state, $form_id) {
  // make sure this is the register form
    if ($form_id == 'user_register_form') {
  // this adds your custom validation function to the form validation array
     $form['#validate'][] = 'registration_restriction_user_register_validation';
    }
  }

  function registration_restriction_user_register_validation($form, &$form_state) {
  // Schools
    $schoolDomains = array('virginia.edu', 'unh.edu', 'wildcats.unh.edu', 'umass.edu');
  
  // Get domain 
        $email = $form_state['values']['mail'];
        $splitIndex = strpos($email, '@')+1;
        $emailLength = strlen($email);
        $domain = substr($email, $splitIndex, $emailLength);
        
  // Error if not legitimate domain  
    if ( !in_array($domain, $schoolDomains) ) {
     form_set_error('mail', 'Invalid email address');
    }
  }

Comments

jmm42’s picture

Could another module that I have written conflict with the above module I wrote? This is my other module that I have written (and works):

<?php
/* $Id$ */

/**
* @file
* Automatically assign role based on email domain associated upon registration.
*/

function user_email_roles_user_presave(&$edit, $account, $category) {

  // Get domain
        $mailContainer = $account->mail;
        $splitIndex = strpos($mailContainer, '@')+1;
        $emailLength = strlen($mailContainer);
        $emailDomain = substr($mailContainer, $splitIndex, $emailLength);

  // Assign role
        if ( $emailDomain == 'unh.edu') {
          $edit['roles']['4'] = 4;
        }
        elseif ( $emailDomain == 'wildcats.unh.edu' ) {
          $edit['roles']['4'] = 4;
        }
        elseif ( $emailDomain == 'virginia.edu' ) {
          $edit['roles']['5'] = 5;
        }
        else {
          $edit['roles']['6'] = 6;
        }

dpm( count($edit['roles']) );       

dpm($edit);

}
jmm42’s picture

So the modules are independent of one another, and should not conflict with one another.

What I've done

  • Inserted dpm('form alter'); into function registration_restriction_form_alter(&$form, &$form_state, $form_id) { }
  • Inserted dpm('register validation'); into function registration_restriction_user_register_validation($form, &$form_state) { }
  • I've granted anonymous users permission to 'Access developer information' on 'admin/people/permissions'

Problem

When I am on: #overlay=admin/modules/list, 'form alter' is displayed via dpm, but 'register validation' is not displayed on the overlay - most likely because the overlay is not a registration form. But, what I find strange is that when I'm not logged in (anonymous user), and goto '/user/register' to attempt to register an invalid email address, I don't get a dpm() error message - or any dpm() messages.

Question

Does anyone know why the dpm() error message is not displaying?

jason_gates’s picture

Hi,
I'm not sure I follow your post. However, I thought a simple reality check might help. Can you please post the file listings for your module(s) (I.E. names of files and which disk/directory you've installed them in).

Sometimes folks simply place their source code in the wrong files and/or locations. Thus, a simply "reality check" might help :)

jmm42’s picture

Thanks for your response. Unfortunately, I put my modules in the correct 'modules' folder - and proof of this is that my 'role assignment' module works correctly, which is where the 'registration restriction' module is located (where I've enabled both in Drupal itself).

jason_gates’s picture

Hi,
Can you please post the file listings and their locations? Just the names will suffice. :)

jmm42’s picture

I actually found out why my dpm(); messages weren't being displayed on 'user/register' page - and this was because I forgot to include the following code in my page.tpl.php:

  if ($messages) {
    print '<div id="messages">' . $messages . '</div>';
  }
jason_gates’s picture

Hi,
Glad to have helped.
....
That's why I suggested a review of your file listings. You had forgot you were using a custom page template.

jmm42’s picture

Oh, yea, I guess I did forget to write the php code in my page.tpl. I'm going to further debug this module later this week. Thanks for your replies!

jason_gates’s picture

Hi,
Actually your module code is not not housed in a .tpl file.

That was my other point.

You need to house your code in a .module, .info, ,install and .inc files.

The .install and .inc files are as needed.

The .info and .module are a minimum requirement.

You also need to abide by the Drupal naming conventions so that Drupal can communicate with your hook implementations.

To summarize, a Drupal module is not a few php statements housed in a template file. (.tpl).

jmm42’s picture

Oh, yes i know -- hence why one of my modules I wrote is working :) I was trying to find out why dpm() was not working, as I wanted to use that as a means to debug my module. Thanks for your response!

Anyways, I put dpm('register validation'); in: function registration_restriction_user_register_validation($form, &$form_state) {}

When I attempt to register a new account with a valid email, I get the dpm() output: 'register validation'. However, no account is created (by login as admin and going to 'admin/people').

jmm42’s picture

Problem

Current status of my module: When I attempt to create an account using an invalid email account (not defined in $schoolDomains), then form_set_error('mail', 'Invalid email address'); displays its message. When I attempt to create a valid account (using a valid email), no account gets created, instead dpm('register validation'); displays at the top of the page. It's clear both hooks are being initiated. Could someone help me enable the ability to create a user account with a valid email defined in $schoolDomains.



Code

/**
 * @file
 * Specifies rules for restricting user registration based on email domains.
 */
 
  function registration_restriction_form_alter(&$form, &$form_state, $form_id) {
    dpm('form alter');
  // make sure this is the register form
    if ($form_id == 'user_register_form') {
  // this adds your custom validation function to the form validation array
     $form['#validate'][] = 'registration_restriction_user_register_validation';
    }
  }

  function registration_restriction_user_register_validation($form, &$form_state) {
  dpm('register validation');
  // Schools
    $schoolDomains = array('virginia.edu', 'unh.edu', 'wildcats.unh.edu', 'umass.edu');
  
  // Get domain 
        $email = $form_state['values']['mail'];
        $splitIndex = strpos($email, '@')+1;
        $emailLength = strlen($email);
        $domain = substr($email, $splitIndex, $emailLength);
        
  // Error if not legitimate domain  
    if ( !in_array($domain, $schoolDomains) ) {
     form_set_error('mail', 'Invalid email address');
    }
  }
jmm42’s picture

If anyone is trying to use my module(s) or something similar, and you have 'User restrictions' (I have 7.x-1.0-bet7) enabled, disable it. For some reason, that module conflicts with some other module / core (who knows). If 'User restrictions' is enabled, it doesn't allow you to create an account (at least for me).

ProperCursive’s picture

I'm trying to implement this module - but even after creating and activating the module, and clearing site cache, I am allowed to register an account regardless of the email used.

I created the module using a standard .info and the .module file.

Thanks!

ProperCursive’s picture

Nevermind - I got it fixed. Simple typo in the module file name.

Sherbet’s picture

got it working, cache wasn't cleared properly. Any chance of this becoming a full-fledged module with a settings page for "Allowed Domains"? Also, it'd be nice if adding a user through the administration panel would still allow all email adresses; currently that is also limited.

vortexcentrum’s picture

Thanks for working to resolve this problem.

However, it is such an important issue that it is incredible, to me, that this capability was removed from the core for v7.

In fact, its absence is one of the primary reasons we have not migrated the substantial number of sites we manage to D7.

It is the single most effective way of preventing spammers and scammers registering on Drupal sites. We have a long list of blocked domains which spammers / scammers often use. We are not concerned (on commercial sites) about blocking out all yahoo or google users, for example. But there are hundreds of free / anonymous accounts which are used to circumvent double opt-in procedures.

D7 (which we have one one non-commercial site) is a leap forwards from D6 in many ways. But if we can't lock out access (without resorting to .htaccess and therefore a list of IP addresses) at the earliest stages of application to the site, then it simply doesn't work for us.

This, note, then is a plea for the restoration of the access rules module into Core.

WorldFallz’s picture

No one who can do anything about it will your plea in the forums.

See #228594: UMN Usability: split access rules into an optional module and http://drupal.org/project/user_restrictions

Judging by the usage statistics though, it doesn't look like many d7 sites would agree, lol. And with that low usage, the odds of it being added back to core are virtually nil. If anything, the impetus is to streamline core even more for d8.

aboutblank’s picture

Hi there,

I just wanted to let you and anyone else who comes across this thread know that I have adapted some of the code here to a contrib module. It's currently going through the project review process, so feel free to help test it: http://drupal.org/node/1884388

If anyone is interested in becoming a co-maintainer, let me know.

// Jason

jmm42’s picture

Sure, I'll try to assist what I can.