t('User domains'),
'path' => 'admin/build/domain/user',
'type' => MENU_LOCAL_TASK,
'access' => user_access('administer domains'),
'callback' => 'drupal_get_form',
'callback arguments' => array('domain_user_configure_form')
);
}
return $items;
}
/**
* Implement hook_perm()
*/
function domain_user_perm() {
return array('create personal domain');
}
/**
* FormsAPI
*/
function domain_user_configure_form() {
drupal_set_title(t('User domain settings'));
$form = array();
$form['domain_user'] = array(
'#type' => 'radios',
'#title' => t('Module behavior'),
'#options' => array(0 => t('Do not create domains for users'), 1 => t('Automatically create domains for new users'), 2 => t('Ask users if they would like to create a domain')),
'#description' => t('Should subdomains be created when users register?'),
'#default_value' => variable_get('domain_user', 0),
);
$form['domain_user_root'] = array(
'#type' => 'textfield',
'#title' => t('Root domain name'),
'#size' => 40,
'#maxlength' => 80,
'#required' => TRUE,
'#default_value' => variable_get('domain_user_root', variable_get('domain_root', '')),
'#description' => t('The root domain to use for creating user domains, typically example.com. No http or slashes.
When users create domains, their username will be added to the root domain to create a custom domain.
For example, user1.example.com or administrator.example.com.')
);
$form['domain_user_scheme'] = array(
'#type' => 'radios',
'#title' => t('User Domain URL scheme'),
'#options' => array('http' => 'http://', 'https' => 'https://'),
'#default_value' => variable_get('domain_user_scheme', 'http'),
'#description' => t('The URL scheme for accessing user domains.')
);
$form['domain_user_login'] = array(
'#type' => 'radios',
'#title' => t('User login behavior'),
'#options' => array(1 => t('On login, go to personal domain'), 0 => t('Do not go to personal domain on login')),
'#default_value' => variable_get('domain_user_login', 1),
'#description' => t('The domain users should go to when they login to the site.')
);
if (module_exists('domain_prefix')) {
$form['domain_user_prefixing'] = array(
'#type' => 'radios',
'#title' => t('Domain table prefixing'),
'#options' => array(0 => t('Never create prefixed tabled for user domains'), 1 => t('Obey the settings in Domain Prefix')),
'#description' => t('Should user domains have detabase talbes created?'),
'#default_value' => variable_get('domain_user_prefixing', 0),
);
}
// Show the rules for username restrictions
$rules = domain_user_rules();
if (!empty($rules)) {
$output = '
The following usernames cannot be registered, since they are used as unique subdomains:
') . $output, ); return system_settings_form($form); } /** * Checks for existing domains to create rules * * @param $generate * A boolean flag indicating whether to generate {access} table entries based on * the current domain set. Default to TRUE. * @return * An array of reserved name strings or an empty array. */ function domain_user_rules($generate = TRUE) { // Find domains that are not user domains. These are blacklisted in user rules. // We set the $reset flag to TRUE, to be sure we catch all changes. $domains = domain_domains(TRUE); $reserved = array(); // Get the root user domain. $root = variable_get('domain_user_root', variable_get('domain_root', '')); foreach ($domains as $domain) { if ($domain['domain_id'] > 0 && !$domain['uid'] && !empty($root)) { // Chop the name of domains to find the username equivalent. $string = str_replace('.'. $root, '', $domain['subdomain']); // In this case, we do strip port protocols, since they make no sense as usernames. $str = explode(':', $string); $name_string = $str[0]; $reserved[] = $name_string; if ($generate && !empty($name_string)) { $check = db_result(db_query("SELECT aid FROM {access} WHERE mask = '%s'", $name_string)); if (!$check) { db_query("INSERT INTO {access} (mask, type, status) VALUES ('%s', '%s', %d)", $name_string, 'user', 0); } } } } return $reserved; } /** * Implement hook_enable() * * When the module is enabled, create the rules for existing domains. */ function domain_user_enable() { domain_user_rules(); } /** * Implement hook_disable() * * Deletes our user access masks. */ function domain_user_disable() { $rules = domain_user_rules(FALSE); foreach ($rules as $rule) { db_query("DELETE FROM {access} WHERE mask = '%s'", $rule); } } /** * Implement hook_domainload() */ function domain_user_domainload(&$domain) { // Zero is the default domain, and we don't want to invalidate it. if ($domain['domain_id'] > 0) { $data = db_fetch_array(db_query("SELECT du.uid, u.status FROM {domain_user} du INNER JOIN {users} u ON du.uid = u.uid WHERE du.domain_id = %d", $domain['domain_id'])); if ($data['uid']) { $domain['uid'] = $data['uid']; } } } /** * Implement hook_user() */ function domain_user_user($op, &$edit, &$account, $category = NULL) { switch ($op) { case 'view': $domain = domain_user_lookup($account->uid); if ($domain != -1) { $items['domain'] = array( 'title' => t(''), 'value' => l($domain['path'], $domain['path']), 'class' => '' ); return array(t('Personal web site') => $items); } break; case 'register': case 'form': // This function will return -1 if no domain exists. If no user exists yet, assume -1. $domain = -1; if (isset($account->uid)) { $domain = domain_user_lookup($account->uid); } // New users throw E_ALL errors. $name = t('username'); if (isset($account->name)) { // Sanitize the username according to the host RFC. $name = domain_user_strip_chars($account->name); } $default = domain_default(); $root = variable_get('domain_user_root', $default['subdomain']); // If the user name is on the ban list, we do not create a domain. // TODO: Maybe we should set a message here. if ($domain == -1 && domain_lookup(NULL, $name .'.'. $root) == -1) { $create_domain = variable_get('domain_user', 0); if (user_access('create personal domain')) { if ($create_domain == 1 && !empty($root)) { $form['domain_user_domain']['domain_create_user'] = array( '#type' => 'value', '#value' => 1, ); } else if ($create_domain == 2 && !empty($root)) { $form['domain_user_domain'] = array( '#type' => 'fieldset', '#title' => t('Personal web site'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#weight' => 1 ); $form['domain_user_domain']['domain_create_user'] = array( '#type' => 'checkbox', '#return_value' => 1, '#title' => t('Yes, I want to create my own site at !user.!site', array('!user' => $name, '!site' => $root)), ); } return $form; } } break; case 'insert': case 'update': // If we did not come from our expected form, do nothing. if (!isset($edit['domain_create_user'])) { return; } if (!empty($edit['domain_create_user']) && user_access('create personal domain', $account)) { $user_root = variable_get('domain_user_root', variable_get('domain_root', '')); $name = domain_user_strip_chars($account->name); $form_values['sitename'] = $account->name; $form_values['subdomain'] = $name .'.'. $user_root; $form_values['valid'] = $account->status; $form_values['user_submitted'] = TRUE; // This function will return -1 if no domain exists. $domain = domain_user_lookup($account->uid); if ($domain == -1) { // Set arguments to be passed to the form $arguments = array('user_submitted' => TRUE); // Include the form file. include_once(drupal_get_path('module', 'domain') .'/domain_admin.inc'); // Set the scheme as needed. $form_values['domain_scheme'] = variable_get('domain_user_scheme', 'http'); drupal_execute('domain_create_form', $form_values, $arguments); $domain = domain_lookup(NULL, $form_values['subdomain'], TRUE); if ($domain['domain_id']) { db_query("INSERT INTO {domain_user} VALUES (%d, %d)", $domain['domain_id'], $account->uid); $edit['domains'][] = $domain['domain_id']; drupal_set_message(t('Your personal URL is !url.', array('!url' => url($domain['path'])))); } else { drupal_set_message(t('Your personal URL could not be created.')); } } // Set the user's default domain to their subdomain. if ($domain['domain_id']) { // If the user cannot assign domain editors, only allow their unique domain. if (!user_access('assign domain editors')) { $edit['domain_user'] = array(); } $edit['domain_user'][$domain['domain_id']] = $domain['domain_id']; // If the user account is blocked, set the domain to invalid. if ($account->status == 0) { db_query("UPDATE {domain} SET valid = 0 WHERE domain_id = %d", $domain['domain_id']); } } } if ($edit['domain_create_user'] && !user_access('create personal domain', $account)) { drupal_set_message(t('Your personal URL could not be created.')); } // Throw away what we do not need. $edit['domain_create_user'] = NULL; $edit['domains'] = NULL; // Special case if the username has changed. if ($op == 'update' && $edit['name'] != $account->name) { $domain = domain_user_lookup($account->uid, TRUE); if ($domain != -1) { $user_root = variable_get('domain_user_root', variable_get('domain_root', '')); $name = domain_user_strip_chars($edit['name']); $string = $name .'.'. $user_root; db_query("UPDATE {domain} SET subdomain = '%s', sitename = '%s' WHERE domain_id = %d", $string, $edit['name'], $domain['domain_id']); } } break; case 'login': // If the user has a personal domain, take them there. $domain = domain_user_lookup($account->uid); if (variable_get('domain_user_login', 1) && $domain != -1) { // We cannot do a redirect on login, which forces us to use a $_SESSION variable. // Only store the uid here, no need to store extra data where it can get hijacked. $_SESSION['domain_user'] = $account->uid; } break; case 'delete': // Delete the record // Run the lookup before we delete the row! $domain = domain_user_lookup($account->uid); if ($domain != -1) { db_query("DELETE FROM {domain} WHERE domain_id = %d", $domain['domain_id']); // Let other modules act. module_invoke_all('domainupdate', 'delete', $domain); } break; } } /** * Turn a user name into a domain-safe string. * * @param $name * The user name to process. * @return * A string with only alphanumeric characters and dashes. */ function domain_user_strip_chars($name) { // Only alphanumeric characters are allowed. $pattern = '/[^a-zA-Z0-9]/'; $name = preg_replace($pattern, '-', $name); return strtolower($name); } /** * Implement hook_domainupdate() */ function domain_user_domainupdate($op, $domain = array(), $edit = array()) { $root = variable_get('domain_user_root', variable_get('domain_root', '')); switch ($op) { case 'update': // If these are different, then we must delete a row from {access}. if ($domain['subdomain'] != $edit['subdomain']) { $mask = str_replace('.'. $root, '', $domain['subdomain']); db_query("DELETE FROM {access} WHERE mask = '%s'", $mask); } domain_user_rules(); break; case 'delete': // Delete from {domain_user} db_query("DELETE FROM {domain_user} WHERE domain_id = %d", $domain['domain_id']); // Delete from the access rules. $user_root = variable_get('domain_user_root', variable_get('domain_root', '')); $mask = str_replace('.'. $user_root, '', $domain['subdomain']); db_query("DELETE FROM {access} WHERE mask = '%s'", $mask); break; } } /** * Check to see if a user has created a domain record * * @param $uid * The user id of the domain to be checked. Optional. * @param $name * The username of the domain to be checked. Optional. * @param $domain_id * The domain_id taken from {domain}. Optional. * @param $clear * A boolean flag to clear the static variable if necessary. Not used. Here for consistency. */ function domain_user_lookup($uid = NULL, $name = NULL, $domain_id = NULL, $clear = FALSE) { if ($uid) { $id = db_result(db_query("SELECT domain_id FROM {domain_user} WHERE uid = %d", $uid)); } else if ($name) { $id = db_result(db_query("SELECT du.domain_id FROM {domain_user} du INNER JOIN {users} u ON du.uid = u.uid WHERE u.name = '%s'", $name)); } else if ($domain_id) { $id = db_result(db_query("SELECT domain_id FROM {domain_user} WHERE domain_id = %d", $domain_id)); } if ($id) { $return = domain_lookup($id); } else { $return = -1; } return $return; } /** * Implement hook_domainview() */ function domain_user_domainview($op, $domain = array()) { switch ($op) { case 'header': return array(array('data' => t('User'), 'field' => 'du.uid')); break; case 'select': return 'du.uid'; case 'join': return "LEFT JOIN {domain_user} du ON du.domain_id = d.domain_id"; break; case 'data': if ($domain['uid']) { $account = user_load(array('uid' => $domain['uid'])); return l($account->name, 'user/'. $account->uid); } break; } }