You are here

hosting_platform.module in Hostmaster (Aegir) 6

Platform node type definition.

File

modules/hosting/platform/hosting_platform.module
View source
<?php

/**
 * @file
 *   Platform node type definition.
 */

/**
 * This platform has been deleted.
 */
define('HOSTING_PLATFORM_DELETED', -2);

/**
 * This platform has been locked, new sites will not be allowed to use it.
 */
define('HOSTING_PLATFORM_LOCKED', -1);

/**
 * This platform has been queued for creation.
 */
define('HOSTING_PLATFORM_QUEUED', 0);

/**
 * This platform is created and enabled, sites may be deployed on it.
 */
define('HOSTING_PLATFORM_ENABLED', 1);

/**
 * Implementation of hook_menu().
 */
function hosting_platform_menu() {
  $items = array();
  $items['hosting/platforms'] = array(
    'title' => 'Platforms',
    'description' => 'List of platforms',
    'page callback' => 'hosting_platform_listing',
    'access arguments' => array(
      'view platform',
    ),
  );
  return $items;
}

/**
 * Implementation of hook_node_info().
 */
function hosting_platform_node_info() {

  #configuration
  $types["platform"] = array(
    "type" => 'platform',
    "name" => 'Platform',
    "module" => 'hosting_platform',
    "has_title" => TRUE,
    "title_label" => t('Name'),
    "description" => hosting_node_help("platform"),
    "has_body" => 0,
    "body_label" => '',
    "min_word_count" => 0,
  );
  return $types;
}

/**
 * Implementation of hook_hosting_tasks().
 */
function hosting_platform_hosting_tasks() {
  $tasks = array();
  $tasks['platform']['verify'] = array(
    'title' => t('Verify'),
    'description' => t('Verify that the platform is correctly installed and working.'),
    'weight' => 10,
    'provision_save' => TRUE,
  );
  $tasks['platform']['delete'] = array(
    'title' => t('Delete'),
    'description' => t('Deleting this platform will completely remove it from the hosting system.
        This process can not be undone. It can not be performed if you have sites currently
        running on this platform.
        Are you really sure you want to delete this platform?'),
    'weight' => 10,
    'dialog' => TRUE,
  );
  $tasks['platform']['lock'] = array(
    'title' => t('Lock'),
    'description' => t('Locking this platform will not delete or disable it or its sites, but will
        prevent any new sites from being created on it. This may be useful when you have sites that
        cannot be migrated onto a newer platform, but you wish to prevent other administrators or
        clients from continuing to provision on this platform. The platform can be unlocked later.
        Are you really sure you want to lock this platform?'),
    'weight' => 10,
  );
  $tasks['platform']['unlock'] = array(
    'title' => t('Unlock'),
    'description' => t('Unlocking this platform will allow sites to be provisioned on it.
        Are you really sure you want to unlock this platform?'),
    'weight' => 10,
  );
  return $tasks;
}

/**
 * Implementation of hook_perm().
 */
function hosting_platform_perm() {
  return array(
    'create platform',
    'view platform',
    'edit platform',
    'delete platform',
    'view locked platforms',
  );
}

/**
 * Implementation of hook_access().
 */
function hosting_platform_access($op, $node, $account) {
  if ($op != 'create' && hosting_feature('client')) {

    // we rely on hosting_node_grants() instead of global configuration
    return NULL;
  }
  switch ($op) {
    case 'create':
      return user_access('create platform', $account);
      break;
    case 'update':
      return user_access('edit platform', $account);
      break;
  }
}

/**
 * Small helper function to get platforms that haven't been deleted.
 */
function _hosting_get_platforms() {
  $return = array();
  $result = db_query("SELECT n.nid, n.title FROM {node} n LEFT JOIN {hosting_platform} h ON n.nid = h.nid \n                      WHERE n.type='platform' AND n.status=1 AND h.status <> %d ORDER BY n.title", HOSTING_PLATFORM_DELETED);
  while ($server = db_fetch_object($result)) {
    $return[$server->nid] = $server->title;
  }
  return $return;
}

/**
 * Small helper function to get platforms that haven't been deleted or locked.
 */
function _hosting_get_enabled_platforms() {
  $return = array();
  $result = db_query("SELECT n.nid, n.title FROM {node} n LEFT JOIN {hosting_platform} h ON n.nid = h.nid \n                      WHERE n.type='platform' AND n.status=1 AND h.status <> %d ORDER BY n.title", HOSTING_PLATFORM_LOCKED);
  while ($server = db_fetch_object($result)) {
    $return[$server->nid] = $server->title;
  }
  return $return;
}

/**
 * Small helper function to get platforms that have been locked.
 */
function _hosting_get_locked_platforms() {
  $return = array();
  $result = db_query("SELECT n.nid, n.title FROM {node} n LEFT JOIN {hosting_platform} h ON n.nid = h.nid \n                      WHERE n.type='platform' AND n.status=1 AND h.status = %d ORDER BY n.title", HOSTING_PLATFORM_LOCKED);
  while ($server = db_fetch_object($result)) {
    $return[$server->nid] = $server->title;
  }
  return $return;
}

/**
 * Small helper function to check if a platform is locked.
 */
function _hosting_platform_is_locked($node) {
  if (in_array($node, array_keys(_hosting_get_locked_platforms()))) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Implementation of hook_form().
 */
function hosting_platform_form(&$node) {
  $type = node_get_types('type', $node);
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#required' => TRUE,
    '#description' => t('Choose a unique descriptive name for your platform. You very likely want this to be something like "Drupal 6.20".'),
    '#size' => 40,
    '#default_value' => $node->title,
    '#maxlength' => 255,
  );
  if (!$node->nid) {
    $form['publish_path'] = array(
      '#type' => 'textfield',
      '#title' => t('Publish path'),
      '#required' => TRUE,
      '#description' => t('The absolute path on the filesystem where the sites will be hosted. This needs to be created manually and initialized before your platform works properly. It also needs to be a unique path not already in use by a platform on any server.<br />For example, run the following shell commands:<pre>%commands</pre>Your publish path is the absolute path to the directory that gets created.<br />Alternatively, you can specify a makefile below, and the platform will be created automatically if the path specified here does not exist.<br />You are still required to enter the absolute path above, as it will be treated as the target directory by the makefile.', array(
        '%commands' => "cd /var/aegir/platforms\ndrush dl drupal\n",
      )),
      '#size' => 40,
      '#default_value' => $node->publish_path,
      '#maxlength' => 255,
    );
  }
  else {

    // display it
    $form['info']['publish_path'] = array(
      '#type' => 'item',
      '#title' => t('Publish path'),
      '#value' => $node->publish_path,
    );

    // send it on form submission
    $form['publish_path'] = array(
      '#type' => 'hidden',
      '#value' => $node->publish_path,
    );
  }
  $form['makefile'] = array(
    '#type' => 'textfield',
    '#title' => t('Makefile'),
    '#description' => t('The absolute path on the filesystem or public URL of a makefile that will be used to create the platform in the directory specified above. If the directory already exists, this file will be ignored.'),
    '#size' => 40,
    '#default_value' => $node->makefile,
    '#maxlength' => 255,
  );
  $servers = hosting_get_servers('http');
  if (sizeof($servers) > 1) {
    $form['web_server'] = array(
      '#type' => 'radios',
      '#title' => t('Web server'),
      '#description' => t('The web server the sites will be hosted on.'),
      '#options' => $servers,
      '#default_value' => $node->web_server ? $node->web_server : HOSTING_DEFAULT_WEB_SERVER,
    );
  }
  else {
    reset($servers);
    $form['web_server'] = array(
      '#type' => 'hidden',
      '#value' => key($servers),
    );
  }
  foreach (array(
    'verified',
    'platform_status',
  ) as $extra_attribute) {
    $form["{$extra_attribute}"] = array(
      '#type' => 'value',
      '#value' => $node->{$extra_attribute},
    );
  }
  return $form;
}

/**
 * Hide the delete button on platform nodes.
 */
function hosting_platform_form_alter(&$form, &$form_state, $form_id) {

  // Remove delete button from platform edit form, unless the platform's already been deleted via the Delete task
  if ($form_id == 'platform_node_form') {
    $node = $form['#node'];
    if ($node->platform_status !== '-2') {
      $form['buttons']['delete']['#type'] = 'hidden';
    }
  }
}

/**
 * Implementation of hook_insert().
 */
function hosting_platform_insert($node) {
  if (!isset($node->no_verify)) {
    hosting_add_task($node->nid, 'verify');
  }
  db_query("INSERT INTO {hosting_platform} (vid, nid, publish_path, makefile, verified, web_server, status) VALUES (%d, %d, '%s', '%s', %d, %d, %d)", $node->vid, $node->nid, $node->publish_path, $node->makefile, $node->verified, $node->web_server, $node->platform_status);
  if (!$node->old_vid) {
    hosting_context_register($node->nid, 'platform_' . preg_replace("/[!\\W]/", "", $node->title));
  }
}

/**
 * Implementation of hook_update().
 *
 * As an existing node is being updated in the database, we need to do our own
 * database updates.
 */
function hosting_platform_update($node) {

  // if this is a new node or we're adding a new revision,
  if (!empty($node->revision)) {
    hosting_platform_insert($node);
  }
  else {
    if ($node->platform_status == HOSTING_PLATFORM_DELETED) {
      $node->no_verify = TRUE;
    }
    db_query("UPDATE {hosting_platform} SET publish_path = '%s', makefile = '%s', web_server = %d, verified = %d, status= %d WHERE nid=%d", $node->publish_path, $node->makefile, $node->web_server, $node->verified, $node->platform_status, $node->nid);
  }
  if (!$node->no_verify) {
    hosting_add_task($node->nid, 'verify');
  }
}

/**
 * Implementation of hook_nodeapi_TYPE_OP().
 */
function hosting_nodeapi_platform_delete_revision(&$node) {
  db_query('DELETE FROM {hosting_platform} WHERE vid = %d', $node->vid);
}

/**
 * Implementation of hook_delete().
 */
function hosting_platform_delete($node) {
  db_query('DELETE FROM {hosting_platform} WHERE nid = %d', $node->nid);
  db_query('DELETE FROM {hosting_package_instance} WHERE rid=%d', $node->nid);
  hosting_context_delete($node->nid);
  $result = db_query("SELECT distinct nid FROM {hosting_task} WHERE rid=%d", $node->nid);
  while ($nid = db_fetch_object($result)) {
    node_delete($nid->nid);
  }
  $result = db_query("SELECT distinct nid FROM {hosting_site} WHERE platform=%d", $node->nid);
  while ($nid = db_fetch_object($result)) {
    node_delete($nid->nid);
  }
}

/**
 * Implementation of hook_validate().
 */
function hosting_platform_validate($node, &$form) {

  // Make sure the platform name is unique, to avoid context clashes.
  if ($node->op != t('Delete') && ($result = db_fetch_object(db_query("SELECT n.title AS name FROM {hosting_platform} AS h INNER JOIN {node} AS n ON n.nid = h.nid WHERE n.title = '%s' AND n.nid <> %d AND h.status >= %d", $node->title, $node->nid, HOSTING_PLATFORM_QUEUED)))) {
    form_set_error('title', t('Platform name %name is already defined. Platform names must be unique across all servers.', array(
      '%name' => $result->name,
    )));
  }

  // Make sure the path is unique. Remote servers can't have the same path to a platform that is in use by another server.
  if ($node->op != t('Delete') && ($result = db_fetch_object(db_query("SELECT n.title AS name FROM {hosting_platform} AS h INNER JOIN {node} AS n ON n.nid = h.nid WHERE publish_path = '%s' AND n.nid <> %d AND h.status >= %d", hosting_path_normalize($node->publish_path), $node->nid, HOSTING_PLATFORM_QUEUED)))) {
    form_set_error('publish_path', t('Path is already in use by platform %name. Platform paths must be unique across all servers.', array(
      '%name' => $result->name,
    )));
  }
}

/**
 * Implementation of hook_load().
 *
 * @param node
 *    Node object
 */
function hosting_platform_load($node) {
  $additions = db_fetch_object(db_query('SELECT publish_path, makefile, verified, web_server, status AS platform_status FROM {hosting_platform} WHERE vid = %d', $node->vid));
  $iid = db_result(db_query("SELECT iid FROM {hosting_package_instance} i left join {hosting_package} p on p.nid=i.package_id WHERE p.package_type='platform' AND i.rid=%d", $node->nid));
  $additions->release = hosting_package_instance_load($iid);
  $additions->profiles = hosting_get_profiles($node->nid, 'short_name');
  return $additions;
}

/**
 * Implementation of hook_load().
 *
 * @param arg
 *    Node's numeric nid
 */
function hosting_platform_node_load($arg) {
  if (!is_numeric($arg)) {
    return FALSE;
  }
  if ($node = node_load($arg)) {
    if ($node->type == 'platform') {
      return $node;
    }
  }
  return FALSE;
}

/**
 * Implementation of hook_view().
 */
function hosting_platform_view($node, $teaser = FALSE, $page = FALSE) {
  modalframe_parent_js();
  $node->content['info'] = array(
    '#prefix' => '<div id="hosting-platform-info">',
    '#suffix' => '</div>',
  );
  $node->content['info']['verified'] = array(
    '#type' => 'item',
    '#title' => t('Verified'),
    '#value' => hosting_format_interval($node->verified),
    '#weight' => -10,
  );
  $node->content['info']['publish_path'] = array(
    '#type' => 'item',
    '#title' => t('Publish path'),
    '#value' => filter_xss($node->publish_path),
    '#weight' => -8,
  );
  $node->content['info']['web_server'] = array(
    '#type' => 'item',
    '#title' => t('Web server'),
    '#value' => _hosting_node_link($node->web_server),
    '#weight' => -7,
  );
  $node->content['info']['status'] = array(
    '#type' => 'item',
    '#title' => t('Status'),
    '#value' => _hosting_platform_status($node),
  );
  if ($node->makefile) {
    $node->content['info']['makefile'] = array(
      '#type' => 'item',
      '#title' => t('Drush makefile'),
      '#value' => preg_match('/^http|^ftp/', $node->makefile) ? l('makefile', $node->makefile) : filter_xss($node->makefile),
    );
  }
  if ($node->release) {
    $release = sprintf("%s %s", $node->release->title, $node->release->version);
    $node->content['info']['release'] = array(
      '#type' => 'item',
      '#title' => t('Release'),
      '#value' => _hosting_node_link($node->release->nid, $release),
      '#weight' => -6,
    );
  }
  if ($page) {
    $node->content['sites_view'] = array(
      '#type' => 'item',
      '#value' => drupal_get_form('hosting_site_list_form', 'platform', $node->nid),
      '#prefix' => '<div id="hosting-site-list">',
      '#suffix' => '</div>',
      '#weight' => 10,
    );

    // Task list
    if ($node->nid) {
      $node->content['tasks_view'] = array(
        '#type' => 'item',
        '#value' => hosting_task_table($node),
        '#prefix' => '<div id="hosting-task-list">',
        '#suffix' => '</div>',
        '#weight' => 10,
      );
      $settings['hostingTaskRefresh'] = array(
        'nid' => $node->nid,
        'changed' => $node->changed,
      );
      drupal_add_js($settings, 'setting');
      drupal_add_js(drupal_get_path('module', 'hosting_task') . '/hosting_task.js');
    }
  }
  return $node;
}
function _hosting_platform_status($node) {
  static $labels = array(
    HOSTING_PLATFORM_QUEUED => "Queued",
    HOSTING_PLATFORM_ENABLED => "Enabled",
    HOSTING_PLATFORM_DELETED => "Deleted",
    HOSTING_PLATFORM_LOCKED => "Locked",
  );
  return $labels[$node->platform_status];
}

/**
 * Implementation of hook_hosting_summary().
 */
function hosting_platform_hosting_summary() {
  $summary = array();
  if (user_access('view locked platforms')) {
    $platforms = _hosting_get_platforms();
    $summary['platforms'] = theme('item_list', array_map('_hosting_node_link', array_keys($platforms)), t('Platforms'));
  }
  else {
    if (user_access('view platform')) {
      $platforms = _hosting_get_enabled_platforms();
      $summary['platforms'] = theme('item_list', array_map('_hosting_node_link', array_keys($platforms)), t('Platforms'));
    }
  }
  return $summary;
}

/**
 * Implementation of hook_views_api().
 */
function hosting_platform_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'hosting_platform'),
  );
}

/**
 * Define the classes that correspond to the platform status.
 */
function _hosting_platform_list_class($node) {
  static $labels = array(
    HOSTING_PLATFORM_QUEUED => "hosting-queue",
    HOSTING_PLATFORM_ENABLED => "hosting-success",
    HOSTING_PLATFORM_DELETED => "hosting-error",
    HOSTING_PLATFORM_LOCKED => "hosting-warning",
  );
  return $labels[$node->platform_status];
}

/**
 * Simple list for top level navigation.
 */
function hosting_platform_listing() {
  $platforms = _hosting_get_platforms();
  $header = array(
    t('Platform'),
    t('Release'),
    t('Server'),
    t('Verified'),
    t('Sites'),
  );
  $rows[] = array();
  $total = 0;
  foreach ($platforms as $nid => $title) {
    $row = array();
    $node = node_load($nid);
    $row[] = array(
      'class' => 'hosting-status',
      'data' => _hosting_node_link($nid),
    );
    $release = sprintf("%s %s", $node->release->title, $node->release->version);
    $row[] = _hosting_node_link($node->release->nid, $release);
    $row[] = _hosting_node_link($node->web_server);
    $row[] = hosting_format_interval($node->verified);
    $total += $count = hosting_site_count($nid, array(
      HOSTING_SITE_ENABLED,
      HOSTING_SITE_DISABLED,
      HOSTING_SITE_QUEUED,
    ));
    $row[] = $count;
    $rows[] = array(
      'data' => $row,
      'class' => _hosting_platform_list_class($node),
    );
  }
  $row = array();
  $row[] = array(
    'data' => t('Total sites hosted'),
    'colspan' => 4,
  );
  $row[] = $total;
  $rows[] = $row;
  return theme('table', $header, $rows, array(
    'class' => 'hosting-table',
  ));
}

Functions

Namesort descending Description
hosting_nodeapi_platform_delete_revision Implementation of hook_nodeapi_TYPE_OP().
hosting_platform_access Implementation of hook_access().
hosting_platform_delete Implementation of hook_delete().
hosting_platform_form Implementation of hook_form().
hosting_platform_form_alter Hide the delete button on platform nodes.
hosting_platform_hosting_summary Implementation of hook_hosting_summary().
hosting_platform_hosting_tasks Implementation of hook_hosting_tasks().
hosting_platform_insert Implementation of hook_insert().
hosting_platform_listing Simple list for top level navigation.
hosting_platform_load Implementation of hook_load().
hosting_platform_menu Implementation of hook_menu().
hosting_platform_node_info Implementation of hook_node_info().
hosting_platform_node_load Implementation of hook_load().
hosting_platform_perm Implementation of hook_perm().
hosting_platform_update Implementation of hook_update().
hosting_platform_validate Implementation of hook_validate().
hosting_platform_view Implementation of hook_view().
hosting_platform_views_api Implementation of hook_views_api().
_hosting_get_enabled_platforms Small helper function to get platforms that haven't been deleted or locked.
_hosting_get_locked_platforms Small helper function to get platforms that have been locked.
_hosting_get_platforms Small helper function to get platforms that haven't been deleted.
_hosting_platform_is_locked Small helper function to check if a platform is locked.
_hosting_platform_list_class Define the classes that correspond to the platform status.
_hosting_platform_status

Constants

Namesort descending Description
HOSTING_PLATFORM_DELETED This platform has been deleted.
HOSTING_PLATFORM_ENABLED This platform is created and enabled, sites may be deployed on it.
HOSTING_PLATFORM_LOCKED This platform has been locked, new sites will not be allowed to use it.
HOSTING_PLATFORM_QUEUED This platform has been queued for creation.