'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;
}
}