| 1 |
<?php
|
| 2 |
// $Id: hosting.module,v 1.122 2009/10/23 11:42:18 mig5 Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file Hosting module
|
| 6 |
*
|
| 7 |
* Contains just about all the interface magic of hostmaster.
|
| 8 |
*/
|
| 9 |
|
| 10 |
/**
|
| 11 |
* Not split for performance reasons. Just to keep code together.
|
| 12 |
*/
|
| 13 |
|
| 14 |
include_once('hosting.inc');
|
| 15 |
include_once('hosting_help.inc');
|
| 16 |
include_once('hosting.queues.inc');
|
| 17 |
include_once('hosting.features.inc');
|
| 18 |
|
| 19 |
/**
|
| 20 |
* Implementation of hook_menu()
|
| 21 |
*/
|
| 22 |
function hosting_menu() {
|
| 23 |
global $user;
|
| 24 |
$items = array();
|
| 25 |
|
| 26 |
|
| 27 |
$items['hosting/disabled'] = array(
|
| 28 |
'title' => 'Site disabled',
|
| 29 |
'page callback' => 'hosting_disabled_site',
|
| 30 |
'access arguments' => array('access content'),
|
| 31 |
'type' => MENU_CALLBACK
|
| 32 |
);
|
| 33 |
|
| 34 |
$items['hosting/js'] = array(
|
| 35 |
'title' => t('ahah callback'),
|
| 36 |
'page callback' => 'hosting_js_page',
|
| 37 |
'access arguments' => array('access content'),
|
| 38 |
'type' => MENU_CALLBACK
|
| 39 |
);
|
| 40 |
|
| 41 |
$items['hosting/maintenance'] = array(
|
| 42 |
'title' => 'Site maintenance',
|
| 43 |
'page callback' => 'hosting_site_maintenance',
|
| 44 |
'access arguments' => array('access content'),
|
| 45 |
'type' => MENU_CALLBACK
|
| 46 |
);
|
| 47 |
|
| 48 |
|
| 49 |
$items['admin/help/provision/requirements'] = array(
|
| 50 |
'title' => 'Provisioning requirements',
|
| 51 |
'description' => "Information of how to configure the provisioning system.",
|
| 52 |
'page callback' => 'hosting_help_requirements',
|
| 53 |
'type' => MENU_CALLBACK
|
| 54 |
);
|
| 55 |
|
| 56 |
|
| 57 |
$items['admin/hosting'] = array(
|
| 58 |
'title' => 'Hosting',
|
| 59 |
'description' => 'Configure and manage the hosting system',
|
| 60 |
'page callback' => 'drupal_get_form',
|
| 61 |
'page arguments' => array('hosting_features_form'),
|
| 62 |
'access arguments' => array('administer hosting'),
|
| 63 |
'type' => MENU_NORMAL_ITEM
|
| 64 |
);
|
| 65 |
|
| 66 |
$items['admin/hosting/features'] = array(
|
| 67 |
'title' => 'Features',
|
| 68 |
'description' => 'Configure the exposed functionality of the Hosting system',
|
| 69 |
'weight' => -100,
|
| 70 |
'page callback' => 'drupal_get_form',
|
| 71 |
'page arguments' => array('hosting_features_form'),
|
| 72 |
'type' => MENU_DEFAULT_LOCAL_TASK,
|
| 73 |
'access arguments' => array('administer hosting features'),
|
| 74 |
);
|
| 75 |
|
| 76 |
$items['admin/hosting/queues'] = array(
|
| 77 |
'title' => 'Queues',
|
| 78 |
'description' => 'Configure the frequency that cron, backup and task events are process',
|
| 79 |
'page callback' => 'drupal_get_form',
|
| 80 |
'page arguments' => array('hosting_queues_configure'),
|
| 81 |
'type' => MENU_LOCAL_TASK,
|
| 82 |
'access arguments' => array('administer hosting queues'),
|
| 83 |
);
|
| 84 |
|
| 85 |
|
| 86 |
$items['hosting/queues'] = array(
|
| 87 |
'page callback' => 'hosting_queues',
|
| 88 |
'type' => MENU_CALLBACK,
|
| 89 |
'access arguments' => array('access task logs')
|
| 90 |
);
|
| 91 |
|
| 92 |
return $items;
|
| 93 |
}
|
| 94 |
|
| 95 |
function hosting_js_page() {
|
| 96 |
modalframe_child_js();
|
| 97 |
|
| 98 |
$args = func_get_args();
|
| 99 |
$path = implode('/', $args);
|
| 100 |
|
| 101 |
menu_set_active_item($path);
|
| 102 |
# $_SERVER['REQUEST_URI'] = str_replace('/hosting/js', '', $_SERVER['REQUEST_URI']);
|
| 103 |
|
| 104 |
if ($router_item = menu_get_item($path)) {
|
| 105 |
if ($router_item['access']) {
|
| 106 |
if ($router_item['file']) {
|
| 107 |
require_once($router_item['file']);
|
| 108 |
}
|
| 109 |
$return = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
|
| 110 |
}
|
| 111 |
}
|
| 112 |
// Menu status constants are integers; page content is a string.
|
| 113 |
if (is_int($return)) {
|
| 114 |
modalframe_close_dialog();
|
| 115 |
}
|
| 116 |
return $return;
|
| 117 |
}
|
| 118 |
|
| 119 |
function hosting_menu_alter(&$items) {
|
| 120 |
$items['node/add']['page callback'] = '_hosting_node_add';
|
| 121 |
|
| 122 |
$types = hosting_feature_node_types(TRUE);
|
| 123 |
foreach ($types as $feature => $type) {
|
| 124 |
$path = sprintf('node/add/%s', str_replace('_', '-', $type));
|
| 125 |
$items[$path]['access callback'] = 'hosting_menu_access';
|
| 126 |
$items[$path]['access arguments'] = array($type, $feature);
|
| 127 |
}
|
| 128 |
|
| 129 |
// These node types should remain hidden, and provide no user interface.
|
| 130 |
unset($items['node/add/package']);
|
| 131 |
unset($items['node/add/task']);
|
| 132 |
}
|
| 133 |
|
| 134 |
function hosting_menu_access($type, $feature) {
|
| 135 |
global $user;
|
| 136 |
return (($user->uid == 1) || user_access('create ' . $type)) && (hosting_feature($feature) != HOSTING_FEATURE_DISABLED);
|
| 137 |
}
|
| 138 |
|
| 139 |
function hosting_disabled_site() {
|
| 140 |
drupal_set_breadcrumb(array());
|
| 141 |
return t("This site has been disabled by the site administrators");
|
| 142 |
}
|
| 143 |
|
| 144 |
function hosting_site_maintenance() {
|
| 145 |
drupal_set_breadcrumb(array());
|
| 146 |
return t("This site is currently in maintenance. Check back later.");
|
| 147 |
}
|
| 148 |
|
| 149 |
/**
|
| 150 |
* Implementation of hook_nodeapi
|
| 151 |
*
|
| 152 |
* This function redirects to hosting_nodeapi_$nodetype_$op calls, to save ourselves
|
| 153 |
* from an incessant amount of intricately nested code, and allow easier extension / maintenance.
|
| 154 |
*/
|
| 155 |
function hosting_nodeapi(&$node, $op, $teaser) {
|
| 156 |
$func = "hosting_nodeapi_" . $node->type . "_" . str_replace(" ", "_", $op);
|
| 157 |
if (function_exists($func)) {
|
| 158 |
$func($node, $op, $teaser);
|
| 159 |
}
|
| 160 |
}
|
| 161 |
/**
|
| 162 |
* Implementation of hook_perm
|
| 163 |
*/
|
| 164 |
function hosting_perm() {
|
| 165 |
return array('access hosting wizard', 'administer hosting queues', 'administer hosting features', 'administer hosting');
|
| 166 |
}
|
| 167 |
|
| 168 |
/**
|
| 169 |
* Implementation of hook_init
|
| 170 |
*/
|
| 171 |
function hosting_init() {
|
| 172 |
// Definitions for the default platforms, clients etc.
|
| 173 |
// Done to avoid using 'magic numbers'
|
| 174 |
define('HOSTING_DEFAULT_CLIENT', variable_get('hosting_default_client', 1));
|
| 175 |
define('HOSTING_DEFAULT_DB_SERVER', variable_get('hosting_default_db_server', 2));
|
| 176 |
define('HOSTING_DEFAULT_WEB_SERVER', variable_get('hosting_default_web_server', 3));
|
| 177 |
define('HOSTING_DEFAULT_PLATFORM', variable_get('hosting_default_platform', 6));
|
| 178 |
|
| 179 |
define('HOSTING_OWN_DB_SERVER', variable_get('hosting_own_db_server', 2));
|
| 180 |
define('HOSTING_OWN_WEB_SERVER', variable_get('hosting_own_web_server', 3));
|
| 181 |
define('HOSTING_OWN_PLATFORM', variable_get('hosting_own_platform', 6));
|
| 182 |
|
| 183 |
|
| 184 |
// These defaults could be temporary.
|
| 185 |
$info = posix_getgrgid(posix_getgid());
|
| 186 |
define('HOSTING_DEFAULT_WEB_GROUP', $info['name']);
|
| 187 |
$user = get_current_user();
|
| 188 |
if ($user == 'root') {
|
| 189 |
$user = 'aegir'; # a better default than root
|
| 190 |
}
|
| 191 |
define('HOSTING_DEFAULT_SCRIPT_USER', $user);
|
| 192 |
|
| 193 |
define('HOSTING_DEFAULT_RESTART_CMD', _hosting_default_restart_cmd());
|
| 194 |
|
| 195 |
$path = ($_SERVER['PWD']) ? $_SERVER['PWD'] : $_SERVER['DOCUMENT_ROOT'];
|
| 196 |
define('HOSTING_DEFAULT_DOCROOT_PATH',rtrim($path, '/'));
|
| 197 |
|
| 198 |
$parts = explode("/", rtrim($path, '/'));
|
| 199 |
array_pop($parts);
|
| 200 |
define('HOSTING_DEFAULT_PARENT_PATH', rtrim(implode("/" , $parts), '/'));
|
| 201 |
define('HOSTING_DEFAULT_BACKUP_PATH', HOSTING_DEFAULT_PARENT_PATH . '/backups');
|
| 202 |
define('HOSTING_DEFAULT_CONFIG_PATH', HOSTING_DEFAULT_PARENT_PATH .'/config');
|
| 203 |
define('HOSTING_DEFAULT_VHOST_PATH', HOSTING_DEFAULT_CONFIG_PATH .'/vhost.d');
|
| 204 |
|
| 205 |
/**
|
| 206 |
* Find the base URL, this is used by the initial 'hosting setup' drush command
|
| 207 |
* This gets defined in the bootstrap, so just using the global definition.
|
| 208 |
*/
|
| 209 |
define('HOSTING_DEFAULT_BASE_URL', $GLOBALS['base_url']);
|
| 210 |
|
| 211 |
// moved from hook_menu()
|
| 212 |
drupal_add_css(drupal_get_path('module', 'hosting') . '/hosting.css');
|
| 213 |
}
|
| 214 |
|
| 215 |
|
| 216 |
/**
|
| 217 |
* This function should not have to be duplicated between hosting/provision
|
| 218 |
*/
|
| 219 |
function _hosting_default_restart_cmd() {
|
| 220 |
$command = '/usr/sbin/apachectl'; # a proper default for most of the world
|
| 221 |
foreach (explode(':', $_SERVER['PATH']) as $path) {
|
| 222 |
$options[] = "$path/apache2ctl";
|
| 223 |
$options[] = "$path/apachectl";
|
| 224 |
}
|
| 225 |
# try to detect the apache restart command
|
| 226 |
$options[] = '/usr/local/sbin/apachectl'; # freebsd
|
| 227 |
$options[] = '/usr/sbin/apache2ctl'; # debian + apache2
|
| 228 |
$options[] = $command;
|
| 229 |
|
| 230 |
foreach ($options as $test) {
|
| 231 |
if (is_executable($test)) {
|
| 232 |
$command = $test;
|
| 233 |
break;
|
| 234 |
}
|
| 235 |
}
|
| 236 |
|
| 237 |
return "sudo $command graceful";
|
| 238 |
}
|
| 239 |
|
| 240 |
/**
|
| 241 |
* Implementation of hook_theme().
|
| 242 |
*/
|
| 243 |
function hosting_theme() {
|
| 244 |
return array(
|
| 245 |
'hosting_summary_block' => array(
|
| 246 |
'file' => 'hosting.module',
|
| 247 |
'arguments' => array(
|
| 248 |
'components' => NULL,
|
| 249 |
),
|
| 250 |
),
|
| 251 |
'hosting_queues_configure' => array(
|
| 252 |
'file' => 'hosting.module',
|
| 253 |
'arguments' => array(
|
| 254 |
'form' => NULL,
|
| 255 |
),
|
| 256 |
),
|
| 257 |
'requirement_help' => array(
|
| 258 |
'file' => 'hosting_help.inc',
|
| 259 |
'arguments' => array(
|
| 260 |
'form' => NULL,
|
| 261 |
),
|
| 262 |
),
|
| 263 |
);
|
| 264 |
}
|
| 265 |
|
| 266 |
function _hosting_node_link($nid, $title = null) {
|
| 267 |
if (is_null($nid)) {
|
| 268 |
return t("None");
|
| 269 |
}
|
| 270 |
$node = node_load($nid);
|
| 271 |
$title = (!is_null($title)) ? $title : filter_xss($node->title);
|
| 272 |
if ($node->nid) {
|
| 273 |
return node_access('view', $node) ? l($title, "node/" . $node->nid) : filter_xss($node->title);
|
| 274 |
}
|
| 275 |
}
|
| 276 |
|
| 277 |
|
| 278 |
function hosting_block($op = 'list', $delta = 0, $edit = array()) {
|
| 279 |
switch ($op) {
|
| 280 |
case 'list' :
|
| 281 |
$blocks['hosting_summary'] = array('info' => t('Hosting summary'),
|
| 282 |
'enabled' => 1, 'region' => 'left', 'weight' => 10);
|
| 283 |
$blocks['hosting_queues'] = array('info' => t('Hosting queues'),
|
| 284 |
'enabled' => 1, 'region' => 'right', 'weight' => 0);
|
| 285 |
$blocks['hosting_queues_summary'] = array('info' => t('Hosting queues summary'),
|
| 286 |
'enabled' => 1, 'region' => 'right', 'weight' => 1);
|
| 287 |
return $blocks;
|
| 288 |
case 'view' :
|
| 289 |
switch ($delta) {
|
| 290 |
case 'hosting_summary':
|
| 291 |
return array(
|
| 292 |
'title' => t('Summary'),
|
| 293 |
'content' => hosting_summary_block());
|
| 294 |
break;
|
| 295 |
case 'hosting_queues':
|
| 296 |
return array('title' => t('Queues'),
|
| 297 |
'content' => hosting_queue_block());
|
| 298 |
break;
|
| 299 |
case 'hosting_queues_summary':
|
| 300 |
return array('title' => t('Queues summary'),
|
| 301 |
'content' => hosting_queue_summary_block());
|
| 302 |
break;
|
| 303 |
}
|
| 304 |
}
|
| 305 |
}
|
| 306 |
|
| 307 |
function hosting_queue_summary_block() {
|
| 308 |
if (user_access('administer hosting queues')) {
|
| 309 |
$queues = hosting_get_queues();
|
| 310 |
$output = '';
|
| 311 |
foreach ($queues as $queue => $info) {
|
| 312 |
$disp = array();
|
| 313 |
# special case
|
| 314 |
if (!$info['enabled']) {
|
| 315 |
$disp[] = t('Status: disabled');
|
| 316 |
continue;
|
| 317 |
}
|
| 318 |
$disp[] = t('Status: enabled');
|
| 319 |
foreach (array('description' => t('Description'), 'frequency' => t('Frequency'), 'items' => t('Items per run'), 'total_items' => t('Items in queue'), 'last_run' => t('Last run')) as $key => $title) {
|
| 320 |
if ($key == 'last_run') {
|
| 321 |
$info[$key] = hosting_format_interval($info[$key]);
|
| 322 |
} elseif ($key == 'frequency') {
|
| 323 |
$info[$key] = t('every @interval', array('@interval' => format_interval($info[$key])));
|
| 324 |
}
|
| 325 |
$disp[] = $title . ": " . $info[$key];
|
| 326 |
}
|
| 327 |
$output .= theme('item_list', $disp, $info['name']);
|
| 328 |
}
|
| 329 |
return $output;
|
| 330 |
}
|
| 331 |
}
|
| 332 |
|
| 333 |
function hosting_queue_block() {
|
| 334 |
if (user_access('access task logs')) {
|
| 335 |
$queues = hosting_get_queues();
|
| 336 |
$output = '';
|
| 337 |
foreach ($queues as $queue => $info) {
|
| 338 |
$func = 'hosting_'.$info['singular'].'_summary';
|
| 339 |
if (function_exists($func)) {
|
| 340 |
$output .= $func();
|
| 341 |
}
|
| 342 |
}
|
| 343 |
return $output;
|
| 344 |
}
|
| 345 |
}
|
| 346 |
|
| 347 |
function hosting_summary_block() {
|
| 348 |
if (user_access('administer hosting')) {
|
| 349 |
return theme('hosting_summary_block', module_invoke_all('hosting_summary'));
|
| 350 |
}
|
| 351 |
}
|
| 352 |
|
| 353 |
function theme_hosting_summary_block($components) {
|
| 354 |
foreach ($components as $component) {
|
| 355 |
$output .= $component;
|
| 356 |
}
|
| 357 |
return $output;
|
| 358 |
}
|
| 359 |
|
| 360 |
/**
|
| 361 |
* Check site URL is allowed
|
| 362 |
*
|
| 363 |
* This function hooks into hook_allow_domain to let contrib modules
|
| 364 |
* weigh in on whether the site should be created.
|
| 365 |
*
|
| 366 |
* All the hooks must return true for the domain to be allowed.
|
| 367 |
*/
|
| 368 |
function hosting_domain_allowed($url, $params = array()) {
|
| 369 |
$results = module_invoke_all('allow_domain', $url, $params);
|
| 370 |
$return = !in_array(FALSE, $results);
|
| 371 |
return $return;
|
| 372 |
}
|
| 373 |
|
| 374 |
/**
|
| 375 |
* Initial hosting setup
|
| 376 |
* Runs the 'hosting dispatch' command, and
|
| 377 |
* move on to setting up the crontab
|
| 378 |
*/
|
| 379 |
function hosting_setup() {
|
| 380 |
variable_set('hosting_dispatch_enabled', FALSE);
|
| 381 |
// attempt to run the dispatch command, to make sure it runs without the queue being enabled.
|
| 382 |
variable_set('hosting_dispatch_enabled', TRUE);
|
| 383 |
drush_print(_hosting_dispatch_cmd());
|
| 384 |
exec(_hosting_dispatch_cmd(), $return, $code);
|
| 385 |
variable_set('hosting_dispatch_enabled', FALSE);
|
| 386 |
$return = join("\n", $return);
|
| 387 |
$data = unserialize($return);
|
| 388 |
if ($code == DRUSH_SUCCESS) {
|
| 389 |
variable_set('hosting_dispatch_enabled', TRUE);
|
| 390 |
drush_log(t("Dispatch command was run successfully"), 'success');
|
| 391 |
_hosting_setup_cron();
|
| 392 |
}
|
| 393 |
else {
|
| 394 |
drush_set_error('DRUSH_FRAMEWORK_ERROR', dt("Dispatch command could not be run. Returned: \n@return", array('@return' => $return)));
|
| 395 |
}
|
| 396 |
if (drush_get_error()) {
|
| 397 |
drush_log(t("The command did not complete successfully, please fix the issues and re-run this script"), 'error');
|
| 398 |
}
|
| 399 |
}
|
| 400 |
|
| 401 |
/**
|
| 402 |
* Set up the hosting dispatch command in the aegir user's crontab
|
| 403 |
* Replace the crontab entry if it exists, else create it from scratch
|
| 404 |
*/
|
| 405 |
function _hosting_setup_cron() {
|
| 406 |
$existing = FALSE;
|
| 407 |
exec('crontab -l 2> /dev/null', $cron);
|
| 408 |
variable_set('hosting_cron_backup', $cron);
|
| 409 |
if (sizeof($cron)) {
|
| 410 |
foreach ($cron as $line => $entry) {
|
| 411 |
if (preg_match('/hosting dispatch/', $entry)) {
|
| 412 |
$pattern = "+(.*)'(.*)/drush.php'(.*)--root='(.*)'.*+";
|
| 413 |
$replace = sprintf("$1 '%s' hosting dispatch --root=%s --uri=%s)",
|
| 414 |
DRUSH_COMMAND,
|
| 415 |
escapeshellarg(HOSTING_DEFAULT_DOCROOT_PATH),
|
| 416 |
drush_get_option('uri')
|
| 417 |
);
|
| 418 |
$cron[$line] = preg_replace($pattern, $replace, $entry);
|
| 419 |
drush_log(dt("Existing hosting dispatch cron entry was found. Replacing"));
|
| 420 |
$existing = TRUE;
|
| 421 |
break;
|
| 422 |
}
|
| 423 |
}
|
| 424 |
}
|
| 425 |
else {
|
| 426 |
drush_log("message", t("No existing crontab was found"));
|
| 427 |
}
|
| 428 |
if (!$existing) {
|
| 429 |
$cron[] = hosting_queues_cron_cmd();
|
| 430 |
}
|
| 431 |
$tmpnam = tempnam('hostmaster', 'hm.cron');
|
| 432 |
$fp = fopen($tmpnam, "w");
|
| 433 |
foreach ($cron as $line) {
|
| 434 |
fwrite($fp, $line . "\n");
|
| 435 |
}
|
| 436 |
fclose($fp);
|
| 437 |
system(sprintf('crontab %s', escapeshellarg($tmpnam)));
|
| 438 |
unlink($tmpnam);
|
| 439 |
drush_log("Notice", t("Installed hosting dispatch cron entry to run every minute"));
|
| 440 |
}
|
| 441 |
|
| 442 |
|
| 443 |
/**
|
| 444 |
* Replacement node/add page.
|
| 445 |
*
|
| 446 |
* Major kludge to remove the hidden node types from node/add page
|
| 447 |
*
|
| 448 |
* Copied from node.module
|
| 449 |
*/
|
| 450 |
function _hosting_node_add($type = '') {
|
| 451 |
global $user;
|
| 452 |
|
| 453 |
$types = node_get_types();
|
| 454 |
$type = ($type) ? str_replace('-', '_', $type) : NULL;
|
| 455 |
// If a node type has been specified, validate its existence.
|
| 456 |
if (isset($types[$type]) && user_access('create ' . $type) && (hosting_feature($type) !== HOSTING_FEATURE_DISABLED)) {
|
| 457 |
// Initialize settings:
|
| 458 |
$node = array('uid' => $user->uid, 'name' => $user->name, 'type' => $type);
|
| 459 |
|
| 460 |
drupal_set_title(t('Submit @name', array('@name' => $types[$type]->name)));
|
| 461 |
$output = drupal_get_form($type .'_node_form', $node);
|
| 462 |
}
|
| 463 |
else {
|
| 464 |
// If no (valid) node type has been provided, display a node type overview.
|
| 465 |
foreach ($types as $type) {
|
| 466 |
if (function_exists($type->module .'_form') && user_access('create ' . $type->type) && (hosting_feature($type->type) !== HOSTING_FEATURE_DISABLED)) {
|
| 467 |
$type_url_str = str_replace('_', '-', $type->type);
|
| 468 |
$title = t('Add a new @s.', array('@s' => $type->name));
|
| 469 |
$out = '<dt>'. l(drupal_ucfirst($type->name), "node/add/$type_url_str", array('attributes' => array('title' => $title))) .'</dt>';
|
| 470 |
$out .= '<dd>'. filter_xss_admin($type->description) .'</dd>';
|
| 471 |
$item[$type->name] = $out;
|
| 472 |
}
|
| 473 |
}
|
| 474 |
|
| 475 |
if (isset($item)) {
|
| 476 |
uksort($item, 'strnatcasecmp');
|
| 477 |
$output = t('Choose the appropriate item from the list:') .'<dl>'. implode('', $item) .'</dl>';
|
| 478 |
}
|
| 479 |
else {
|
| 480 |
$output = t('No content types available.');
|
| 481 |
}
|
| 482 |
}
|
| 483 |
|
| 484 |
return $output;
|
| 485 |
}
|
| 486 |
|
| 487 |
/**
|
| 488 |
* List queues or tasks in a queue if a key is provided
|
| 489 |
*/
|
| 490 |
|
| 491 |
function hosting_queues($key='') {
|
| 492 |
$queues = hosting_get_queues();
|
| 493 |
|
| 494 |
if ($queues[$key]) {
|
| 495 |
if ($queues[$key]['name'])
|
| 496 |
{
|
| 497 |
$output .= "<h1>".$queues[$key]['name']."</h1>";
|
| 498 |
}
|
| 499 |
|
| 500 |
$func = 'hosting_'.$queues[$key]['singular'].'_list';
|
| 501 |
if (function_exists($func)) {
|
| 502 |
$output .= $func();
|
| 503 |
}
|
| 504 |
}
|
| 505 |
else
|
| 506 |
{
|
| 507 |
foreach($queues as $key => $queue) {
|
| 508 |
$item[] = l($queue['name'], 'hosting/queues/'.$key);
|
| 509 |
}
|
| 510 |
$output .= theme('item_list', $item, t('Queues'));
|
| 511 |
}
|
| 512 |
|
| 513 |
return $output;
|
| 514 |
}
|
| 515 |
|
| 516 |
/**
|
| 517 |
* Generate context sensitive breadcrumbs
|
| 518 |
*/
|
| 519 |
function hosting_set_breadcrumb($node) {
|
| 520 |
$breadcrumbs[] = l(t('Home'), NULL);
|
| 521 |
switch ($node->type) {
|
| 522 |
case 'task':
|
| 523 |
$breadcrumbs[] = _hosting_node_link($node->rid);
|
| 524 |
break;
|
| 525 |
case 'platform' :
|
| 526 |
$breadcrumbs[] = _hosting_node_link($node->web_server);
|
| 527 |
break;
|
| 528 |
case 'site' :
|
| 529 |
$breadcrumbs[] = _hosting_node_link($node->platform);
|
| 530 |
break;
|
| 531 |
}
|
| 532 |
drupal_set_breadcrumb($breadcrumbs);
|
| 533 |
}
|
| 534 |
|
| 535 |
/**
|
| 536 |
* Page callback
|
| 537 |
*
|
| 538 |
* Configure the frequency of tasks.
|
| 539 |
*/
|
| 540 |
function hosting_queues_configure() {
|
| 541 |
drupal_add_css(drupal_get_path('module', 'hosting') . '/hosting.css');
|
| 542 |
$units = array(
|
| 543 |
strtotime("1 second", 0) => t("Seconds"),
|
| 544 |
strtotime("1 minute", 0) => t("Minutes"),
|
| 545 |
strtotime("1 hour", 0) => t("Hours"),
|
| 546 |
strtotime("1 day", 0) => t("Days"),
|
| 547 |
strtotime("1 week", 0) => t("Weeks"),
|
| 548 |
);
|
| 549 |
|
| 550 |
$queues = hosting_get_queues();
|
| 551 |
$form['#tree'] = TRUE;
|
| 552 |
|
| 553 |
foreach ($queues as $queue => $info) {
|
| 554 |
$form[$queue]['description'] = array(
|
| 555 |
'#type' => 'item',
|
| 556 |
'#value' => $info['name'],
|
| 557 |
'#description' => $info['description']
|
| 558 |
);
|
| 559 |
|
| 560 |
$form[$queue]["enabled"] = array(
|
| 561 |
'#type' => 'checkbox',
|
| 562 |
'#default_value' => $info['enabled']
|
| 563 |
);
|
| 564 |
|
| 565 |
$form[$queue]["last_run"] = array(
|
| 566 |
'#value' => hosting_format_interval(variable_get('hosting_queue_' . $queue . '_last_run', false))
|
| 567 |
);
|
| 568 |
$form[$queue]['frequency']['#prefix'] = "<div class='hosting-queue-frequency'>";
|
| 569 |
$form[$queue]['frequency']['#suffix'] = "</div>";
|
| 570 |
|
| 571 |
if ($info['type'] == 'batch') {
|
| 572 |
$form[$queue]['frequency']['items'] = array(
|
| 573 |
'#value' => t('%count %items every ', array("%count" => $info['total_items'], "%items" => format_plural($info['total_items'], $info['singular'], $info['plural']))),
|
| 574 |
);
|
| 575 |
}
|
| 576 |
else {
|
| 577 |
$form[$queue]['frequency']['items'] = array(
|
| 578 |
'#type' => 'textfield',
|
| 579 |
'#size' => 3,
|
| 580 |
'#maxlength' => 3,
|
| 581 |
'#default_value' => $info['items'],
|
| 582 |
'#suffix' => t(' %items every ', array('%items' => $info['plural'])),
|
| 583 |
);
|
| 584 |
}
|
| 585 |
foreach (array_reverse(array_keys($units)) as $length) {
|
| 586 |
$unit = $units[$length];
|
| 587 |
|
| 588 |
if (!($info['frequency'] % $length)) {
|
| 589 |
$frequency_ticks = $info['frequency'] / $length;
|
| 590 |
$frequency_length = $length;
|
| 591 |
break;
|
| 592 |
}
|
| 593 |
}
|
| 594 |
$form[$queue]['frequency']["ticks"] = array(
|
| 595 |
'#type' => 'textfield',
|
| 596 |
'#default_value' => $frequency_ticks,
|
| 597 |
'#maxlength' => 5,
|
| 598 |
'#size' => 5
|
| 599 |
);
|
| 600 |
$form[$queue]['frequency']["unit"] = array(
|
| 601 |
'#type' => 'select',
|
| 602 |
'#options' => $units,
|
| 603 |
'#default_value' => $frequency_length,
|
| 604 |
);
|
| 605 |
}
|
| 606 |
$form['submit'] = array('#type' => 'submit', '#value' => t('Save changes'));
|
| 607 |
return $form;
|
| 608 |
}
|
| 609 |
|
| 610 |
function theme_hosting_queues_configure($form) {
|
| 611 |
$queues = hosting_get_queues();
|
| 612 |
|
| 613 |
$rows = array();
|
| 614 |
$header = array('', t('Description'),
|
| 615 |
array('data' => t('Frequency'), 'class' => 'hosting-queue-frequency-head'),
|
| 616 |
t('Last run'),);
|
| 617 |
foreach ($queues as $key => $info) {
|
| 618 |
$row = array();
|
| 619 |
$row[] = drupal_render($form[$key]['enabled']);
|
| 620 |
$row[] = drupal_render($form[$key]['description']);
|
| 621 |
$row[] = drupal_render($form[$key]['frequency']);
|
| 622 |
$row[] = drupal_render($form[$key]['last_run']);
|
| 623 |
$rows[] = $row;
|
| 624 |
}
|
| 625 |
$output = theme('table', $header, $rows);
|
| 626 |
$output .= drupal_render($form['submit']);
|
| 627 |
$output .= drupal_render($form);
|
| 628 |
return $output;
|
| 629 |
}
|
| 630 |
|
| 631 |
/**
|
| 632 |
* Implementation of hook_validate()
|
| 633 |
*/
|
| 634 |
function hosting_queues_configure_validate($form, &$form_state) {
|
| 635 |
foreach (hosting_get_queues() as $queue => $info) {
|
| 636 |
if ($form_state['values'][$queue]) {
|
| 637 |
if ($form_state['values'][$queue]['frequency']['ticks'] && !is_numeric($form_state['values'][$queue]['frequency']['ticks'])) {
|
| 638 |
form_set_error($queue, t('Please enter a valid frequency.'));
|
| 639 |
}
|
| 640 |
if ($form_state['values'][$queue]['frequency']['items'] && !is_numeric($form_state['values'][$queue]['frequency']['items'])) {
|
| 641 |
form_set_error($queue, t('Please enter a valid amount of items.'));
|
| 642 |
}
|
| 643 |
}
|
| 644 |
}
|
| 645 |
}
|
| 646 |
|
| 647 |
/**
|
| 648 |
* Implementation of hook_submit()
|
| 649 |
*/
|
| 650 |
function hosting_queues_configure_submit($form, &$form_state) {
|
| 651 |
foreach (hosting_get_queues() as $queue => $info) {
|
| 652 |
if ($form_state['values'][$queue]) {
|
| 653 |
variable_set("hosting_queue_" . $queue . "_enabled", $form_state['values'][$queue]['enabled']);
|
| 654 |
variable_set("hosting_queue_" . $queue . "_frequency", $form_state['values'][$queue]['frequency']['ticks'] * $form_state['values'][$queue]['frequency']['unit']);
|
| 655 |
if ($info['type'] == 'serial') {
|
| 656 |
variable_set("hosting_queue_" . $queue . "_items", $form_state['values'][$queue]['frequency']['items']);
|
| 657 |
}
|
| 658 |
}
|
| 659 |
}
|
| 660 |
drupal_set_message(t('The queue settings have been updated.'));
|
| 661 |
}
|
| 662 |
|
| 663 |
/**
|
| 664 |
* Implementation of hook_form_alter()
|
| 665 |
*/
|
| 666 |
function hosting_form_alter(&$form, &$form_state, $form_id) {
|
| 667 |
// Alter the 'Add User' form to remind users that this is not the New Client form
|
| 668 |
if ($form_id == 'user_register') {
|
| 669 |
$form[user_registration_help] = array(
|
| 670 |
'#type' => 'item',
|
| 671 |
'#description' => t('<strong>Adding a system user account does not make the user a Client that can add sites.</strong><br />
|
| 672 |
To add a Client, enable the Client feature and then add a new Client node.<br />
|
| 673 |
If you wish, you may then assign this system user to the Client as an \'Allowed user\' to inherit the permissions to add sites.'),
|
| 674 |
'#weight' => '-10'
|
| 675 |
);
|
| 676 |
}
|
| 677 |
}
|
| 678 |
|