View source
<?php
include 'hosting_client.access.inc';
include drupal_get_path('module', 'node') . '/node.pages.inc';
define('MAX_GROUP_LENGTH', 16);
function hosting_client_node_info() {
$types["client"] = array(
"type" => 'client',
"name" => 'Client',
"module" => 'hosting_client',
"has_title" => TRUE,
"title_label" => 'Client name',
"description" => hosting_node_help("client"),
"has_body" => 0,
"body_label" => '',
"min_word_count" => 0,
);
return $types;
}
function hosting_client_theme($existing, $type, $theme, $path) {
return array(
'hosting_client_user_form' => array(
'file' => 'hosting_client.access.inc',
'arguments' => array(
'form' => NULL,
),
),
'hosting_client_form' => array(
'file' => 'hosting_client.module',
'arguments' => array(
'form' => NULL,
),
),
);
}
function hosting_client_perm() {
return array(
'create client',
'view client',
'edit own client',
'delete own client',
'administer clients',
'edit client users',
'edit client uname',
);
}
function hosting_client_access($op, $node, $account) {
if (!hosting_feature('client')) {
return FALSE;
}
if (user_access('administer clients', $account)) {
return TRUE;
}
else {
switch ($op) {
case 'create':
return user_access('create client', $account);
break;
case 'view':
return user_access('view client', $account) && db_fetch_array(db_query("SELECT user FROM {hosting_client_user} WHERE user=%d and client=%d", $account->uid, $node->nid));
case 'update':
if (user_access('edit own client', $account) && $account->uid == $node->uid) {
return TRUE;
}
break;
case 'delete':
if (user_access('delete own client', $account) && $account->uid == $node->uid) {
return TRUE;
}
break;
default:
break;
}
}
}
function hosting_get_client($client) {
if (is_numeric($client)) {
$result = db_result(db_query("SELECT n.nid FROM {hosting_client} h INNER JOIN {node} n ON n.nid = h.nid WHERE n.nid = %d", $client));
}
else {
$result = db_result(db_query("SELECT c.nid FROM {hosting_client} c JOIN {node} n ON c.nid = n.nid WHERE n.title = '%s' AND n.type = 'client'", $client));
}
if ($result) {
return node_load($result);
}
return false;
}
function hosting_get_client_by_uname($uname) {
$result = db_result(db_query("SELECT c.nid FROM {hosting_client} c JOIN {node} n ON c.nid = n.nid WHERE c.uname = '%s' AND n.type = 'client'", $uname));
if ($result) {
return node_load($result);
}
else {
return false;
}
}
function hosting_get_client_by_email($email) {
$caller = next(debug_backtrace());
trigger_error(t("@function() is deprecated and may yield undefined results, replace with @newfunction(), called from @caller in @file", array(
'@file' => $caller['file'] . ':' . $caller['line'],
'@caller' => $caller['function'],
'@function' => __FUNCTION__,
'@newfunction' => 'hosting_get_client',
)), E_USER_DEPRECATED);
$result = db_result(db_query("SELECT c.nid FROM {hosting_client} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.email = '%s'", $email));
if ($result) {
return node_load($result);
}
return false;
}
function hosting_client_form(&$node) {
$type = node_get_types('type', 'client');
$form['title'] = array(
'#type' => 'textfield',
'#title' => $type->title_label,
'#required' => TRUE,
'#size' => 40,
'#default_value' => $node->title,
'#maxlength' => 100,
'#description' => t('The name of this client, generally the organization name or the contact name for individuals.'),
);
$form['uname'] = array(
'#type' => 'textfield',
'#title' => t('Internal name'),
'#size' => MAX_GROUP_LENGTH,
'#maxlength' => MAX_GROUP_LENGTH,
'#default_value' => $node->uname,
'#access' => user_access('edit client uname'),
'#description' => t('A machine-usable name that can be used internally, for example to map to a UNIX group in the backend. It is unique accross the system. If no value is provided, it is deduced from the client name, by stripping spaces and metacharacters and adding a prefix (%prefix).', array(
'%prefix' => variable_get('hosting_client_prefix', 'no prefix define'),
)),
);
if (!$node->nid && variable_get('hosting_client_register_user', FALSE)) {
$form['email'] = array(
'#type' => 'textfield',
'#title' => t('Email address'),
'#description' => t('Email address of the contact created with this client. Optional - if none is provided, no user will be created with this client.'),
'#required' => FALSE,
'#size' => 40,
'#default_value' => $node->email,
'#maxlength' => 100,
);
$form['email_confirm'] = array(
'#type' => 'textfield',
'#title' => t('Confirm Email address'),
'#required' => FALSE,
'#size' => 40,
'#maxlength' => 100,
);
}
if ($node->nid) {
$users = hosting_client_users($node);
foreach ($users as $uid => $uname) {
$form['user_edit']['name'][$uid] = array(
'#type' => 'markup',
'#value' => l($uname, 'user/' . $uid),
);
$user_list[$uid] = '';
}
if (user_access('edit client users')) {
$form['user_edit']['users'] = array(
'#type' => 'checkboxes',
'#options' => $user_list,
);
}
$form['user_edit']['header'] = array(
'#type' => 'value',
'#value' => array(
array(
'data' => t('Allowed users'),
),
array(
'data' => t('Remove'),
),
),
);
if (user_access('edit client users')) {
$form['user_edit']['new_user'] = array(
'#type' => 'textfield',
'#title' => t('Associate a user to this Client'),
'#weight' => 2,
'#autocomplete_path' => 'user/autocomplete',
'#description' => t('This field allows you to associate an existing system user to this Client.
It does not create a new system user, but allows an existing user
to manage sites belonging to the Client.'),
);
}
$form['user_edit']['#theme'] = 'hosting_client_form';
}
else {
global $user;
$form['new_user'] = array(
'#type' => 'value',
'#value' => $user->name,
);
}
return $form;
}
function theme_hosting_client_form($form) {
foreach (element_children($form['name']) as $user) {
$row = array();
$row['data'][] = drupal_render($form['name'][$user]);
if (user_access('edit client users')) {
$row['data'][] = drupal_render($form['users'][$user]);
}
$rows[] = $row;
}
$output = theme('table', $form['header']['#value'], $rows);
$output .= drupal_render($form);
return $output;
}
function hosting_client_validate(&$node) {
if ($node->uname) {
$node->uname = hosting_client_sanitize($node->uname);
}
else {
$node->uname = hosting_client_sanitize($node->title);
}
$nid = db_result(db_query("SELECT nid FROM {hosting_client} WHERE uname LIKE '%s'", addcslashes($node->uname, '\\%_')));
if ($nid && $node->nid != $nid) {
$suggestion = hosting_client_validate_suggest($node);
if ($suggestion) {
form_set_error('title', t("Client name already in use, try %suggestion.", array(
'%suggestion' => $suggestion,
)));
}
else {
form_set_error('title', t("Client name already in use."));
}
}
if (!$node->nid && $node->email) {
$user = user_load(array(
'mail' => $node->email,
));
if ($user) {
form_set_error('email', t("Email address already exists."));
}
if ($node->email != $node->email_confirm) {
form_set_error('email_confirm', t("Email addresses do not match"));
}
if (!valid_email_address($node->email)) {
form_set_error('email', t("Email address invalid."));
}
}
}
function hosting_client_validate_suggest($node) {
$suggestion = FALSE;
for ($i = 0; $i < 10; $i++) {
$nid = db_result(db_query("SELECT nid FROM {hosting_client} WHERE uname LIKE '%s%%'", addcslashes(hosting_client_sanitize($node->title) . $i, '\\%_')));
if (!$nid) {
$suggestion = $node->title . $i;
break;
}
}
return $suggestion;
}
function hosting_client_insert($node) {
if ($node->uname) {
$node->uname = hosting_client_sanitize($node->uname);
}
else {
$node->uname = hosting_client_sanitize($node->title);
}
db_query("INSERT INTO {hosting_client} (vid, nid, uname) VALUES (%d, %d, '%s' )", $node->vid, $node->nid, $node->uname);
if (variable_get('hosting_client_register_user', FALSE) && !user_load(array(
'mail' => $node->email,
))) {
$user = hosting_client_register_user($node);
$node->uid = $user->uid;
db_query("UPDATE {node} SET uid = %d WHERE nid = %d", $user->uid, $node->nid);
db_query("UPDATE {node_revisions} SET uid = %d WHERE vid = %d", $user->uid, $node->vid);
}
if (isset($node->new_user)) {
$user = user_load(array(
'name' => $node->new_user,
));
if ($user) {
db_query("INSERT INTO {hosting_client_user} (client, user, contact_type) VALUES (%d, %d, '%s')", $node->nid, $user->uid, '');
}
}
}
function _hosting_client_get_role() {
return db_result(db_query("SELECT rid FROM {role} WHERE name='aegir client'"));
}
function hosting_client_register_user($node) {
$pass = user_password();
$user = new stdClass();
$edit['name'] = $node->email;
$edit['hosting_client'] = $node->nid;
$edit['mail'] = $node->email;
$edit['pass'] = $pass;
$edit['status'] = 1;
$edit['roles'][_hosting_client_get_role()] = TRUE;
$user = user_save($user, $edit);
if ($user->uid && variable_get('hosting_client_send_welcome', FALSE)) {
if ($node->client_name) {
$to = sprintf("%s <%s>", $node->client_name, $node->email);
}
else {
$to = $node->email;
}
$params = array(
'!username' => $user->name,
'!site' => variable_get('site_name', 'Drupal'),
'!password' => $pass,
'!uri' => $GLOBALS['base_url'],
'!uri_brief' => substr($base_url, strlen('http://')),
'!date' => format_date(time()),
'!login_uri' => url('user', array(
'absolute' => TRUE,
)),
'!edit_uri' => url('user/' . $user->uid . '/edit', array(
'absolute' => TRUE,
)),
'!login_url' => user_pass_reset_url($user),
);
$language = user_preferred_language($user);
drupal_mail('hosting_client', 'hosting-client-register-welcome', $to, $language, $params);
}
return $user;
}
function hosting_client_mail($key, &$message, $params) {
switch ($key) {
case 'hosting-client-register-welcome':
$message['subject'] = _hosting_client_mail_text('welcome_subject', $params);
$message['body'] = _hosting_client_mail_text('welcome_body', $params);
break;
}
}
function hosting_client_update($node) {
if ($node->revision) {
hosting_client_insert($node);
}
else {
if ($node->uname) {
$node->uname = hosting_client_sanitize($node->uname);
}
else {
$node->uname = hosting_client_sanitize($node->title);
}
db_query("UPDATE {hosting_client} SET nid=%d, uname='%s' WHERE vid=%d", $node->nid, $node->uname, $node->vid);
}
if ($node->users) {
foreach ($node->users as $user) {
db_query('DELETE FROM {hosting_client_user} WHERE user = %d AND client = %d', $user, $node->nid);
}
}
if ($node->new_user) {
$user = user_load(array(
'name' => $node->new_user,
));
db_query('INSERT INTO {hosting_client_user} (client, user, contact_type) VALUES (%d, %d, "%s")', $node->nid, $user->uid, '');
}
}
function hosting_nodeapi_client_delete_revision(&$node) {
db_query('DELETE FROM {hosting_client} WHERE vid = %d', $node->vid);
}
function hosting_client_delete($node) {
db_query('DELETE FROM {hosting_client} WHERE nid = %d', $node->nid);
}
function hosting_client_load($node) {
$additions = db_fetch_object(db_query('SELECT uname FROM {hosting_client} WHERE vid = %d', $node->vid));
return $additions;
}
function hosting_client_node_load($arg) {
if (!is_numeric($arg)) {
return FALSE;
}
if ($node = node_load($arg)) {
if ($node->type == 'client') {
return $node;
}
}
return FALSE;
}
function hosting_client_users($node) {
if (is_object($node)) {
$node = $node->nid;
}
elseif (!is_numeric($node)) {
return array();
}
$users = array();
$q = db_query("SELECT u.uid, u.name FROM {hosting_client_user} h INNER JOIN {users} u ON u.uid = h.user WHERE h.client = %d", $node);
while ($result = db_fetch_array($q)) {
$users[$result['uid']] = $result['name'];
}
return $users;
}
function hosting_client_view($node, $teaser = FALSE, $page = FALSE) {
$type = node_get_types('type', $node);
$node->content['info']['#prefix'] = '<div id="hosting-client-info">';
$node->content['info']['title'] = array(
'#type' => 'item',
'#title' => $type->title_label,
'#value' => filter_xss($node->title),
);
$node->content['info']['uname'] = array(
'#type' => 'item',
'#title' => t('Internal name'),
'#weight' => 1,
'#value' => filter_xss($node->uname),
);
$node->content['info']['#suffix'] = '</div>';
if ($page) {
$node->content['sites_view'] = array(
'#type' => 'item',
'#value' => drupal_get_form('hosting_site_list_form', 'client', $node->nid),
'#prefix' => '<div id="hosting-site-list">',
'#suffix' => '</div>',
'#weight' => 10,
);
$users = hosting_client_users($node);
foreach ($users as $uid => $uname) {
if (user_access('access user profiles') || $uid == $GLOBALS['user']->uid) {
$rows[] = array(
l($uname, 'user/' . $uid),
);
}
else {
$rows[] = array(
$uname,
);
}
}
$header = array(
t('Allowed users'),
);
$node->content['users_view'] = array(
'#type' => 'item',
'#value' => theme('table', $header, $rows),
'#class' => 'client',
'#prefix' => '<div id="hosting-site-list">',
'#suffix' => '</div>',
'#weight' => 11,
);
}
return $node;
}
function hosting_import_client($name, $organization = '') {
$client = hosting_get_client_by_uname($name);
if (!$client) {
$client = hosting_get_client($name);
}
if (!$client) {
$client = hosting_get_client_by_email($name);
}
if (!$client) {
$client = new stdClass();
$client->type = 'client';
$client->uid = 1;
$client->title = trim($name);
$client->status = 1;
node_save($client);
}
return $client;
}
function hosting_client_menu() {
$items['node/%node/site/add'] = array(
'title' => 'Add site',
'description' => 'Add a site to the current client',
'page callback' => 'hosting_client_site_form',
'page arguments' => array(
'site_node_form',
1,
),
'access callback' => 'hosting_client_menu_access',
'access arguments' => array(
'create site',
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
);
$items['hosting_client/autocomplete'] = array(
'title' => 'hosting client get client autocomplete',
'page callback' => 'hosting_client_autocomplete',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
$items['admin/hosting/client'] = array(
'title' => 'Clients',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'hosting_client_configure',
),
'access callback' => '_hosting_client_configure_access',
'type' => MENU_LOCAL_TASK,
);
return $items;
}
function _hosting_client_site_default($node) {
global $user;
$current_client_id = 0;
if ($user->uid) {
$client_ids = hosting_get_client_from_user($user->uid);
$clients = array();
foreach ($client_ids as $client_id => $client_permissions) {
$client_id = $client_id ? $client_id : HOSTING_DEFAULT_CLIENT;
$client = node_load($client_id);
$clients[$client->title] = $client->title;
if ($node->client == $client_id || !$current_client_id) {
$current_client_id = $client_id;
}
}
if (!$current_client_id && !user_access('administer clients')) {
form_set_error('client', t('Your user is not associated with any clients so you are not allowed to create new sites'));
}
}
if (!$current_client_id) {
$current_client_id = HOSTING_DEFAULT_CLIENT;
}
if ($node->client && user_access('administer clients')) {
$current_client_id = $node->client;
}
$client = node_load($current_client_id);
if (!$client) {
$client = new stdClass();
$client->title = $node->client;
}
return $client->title;
}
function hosting_client_site_form($form, $node) {
$site = new stdClass();
$site->type = 'site';
$site->client = $node->nid;
return drupal_get_form('site_node_form', $site);
}
function hosting_client_menu_access($perm, $node) {
if ($node->type == 'client') {
return user_access($perm);
}
else {
return false;
}
}
function _hosting_client_configure_access() {
return user_access('administer clients') && hosting_feature('client');
}
function _hosting_client_mail_text($messageid, $variables = array()) {
if ($admin_setting = variable_get('hosting_client_mail_' . $messageid, FALSE)) {
return strtr($admin_setting, $variables);
}
switch ($messageid) {
case 'welcome_subject':
return t('Account details for !username at !site', $variables);
case 'welcome_body':
return t("!username,\n\nThank you for registering at !site. You may now log in to !login_uri using the following username and password:\n\nusername: !username\npassword: !password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n!login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to !edit_uri so you can change your password.\n\n\n-- !site team", $variables);
}
}
function hosting_client_configure() {
$form['hosting_client_prefix'] = array(
'#type' => 'textfield',
'#title' => t('Client internal name prefix'),
'#description' => t('Client nodes have an internal name that can be mapped to a UNIX group. This is the prefix assigned to that internal name to make sure it is in a separate namespace. Note that UNIX groups are generally limited to 16 characters so this prefix should be kept short. It can also be empty, in which case no prefix will be added.'),
'#default_value' => variable_get('hosting_client_prefix', ''),
'#size' => 5,
'#maxlength' => 16,
);
$form['hosting_client_register_user'] = array(
'#type' => 'checkbox',
'#title' => t('Automatically create user accounts for new clients.'),
'#description' => t('If this setting is on, any new client nodes will automatically have a system user account generated for them, and associated with the new client node. Users going through the signup form module have a user created regardless of this setting.'),
'#default_value' => variable_get('hosting_client_register_user', FALSE),
);
$form['email'] = array(
'#type' => 'fieldset',
'#title' => t('User e-mail settings'),
);
$form['email']['hosting_client_send_welcome'] = array(
'#type' => 'checkbox',
'#title' => t('Send welcome mail to new clients.'),
'#description' => t('If this setting is on, new clients will receive a welcome email containing their login details.'),
'#default_value' => variable_get('hosting_client_send_welcome', FALSE),
);
$form['email']['hosting_client_mail_welcome_subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject of welcome e-mail'),
'#default_value' => _hosting_client_mail_text('welcome_subject'),
'#maxlength' => 180,
'#description' => t('Customize the subject of your welcome e-mail, which is sent to new members upon registering.') . ' ' . t('Available variables are:') . ' !username, !site, !password, !uri, !uri_brief, !date, !login_uri, !edit_uri, !login_url.',
);
$form['email']['hosting_client_mail_welcome_body'] = array(
'#type' => 'textarea',
'#title' => t('Body of welcome e-mail'),
'#default_value' => _hosting_client_mail_text('welcome_body'),
'#rows' => 15,
'#description' => t('Customize the body of the welcome e-mail, which is sent to new members upon registering.') . ' ' . t('Available variables are:') . ' !username, !site, !password, !uri, !uri_brief, !login_uri, !edit_uri, !login_url.',
);
return system_settings_form($form);
}
function _hosting_get_clients() {
$return = array();
$result = pager_query(db_rewrite_sql('SELECT n.nid, n.title from {node} n WHERE n.type = "client"'), 25);
while ($client = db_fetch_object($result)) {
$return[$client->nid] = $client->title;
}
return $return;
}
function hosting_client_list() {
$summary = array();
$clients = _hosting_get_clients();
return theme('item_list', array_map('_hosting_node_link', array_keys($clients)));
}
function hosting_client_block($op = 'list', $delta = 0, $edit = array()) {
$blocks = array();
switch ($op) {
case 'list':
$blocks['hosting_clients'] = array(
'info' => t('Hosting clients'),
'enabled' => 1,
'region' => 'left',
'weight' => 10,
);
break;
case 'view':
switch ($delta) {
case 'hosting_clients':
$blocks['title'] = t('Clients');
$blocks['content'] = user_access('view client') ? hosting_client_list() : '';
break;
}
}
return $blocks;
}
function hosting_client_autocomplete($type, $keyword) {
$matches = array();
if ($type == 'client') {
$query = db_query(db_rewrite_sql("SELECT * FROM {node} n WHERE type = '%s' AND title LIKE '%s%%'"), $type, addcslashes($keyword, '\\%_'));
while ($result = db_fetch_object($query)) {
$matches[$result->title] = $result->title;
}
}
drupal_json($matches);
exit;
}
function hosting_client_form_alter(&$form, $form_state, $form_id) {
if (user_access('administer clients')) {
if (hosting_feature('client') && $form_id == 'platform_node_form') {
global $user;
$node = $form["#node"];
$clients = _hosting_get_clients();
$form['clients'] = array(
'#type' => 'checkboxes',
'#title' => t('Platform access control'),
'#options' => $clients,
'#default_value' => isset($node->clients) ? $node->clients : array(),
'#description' => t('Grant access to this platform for relevant clients where required. Leave all checkboxes unchecked to grant all clients access to this platform.'),
);
}
}
}
function hosting_nodeapi_platform_load($node) {
$result = db_query("SELECT cid FROM {hosting_platform_client_access} WHERE pid = %d", $node->nid);
$additions = array();
while ($record = db_fetch_object($result)) {
$additions['clients'][$record->cid] = $record->cid;
}
return $additions;
}
function hosting_client_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'insert':
case 'update':
if ($node->type == 'platform') {
if (!empty($node->clients)) {
$clients = $node->clients;
foreach ($clients as $cid => $choice) {
if ($choice) {
$existing = db_result(db_query("SELECT cid FROM {hosting_platform_client_access} WHERE pid = %d AND cid = %d", $node->nid, $cid));
if (!$existing) {
db_query("INSERT INTO {hosting_platform_client_access} (pid, cid) VALUES (%d, %d)", $node->nid, $cid);
}
}
else {
$existing = db_result(db_query("SELECT cid FROM {hosting_platform_client_access} WHERE pid = %d AND cid = %d", $node->nid, $cid));
if ($existing) {
db_query("DELETE FROM {hosting_platform_client_access} WHERE pid = %d AND cid = %d", $node->nid, $cid);
}
}
}
}
}
break;
case 'delete':
if ($node->type == 'platform') {
db_query("DELETE FROM {hosting_platform_client_access} WHERE pid = %d", $node->nid);
}
}
}
function _hosting_get_allowed_platforms($uid = NULL, $reset = FALSE) {
static $platforms = array();
if ($reset) {
$platforms = array();
}
if (is_null($uid)) {
global $user;
$uid = $user->uid;
}
if (!isset($platforms[$uid])) {
$platforms[$uid] = array();
$result = db_query("SELECT n.nid, n.title FROM {node} n LEFT JOIN {hosting_platform} h ON n.nid = h.nid\n LEFT JOIN {hosting_platform_client_access} p ON n.nid = p.pid\n LEFT JOIN {hosting_client_user} c ON c.client = p.cid\n WHERE n.type='platform' AND n.status=1 AND h.status > '%d'\n AND (c.user= %d OR p.pid IS NULL)", HOSTING_PLATFORM_LOCKED, $uid);
while ($server = db_fetch_object($result)) {
$platforms[$uid][$server->nid] = $server->title;
}
}
return $platforms[$uid];
}
function hosting_client_sanitize($title) {
$prefix = variable_get('hosting_client_prefix', '');
$title = preg_replace("/[!\\W\\.\\-]/", "", preg_replace("/^{$prefix}/", "", $title));
return substr(strtolower($prefix . $title), 0, MAX_GROUP_LENGTH);
}
function hosting_client_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'hosting_client'),
);
}