You are here

hosting_signup.module in Hosting 5

Provides a signup form that can be run on remote sites

File

signup/hosting_signup.module
View source
<?php

/**
 * @file Provides a signup form that can be run on remote sites
 */

/**
 * Implementation of hook_xmlrpc
 */
function hosting_signup_xmlrpc() {
  return array(
    array(
      'hosting_signup.getForm',
      'hosting_signup_get_form',
      array(
        'struct',
        'string',
        'struct',
      ),
      t("Retrieve the form to build"),
    ),
    array(
      'hosting_signup.submitForm',
      'hosting_signup_submit_form',
      array(
        'struct',
        'string',
        'struct',
      ),
      t('Submit your form'),
    ),
    array(
      'hosting_signup.validateForm',
      'hosting_signup_validate_form',
      array(
        'struct',
        'string',
        'struct',
      ),
      t('Validate your form'),
    ),
  );
}

/**
 * Implementation of hook_menu
 */
function hosting_signup_menu($may_cache) {
  if (!$may_cache) {
    global $user;
    $items[] = array(
      'path' => 'hosting/signup',
      'title' => t('Sign up for a site'),
      'description' => t('Create your own hosted site'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'hosting_signup_form',
      ),
      'access' => $user->uid == 0 && user_access('access hosting signup form'),
    );
  }
  else {
    $items[] = array(
      'path' => 'admin/hosting/signup',
      'title' => t('Signup form'),
      'description' => t('Configure the behaviour of the simplified hosting signup form'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'hosting_signup_settings',
      ),
      'access' => user_access('administer hosting signup form'),
      'type' => MENU_LOCAL_TASK,
    );
    $items[] = array(
      'path' => 'hosting/signup/get_form',
      'title' => t('Sign up for a site'),
      'description' => t('Create your own hosted site'),
      'callback' => 'hosting_signup_get_form',
      'type' => MENU_CALLBACK,
      'access' => TRUE,
    );
    $items[] = array(
      'path' => 'hosting/signup/form_populate',
      'callback' => '_hosting_signup_form_populate',
      'type' => MENU_CALLBACK,
      'access' => TRUE,
    );
    $items[] = array(
      'path' => 'hosting/signup/thanks',
      'callback' => 'hosting_signup_thanks',
      'type' => MENU_CALLBACK,
      'access' => TRUE,
    );
  }
  return $items;
}

/**
 * Menu callback for settings page
 */
function hosting_signup_settings() {
  $form['hosting_signup_uri'] = array(
    '#type' => 'textfield',
    '#title' => t('Server URI'),
    '#description' => t('The address of the hostmaster system, in the format http://masterdomain.com'),
    '#default_value' => variable_get('hosting_signup_uri', 'http://' . $_SERVER['HTTP_HOST']),
  );
  $form['hosting_signup_server_key'] = array(
    '#type' => 'textfield',
    '#title' => t('Server key'),
    '#description' => t('A unique identifier used when communicating with the server'),
    '#default_value' => variable_get('hosting_signup_server_key', ''),
  );
  return system_settings_form($form);
}

/**
 * Implementation of hook_perm
 */
function hosting_signup_perm() {
  return array(
    'administer hosting signup form',
    'access hosting signup form',
  );
}

/**
 * Populate hosting site node form element with specified arguments
 *
 * This function does a drupal_http_request to the existing form_populate callbacks and
 * passes through the information from there.
 */
function _hosting_signup_form_populate($element, $value, $value2 = null) {
  $path = "/hosting/hosting_site_form_populate/{$element}/{$value}" . ($value2 ? "/{$value2}" : "");
  $request = drupal_http_request(_hosting_signup_get_url($path));
  print $request->data;
  exit;
}

/**
 * Small helper function to provide a clean default URL
 */
function _hosting_signup_get_url($path = '/xmlrpc.php') {
  $url = variable_get('hosting_signup_uri', 'http://' . $_SERVER['HTTP_HOST']);
  $url .= $path;
  return $url;
}

/**
 * Small helper function to get the key
 */
function _hosting_signup_get_key() {
  return variable_get('hosting_signup_server_key', '');
}

/**
 * Provide a simple getter/setter for the remote form
 * 
 * This allows us to return the results from submission
 * and validation, where the return values of the function
 * are not returned in any way to the caller.
 *
 * So instead we set what we want to return with this, 
 * and return the output of this from the xmlrpc methods.
 */
function hosting_signup_singleton($data = null) {
  static $static = null;
  if ($data) {
    $static = $data;
  }
  return $static;
}

/**
 * Form callback for signup form
 *
 * This function connects to the xmlrpc method on the master
 * server to retrieve the form to be generated.
 *
 * Replaces the remote form's validation and submission callbacks with local
 * callbacks, that in turn contact the remote form to validate / process the form.
 */
function hosting_signup_form() {
  drupal_add_js(drupal_get_path('module', 'hosting_signup') . '/hosting_signup_form.js');
  $form = xmlrpc(_hosting_signup_get_url(), 'hosting_signup.getForm', _hosting_signup_get_key(), $_POST);
  $form['#action'] = '/hosting/signup';
  $form['#submit'] = array(
    'hosting_signup_form_submit' => array(),
  );
  $form['#validate'] = array(
    'hosting_signup_form_validate' => array(),
  );
  return $form;
}

/**
 * XMLRPC function to retrieve the form
 *
 * A simple function that builds the form on the remote site and 
 * sends the structured array back over the line to the local site
 */
function hosting_signup_get_form($server_key, $post = array()) {
  if ($server_key != variable_get('hosting_signup_server_key', '')) {
    $form['error'] = array(
      '#type' => 'item',
      '#value' => t("The signup form has not been correctly configured"),
    );
  }
  else {
    $form = drupal_retrieve_form('_hosting_signup_form');
    unset($form['#token']);
  }
  return $form;
}

/**
 * Local validate function for hosting_signup form.
 *
 * Passes through the values to the remote validation function
 * through the xmlrpc method.
 *
 * Sets any errors that are returned from the remote site on the local site.
 */
function hosting_signup_form_validate($form_id, $values) {
  $key = variable_get('hosting_signup_server_key', '');
  $values['form_id'] = '_hosting_signup_form';
  $return = xmlrpc(_hosting_signup_get_url(), 'hosting_signup.validateForm', $key, $values);
  if (is_array($return) && sizeof($return)) {
    foreach ($return as $field => $message) {
      form_set_error($field, $message);
    }
  }
}

/**
 * XMLRPC method for validating the form
 *
 * This prepares and validates the form with the values
 * passed to the xmlrpc method (which are actually $_POST on the local site)
 *
 * @return
 *   The result of form_get_errors()
 */
function hosting_signup_validate_form($server_key, $values = array()) {
  $form = hosting_signup_get_form($server_key, $values);
  $form['#post'] = $values;
  drupal_prepare_form('_hosting_signup_form', $form);
  drupal_validate_form('_hosting_signup_form', $form);
  return hosting_signup_singleton();
}

/**
 * Local submit function for hosting_signup_form.
 *
 * Passes through the values to the remote for submission
 * through the xmlrpc method.
 *
 * Redirects to the thank you page on success.
 */
function hosting_signup_form_submit($form_id, $values) {
  $key = variable_get('hosting_signup_server_key', '');
  $values['form_id'] = '_hosting_signup_form';
  $return = xmlrpc(_hosting_signup_get_url(), 'hosting_signup.submitForm', $key, $values);
  if (isset($return['site']['nid']) && isset($return['site']['nid'])) {
    $path = sprintf("hosting/signup/thanks/%s/%s/%s", $return['site']['title'], $return['client']['email'], $return['client']['client_name']);
    drupal_goto($path);
  }
}

/**
 * XMLRPC method for submitting a form
 *
 * This function runs on the remote site, pulls th eform definition
 * and processes the submitted form
 *
 * @return 
 *   An associative array containing both the site and client records created as arrays
 */
function hosting_signup_submit_form($server_key, $values = array()) {
  $form = hosting_signup_get_form($server_key, $values);
  $form['#post'] = $values;
  drupal_prepare_form('_hosting_signup_form', $form);
  drupal_process_form('_hosting_process_form', $form);
  return hosting_signup_singleton();
}

/**
 * Remote form definition
 *
 * This is a mixture of the client form and node form, 
 * and in the future we will be able to configure which
 * forms we want to be present.
 * 
 * This form is only indirectly access via the XMLRPC methods,
 * and not displayed directly
 */
function _hosting_signup_form() {
  $node = new stdClass();
  $form['site'] = hosting_site_form($node);
  unset($form['site']['client']);
  $form['site']['platform'] = array(
    '#type' => 'hidden',
    '#value' => HOSTING_DEFAULT_PLATFORM,
  );
  foreach (module_implements('form_alter') as $module) {
    $function = $module . '_form_alter';
    $function('site_node_form', $form['site']);
  }
  unset($form['site']['info']['client']);
  $form['client'] = hosting_client_form($node);
  foreach (module_implements('form_alter') as $module) {
    $function = $module . '_form_alter';
    $function('client_node_form', $form['client']);
  }
  $form['new_client'] = array(
    '#type' => 'value',
    '#value' => TRUE,
  );
  unset($form['client']['title']);
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t("Sign up"),
  );
  return $form;
}

/**
 * Remote form validation
 *
 * This is the actual validation that the remote form
 * does. It sets any form errors into the hosting_signup_singleton
 * so they can be propogated to the local site.
 */
function _hosting_signup_form_validate($form_id, $values) {
  $client = (object) $values;
  $client->type = 'client';
  $client->title = '';
  node_validate($client);
  $site = (object) $values;
  $site->type = 'site';
  node_validate($site);
  hosting_signup_singleton(form_get_errors());
}

/**
 * Remote form submission
 *
 * Generates the nodes and saves them into hosting_signup_singleton,
 * so the local submission function can re-act to them.
 */
function _hosting_signup_form_submit($form_id, $values) {
  $client = (object) $values;
  $client->type = 'client';
  $client->title = '';
  $client->status = 1;
  node_save($client, 'submit');
  $site = (object) $values;
  $site->type = 'site';
  $site->status = 1;
  $site->client = $client->nid;
  node_save($site);
  hosting_signup_singleton(array(
    'client' => $client,
    'site' => $site,
  ));
}

/**
 * Thank you page callback
 */
function hosting_signup_thanks($url = '', $email = '', $name = '') {
  return t("<h3>Thank you @name</h3>\n    Your site (@url) has been requested, and the moment it is ready you will receive a mail at @email\n with instructions on how to log into it.", array(
    "@name" => $name,
    "@url" => $url,
    "@email" => $email,
  ));
}

Functions

Namesort descending Description
hosting_signup_form Form callback for signup form
hosting_signup_form_submit Local submit function for hosting_signup_form.
hosting_signup_form_validate Local validate function for hosting_signup form.
hosting_signup_get_form XMLRPC function to retrieve the form
hosting_signup_menu Implementation of hook_menu
hosting_signup_perm Implementation of hook_perm
hosting_signup_settings Menu callback for settings page
hosting_signup_singleton Provide a simple getter/setter for the remote form
hosting_signup_submit_form XMLRPC method for submitting a form
hosting_signup_thanks Thank you page callback
hosting_signup_validate_form XMLRPC method for validating the form
hosting_signup_xmlrpc Implementation of hook_xmlrpc
_hosting_signup_form Remote form definition
_hosting_signup_form_populate Populate hosting site node form element with specified arguments
_hosting_signup_form_submit Remote form submission
_hosting_signup_form_validate Remote form validation
_hosting_signup_get_key Small helper function to get the key
_hosting_signup_get_url Small helper function to provide a clean default URL