Drupal - How can anonymous users be allowed to post while still maintaining content integrity?
I don't think this is possible with rules alone.
You need to alter the submission form in order to capture the verification email address, and you also need some logic to ban spammers and recognise returning visitors.
I am the maintainer of a project named Anonymous Publishing. It looks as if this module does what you want.
It still in development, but a Drupal 7 version has been used at several of my production sites without any issues. Please check it out.
You may also want to look at the answers under this question.
I achieved something similar to this on a recent project by creating a new menu callback – something like example.com/anon_user
– which provides a form that doubles as a login and a registration form. This allows the user to very quickly go through the registration process OR to login without making them perform too many actions. It's actually been received fairly well.
Here's some simplified code to demonstrate this:
function example_form($form, &$form_state) {
// Don't let authenticated users use this form.
global $user;
if ($user->uid != 0) {
return MENU_ACCESS_DENIED;
}
// Let the user know what they can do.
$form['intro']['#markup'] = "Already have an account? Login here. Don't have an account? Enter your email address and create a password and we'll setup an account for you.");
$form['login'] = array(
'#type' => 'fieldset',
'user_email' => array(
'#type' => 'textfield',
'#required' => TRUE,
'#title' => t('E-mail Address'),
),
'user_pass' => array(
'#type' => 'password',
'#required' => TRUE,
'#title' => t('Password'),
),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Continue',
);
return $form;
}
Validate it however you need:
function example_form_validate(&$form, &$form_state) {
if (!valid_email_address($form_state['values']['user_email'])) {
form_set_error('user_email', 'You entered an invalid email address.');
}
}
In the submit handler, we need to figure out if this email already exists and attempt to log them in. If it doesn't exist, try to create an account for them.
function example_form_submit(&$form, &$form_state) {
global $user;
// Does this account already exist?
if ($user_name = db_query("SELECT name FROM {users} WHERE mail = :mail", array(':mail' => $form_state['values']['user_email']))->fetchField()) {
// Attempt to log them in.
if ($account_id = user_authenticate($user_name, $form_state['values']['user_pass'])) {
drupal_set_message('You have been logged in.');
$user = user_load($account_id);
} else {
drupal_set_message('You have an account here, but you entered the wrong password.', 'error');
}
}
// Create the account.
else {
// Use their email address as their username. Or handle this with a more complex login form.
$account_name = str_replace('@', '_', $form_state['values']['user_email']);
$account = user_save(null, array(
'name' => $account_name,
'pass' => $form_state['values']['user_pass'],
'mail' => $form_state['values']['user_email'],
'init' => $form_state['values']['user_email'],
'status' => 1,
'access' => REQUEST_TIME,
));
// Log 'em in to their new account.
drupal_set_message('Your account has been created and you have been successfully logged in!');
);
$user = user_load(user_authenticate($account->name, $form_state['values']['user_pass']));
}
}
This is a pretty simple example. You could add password requirements, password confirmation via a 2nd field, a username field, better warnings, etc. The more restrictions the longer the process, so that's something to keep in mind.
There are many ways you can go about lowering the "registration hurdle":
- use Facebook connect to allow login with a facebook account (I use and like fboauth module)
- there are other social login modules that support google, paypal, yahoo, openid, etc.
- you can change the registration option to not require email confirmations.
To answer your last question:
What direction or recipe would you suggest to achieve the functionality? Of course the ultimate goal here is to allow anon users to post; create an account behind the scenes for future use; allow use of the anon form even for users with emails that already have accounts (and assign content accordingly.) all while maintaining the security (from spam, bots) that is afforded by having a user sign up and authenticate an account.
I suggest to use a "anonymous node registration" feature (I can share code if you like). I adds "name" and "email address" fields to a "node add" form.
If the email doesn't exist already it will create a new user account. It uses the firstname to create the username and adds numbers if necessary to make it unique.
The password is set randomly and displayed to the user after submitting the node with a link to change the password.
Also, email confirmations won't prevent spam bots from signing up. I highly recommend the spambot module.