diff --git a/modules/hosting/package/hosting_package.module b/modules/hosting/package/hosting_package.module index 98d893f..ec3d370 100644 --- a/modules/hosting/package/hosting_package.module +++ b/modules/hosting/package/hosting_package.module @@ -32,45 +32,6 @@ function hosting_package_node_info() { return $types; } -/** - * Implementation of hook_menu(). - */ -function hosting_package_menu() { - $items = array(); - - $items['node/%hosting_package_node/packages'] = array( - 'title' => 'Packages', - 'description' => 'List of packages available for this platform', - 'page callback' => 'hosting_package_list', - 'page arguments' => array(1), - 'type' => MENU_LOCAL_TASK, - 'access arguments' => array('view package'), - 'weight' => 1, - ); - $items['node/%hosting_package_node/packages/all'] = array( - 'title' => 'All packages', - 'description' => 'List of all packages', - 'page callback' => 'hosting_package_list', - 'page arguments' => array(1), - 'access arguments' => array('view package'), - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -1, - ); - $x = 0; - foreach (_hosting_package_types() as $type => $description) { - $items['node/%hosting_package_node/packages/' . $type] = array( - 'title' => $description, - 'description' => $description, - 'page callback' => 'hosting_package_list', - 'page arguments' => array(1, $type), - 'access arguments' => array('view package'), - 'type' => MENU_LOCAL_TASK, - 'weight' => $x++, - ); - } - return $items; -} - function hosting_package_node_load($arg) { if (!is_numeric($arg)) { return FALSE; @@ -451,55 +412,11 @@ function hosting_package_sync(&$data) { } /** - * Display a list of packages associated to a node - * @TODO Add ability to filter by additional fields - * @TODO Add paging. - */ -function hosting_package_list($ref, $type = null) { - drupal_set_title(t('Packages on @reference', array('@reference' => $ref->title))); - $header = array( - array('data' => t('Status'), 'field' => 'status', 'sort' => 'DESC'), - array('data' => t('Package'), 'field' => 'short_name'), - array('data' => t('Release'), 'field' => 'version'), - array('data' => t('Package type'), 'field' => 'package_type'), - ); - $args[] = $ref->nid; - - if (!is_null($type)) { - $cond = " AND h.package_type = '%s'"; - $args[] = $type; - } - - $sql = "SELECT h.nid as 'package', i.status, h.short_name, i.version, h.package_type, i.status FROM {hosting_package} h - LEFT JOIN {hosting_package_instance} i ON i.package_id=h.nid WHERE i.rid=%d" . $cond; - $sql .= tablesort_sql($header); - // @TODO hide deleted sites - $result = pager_query(db_rewrite_sql($sql, 'h'), 25, 2, null, $args); - $view_package_perm = user_access('view package'); - - if (!$result) { - return t('No packages are associated with @reference', array('@reference' => $ref->title)); - } - $rows = array(); - while ($package = db_fetch_object($result)) { - $row_class = ($package->status == 1) ? 'hosting-success' : 'hosting-info'; - $row = array(); - $row[] = array('data' => ($package->status) ? t('Enabled') : t('Available') , 'class'=> 'hosting-status'); - $row[] = ($view_package_perm) ? l(filter_xss($package->short_name), 'node/' . $package->package) : $package->short_name; - $row[] = $package->version; - $row[] = filter_xss($package->package_type); - $rows[] = array('data' => $row, 'class' => $row_class); - } - - return theme('table', $header, $rows, array('class' => 'hosting-table')) . theme('pager', null, 25, 2); -} - -/** * Implementation of hook_views_api(). */ function hosting_package_views_api() { return array( - 'api' => 2, + 'api' => 3, 'path' => drupal_get_path('module', 'hosting_package'), ); } diff --git a/modules/hosting/package/hosting_package.views.inc b/modules/hosting/package/hosting_package.views.inc index 89772cf..446b93e 100644 --- a/modules/hosting/package/hosting_package.views.inc +++ b/modules/hosting/package/hosting_package.views.inc @@ -11,10 +11,11 @@ function hosting_package_views_handlers() { return array( 'info' => array( 'path' => drupal_get_path('module', 'hosting_package'), - ), + ), 'handlers' => array( - 'hosting_package_handler_filter_hosting_package_type' => array( - 'parent' => 'views_handler_filter_in_operator', + // field handlers + 'views_handler_field_hosting_package_status' => array( + 'parent' => 'views_handler_field_hosting_site_status', ), ), ); @@ -24,46 +25,193 @@ function hosting_package_views_handlers() { * Implementation of hook_views_data(). */ function hosting_package_views_data() { - $data['hosting_package'] = array( - 'table' => array( - 'group' => 'Hosting Package', - 'title' => 'Package', - 'join' => array( - 'node' => array( - 'left_field' => 'vid', - 'field' => 'vid', - ), + // Hosting package. + $data['hosting_package']['table'] = array( + 'group' => 'Hosting Package', + 'title' => 'Package', + 'join' => array( + 'node' => array( + 'left_field' => 'vid', + 'field' => 'vid', ), ), - 'package_type' => array( - 'title' => t('Type'), - 'help' => t('The type of the package (e.g. module, theme, profile).'), - 'field' => array( - 'handler' => 'views_handler_field', - 'click sortable' => TRUE, - ), - 'filter' => array( - 'handler' => 'hosting_package_handler_filter_hosting_package_type', - ), + ); + + $data['hosting_package']['package_type'] = array( + 'title' => t('Type'), + 'help' => t('The package type.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_in_operator', + 'options callback' => '_hosting_package_types', ), - 'short_name' => array( - 'title' => t('Name'), - 'help' => t('The name used .'), - 'field' => array( - 'handler' => 'views_handler_field', - 'click sortable' => TRUE, - ), - 'sort' => array( - 'handler' => 'views_handler_sort', - ), + 'sort' => array( + 'handler' => 'views_handler_sort', ), - 'description' => array( - 'title' => t('Description'), - 'help' => t('The description information for this package.'), - 'field' => array( - 'handler' => 'views_handler_field', - 'click sortable' => TRUE, - ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + + // Hosting package instance. + $data['hosting_package_instance']['table']['group'] = t('Hosting Package Instance'); + + $data['hosting_package_instance']['table']['base'] = array( + 'field' => 'filename', + 'title' => t('Hosting package instances'), + 'help' => t('Hosting package instances'), + ); + + $data['hosting_package_instance']['iid'] = array( + 'title' => t('Instance ID'), + 'help' => t('The package instance ID.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'numeric' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + $data['hosting_package_instance']['rid'] = array( + 'title' => t('Reference ID'), + 'help' => t('The package instance reference ID.'), + 'field' => array( + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'relationship' => array( + 'handler' => 'views_handler_relationship', + 'base' => 'node', + 'base field' => 'nid', + 'label' => t('site'), + ), + 'argument' => array( + 'handler' => 'views_handler_argument_node_nid', + ), + ); + + $data['hosting_package_instance']['package_id'] = array( + 'title' => t('Package ID'), + 'help' => t('The package ID.'), + 'field' => array( + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'relationship' => array( + 'handler' => 'views_handler_relationship', + 'base' => 'node', + 'base field' => 'nid', + 'label' => t('package'), + ), + 'argument' => array( + 'handler' => 'views_handler_argument_node_nid', + ), + ); + + $data['hosting_package_instance']['filename'] = array( + 'title' => t('File'), + 'help' => t('The package instance file.'), + 'field' => array( + 'handler' => 'views_handler_field_file', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + $data['hosting_package_instance']['schema_version'] = array( + 'title' => t('Schema version'), + 'help' => t('The package instance schema version.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'numeric' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + $data['hosting_package_instance']['version'] = array( + 'title' => t('Version'), + 'help' => t('The package instance version.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'numeric' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + $data['hosting_package_instance']['version_code'] = array( + 'title' => t('Version code'), + 'help' => t('The package instance version code.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'numeric' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + $data['hosting_package_instance']['status'] = array( + 'title' => t('Status'), + 'help' => t('The status of the pckage instance.'), + 'field' => array( + 'handler' => 'views_handler_field_hosting_package_status', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Status'), + 'type' => 'on-off', + // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statment + 'use equal' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', ), ); diff --git a/modules/hosting/package/hosting_platform.views_default.inc b/modules/hosting/package/hosting_platform.views_default.inc new file mode 100644 index 0000000..9078251 --- /dev/null +++ b/modules/hosting/package/hosting_platform.views_default.inc @@ -0,0 +1,249 @@ +name = 'hosting_package_list'; + $view->description = 'Display a list of packages for a hosted site'; + $view->tag = ''; + $view->base_table = 'hosting_package_instance'; + $view->human_name = ''; + $view->core = 6; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['use_ajax'] = TRUE; + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '25'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['pager']['options']['expose']['items_per_page_options_all'] = 0; + $handler->display->display_options['style_plugin'] = 'table'; + $handler->display->display_options['style_options']['row_class'] = '[status]'; + $handler->display->display_options['style_options']['columns'] = array( + 'status' => 'status', + 'status_1' => 'status_1', + 'title' => 'title', + 'version' => 'version', + 'package_type' => 'package_type', + ); + $handler->display->display_options['style_options']['default'] = 'status_1'; + $handler->display->display_options['style_options']['info'] = array( + 'status' => array( + 'sortable' => 0, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + ), + 'status_1' => array( + 'sortable' => 1, + 'default_sort_order' => 'desc', + 'align' => '', + 'separator' => '', + ), + 'title' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + ), + 'version' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + ), + 'package_type' => array( + 'sortable' => 1, + 'default_sort_order' => 'asc', + 'align' => '', + 'separator' => '', + ), + ); + $handler->display->display_options['style_options']['override'] = 1; + $handler->display->display_options['style_options']['sticky'] = 0; + $handler->display->display_options['style_options']['empty_table'] = 0; + /* Relationship: Hosting Package Instance: Package ID */ + $handler->display->display_options['relationships']['package_id']['id'] = 'package_id'; + $handler->display->display_options['relationships']['package_id']['table'] = 'hosting_package_instance'; + $handler->display->display_options['relationships']['package_id']['field'] = 'package_id'; + $handler->display->display_options['relationships']['package_id']['required'] = 0; + /* Field: Class */ + $handler->display->display_options['fields']['status']['id'] = 'status'; + $handler->display->display_options['fields']['status']['table'] = 'hosting_package_instance'; + $handler->display->display_options['fields']['status']['field'] = 'status'; + $handler->display->display_options['fields']['status']['ui_name'] = 'Class'; + $handler->display->display_options['fields']['status']['exclude'] = TRUE; + $handler->display->display_options['fields']['status']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['status']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['status']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['status']['alter']['external'] = 0; + $handler->display->display_options['fields']['status']['alter']['replace_spaces'] = 0; + $handler->display->display_options['fields']['status']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['status']['alter']['nl2br'] = 0; + $handler->display->display_options['fields']['status']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['status']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['status']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['status']['alter']['trim'] = 0; + $handler->display->display_options['fields']['status']['alter']['html'] = 0; + $handler->display->display_options['fields']['status']['element_label_colon'] = 1; + $handler->display->display_options['fields']['status']['element_default_classes'] = 1; + $handler->display->display_options['fields']['status']['hide_empty'] = 0; + $handler->display->display_options['fields']['status']['empty_zero'] = 0; + $handler->display->display_options['fields']['status']['hide_alter_empty'] = 1; + $handler->display->display_options['fields']['status']['status_mode'] = 'class'; + /* Field: Hosting Package Instance: Status */ + $handler->display->display_options['fields']['status_1']['id'] = 'status_1'; + $handler->display->display_options['fields']['status_1']['table'] = 'hosting_package_instance'; + $handler->display->display_options['fields']['status_1']['field'] = 'status'; + $handler->display->display_options['fields']['status_1']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['external'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['replace_spaces'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['nl2br'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['status_1']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['status_1']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['trim'] = 0; + $handler->display->display_options['fields']['status_1']['alter']['html'] = 0; + $handler->display->display_options['fields']['status_1']['element_class'] = 'hosting-status'; + $handler->display->display_options['fields']['status_1']['element_label_colon'] = 1; + $handler->display->display_options['fields']['status_1']['element_default_classes'] = 1; + $handler->display->display_options['fields']['status_1']['hide_empty'] = 0; + $handler->display->display_options['fields']['status_1']['empty_zero'] = 0; + $handler->display->display_options['fields']['status_1']['hide_alter_empty'] = 1; + /* Field: Node: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['relationship'] = 'package_id'; + $handler->display->display_options['fields']['title']['label'] = 'Package'; + $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['title']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['title']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['title']['alter']['external'] = 0; + $handler->display->display_options['fields']['title']['alter']['replace_spaces'] = 0; + $handler->display->display_options['fields']['title']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['title']['alter']['nl2br'] = 0; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['title']['alter']['trim'] = 0; + $handler->display->display_options['fields']['title']['alter']['html'] = 0; + $handler->display->display_options['fields']['title']['element_label_colon'] = 1; + $handler->display->display_options['fields']['title']['element_default_classes'] = 1; + $handler->display->display_options['fields']['title']['hide_empty'] = 0; + $handler->display->display_options['fields']['title']['empty_zero'] = 0; + $handler->display->display_options['fields']['title']['hide_alter_empty'] = 1; + $handler->display->display_options['fields']['title']['link_to_node'] = 1; + /* Field: Hosting Package Instance: Version */ + $handler->display->display_options['fields']['version']['id'] = 'version'; + $handler->display->display_options['fields']['version']['table'] = 'hosting_package_instance'; + $handler->display->display_options['fields']['version']['field'] = 'version'; + $handler->display->display_options['fields']['version']['label'] = 'Release'; + $handler->display->display_options['fields']['version']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['version']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['version']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['version']['alter']['external'] = 0; + $handler->display->display_options['fields']['version']['alter']['replace_spaces'] = 0; + $handler->display->display_options['fields']['version']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['version']['alter']['nl2br'] = 0; + $handler->display->display_options['fields']['version']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['version']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['version']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['version']['alter']['trim'] = 0; + $handler->display->display_options['fields']['version']['alter']['html'] = 0; + $handler->display->display_options['fields']['version']['element_label_colon'] = 1; + $handler->display->display_options['fields']['version']['element_default_classes'] = 1; + $handler->display->display_options['fields']['version']['hide_empty'] = 0; + $handler->display->display_options['fields']['version']['empty_zero'] = 0; + $handler->display->display_options['fields']['version']['hide_alter_empty'] = 1; + $handler->display->display_options['fields']['version']['format_plural'] = 0; + /* Field: Hosting Package: Type */ + $handler->display->display_options['fields']['package_type']['id'] = 'package_type'; + $handler->display->display_options['fields']['package_type']['table'] = 'hosting_package'; + $handler->display->display_options['fields']['package_type']['field'] = 'package_type'; + $handler->display->display_options['fields']['package_type']['relationship'] = 'package_id'; + $handler->display->display_options['fields']['package_type']['label'] = 'Package type'; + $handler->display->display_options['fields']['package_type']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['external'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['replace_spaces'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['nl2br'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['package_type']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['package_type']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['trim'] = 0; + $handler->display->display_options['fields']['package_type']['alter']['html'] = 0; + $handler->display->display_options['fields']['package_type']['element_label_colon'] = 1; + $handler->display->display_options['fields']['package_type']['element_default_classes'] = 1; + $handler->display->display_options['fields']['package_type']['hide_empty'] = 0; + $handler->display->display_options['fields']['package_type']['empty_zero'] = 0; + $handler->display->display_options['fields']['package_type']['hide_alter_empty'] = 1; + /* Sort criterion: Hosting Package Instance: Status */ + $handler->display->display_options['sorts']['status']['id'] = 'status'; + $handler->display->display_options['sorts']['status']['table'] = 'hosting_package_instance'; + $handler->display->display_options['sorts']['status']['field'] = 'status'; + $handler->display->display_options['sorts']['status']['order'] = 'DESC'; + /* Sort criterion: Node: Title */ + $handler->display->display_options['sorts']['title']['id'] = 'title'; + $handler->display->display_options['sorts']['title']['table'] = 'node'; + $handler->display->display_options['sorts']['title']['field'] = 'title'; + $handler->display->display_options['sorts']['title']['relationship'] = 'package_id'; + /* Argument: Hosting Package Instance: Reference ID */ + $handler->display->display_options['arguments']['rid']['id'] = 'rid'; + $handler->display->display_options['arguments']['rid']['table'] = 'hosting_package_instance'; + $handler->display->display_options['arguments']['rid']['field'] = 'rid'; + $handler->display->display_options['arguments']['rid']['default_action'] = 'default'; + $handler->display->display_options['arguments']['rid']['style_plugin'] = 'default_summary'; + $handler->display->display_options['arguments']['rid']['title'] = 'Packages on %1'; + $handler->display->display_options['arguments']['rid']['default_argument_type'] = 'node'; + $handler->display->display_options['arguments']['rid']['default_argument_skip_url'] = 0; + $handler->display->display_options['arguments']['rid']['validate_type'] = 'node'; + $handler->display->display_options['arguments']['rid']['validate_options']['types'] = array( + 'site' => 'site', + ); + $handler->display->display_options['arguments']['rid']['validate_options']['access'] = 0; + $handler->display->display_options['arguments']['rid']['break_phrase'] = 0; + $handler->display->display_options['arguments']['rid']['not'] = 0; + /* Filter: Hosting Package: Type */ + $handler->display->display_options['filters']['package_type']['id'] = 'package_type'; + $handler->display->display_options['filters']['package_type']['table'] = 'hosting_package'; + $handler->display->display_options['filters']['package_type']['field'] = 'package_type'; + $handler->display->display_options['filters']['package_type']['relationship'] = 'package_id'; + $handler->display->display_options['filters']['package_type']['exposed'] = TRUE; + $handler->display->display_options['filters']['package_type']['expose']['operator'] = 'package_type_op'; + $handler->display->display_options['filters']['package_type']['expose']['limit_operators'] = array(); + $handler->display->display_options['filters']['package_type']['expose']['label'] = 'Type'; + $handler->display->display_options['filters']['package_type']['expose']['identifier'] = 'package_type'; + $handler->display->display_options['filters']['package_type']['expose']['reduce'] = 0; + + /* Display: Page */ + $handler = $view->new_display('page', 'Page', 'page_1'); + $handler->display->display_options['path'] = 'node/%/packages'; + $handler->display->display_options['menu']['type'] = 'tab'; + $handler->display->display_options['menu']['title'] = 'Packages'; + $handler->display->display_options['menu']['weight'] = '1'; + + $views[$view->name] = $view; + + return $views; +} diff --git a/modules/hosting/package/views_handler_field_hosting_package_status.inc b/modules/hosting/package/views_handler_field_hosting_package_status.inc new file mode 100644 index 0000000..d5fe7d4 --- /dev/null +++ b/modules/hosting/package/views_handler_field_hosting_package_status.inc @@ -0,0 +1,33 @@ +{$this->field_alias}; + $output = $value ? t('Enabled') : t('Disabled'); + + switch ($this->options['status_mode']) { + case 'image': + return ""; + + case 'text_image': + return "{$output}"; + + case 'class': + return $value ? 'hosting-success' : 'hosting-info'; + } + return $output; + } +} diff --git a/modules/hosting/server/hosting_server.module b/modules/hosting/server/hosting_server.module index db65746..7a09e41 100644 --- a/modules/hosting/server/hosting_server.module +++ b/modules/hosting/server/hosting_server.module @@ -237,7 +237,6 @@ function hosting_server_form(&$node) { if (!$node->nid) { $node->services = array(); - $node->ip_addresses = array(); } // taken mostly from the hosting_site alias stuff @@ -261,7 +260,6 @@ function hosting_server_form(&$node) { // Get the list of existing IPs $ips = $node->ip_addresses; $ips_count = max(3, empty($ips) ? 3 : count($ips) + 1); - // Add alias textfields foreach ($ips as $id => $ip) { $form['ips_wrapper']['ip_addresses'][$id] = array( @@ -575,3 +573,13 @@ function hosting_get_servers($service) { drupal_alter('hosting_servers_titles', $return, $service); return $return; } + +/** + * Views integration + */ +function hosting_server_views_api() { + return array( + 'api' => 3, + 'path' => drupal_get_path('module', 'hosting_server'), + ); +} diff --git a/modules/hosting/server/hosting_server.views.inc b/modules/hosting/server/hosting_server.views.inc new file mode 100644 index 0000000..bc60a3b --- /dev/null +++ b/modules/hosting/server/hosting_server.views.inc @@ -0,0 +1,68 @@ + 'Hosting Server', + 'title' => 'Server', + 'join' => array( + 'node' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + ), + ); + + $data['hosting_service']['service'] = array( + 'title' => t('Service'), + 'help' => t('The type of service.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + ); + + $data['hosting_service']['type'] = array( + 'title' => t('Type'), + 'help' => t('The service sub-type.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + ); + + $data['hosting_service']['restart_cmd'] = array( + 'title' => t('Restart command'), + 'help' => t('The restart command for the service.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + ); + + $data['hosting_service']['port'] = array( + 'title' => t('Port'), + 'help' => t('The port for the service.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + ); + + $data['hosting_service']['available'] = array( + 'title' => t('Available'), + 'help' => t('Whether the service is available.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + ); + + return $data; +} diff --git a/modules/hosting/task/hosting_task.module.orig b/modules/hosting/task/hosting_task.module.orig deleted file mode 100644 index d23f151..0000000 --- a/modules/hosting/task/hosting_task.module.orig +++ /dev/null @@ -1,1203 +0,0 @@ - $info) { - if (empty($info['hidden'])) { - $path = sprintf("node/%%hosting_%s_node/%s_%s", $type, $type, $task); - $items[$path] = array( - 'title' => $info['title'], - 'description' => $info['description'], - 'page callback' => 'drupal_get_form', - 'page arguments' => array('hosting_task_confirm_form', 1, $task), - 'access callback' => 'hosting_task_menu_access_csrf', - 'access arguments' => array(1, $task), - 'type' => MENU_CALLBACK, - ); - $items[$path] = array_merge($items[$path], $info); - } - } - } - - $items['hosting/tasks/%node/list'] = array( - 'title' => t('Task list'), - 'description' => t('AJAX callback for refreshing task list'), - 'page callback' => 'hosting_task_ajax_list', - 'page arguments' => array(2), - 'access callback' => 'node_access', - 'access arguments' => array('view', 2), - 'type' => MENU_CALLBACK - ); - - - $items['hosting/tasks/%node/cancel'] = array( - 'title' => t('Task list'), - 'description' => t('Callback for stopping tasks'), - 'page callback' => 'hosting_task_cancel', - 'page arguments' => array(2), - 'access callback' => 'hosting_task_cancel_access', - 'access arguments' => array(2), - 'type' => MENU_CALLBACK - ); - - - $items['hosting/tasks/queue'] = array( - 'title' => t('Task list'), - 'description' => t('AJAX callback for refreshing task queue'), - 'page callback' => 'hosting_task_ajax_queue', - 'access arguments' => array('access task logs'), - 'type' => MENU_CALLBACK - ); - - return $items; -} - -function hosting_task_ajax_list($node) { - $return['markup'] = hosting_task_table($node); - $return['changed'] = $node->changed; - $return['navigate_url'] = url('node/' . $node->nid); - drupal_json($return); - exit(); -} - -function hosting_task_ajax_queue() { - $return['markup'] = hosting_task_queue_block(); - drupal_json($return); - exit(); -} - -function hosting_task_cancel($node) { - if ($node->type == 'task') { - if ($node->task_status == 0) { - $ref = node_load($node->rid); - - hosting_add_task($node->rid, $node->task_type, array(), HOSTING_TASK_ERROR); - // Log the cancellation - hosting_task_log($node->vid, 'error', t("Task was cancelled.")); - drupal_goto('node/' . $node->rid); - } - } - - drupal_access_denied(); -} - -/* - * Implementation of hook_access() - */ - -function hosting_task_cancel_access($node) { - // bring $user into scope, so we can test task ownership - global $user; - - // To prevent CSRF attacks, a unique token based upon user is used. Deny - // access if the token is missing or invalid. - if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], $user->uid)) { - return FALSE; - } - - // 'administer tasks' allows cancelling any and all tasks on the system - if (user_access('administer tasks')) { - return TRUE; - } - // 'cancel own tasks' allows cancelling any task the user *could have* created, on nodes she can view - if (user_access('cancel own tasks') && user_access('create ' . $node->task_type . ' task') && node_access('view', $node)) { - return TRUE; - } -} - -/** - * Task access controls - * - * This function defines which tasks should be showed to the user but - * especially which will be accessible to him, in the permissions system. - * - * @arg $node object - * the node object we're trying to access - * - * @arg $task string - * the task type we're trying to do on the $node - * - * @see hosting_task_menu() - */ -function hosting_task_menu_access($node, $task) { - if (user_access("create " . $task . " task")) { - if ($node->type == 'site') { - if (hosting_task_outstanding($node->nid, 'delete') || ($node->site_status == HOSTING_SITE_DELETED)) { - return FALSE; - } - if (($task == 'login-reset') && ($node->site_status != HOSTING_SITE_ENABLED)) { - return FALSE; - } - $safe_tasks = array('backup', 'backup-delete', 'verify', 'enable'); - if (!in_array($task, $safe_tasks)) { - // Don't show certain tasks if the site is the 'special' main aegir site - $profile = node_load($node->profile); - if ($profile->short_name == 'hostmaster') { - return FALSE; - } - } - - $site_enabled = (hosting_task_outstanding($node->nid, 'enable') || ($node->site_status == HOSTING_SITE_ENABLED)); - $deletable = ($task == "delete"); - $enabable = ($task == "enable"); - - $delete_or_enable = ($deletable || $enabable); - - // If the site is not enabled, we can either delete it, or enable it again - if (!$site_enabled) { - return ($delete_or_enable); - } - else { - // Site is enabled - return ( - // If we can just delete a site without disabling, allow that - (!variable_get('hosting_require_disable_before_delete', TRUE)) && $deletable - // Otherwise we must disable it first, hide the delete task and the enable task as well - || !$delete_or_enable - ); - } - } - if ($node->type == 'platform') { - // if the user can't edit this node, he can't create tasks on it - if (!node_access('update', $node, $GLOBALS['user'])) { - return FALSE; - } - // If the platform is in a deleted state, nothing else can be done with it - if (hosting_task_outstanding($node->nid, 'delete') || ($node->platform_status == HOSTING_PLATFORM_DELETED)) { - return FALSE; - } - // If the platform's been locked, we can unlock it, delete, batch migrate existing sites or verify - if ($node->platform_status == HOSTING_PLATFORM_LOCKED) { - $platform_tasks = array('verify', 'unlock', 'delete', 'migrate'); - } - else { - // If the platform's unlocked, we can lock it, delete it or batch migrate sites - $platform_tasks = array('verify', 'lock', 'delete', 'migrate'); - } - return (in_array($task, $platform_tasks)); - } - if ($node->type === 'server') { - // If the user can't edit this node, he can't create tasks on it. - if (!node_access('update', $node, $GLOBALS['user'])) { - return FALSE; - } - // todo probably need more checks - return TRUE; - } - } - return FALSE; -} - -/** - * Access callback helper for hosting task menu items. - * - * Implemented as a helper function since we only want to validate the CSRF - * token when the user accesses a certain path, not when (for example) building - * the list of tasks a user has access to. - * - * @see hosting_task_menu_access() - */ -function hosting_task_menu_access_csrf($node, $task) { - global $user; - - $interactive_tasks = array('migrate', 'clone'); - - // To prevent CSRF attacks, a unique token based upon user is used. Deny - // access if the token is missing or invalid. We only do this on - // non-interactive tasks. - if (!in_array($task, $interactive_tasks) && (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], $user->uid))) { - return FALSE; - } - // Call the main menu access handler. - return hosting_task_menu_access($node, $task); -} - -/** - * Implementation of hook_node_info() - */ -function hosting_task_node_info() { - #management - $types["task"] = array( - "type" => 'task', "name" => 'Task', - "module" => 'hosting_task', - "has_title" => FALSE, "title_label" => '', - "description" => hosting_node_help("task"), - "has_body" => 0, "body_label" => '', "min_word_count" => 0); - - return $types; -} - -/** - * Implementation of hook_access() - */ -function hosting_task_access($op, $node, $account) { - if(user_access('administer tasks', $account)) { - return TRUE; - } -} - -/** - * Implementation of hook_perm() - */ -function hosting_task_perm() { - return array( - 'administer tasks', - 'create backup task', - 'create restore task', - 'create disable task', - 'create enable task', - 'create delete task', - 'create verify task', - 'create lock task', - 'create unlock task', - 'create login-reset task', - 'create backup-delete task', - 'view own tasks', - 'view task', - 'access task logs', - 'retry failed tasks', - 'cancel own tasks', -); -} - -/** - * Implementation of hook_hosting_queues - * - * Return a list of queues that this module needs to manage. - */ -function hosting_task_hosting_queues() { - $queue['tasks'] = array( - 'name' => t('Task queue'), - 'description' => t('Process the queue of outstanding hosting tasks.'), - 'type' => 'serial', # run queue sequentially. always with the same parameters. - 'frequency' => strtotime("1 minute", 0), # run queue every minute. - 'items' => 5, # process 20 queue items per execution. - 'total_items' => hosting_task_count(), - 'singular' => t('task'), - 'plural' => t('tasks'), - 'running_items' => hosting_task_count_running(), - ); - return $queue; -} - -/** - * Insert an entry in the task log. - * - * @param $vid - * The vid of the task to add an entry for. - * @param $type - * The type of log entry being added. - * @param $message - * The message for this log entry. - * @param $error - * (optional) The error code associated to this log entry. - * @param $timestamp - * (optional) The UNIX timestamp of this log message, this defaults to the - * current time. - */ -function hosting_task_log($vid, $type, $message, $error = '', $timestamp = NULL) { - // We keep track of nids we've looked up in this request, for faster lookups. - static $nids = array(); - $timestamp = ($timestamp) ? $timestamp : time(); - - // We need to insert the nid in addition to the vid, so look it up. - if (!isset($nids[$vid])) { - $nids[$vid] = (int)db_result(db_query('SELECT nid FROM {hosting_task} WHERE vid = %d', $vid)); - } - - db_query("INSERT INTO {hosting_task_log} (vid, nid, type, message, error, timestamp) VALUES (%d, %d, '%s', '%s', '%s', %d)", $vid, $nids[$vid], $type, $message, $error, $timestamp); -} - -/** - * Retry the given task - */ -function hosting_task_retry($task_id) { - $node = node_load($task_id); - if ($node->task_status != HOSTING_TASK_QUEUED) { - drupal_set_message(t("The task is being retried and has been added to the hosting queue again")); - hosting_task_log($node->vid, 'queue', t("The task is being retried and has been added to the hosting queue again")); - $node->revision = TRUE; - $node->changed = time(); - $node->task_status = HOSTING_TASK_QUEUED; - node_save($node); - } -} - -/** - * Helper function to generate new task node - */ -function hosting_add_task($nid, $type, $args = null, $status = HOSTING_TASK_QUEUED) { - global $user; - - $task = hosting_get_most_recent_task($nid, $type); - - $node = db_fetch_object(db_query("SELECT nid, uid, title FROM {node} WHERE nid=%d", $nid)); - if (!$task) { - $task = new stdClass(); - } - $task->type = 'task'; -# TODO: make this pretty - $task->title = t("!type !title", array('!type' => $type, '!title' => $node->title)); - $task->task_type = $type; - $task->rid = $node->nid; - /* - * fallback the owner of the task to the owner of the node we operate - * upon - * - * this is mostly for the signup form, which runs as the anonymous - * user, but for which the node is set to the right user - */ - $task->uid = $user->uid ? $user->uid : $node->uid; - $task->status = 1; - $task->task_status = $status; - if ($status == HOSTING_TASK_QUEUED) { - $task->revision = TRUE; - } - #arguments, such as which backup to restore. - if (is_array($args)) { - $task->task_args = $args; - } - node_save($task); - - drupal_set_message(t("Task %type was added to the queue. Next queue run is %date, server time is %time.", array('%type' => $type, '%date' => format_date(_hosting_queue_next_run('tasks'), 'custom', 'H:i:sO'), '%time' => format_date(time(), 'custom', 'H:i:sO')))); - - return $task; -} -/** - * Implementation of hook_form(). - */ -function hosting_task_confirm_form($form_state, $node, $task) { - drupal_add_js(drupal_get_path('module','hosting_task') . '/hosting_task.js'); - $tasks = hosting_available_tasks($node->type); - - if (!isset($tasks[$task]['dialog']) || !$tasks[$task]['dialog']) { - hosting_add_task($node->nid, $task); - drupal_goto('node/' . $node->nid); - } - - $form['help'] = array('#value' => $tasks[$task]['description']); - $form['nid'] = array('#type' => 'value', '#value' => $node->nid); - $form['task'] = array('#type' => 'value', '#value' => $task); - $form['parameters'] = array('#tree' => TRUE); - $func = 'hosting_task_' . str_replace('-', '_', $task) . '_form'; - if (function_exists($func)) { - $form['parameters'] += $func($node); - } - $func = $func . '_validate'; - if (function_exists($func)) { - $form['#validate'][] = $func; - $form['#func_param_1'] = $node; - $form['#func_param_2'] = $task; - } - $question = t("Are you sure you want to @task @object?", array('@task' => $task, '@object' => $node->title)); - $form = confirm_form($form, $question, 'node/' . $node->nid, '', $tasks[$task]['title']); - - // add an extra class to the actions to allow us to disable the cancel link via javascript for the modal dialog - - $form['actions']['#prefix'] = '
'; - return $form; -} - -/** - * Customize the task confirmation form for restore. - * - * This adds the backup listing to the confirmation dialog. - */ -function hosting_task_restore_form($node) { - $list = hosting_site_backup_list($node->nid); - if (sizeof($list)) { - $form['bid'] = array( - '#type' => 'radios', - '#title' => t('Backups'), - '#options' => $list, - '#required' => TRUE - ); - } - else { - $form['no_backups'] = array( - '#type' => 'item', - '#title' => t('Backups'), - '#value' => t('There are no valid backups available.') - ); - } - return $form; -} - -/** - * Implementation of hook_form_alter() - */ -function hosting_task_restore_form_validate($form, &$form_state) { - if ($form['parameters']['no_backups']) { - form_set_error('no_backups', t('There are no valid backups available.')); - } -} - -/** - * Generic form submit handler for tasks confirmation - * - * This handler gets called after any task has been confirmed by the user. It - * will inject a new task in the queue and redirect the user to the - * originating node. - * - * @see hosting_add_task() - */ -function hosting_task_confirm_form_submit($form, &$form_state) { - $values = $form_state['values']; - hosting_add_task($values['nid'], $values['task'], $values['parameters']); - $form_state['redirect'] = 'node/' . $values['nid']; - modalframe_close_dialog(); -} - -/** - * Set the title of tasks automatically and in a consistent way - * - * Tasks should always be named 'task_type node_title'. - */ -function hosting_task_set_title(&$node) { - $ref = db_fetch_object(db_query("SELECT vid, nid, title, type FROM {node} WHERE nid=%d", $node->rid)); - $tasks = hosting_available_tasks($ref->type); - - $node->title = drupal_ucfirst($tasks[$node->task_type]['title']) . ': ' . $ref->title; - db_query("UPDATE {node} SET title='%s' WHERE nid=%d", $node->title, $node->nid); - db_query("UPDATE {node_revisions} SET title='%s' WHERE vid=%d", $node->title, $node->vid); -} - -/** - * Process the hosting task queue. - * - * Iterates through the list of outstanding tasks, and execute the commands on the back end. - */ -function hosting_tasks_queue($count = 20) { - global $provision_errors; - - drush_log(dt("Running tasks queue")); - $tasks = _hosting_get_new_tasks($count); - foreach ($tasks as $task) { - drush_invoke_process('@self', "hosting-task", array($task->nid), array('invoke' => TRUE), array('fork' => TRUE)); - } -} - -/** - * Determine whether there is an outstanding task of a specific type. - * - * This is used to ensure that there are not multiple tasks of the same type queued. - */ -function hosting_task_outstanding($nid, $type) { - $return = db_result(db_query(" - SELECT t.nid FROM {hosting_task} t - INNER JOIN {node} n ON t.vid = n.vid - WHERE - t.rid = %d - AND t.task_status = %d - AND t.task_type = '%s' - ORDER BY t.vid DESC - LIMIT 1", $nid, HOSTING_TASK_QUEUED, $type)); - return $return; -} - -/** - * Return the amount of items still in the queue - */ -function hosting_task_count() { - return db_result(db_query("SELECT COUNT(t.vid) FROM {hosting_task} t INNER JOIN {node} n ON t.vid = n.vid WHERE t.task_status = %d", HOSTING_TASK_QUEUED)); -} - -/** - * Return the amount of items running in the queue - */ -function hosting_task_count_running() { - return db_result(db_query("SELECT COUNT(t.nid) FROM {node} n INNER JOIN {hosting_task} t ON n.vid=t.vid WHERE type='task' AND t.task_status = '%d'", HOSTING_TASK_PROCESSING)); -} - -/** - * Get a list of tasks that can be invoked by the user. - * - * Note this does not check permissions or relevance of the tasks. - * - * Modules can extend this list using hook_hosting_tasks(). - * - * @param $type - * Tasks are grouped by the type of thing that the task is performed on. This - * parameter should either be NULL, or a string indicating the type of thing - * that you want possible tasks to operate on. - * @param $reset - * This function has an internal static cache, to reset the cache, pass in - * TRUE. - * - * @return - * Depending on the value of the $type parameter, you will either be returned: - * - If $type is NULL: an associative array whose keys are things that can be - * acted upon by the tasks defined in the corresponding values. - * - If $type is a string, then an associative array whose keys are task types - * and whose values are definitions for those tasks. - * - * @see hook_hosting_tasks() - * @see hook_hosting_tasks_alter() - * @see hosting_task_menu_access() - */ -function hosting_available_tasks($type = NULL, $reset = FALSE) { - static $cache = array(); - - if (!sizeof($cache) || $reset) { - $cache = module_invoke_all('hosting_tasks'); - drupal_alter('hosting_tasks', $cache); - } - if (isset($type)) { - return $cache[$type]; - } - else { - return $cache; - } -} - -/** - * Implementation of hook_insert(). - */ -function hosting_task_insert($node) { - $node->executed = isset($node->executed) ? $node->executed : NULL; - $node->delta = isset($node->delta) ? $node->delta : NULL; - db_query("INSERT INTO {hosting_task} (vid, nid, task_type, task_status, rid, executed, delta) VALUES (%d, %d, '%s', %d, %d, %d, %d)", - $node->vid, $node->nid, $node->task_type, $node->task_status, $node->rid, $node->executed, $node->delta); - - if (isset($node->task_args) && is_array($node->task_args)) { - foreach ($node->task_args as $key => $value) { - db_query("INSERT INTO {hosting_task_arguments} (vid, nid, name, value) VALUES (%d, %d, '%s', '%s')", - $node->vid, $node->nid, $key, $value); - } - } - hosting_task_set_title($node); -} - -/** - * Implementation of hook_update(). - * - * As an existing node is being updated in the database, we need to do our own - * database updates. - */ -function hosting_task_update($node) { - // if this is a new node or we're adding a new revision, - if (!empty($node->revision)) { - hosting_task_insert($node); - } - else { - hosting_task_set_title($node); - db_query("UPDATE {hosting_task} SET nid=%d, task_type = '%s', task_status = %d, rid = %d, executed=%d, delta=%d WHERE vid=%d", - $node->nid, $node->task_type, $node->task_status, $node->rid, $node->executed, $node->delta, $node->vid); - if (isset($node->task_args) && is_array($node->task_args)) { - # Wipe out old arguments first, since arguments could theoretically be removed. - db_query("DELETE FROM {hosting_task_arguments} WHERE vid=%d", $node->vid); - foreach ($node->task_args as $key => $value) { - db_query("INSERT INTO {hosting_task_arguments} (vid, nid, name, value) VALUES (%d, %d, '%s', '%s')", - $node->vid, $node->nid, $key, $value); - } - } - - } -} - -/** - * Implementation of hook_delete_revision() - */ -function hosting_nodeapi_task_delete_revision(&$node) { - db_query('DELETE FROM {hosting_task} WHERE vid = %d', $node->vid); - db_query('DELETE FROM {hosting_task_arguments} WHERE vid = %d', $node->vid); - db_query('DELETE FROM {hosting_task_log} WHERE vid = %d', $node->vid); -} - -/** - * Implementation of hook_delete(). - */ -function hosting_task_delete($node) { - db_query('DELETE FROM {hosting_task} WHERE nid = %d', $node->nid); - db_query('DELETE FROM {hosting_task_arguments} WHERE nid = %d', $node->nid); - db_query('DELETE FROM {hosting_task_log} WHERE nid = %d', $node->nid); -} - -/** - * Implementation of hook_load(). - */ -function hosting_task_load($node) { - $additions = db_fetch_object(db_query('SELECT task_type, executed, delta, rid, task_status FROM {hosting_task} WHERE vid = %d', $node->vid)); - $result = db_query("SELECT name, value FROM {hosting_task_arguments} WHERE vid=%d", $node->vid); - if ($result) { - while ($arg = db_fetch_object($result)) { - $additions->task_args[$arg->name] = $arg->value; - } - } - return $additions; -} - -function hosting_task_retry_form($form_state, $nid) { - $form['#prefix'] = '
'; - $form['task'] = array( - '#type' => 'hidden', - '#default_value' => $nid - ); - $form['retry'] = array( - '#type' => 'submit', - '#value' => t('Retry') - ); - $form['#suffix'] = '
'; - return $form; -} - -function hosting_task_retry_form_submit($form, &$form_state) { - hosting_task_retry($form_state['values']['task']); - modalframe_close_dialog(); -} - -/** - * Implementation of hook_view(). - */ -function hosting_task_view($node, $teaser = FALSE, $page = FALSE) { - drupal_add_js(drupal_get_path('module', 'hosting') . '/hosting.js'); - $node = node_prepare($node, $teaser); - - $ref = node_load($node->rid); - - hosting_set_breadcrumb($node); - $node->content['info']['#prefix'] = '
'; - $node->content['info']['reference'] = array( - '#type' => 'item', - '#title' => drupal_ucfirst($ref->type), - '#value' => _hosting_node_link($node->rid), - ); - - if ($node->task_status != HOSTING_TASK_QUEUED) { - if ($node->task_status == HOSTING_TASK_PROCESSING) { - $node->content['info']['started'] = array( - '#type' => 'item', - '#title' => t('Started'), - '#value' => format_date($node->executed), - '#weight' => 1, - ); - $node->content['info']['delta'] = array( - '#type' => 'item', - '#title' => t('Processing time'), - '#value' => format_interval(time() - $node->executed), - '#weight' => 2, - ); - } - else { - $node->content['info']['executed'] = array( - '#type' => 'item', - '#title' => t('Executed'), - '#value' => format_date($node->executed), - '#weight' => 1, - ); - $node->content['info']['delta'] = array( - '#type' => 'item', - '#title' => t('Execution time'), - '#value' => format_interval($node->delta), - '#weight' => 2, - ); - } - } else { - $queues = hosting_get_queues(); - $queue = $queues['tasks']; - $next = _hosting_queue_next_run($queue); - $node->content['info']['notexecuted'] = array( - '#type' => 'item', - '#title' => t('This task has not been processed yet'), - '#value' => t('It will be processed around %date, if the queue is not too crowded. The queue is currently run every %freq, was last run %last and processes %items items at a time. Server time is %time.', array('%freq' => format_interval($queue['frequency']), '%date' => format_date($next, 'custom', 'H:i:sO'), '%last' => hosting_format_interval($queue['last_run']), '%items' => $queue['items'], '%time' => format_date(time(), 'custom', 'H:i:sO'))), - ); - } - if ($node->task_status) { - $node->content['info']['status'] = array( - '#type' => 'item', - '#title' => t('Status'), - '#value' => _hosting_parse_error_code($node->task_status), - ); - } - $node->content['info']['#suffix'] = '
'; - - if (user_access('retry failed tasks') && ($node->task_status == HOSTING_TASK_ERROR)) { - $node->content['retry'] = array( - '#type' => 'markup', - '#value' => drupal_get_form('hosting_task_retry_form', $node->nid), - '#weight' => 5, - ); - } - - if (user_access('access task logs')) { - if ($table = _hosting_task_log_table($node->vid)) { - $node->content['hosting_log'] = array( - '#weight' => 10, - '#type' => 'item', - '#value' => $table - ); - } - } - return $node; -} - -/** - * Display table containing the logged information for this task - */ -function _hosting_task_log_table($vid) { - $result = db_query("SELECT * FROM {hosting_task_log} WHERE vid = %d ORDER BY lid", $vid); - if ($result) { - $header = array('data' => 'Log message'); - while ($entry = db_fetch_object($result)) { - if (strlen($entry->message) > 300) { - $summary = "" . filter_xss(substr($entry->message, 0, 75), array()) . "... (" . t('Expand') . ')'; - $message = $summary . "" . filter_xss($entry->message) . ''; - } - else { - $message = filter_xss($entry->message); - } - $row = array(array('data' => $message, 'class' => 'hosting-status')); - $rows[] = array('data' => $row, 'class' => _hosting_task_log_class($entry->type)); - } - - return theme("table", $header, (array) $rows, array('id' => 'hosting-task-log', 'class' => 'hosting-table')); - } - - return false; -} - -/** - * Map entry statuses to coincide. - * - * @todo make this irrelevant. - */ -function _hosting_task_log_class($type) { - switch (strtolower($type)) { - case "warning": - $type = "warning"; - break; - case "error": - case "failed": - $type = "error"; - break; - case "queue": - $type = "queue"; - break; - case "command": - case "notice": - $type = "info"; - break; - default: - $type = 'success'; - break; - } - - return 'hosting-' . $type; -} - -/** - * Retrieve the latest task related to the specified platform, of a specific type - * - * This is used for documenting issues with verification. - */ -function hosting_get_most_recent_task($rid, $type) { - $nid = db_result(db_query("SELECT t.nid FROM {hosting_task} t INNER JOIN {node} n ON n.vid = t.vid WHERE task_type='%s' and t.rid=%d ORDER BY t.vid DESC limit 1", $type, $rid)); - if ($nid) { - return node_load($nid); - } - return false; -} - -/** - * Retrieve tasks with specified criterias - * - * @arg $filter_by string a field to filter the list with, unchecked - * @arg $filter_value string what to restrict the field to, checked - * @arg $count integer the number of tasks to return - * @arg $element integer which element to start from - */ -function hosting_get_tasks($filter_by = null, $filter_value = null, $count = 5, $element = 0) { - $nodes = array(); - $args[] = 'task'; - $cond = ''; - - if ($filter_by && $filter_value) { - $cond = ' AND t.' . $filter_by . ' = %d'; - $args[] = $filter_value; - } - $result = pager_query(db_rewrite_sql("SELECT n.*, t.task_status, t.task_type, t.rid FROM {node} n INNER JOIN {hosting_task} t on n.vid=t.vid WHERE type='%s'" . $cond . " ORDER BY n.vid DESC"), $count, $element, NULL, $args); - - while ($row = db_fetch_object($result)) { - $nodes[] = $row; - } - - return $nodes; -} - -/** - * Retrieve a list of outstanding tasks. - * - * @param limit - * The amount of items to return. - * @return - * An associative array containing task nodes, indexed by node id. - */ -function _hosting_get_new_tasks($limit = 20) { - $return = array(); - $result = db_query("SELECT t.nid FROM {hosting_task} t INNER JOIN {node} n ON t.vid = n.vid WHERE t.task_status = %d GROUP BY t.rid ORDER BY n.changed, n.nid ASC LIMIT %d", 0, $limit); - while ($node = db_fetch_object($result)) { - $return[$node->nid] = node_load($node->nid); - } - return $return; -} - -/** - * @name Error status definitions - * @{ - * Bitmask values used to generate the error code to return. - * @see drush_set_error(), drush_get_error(), drush_cmp_error() - */ - -/** - * The task is being processed - */ -define('HOSTING_TASK_PROCESSING', -1); - - -/** - * The task is queued - */ -define('HOSTING_TASK_QUEUED', 0); - -/** - * The command completed succesfully. - */ -define('HOSTING_TASK_SUCCESS', 1); - -/** - * The command was not successfully completed. This is the default error - * status. - */ -define('HOSTING_TASK_ERROR', 2); - -/** - * The command was completed successfully, but with warnings. This is requires - * attention. - */ -define('HOSTING_TASK_WARNING', 3); - - -/** - * @} End of "name Error status definitions". - */ - -/** - * Turn bitmask integer error code into associative array - */ -function _hosting_parse_error_code($code) { - $messages = array( - HOSTING_TASK_SUCCESS => t('Successful'), - HOSTING_TASK_QUEUED => t('Queued'), - HOSTING_TASK_ERROR => t('Failed'), - HOSTING_TASK_PROCESSING => t('Processing'), - HOSTING_TASK_WARNING => t('Warning'), - ); - return $messages[$code]; -} - -/** - * Return the status of the task matching the specification - */ -function hosting_task_status($filter_by, $filter_value, $type = 'install') { - $args[] = 'task'; - $args[] = $type; - $cond = ''; - if ($filter_by && $filter_value) { - $cond = ' AND t.' . $filter_by . ' = %d'; - $args[] = $filter_value; - } - $result = db_fetch_array(db_query("SELECT t.task_status AS status FROM {node} n INNER JOIN {hosting_task} t on n.vid=t.vid WHERE n.type='%s' AND t.task_type='%s' " . $cond . " ORDER BY t.vid DESC", $args)); - return $result['status']; -} - -/** - * Return the status of a task in human-readable form - * - * @see hosting_task_status() - */ -function hosting_task_status_output($filter_by, $filter_value, $type = 'install') { - $status = hosting_task_status($filter_by, $filter_value, $type); - if (is_int($status)) { - return _hosting_parse_error_code($status); - } else { - return $status; # should be NULL - } -} - -/** - * Display list of tasks - */ -function hosting_task_list($filter_by = null, $filter_value = null) { - return _hosting_task_list($filter_by, $filter_value, 25, 12, 'title'); -} - -/** - * Implementation of hosting_hook_summary() - */ -function hosting_task_summary($filter_by = null, $filter_value = null) { - - modalframe_parent_js(); - $more_link = l(t('More tasks'), 'hosting/queues/tasks'); - return hosting_task_queue_block() . $more_link; -} - -/** - * Hosting task list queue block - */ -function hosting_task_queue_block() { - drupal_add_js(drupal_get_path('module','hosting_task') . '/hosting_task.js'); - - $settings['hostingTaskRefresh'] = array( - 'queueBlock' => 1 - ); - drupal_add_js($settings, 'setting'); - - $nodes = hosting_get_tasks('t.task-status', HOSTING_TASK_QUEUED, 5); - - $headers = array( t('Task'), t('Actions') ); - $rows[] = array(); - foreach ($nodes as $node) { - $row = array(); - $row['type'] = array( - 'data' => drupal_ucfirst(str_replace(array('_', '-'), ' ', $node->task_type)) . ' ' . _hosting_node_link($node->rid), - 'class' => 'hosting-status' - ); - - - $log_button = _hosting_task_button(t('View'), 'node/' . $node->nid, t("Display the task log"), 'hosting-button-log', isset($node->nid) && user_access('access task logs'), true, false); - - $row['actions'] = array( - 'data' => $log_button, - 'class' => 'hosting-actions', - ); - $class = hosting_task_status_class($node->task_status); - $rows[] = array('data' => $row, 'class' => $class); - } - return "
" . theme('table', $headers, $rows, array('class' => 'hosting-table')) . "
" ; - -} - -/** - * A concise table listing of the tasks affecting this node - * - * This shows a table view of the tasks relevant to this node. It will show - * tasks that can be executed as well as tasks that have been in a single - * simple interface. - */ -function hosting_task_table($node) { - $output = ''; - - - $headers[] = t('Task'); - $headers[] = array('data' => t('Actions'), 'class' => 'hosting-actions'); - - $tasklist = hosting_task_fetch_tasks($node->nid); - - foreach ($tasklist as $task => $info) { - $row = array(); - - if (!isset($info['nid']) && !$info['task_permitted']) { - // just don't show those tasks, since we'll not be able to run them - continue; - } - - $row['type'] = array('data' => $info['title'], 'class' => 'hosting-status'); - $actions = array(); - - if (isset($info['task_status']) && ($info['task_status'] == 0)) { - $actions['cancel'] = _hosting_task_button(t('Cancel'), sprintf("hosting/tasks/%d/cancel", $info['nid']), t("Cancel the task and remove it from the queue"), 'hosting-button-stop', !$info['task_permitted']); - } - else { - $actions['run'] = _hosting_task_button(t('Run'), sprintf("node/%d/%s_%s", $node->nid, $node->type, $task), $info['description'], 'hosting-button-run', $info['task_permitted'], $info['dialog']); - } - - $actions['log'] = _hosting_task_button(t('View'), isset($info['nid'])? 'node/' . $info['nid']: '', t("Display the task log"), 'hosting-button-log', isset($info['nid']) && user_access('access task logs'), TRUE, FALSE); - $row['actions'] = array( - 'data' => implode('', $actions), - 'class' => 'hosting-actions' - ); - - $rows[] = array('data' => $row, 'class' => $info['class']); - } - $output .= theme('table', $headers, $rows, array('class' => 'hosting-table')); - return $output; -} - -function _hosting_task_button($title, $link, $description, $class = '', $status = TRUE, $dialog = FALSE, $add_token = TRUE) { - global $user; - - if ($status) { - $classes[] = 'hosting-button-enabled'; - if (!empty($class)) { - $classes[] = $class; - } - if ($dialog) { - $classes[] = 'hosting-button-dialog'; - } - - $options['attributes'] = array( - 'title' => $description, - 'class' => implode(" ", $classes), - ); - if ($add_token) { - $options['query'] = array( - 'token' => drupal_get_token($user->uid), - ); - } - return l($title, $link, $options); - } - else { - return "" . $title . ""; - } -} - -/** - * Theme a task list - */ -function _hosting_task_list($filter_by, $filter_value, $count = 5, $element = 0, $field = 'title', $skip = array(), $pager = TRUE) { - $nodes = hosting_get_tasks($filter_by, $filter_value, $count, $element); - - if (!$nodes) { - return t('No tasks available'); - } - else { - $headers[t('Task')] = ''; - foreach ($nodes as $node) { - $row = array(); - - if ($field == 'title') { - $data = drupal_ucfirst($node->task_type) . ' ' . _hosting_node_link($node->rid); - } else { - $data = $node->{$field}; - } - $row['type'] = array( - 'data' => $data, - 'class' => 'hosting-status' - ); - - if (!in_array('created', $skip)) { - $row['created'] = t("@interval ago", array('@interval' => format_interval(time() - $node->created, 1))); - $headers[t('Created')] = ''; - } - - $row['executed'] = t("@interval ago", array('@interval' => format_interval(time() - $node->changed, 1))); - $headers[t('Executed')] = ''; - - $headers[t('Actions')] = ''; - - $actions['log'] = l(t('View'), 'node/' . $node->nid, array('attributes' => array('class' => 'hosting-button-dialog hosting-button-enabled hosting-button-log'))); - - $row['actions'] = array( - 'data' => $actions['log'], - 'class' => 'hosting-actions' - ); - - $class = hosting_task_status_class($node->task_status); - - $rows[] = array('data' => $row, 'class' => $class); - } - - $output = theme('table', array_keys($headers), $rows, array('class' => 'hosting-table')); - if ($pager === TRUE) { - $output .= theme('pager', NULL, $count, $element); - } - elseif (is_string($pager)) { - $output .= $pager; - } - return $output; - } -} - -function hosting_task_fetch_tasks($rid) { - $node = node_load($rid); - - $result = db_query("SELECT n.nid, t.task_type, t.task_status FROM {node} n INNER JOIN {hosting_task} t ON n.vid = t.vid - WHERE n.type = 'task' AND t.rid = %d - ORDER BY t.task_status ASC, n.changed DESC", $rid); - - while ($obj = db_fetch_object($result)) { - $return[$obj->task_type] = array('nid' => $obj->nid, 'task_status' => $obj->task_status, 'exists' => TRUE); - } - - $tasks = hosting_available_tasks($node->type); - ksort($tasks); - - foreach ($tasks as $type => $hook_task) { - - if (!isset($return[$type])) { - $return[$type] = array(); - } - - $access_callback = !empty($hook_task['access callback']) ? $hook_task['access callback'] : 'hosting_task_menu_access'; - - $task = array(); - $task = array_merge($return[$type], $hook_task); - - $allowed = (isset($task['exists']) && !in_array($task['task_status'], array(HOSTING_TASK_QUEUED, HOSTING_TASK_PROCESSING))) || !isset($task['exists']); - if ($allowed && empty($task['hidden']) && $access_callback($node, $type)) { - $task['task_permitted'] = TRUE; - } - else { - $task['task_permitted'] = FALSE; - } - // @TODO: Use task defaults array to prevent notices. - if (!isset($task['dialog'])) { - $task['dialog'] = FALSE; - } - if (!isset($task['task_status'])) { - $task['task_status'] = NULL; - } - $task['class'] = hosting_task_status_class($task['task_status']); - - $return[$type] = $task; - } - - return $return; -} - -function hosting_task_status_class($status = null) { - $class = null; - if (!is_null($status)) { - switch($status) { - case HOSTING_TASK_SUCCESS : - $class = 'hosting-success'; - break; - case HOSTING_TASK_ERROR : - $class = 'hosting-error'; - break; - case HOSTING_TASK_QUEUED : - $class = 'hosting-queue'; - break; - case HOSTING_TASK_PROCESSING : - $class = 'hosting-processing'; - break; - case HOSTING_TASK_WARNING : - $class = 'hosting-warning'; - break; - } - } - - return $class; -} - -/** - * Views integration - */ -function hosting_task_views_api() { - return array( - 'api' => 2, - 'path' => drupal_get_path('module', 'hosting_task'), - ); -} diff --git a/modules/hosting/task/hosting_task.views_default.inc b/modules/hosting/task/hosting_task.views_default.inc index 6767c33..0747da9 100644 --- a/modules/hosting/task/hosting_task.views_default.inc +++ b/modules/hosting/task/hosting_task.views_default.inc @@ -63,6 +63,11 @@ function hosting_task_views_default_views() { $handler->display->display_options['style_options']['override'] = 1; $handler->display->display_options['style_options']['sticky'] = 0; $handler->display->display_options['style_options']['empty_table'] = 0; + /* Relationship: Hosting Task: Reference */ + $handler->display->display_options['relationships']['rid']['id'] = 'rid'; + $handler->display->display_options['relationships']['rid']['table'] = 'hosting_task'; + $handler->display->display_options['relationships']['rid']['field'] = 'rid'; + $handler->display->display_options['relationships']['rid']['required'] = 0; /* Field: Hosting Task: Status */ $handler->display->display_options['fields']['task_status']['id'] = 'task_status'; $handler->display->display_options['fields']['task_status']['table'] = 'hosting_task'; @@ -91,7 +96,8 @@ function hosting_task_views_default_views() { $handler->display->display_options['fields']['title']['id'] = 'title'; $handler->display->display_options['fields']['title']['table'] = 'node'; $handler->display->display_options['fields']['title']['field'] = 'title'; - $handler->display->display_options['fields']['title']['label'] = 'Task'; + $handler->display->display_options['fields']['title']['relationship'] = 'rid'; + $handler->display->display_options['fields']['title']['exclude'] = TRUE; $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['title']['alter']['make_link'] = 0; $handler->display->display_options['fields']['title']['alter']['absolute'] = 0; @@ -104,13 +110,36 @@ function hosting_task_views_default_views() { $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0; $handler->display->display_options['fields']['title']['alter']['trim'] = 0; $handler->display->display_options['fields']['title']['alter']['html'] = 0; - $handler->display->display_options['fields']['title']['element_class'] = 'hosting-status'; $handler->display->display_options['fields']['title']['element_label_colon'] = 1; $handler->display->display_options['fields']['title']['element_default_classes'] = 1; $handler->display->display_options['fields']['title']['hide_empty'] = 0; $handler->display->display_options['fields']['title']['empty_zero'] = 0; $handler->display->display_options['fields']['title']['hide_alter_empty'] = 1; - $handler->display->display_options['fields']['title']['link_to_node'] = 0; + $handler->display->display_options['fields']['title']['link_to_node'] = 1; + /* Field: Hosting Task: Type */ + $handler->display->display_options['fields']['task_type']['id'] = 'task_type'; + $handler->display->display_options['fields']['task_type']['table'] = 'hosting_task'; + $handler->display->display_options['fields']['task_type']['field'] = 'task_type'; + $handler->display->display_options['fields']['task_type']['label'] = 'Task'; + $handler->display->display_options['fields']['task_type']['alter']['alter_text'] = 1; + $handler->display->display_options['fields']['task_type']['alter']['text'] = '[task_type]: [title]'; + $handler->display->display_options['fields']['task_type']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['external'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['replace_spaces'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['nl2br'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['task_type']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['task_type']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['trim'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['html'] = 0; + $handler->display->display_options['fields']['task_type']['element_class'] = 'hosting-status'; + $handler->display->display_options['fields']['task_type']['element_label_colon'] = 1; + $handler->display->display_options['fields']['task_type']['element_default_classes'] = 1; + $handler->display->display_options['fields']['task_type']['hide_empty'] = 0; + $handler->display->display_options['fields']['task_type']['empty_zero'] = 0; + $handler->display->display_options['fields']['task_type']['hide_alter_empty'] = 1; /* Field: Node: Link */ $handler->display->display_options['fields']['view_node']['id'] = 'view_node'; $handler->display->display_options['fields']['view_node']['table'] = 'node'; @@ -196,7 +225,8 @@ function hosting_task_views_default_views() { $handler->display->display_options['fields']['title']['id'] = 'title'; $handler->display->display_options['fields']['title']['table'] = 'node'; $handler->display->display_options['fields']['title']['field'] = 'title'; - $handler->display->display_options['fields']['title']['label'] = 'Task'; + $handler->display->display_options['fields']['title']['relationship'] = 'rid'; + $handler->display->display_options['fields']['title']['exclude'] = TRUE; $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['title']['alter']['make_link'] = 0; $handler->display->display_options['fields']['title']['alter']['absolute'] = 0; @@ -215,7 +245,31 @@ function hosting_task_views_default_views() { $handler->display->display_options['fields']['title']['hide_empty'] = 0; $handler->display->display_options['fields']['title']['empty_zero'] = 0; $handler->display->display_options['fields']['title']['hide_alter_empty'] = 1; - $handler->display->display_options['fields']['title']['link_to_node'] = 0; + $handler->display->display_options['fields']['title']['link_to_node'] = 1; + /* Field: Hosting Task: Type */ + $handler->display->display_options['fields']['task_type']['id'] = 'task_type'; + $handler->display->display_options['fields']['task_type']['table'] = 'hosting_task'; + $handler->display->display_options['fields']['task_type']['field'] = 'task_type'; + $handler->display->display_options['fields']['task_type']['label'] = 'Task'; + $handler->display->display_options['fields']['task_type']['alter']['alter_text'] = 1; + $handler->display->display_options['fields']['task_type']['alter']['text'] = '[task_type]: [title]'; + $handler->display->display_options['fields']['task_type']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['external'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['replace_spaces'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['nl2br'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['task_type']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['task_type']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['trim'] = 0; + $handler->display->display_options['fields']['task_type']['alter']['html'] = 0; + $handler->display->display_options['fields']['task_type']['element_class'] = 'hosting-status'; + $handler->display->display_options['fields']['task_type']['element_label_colon'] = 1; + $handler->display->display_options['fields']['task_type']['element_default_classes'] = 1; + $handler->display->display_options['fields']['task_type']['hide_empty'] = 0; + $handler->display->display_options['fields']['task_type']['empty_zero'] = 0; + $handler->display->display_options['fields']['task_type']['hide_alter_empty'] = 1; /* Field: Node: Post date */ $handler->display->display_options['fields']['created']['id'] = 'created'; $handler->display->display_options['fields']['created']['table'] = 'node';