'User domains', 'type' => MENU_LOCAL_TASK, 'access arguments' => array('administer domains'), 'page callback' => 'drupal_get_form', 'page arguments' => array('domain_user_configure_form'), 'file' => 'domain_user.admin.inc' ); return $items; } /** * Implement hook_perm() */ function domain_user_perm() { return array('create personal domain', 'create user domains'); } /** * 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 && empty($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); if (!empty($rules)) { 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) { $account->content['summary']['domain_user'] = array( '#type' => 'user_profile_item', '#title' => t('Personal web site'), '#weight' => 6, '#value' => l($domain['path'], $domain['path']), ); } 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); } else { $account->uid = 0; $account->roles = array(0 => t('anonymous user')); } // 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', $account) || user_access('create user domains')) { // For the add user page, we force the checkbox. if (empty($account->uid) && arg(0) == 'admin' && $create_domain == 1) { $create_domain = 2; } 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_access('create user domains'))) { $user_root = variable_get('domain_user_root', variable_get('domain_root', '')); $name = domain_user_strip_chars($account->name); $form_state['values']['sitename'] = $account->name; $form_state['values']['subdomain'] = $name .'.'. $user_root; $form_state['values']['valid'] = $account->status; $form_state['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, 'ignore_domain_status_check' => TRUE); // Include the form file. include_once drupal_get_path('module', 'domain') .'/domain.admin.inc'; // Set the scheme as needed. $form_state['values']['domain_scheme'] = variable_get('domain_user_scheme', 'http'); drupal_execute('domain_form', $form_state, array(), $arguments); $domain = domain_lookup(NULL, $form_state['values']['subdomain'], TRUE); if ($domain['domain_id']) { db_query("INSERT INTO {domain_user} (domain_id, uid) VALUES (%d, %d)", $domain['domain_id'], $account->uid); // If this user has never registered before, or settings require it, remove other domain editing permissions. if (empty($account->login) || !variable_get('domain_user_assign', 0)) { db_query("DELETE FROM {domain_editor} WHERE uid = %d", $account->uid); } db_query("INSERT INTO {domain_editor} (domain_id, uid) 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'] > 0) { // 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 = %d WHERE domain_id = %d", 0, $domain['domain_id']); } } } if (isset($edit['domain_create_user']) && !(user_access('create personal domain', $account) || user_access('create user domains'))) { 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' && isset($edit['name']) && $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, $form_state = 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 (isset($form_state['values']['subdomain']) && $domain['subdomain'] != $form_state['values']['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']); // Move from user domain to default domain for {domain_editor} $check = db_result(db_query("SELECT COUNT(uid) FROM {domain_editor} WHERE uid = %d AND domain_id = 0", $domain['uid'])); if (empty($check)) { db_query("INSERT INTO {domain_editor} (domain_id, uid) VALUES (0, %d)", $domain['uid'], $domain['domain_id']); } else { db_query("DELETE FROM {domain_editor} WHERE uid = %d AND domain_id = %d", $domain['uid'], $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 (!empty($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 (isset($domain['uid'])) { $account = user_load(array('uid' => $domain['uid'])); return l($account->name, 'user/'. $account->uid); } break; } }