Revert "Re-applying patch from http://drupal.org/files/views_integration-588728-11...
[sandbox/ergonlogic/1226310.git] / modules / hosting / site / hosting_site.module
1 <?php
2
3 /**
4 * This site is deleted from the backend.
5 */
6 define('HOSTING_SITE_DELETED', -2);
7
8 /**
9 * This site is disabled.
10 */
11 define('HOSTING_SITE_DISABLED', -1);
12
13 /**
14 * This site is queued for creation.
15 */
16 define('HOSTING_SITE_QUEUED', 0);
17
18 /**
19 * This site is created and enabled in the backend.
20 */
21 define('HOSTING_SITE_ENABLED', 1);
22
23 include_once('hosting_site.nodeapi.inc');
24 include_once('hosting_site.form.inc');
25 include_once('hosting_site.backups.inc');
26
27 //Conditonally include site quotas
28 if (module_exists('hosting_quota')) {
29 include_once('hosting_site.quota.inc');
30 }
31
32 /**
33 * Implementation of hook_menu()
34 */
35 function hosting_site_menu() {
36 $items = array();
37
38 $items['hosting/sites'] = array(
39 'title' => 'Sites',
40 'description' => 'Display a list of sites',
41 'page callback' => 'hosting_sites',
42 'access arguments' => array('view site'),
43 'type' => MENU_NORMAL_ITEM,
44 );
45
46 $items['hosting/sites/list'] = array(
47 'title' => 'List',
48 'type' => MENU_DEFAULT_LOCAL_TASK,
49 'weight' => -10,
50 );
51
52 $items['hosting/sites/add'] = array(
53 'title' => 'Add site',
54 'type' => MENU_LOCAL_TASK,
55 'page callback' => 'drupal_goto',
56 'page arguments' => array('node/add/site'),
57 'access callback' => 'node_access',
58 'access arguments' => array('create', 'site'),
59 );
60
61 $items['hosting/hosting_site_form_check'] = array(
62 'page callback' =>'_hosting_site_form_check',
63 'type' => MENU_CALLBACK,
64 'access arguments' => array('access content'),
65 );
66
67
68 $items['node/%hosting_site_node/goto_site'] = array(
69 'page callback' => 'hosting_site_goto',
70 'page arguments' => array(1),
71 'access callback' => 'node_access',
72 'access arguments' => array('view', 1),
73 'type' => MENU_CALLBACK,
74 );
75
76 return $items;
77 }
78
79 function _hosting_site_form_check() {
80 drupal_json(
81 hosting_site_available_options($_POST)
82 );
83 exit();
84 }
85
86 /**
87 * Implementation of hook_load().
88 *
89 * @param arg
90 * Node's numeric nid
91 */
92 function hosting_site_node_load($arg) {
93 if (!is_numeric($arg)) {
94 return FALSE;
95 }
96 if ($node = node_load($arg)) {
97 if ($node->type == 'site') {
98 return $node;
99 }
100 }
101 return FALSE;
102 }
103
104 /**
105 * Page handler for displaying list of hosted sites on front page
106 */
107 function hosting_sites() {
108 if ($list = drupal_get_form('hosting_site_list_form')) {
109 return $list;
110 }
111 $create_site_link = l(t('Create a site now?'), 'node/add/site');
112 return t("No sites have been created yet. !link", array(
113 '!link' => $create_site_link));
114 }
115
116 /**
117 * Generate a link allowing the user to log into their new site, or simply
118 * go to the site front page if the link has expired.
119 */
120 function _hosting_site_goto_link($node) {
121 $cache = cache_get("hosting:site:" . $node->nid . ":login_link");
122 if (!is_null($cache) && (time() < $cache->data['expire'])) {
123 $title = t("Log in to !url" , array('!url' => $node->title));
124 }
125 else {
126 $title = t("Go to !url" , array('!url' => $node->title));
127 }
128 $options['attributes']['class'] = 'hosting-goto-site-link';
129 return l($title, "node/" . $node->nid . "/goto_site", $options);
130 }
131
132 /**
133 * Menu callback to go to your site.
134 *
135 * This needs to be a callback because the link is only going to work once,
136 * so this will remove the link from the cache and just redirect to the site
137 * not the login page.
138 */
139 function hosting_site_goto($node) {
140 $cid = "hosting:site:" . $node->nid . ":login_link";
141 $cache = cache_get($cid);
142 if (!is_null($cache) && (time() < $cache->data['expire'])) {
143 $theurl = $cache->data['link'];
144 cache_clear_all($cid, 'cache');
145 }
146 else {
147 $theurl = _hosting_site_url($node);
148 }
149
150 drupal_goto($theurl);
151 exit();
152 }
153
154 /**
155 * Retrieve the port the site will be available on, so we can redirect.
156 */
157 function hosting_site_get_port($node) {
158 $platform = node_load($node->platform);
159 $server = node_load($platform->web_server);
160 return $server->services['http']->port;
161 }
162
163 /**
164 * Get site's URL.
165 */
166 function _hosting_site_url($node) {
167 $schema = 'http';
168 $port = null;
169
170 $url = strtolower(trim($node->title));
171
172 $platform = node_load($node->platform);
173 $server = node_load($platform->web_server);
174
175
176 if ($server->services['http']->has_port()) {
177 $port = $server->services['http']->port;
178 if ($port == 80) {
179 $port = null;
180 }
181 }
182
183 /**
184 * This is part of the ssl feature, but is better to implement here.
185 */
186 if (isset($node->ssl_enabled) && ($node->ssl_enabled == 2)) {
187 // this is a bit of a magic number, because we cant rely on the constant being available yet.
188 // 2 == Only SSL is enabled.
189 $schema = 'https';
190
191 if ($server->services['http']->has_port()) {
192 $port = $server->services['http']->ssl_port;
193 if ($port == 443) {
194 $port = null;
195 }
196 }
197 }
198
199 if (is_numeric($port)) {
200 return "{$schema}://{$url}:{$port}";
201 }
202
203 return "{$schema}://{$url}";
204 }
205
206 /**
207 * Implementation of hook_hosting_tasks
208 */
209 function hosting_site_hosting_tasks() {
210 $tasks = array();
211
212 $tasks['site']['backup'] = array(
213 'title' => t('Backup'),
214 'description' => t('Generate a backup of this site that can be restored to at any time'),
215 'dialog' => TRUE,
216 );
217
218 $tasks['site']['restore'] = array(
219 'title' => t('Restore'),
220 'description' => t('Restore this site to a previous backup. A new backup will be created before this is attempted.'),
221 'dialog' => TRUE,
222 );
223
224 $tasks['site']['verify'] = array(
225 'title' => t('Verify'),
226 'description' => t('Confirm that the site has been correctly installed and regenerate all configuration files to match the hosting front end.'),
227 'provision_save' => TRUE,
228 );
229
230 $tasks['site']['disable'] = array(
231 'title' => t('Disable'),
232 'description' => t('Disabling this site will stop it from being accessible.
233 It can be enabled again later.'),
234 'dialog' => TRUE,
235 );
236 $tasks['site']['enable'] = array(
237 'title' => t('Enable'),
238 'description' => t('Enabling this site will allow it to be accesible again.
239 It may be disabled again if needed.'),
240 );
241 $tasks['site']['delete'] = array(
242 'title' => t('Delete'),
243 'description' => t('Deleting this site will completely remove it from the hosting system,
244 but will keep the last backup available. This process can not be undone.
245 Are you really sure you want to delete this site?'),
246 'dialog' => TRUE,
247 );
248
249 $tasks['site']['login-reset'] = array(
250 'title' => t('Reset password'),
251 'description' => t('Generate a one-time login reset url for this site.'),
252 );
253
254 $tasks['site']['backup-delete'] = array(
255 'title' => t('Delete backups'),
256 'description' => t('Delete one or more backup files of a site.'),
257 'dialog' => TRUE,
258 );
259
260 $tasks['site']['install'] = array(
261 'title' => t('Install'),
262 'description' => t('Install a site'),
263 'hidden' => TRUE,
264 'provision_save' => TRUE,
265 );
266
267 $tasks['site']['import'] = array(
268 'title' => t('Import'),
269 'description' => t('Import an existing site into Aegir'),
270 'hidden' => TRUE,
271 'provision_save' => TRUE,
272 );
273
274 return $tasks;
275 }
276
277 /**
278 * Implementation of hook_perm
279 */
280 function hosting_site_perm() {
281 return array('create site', 'view site', 'edit site', 'delete site', 'administer sites');
282 }
283
284 /**
285 * Implementation of hook_access
286 */
287 function hosting_site_access($op, $node, $account) {
288 switch ($op) {
289 case 'create':
290 return user_access('create site', $account);
291 break;
292 case 'update':
293 return user_access('edit site', $account);
294 break;
295 case 'delete':
296 return user_access('delete site', $account);
297 break;
298 case 'view':
299 return user_access('view site', $account);
300 break;
301 }
302 }
303
304 /**
305 * Returns a count of sites.
306 *
307 * This is used by cron and statistics to batch the number of sites that are
308 * processed with each call. It is also used to generate the 'site count' per
309 * platform at /hosting/platforms
310 *
311 * By default it only counts enabled sites.
312 *
313 * Optionally can include an array of site statuses by which to consider in the
314 * count.
315 *
316 * @param $platform
317 * (optional) A platform nid to only count sites on that specific platform.
318 * @param $statuses
319 * (optional) An array of site statuses (defined by their constants) by which
320 * to include such sites in the site count.
321 *
322 * @return
323 * The number of sites matching the specified criteria.
324 */
325 function hosting_site_count($platform = NULL, $statuses = NULL) {
326 if (is_null($statuses)) {
327 $statuses = array(HOSTING_SITE_ENABLED);
328 }
329 $args = array();
330 $query = "SELECT count(nid) FROM {hosting_site}";
331 $where = array();
332
333 if (count($statuses)) {
334 $where[] = '(status IN (' . db_placeholders($statuses) . '))';
335 $args = array_merge($args, $statuses);
336 }
337
338 if (!is_null($platform)) {
339 $where[] = "(platform = %d)";
340 $args[] = $platform;
341 }
342
343 if (!empty($where)) {
344 $query .= ' WHERE ' . implode(' AND ', $where);
345 }
346
347 return db_result(db_query($query, $args));
348 }
349
350 /**
351 * Retrieve sites on a specific platform, with a specific status
352 */
353 function hosting_get_sites_by_status($platform, $status) {
354 $nodes = array();
355 $result = db_query("SELECT nid FROM {hosting_site} WHERE platform=%d AND status = %d", $platform, $status);
356 while ($nid = db_fetch_object($result)) {
357 $nodes[$nid->nid] = node_load($nid->nid);
358 }
359
360 return $nodes;
361 }
362
363 /**
364 * Retrieve a node based on the url
365 */
366 function hosting_get_site_by_url($url) {
367 // If the Aliases feature is enabled, try and get the site by its alias too
368 if (hosting_feature('alias')) {
369 $nid = db_result(db_query("SELECT n.nid FROM {node} n JOIN {hosting_site} h ON n.nid = h.nid LEFT JOIN {hosting_site_alias} ha ON h.vid = ha.vid WHERE (n.title = '%s' OR ha.alias = '%s') AND n.type = 'site' AND NOT (h.status = %d)", $url, $url, HOSTING_SITE_DELETED));
370 }
371 else {
372 $nid = db_result(db_query("SELECT n.nid FROM {node} n JOIN {hosting_site} h ON n.nid = h.nid WHERE n.title='%s' AND n.type = 'site' AND NOT (h.status=%d)", $url, HOSTING_SITE_DELETED));
373 }
374 if ($nid) {
375 return node_load($nid);
376 }
377 return false;
378 }
379
380 /**
381 * Helper function to generate update a site node during import.
382 *
383 * @param $site_id
384 * The node ID of the existing site node to update.
385 * @param $data
386 * An associative array of data to add to the site node. Keys should correspond
387 * to properties on the node object to overwrite.
388 * @param $platform
389 * The node ID of the platform that the site is deployed on.
390 */
391 function hosting_import_site($site_id, $data, $platform) {
392 global $user;
393 $client = node_load(HOSTING_DEFAULT_CLIENT);
394
395 if ($data['client_name']) {
396 $client = hosting_import_client($data['client_name']);
397 }
398
399 $site = node_load($site_id);
400 $site->nid = $site_id;
401 $site->uid = $client->uid;
402 $site->status = 1;
403 $site->site_status = 1;
404 $site->platform = $platform;
405 $site->no_verify = TRUE;
406 $site->verified = time();
407 $site->client = $client->nid ? $client->nid : HOSTING_DEFAULT_CLIENT;
408 $site->ip_addresses = array_values($data['site_ip_addresses']);
409 $site->cron_key = ($data['cron_key']) ? $data['cron_key'] : '';
410
411 $site->aliases = ($data['aliases']) ? $data['aliases'] : array();
412 $site->db_server = ($site->db_server) ? $site->db_server : HOSTING_DEFAULT_DB_SERVER;
413 $site->site_language = $data['language'] ? $data['language'] : 'en';
414
415 // Drupal 6 introduced a language field on nodes
416 unset($data['language']);
417
418
419 $profile = hosting_package_instance_load(array(
420 'i.rid' => $platform,
421 'p.short_name' => $data['profile']
422 ));
423 if (!$profile) {
424 $profile = hosting_package_instance_load(array(
425 'i.rid' => $platform,
426 'p.short_name' => 'default'));
427 }
428 $site->profile = $profile->package_id;
429
430 // cast site object to array, will be using various array_* functions on the data.
431 $site = (array) $site;
432
433 // Protect the fields already in the site object.
434 foreach (array_keys($site) as $key) {
435 unset($data[$key]);
436 }
437
438 // Load all the original node fields.
439 $site = array_merge( (array) node_load($site_id), $site);
440
441 // Map the imported fields onto the node object.
442 $site = array_merge($site, $data);
443
444 // Cast back to object.
445 $site = (object) $site;
446 node_save($site);
447 }
448
449 /**
450 * Define the status types of a site
451 */
452 function _hosting_site_status($node) {
453 $status = (is_numeric($node)) ? $node : $node->site_status;
454 static $labels = array(
455 HOSTING_SITE_QUEUED => "Queued",
456 HOSTING_SITE_ENABLED => "Enabled",
457 HOSTING_SITE_DELETED => "Deleted",
458 HOSTING_SITE_DISABLED => "Disabled",
459 );
460 return $labels[$status];
461 }
462
463 /**
464 * Implementation of hook_allow_domain().
465 *
466 * @see hosting_domain_allowed()
467 */
468 function hosting_site_allow_domain($url, $params = array()) {
469 $query = "SELECT COUNT(n.nid) FROM {node} n
470 JOIN {hosting_site} h ON n.nid = h.nid
471 WHERE type='site' AND title='%s' AND h.status <> %d ";
472 $args[] = $url;
473 $args[] = HOSTING_SITE_DELETED;
474
475 if (isset($params['nid'])) {
476 $query .= ' AND n.nid <> %d';
477 $args[] = $params['nid'];
478 }
479 $result = !db_result(db_query($query, $args));
480 return $result;
481 }
482
483 function hosting_site_task_status($nid) {
484 return hosting_task_status_output('nid', $nid, 'install');
485 }
486
487 /**
488 * Create a form for building a list of sites.
489 * @TODO Add ability to filter by additional fields
490 */
491 function hosting_site_list_form($form_state, $filter_by = NULL, $filter_value = NULL) {
492 $step = isset($form_state['storage']['step']) ? $form_state['storage']['step'] : 1;
493
494 // Step 1 - select sites
495 if ($step == 1) {
496 $args[] = 'site';
497 $cond = '';
498
499 if ($filter_by && $filter_value) {
500 if ($filter_by == 'status') {
501 $cond = ' AND s.' . $filter_by . ' & %d';
502 } else {
503 $cond = ' AND s.' . $filter_by . ' = %d';
504 }
505 $args[] = $filter_value;
506 }
507
508 $header = array(
509 array('data' => t('Site'), 'field' => 'title'),
510 array('data' => t('Profile'), 'field' => 'profile'),
511 array('data' => t('Language'), 'field' => 'site_language'),
512 array('data' => t('Created'), 'field' => 'created', 'sort' => 'desc'),
513 );
514 $platforms = _hosting_get_platforms();
515 if (sizeof($platforms) > 1) {
516 $header[] = array('data' => t('Platform'), 'field' => 'platform');
517 }
518
519 $sql = "SELECT n.nid, n.title, n.created, s.status as site_status, profile, s.language as site_language, platform, verified FROM {node} n left join {hosting_site} s ON n.vid=s.vid WHERE type='%s' AND s.status != -2 " . $cond;
520 $sql .= tablesort_sql($header);
521
522 // @TODO hide deleted sites
523 $result = pager_query(db_rewrite_sql($sql), 25, 1, null, $args);
524
525 $form['options'] = array(
526 '#type' => 'fieldset',
527 '#title' => t('Site tasks'),
528 '#prefix' => '<div class="container-inline">',
529 '#suffix' => '</div>',
530 );
531 $options = array();
532
533 foreach (hosting_available_tasks('site') as $task => $array) {
534 // At this stage we only want to handle simple tasks, the presense of a
535 // specific task form means there are other options for this tasks.
536 $func = 'hosting_task_' . $task . '_form';
537 if (!function_exists($func) && user_access('create '. $task .' task')) {
538 $options[$task] = $array['title'];
539 }
540 }
541 $form['options']['task'] = array(
542 '#type' => 'select',
543 '#options' => $options,
544 '#default_value' => 'backup',
545 );
546 $form['options']['submit'] = array(
547 '#type' => 'submit',
548 '#value' => t('Add to queue'),
549 '#submit' => array('hosting_site_list_form_submit'),
550 );
551
552 $sites = array();
553 while ($node = db_fetch_object($result)) {
554 $sites[$node->nid] = '';
555 $form['site'][$node->nid] = array('#value' => l($node->title, 'node/' . $node->nid));
556 $form['profile'][$node->nid] = array('#value' => ($node->profile) ? _hosting_node_link($node->profile) : t('n/a'));
557 $form['language'][$node->nid] = array('#value' => ($node->site_language) ? _hosting_language_name($node->site_language) : t('n/a'));
558 $form['created'][$node->nid] = array('#value' => t("@interval ago", array('@interval' => format_interval(time() - $node->created, 1))));
559 if (sizeof($platforms) > 1) {
560 $form['platform'][$node->nid] = array('#value' => ($node->platform) ? _hosting_node_link($node->platform) : t('n/a'));
561 }
562 $form['site_class'][$node->nid] = array('#value' => _hosting_site_list_class($node, $node->verified));
563 }
564 $form['sites'] = array('#type' => 'checkboxes', '#options' => $sites);
565 $form['pager'] = array('#value' => theme('pager', NULL, 25, 1));
566 $form['#theme'] = 'hosting_site_list';
567 $form['#action'] = url('hosting/sites');
568 return $form;
569 }
570 elseif ($step == 2) {
571 $task = $form_state['values']['task'];
572 $tasks = hosting_available_tasks('site');
573
574 $title = array(
575 'passed' => t("The following sites will be processed"),
576 'failed' => t("The following sites failed validation checks and will not be processed")
577 );
578 foreach (array('passed', 'failed') as $type) {
579 if (sizeof($form_state['storage'][$type])) {
580 foreach ($form_state['storage'][$type] as $site_id => $url) {
581 $row = array(
582 'data' => array(
583 array('data' => l($url, 'node/'.$site_id), 'class' => 'hosting-status'),
584 ),
585 'class' => ($type == 'passed' ? 'hosting-success' : 'hosting-error'),
586 );
587 $rows[] = $row;
588 }
589 }
590 }
591
592 $header = array(t('Site'));
593 $form['sites_test'] = array(
594 '#value' => theme('table', $header, $rows)
595 );
596
597 if (sizeof($form_state['storage']['failed']) && sizeof($form_state['storage']['passed'])) {
598 drupal_set_message(t('The task @task is not able to be performed on all the sites selected, the sites below that failed will not be added to the queue.', array('@task' => $task)), 'warning');
599 }
600 elseif (sizeof($form_state['storage']['failed'])) {
601 drupal_set_message(t('The task @task is not able to be performed on any of the selected sites.', array('@task' => $task)), 'error');
602 $form['return_link'] = array('#value' => l('Return to site listing', 'hosting/sites'));
603 return $form;
604 }
605
606 $form['help'] = array('#value' => $tasks[$task]['description']);
607
608 $question = t('Are you sure you want to perform the "@task" task on each of the following sites?', array('@task' => $tasks[$task]['title']));
609 return confirm_form($form, $question, 'hosting/sites', '', $tasks[$task]['title']);
610 }
611 }
612 /**
613 * Validate hosting_site_list form submissions.
614 */
615 function hosting_site_list_form_validate($form, &$form_state) {
616 if (isset($form_state['values']['sites'])) {
617 $sites = array_filter($form_state['values']['sites']);
618 if (count($sites) == 0) {
619 form_set_error('', t('No sites selected.'));
620 }
621 }
622 }
623
624 /**
625 * Process hosting_site_list form submissions.
626 */
627 function hosting_site_list_form_submit($form, &$form_state) {
628 $step = isset($form_state['storage']['step']) ? $form_state['storage']['step'] : 1;
629
630 $task = $form_state['values']['task'];
631 switch ($step) {
632 case 1:
633 $form_state['storage']['task'] = $task;
634 // Verify tasks can be performed on each site.
635 $tasks = hosting_available_tasks('site');
636
637 // Filter out unchecked sites
638 $sites = array_filter($form_state['values']['sites']);
639
640 $operations = array();
641 foreach ($sites as $site) {
642 $operations[] = array('hosting_sites_batch_process',
643 array($site, $task));
644 }
645 if (sizeof($operations)) {
646 $batch = array(
647 'operations' => $operations,
648 'title' => t('Processing'),
649 'progress_message' => t('Evaluated @current out of @total sites.'),
650 'error_message' => t('The update has encountered an error.'),
651 );
652 batch_set($batch);
653 }
654 break;
655 case 2:
656 $values = $form_state['values'];
657 foreach ($form_state['storage']['passed'] as $site_id => $url) {
658 hosting_add_task($site_id, $form_state['storage']['task'], $values['parameters']);
659 }
660 unset($form_state['storage']);
661 $step = 0;
662 drupal_set_message(t('The task @task will be applied to the selected sites and have been added to the task queue.', array('@task' => $form_state['storage']['task'])));
663 break;
664 }
665 $form_state['storage']['step'] = $step + 1;
666 }
667
668 function hosting_sites_batch_process($site_id, $task, &$context) {
669 if (!isset($context['sandbox']['progress'])) {
670 $context['sandbox']['progress'] = 0;
671 }
672
673 $site = node_load($site_id);
674 $batch =& batch_get();
675
676 if (hosting_task_menu_access($site, $task)) {
677 $batch['form_state']['storage']['passed'][$site->nid] = $site->title;
678 }
679 else {
680 $batch['form_state']['storage']['failed'][$site->nid] = $site->title;
681 }
682 }
683
684 /**
685 * Implementation of hook_theme().
686 */
687 function hosting_site_theme() {
688 return array(
689 'hosting_site_list' => array(
690 'arguments' => array('form' => NULL),
691 ),
692 );
693 }
694
695 /**
696 * Build the site list form.
697 */
698 function theme_hosting_site_list($form) {
699 // If there are rows in this form, then $form['site'] contains a list of
700 // the title form elements.
701 $has_posts = isset($form['site']) && is_array($form['site']);
702 $select_header = $has_posts ? theme('table_select_header_cell') : '';
703 $header = array(
704 $select_header,
705 array('data' => t('Site'), 'field' => 'title'),
706 array('data' => t('Profile'), 'field' => 'profile'),
707 array('data' => t('Language'), 'field' => 'site_language'),
708 array('data' => t('Created'), 'field' => 'created', 'sort' => 'desc'),
709 );
710 if (isset($form['platform'])) {
711 $header[] = array('data' => t('Platform'), 'field' => 'platform');
712 }
713 $output = '';
714
715 $output .= drupal_render($form['options']);
716 if ($has_posts) {
717 foreach (element_children($form['site']) as $key) {
718 $row = array();
719 $row[] = drupal_render($form['sites'][$key]);
720 $row[] = array('data' => drupal_render($form['site'][$key]), 'class'=> 'hosting-status');
721 $row[] = drupal_render($form['profile'][$key]);
722 $row[] = drupal_render($form['language'][$key]);
723 $row[] = drupal_render($form['created'][$key]);
724 if (isset($form['platform'])) {
725 $row[] = drupal_render($form['platform'][$key]);
726 }
727 $rows[] = array('data' => $row, 'class' => drupal_render($form['site_class'][$key]));
728 }
729
730 }
731 else {
732 $rows[] = array(array('data' => t('No sites available.'), 'colspan' => sizeof($header)));
733 }
734
735 $output .= theme('table', $header, $rows, array('class' => 'hosting-table'));
736 if ($form['pager']['#value']) {
737 $output .= drupal_render($form['pager']);
738 }
739
740 $output .= drupal_render($form);
741
742 return $output;
743 }
744
745
746 /**
747 * Define the classes that correspond to the site status.
748 * @see _hosting_site_status()
749 */
750 function _hosting_site_list_class($node, $verified = null) {
751 $status = (is_numeric($node)) ? $node : $node->site_status;
752 static $classes = array(
753 HOSTING_SITE_QUEUED => "hosting-queue",
754 HOSTING_SITE_ENABLED => "hosting-success",
755 HOSTING_SITE_DELETED => "hosting-error",
756 HOSTING_SITE_DISABLED => "hosting-error",
757 );
758 if (($status == HOSTING_SITE_ENABLED) && (!$verified)) {
759 return 'hosting-warning';
760 }
761
762 return $classes[$status];
763 }
764
765 /**
766 * Views integration
767 */
768 function hosting_site_views_api() {
769 return array(
770 'api' => 2,
771 'path' => drupal_get_path('module', 'hosting_site'),
772 );
773 }
774
775
776 function hosting_site_preprocess_views_view_table(&$variables) {
777 $view = $variables['view'];
778 if ($view->plugin_name == 'hosting_site_list') {
779 foreach ($view->result as $num => $result) {
780 if (isset($result->hosting_site_status) && isset($result->hosting_site_verified)) {
781 $variables['row_classes'][$num][] = _hosting_site_list_class($result->hosting_site_status, $result->hosting_site_verified);
782 }
783 }
784 }
785 $variables['class'] .= " hosting-table";
786 }