diff --git a/css/views-admin.css b/css/views-admin.css index 9b708ee9c2c47fe20a8b8a4ebb3289f02035c9e7..10b8b9574538fffd541ffefb040a02960650e65e 100644 --- a/css/views-admin.css +++ b/css/views-admin.css @@ -283,3 +283,16 @@ html.js span.js-only { } /* @end */ + +/* @group Inline lists */ + +.views-ui-operations { + min-width: 22em; +} + +.views-ui-name { + min-width: 15em; +} + +/* @end */ + diff --git a/css/views-admin.seven.css b/css/views-admin.seven.css index a14d88dea8e91518e817fee0a2b11913d9d00354..8ba405951ead75ddc93ce640718a80ea596aaf8d 100644 --- a/css/views-admin.seven.css +++ b/css/views-admin.seven.css @@ -47,6 +47,11 @@ margin-right: 1em; } +/* Override for filter button on the vies list screen */ +.page-admin-structure-views #ctools-export-ui-list-form .form-submit { + margin-top: 1.3em; +} + .page-admin-structure-views #content .form-item { margin-bottom: 0; padding-bottom: 0; diff --git a/includes/admin.inc b/includes/admin.inc index 26a70e3a27ee44cd474d8905e472bb1b5c134942..f20ec2317bf977f34cda0d8751b17cd5806c8536 100644 --- a/includes/admin.inc +++ b/includes/admin.inc @@ -5,99 +5,6 @@ * Provides the Views' administrative interface. */ -/** - * Page callback to list enabled views. - * - * @return - * A renderable page build array. - */ -function views_ui_list_enabled_views() { - views_ui_add_admin_css(); - $build = array(); - $build['filters'] = array(); - $views = views_get_enabled_views(); - $build['table'] = views_ui_build_view_list($views); - // Let advanced users filter the list of views by type, tag, etc. - if (variable_get('views_ui_show_listing_filters', FALSE)) { - // TODO: Add filters. - } - return $build; -} - -/** - * Page callback to list disabled views. - * - * @return - * A renderable page build array. - */ -function views_ui_list_disabled_views() { - views_ui_add_admin_css(); - drupal_set_title(t('Browse view templates')); - $views = views_get_disabled_views(); - return views_ui_build_view_list($views); -} - -/** - * Builds a renderable array of views, for display in a table. - * - * @param $views - * The list of views to render, as returned, for example, from - * views_get_all_views(). - * - * @return - * A renderable array. - */ -function views_ui_build_view_list($views) { - $rows = array(); - foreach ($views as $view) { - // Determine the display title based on the view's human name, current - // (dynamic) title, or machine name, in that order. - if (!empty($view->human_name)) { - $title = $view->human_name; - } - else { - $title = $view->get_title(); - if (empty($title)) { - $title = $view->name; - } - } - - // Add a row to the table listing. - $rows[] = array( - array( - 'data' => array( - '#theme' => 'views_ui_view_info', - '#title' => check_plain($title), - '#paths' => _views_ui_get_paths($view), - '#displays' => _views_ui_get_displays_list($view), - ), - ), - array( - 'data' => '
' . check_plain($view->description) . '
', - ), - array( - 'data' => array( - '#theme' => 'links', - '#links' => _views_ui_get_operation_links($view), - '#attributes' => array('class' => array('links', 'inline')), - ), - ) - ); - } - - $build = array( - '#theme' => 'table', - '#header' => array( - t('View name'), - t('Description'), - t('Operations'), - ), - '#rows' => $rows, - '#empty' => t('No views have been added.'), - ); - - return $build; -} /** * Adds standard Views administration CSS to the current page. @@ -309,21 +216,6 @@ function views_ui_add_page() { return drupal_get_form('views_ui_add_form'); } -/** - * Page callback to add a new view. - */ -function views_ui_clone_page($view) { - $form_state = array( - 'view' => $view->copy(), - 'build_info' => array( - 'args' => array(), - ), - ); - - drupal_set_title(t('Clone view %view', array('%view' => $view->name)), PASS_THROUGH); - return drupal_render(drupal_build_form('views_ui_add_form', $form_state)); -} - /** * Form builder for the "add new view" page. */ @@ -558,179 +450,47 @@ function views_ui_taxonomy_autocomplete_validate($element, &$form_state) { } /** - * Helper function to get a list of available operation links for a given view. - * - * @param $view - * The view. + * Theme function; returns basic administrative information about a view. * - * @return - * An array of links as expected by theme_links(). + * TODO: template + preprocess */ -function _views_ui_get_operation_links($view) { - $links = array(); - - if (empty($view->disabled)) { - $links[] = array('title' => t('edit'), 'href' => "admin/structure/views/view/$view->name/edit"); - $links[] = array('title' => t('duplicate'), 'href' => "admin/structure/views/view/$view->name/duplicate"); - } - - if ($view->type != t('Default')) { - if ($view->type == t('Overridden')) { - $links[] = array( - 'title' => t('revert'), - 'href' => "admin/structure/views/view/$view->name/delete", - 'attributes' => array('title' => t('Reverting a view deletes your changes and replaces it with the original default view')), - ); - } - else { - $links[] = array( - 'title' => t('delete'), - 'href' => "admin/structure/views/view/$view->name/delete", - ); - } +function theme_views_ui_view_info($variables) { + $view = $variables['view']; + if (!empty($view->human_name)) { + $title = $view->human_name; } else { - if (empty($view->disabled)) { - $links[] = array( - 'title' => t('disable'), - 'href' => "admin/structure/views/view/$view->name/disable", - 'query' => array('token' => drupal_get_token('views-disable')), - ); - } - else { - $links[] = array( - 'title' => t('enable'), - 'href' => "admin/structure/views/view/$view->name/enable", - 'query' => array('token' => drupal_get_token('views-enable')), - ); + $title = $view->get_title(); + if (empty($title)) { + $title = $view->name; } } - return $links; -} + $displays = _views_ui_get_displays_list($view); + $displays = empty($displays) ? t('None') : format_plural(count($displays), 'Display', 'Displays') . ': ' . '' . implode(', ', $displays) . ''; -/** - * Helper function to get a list of paths assigned to a view. - * - * @param $view - * The view. - * - * @return - * An array of links to this view's display paths. - */ -function _views_ui_get_paths($view) { - $all_paths = array(); - if (empty($view->display)) { - $all_paths[] = t('Edit this view to add a display.'); - } - else { - $view->init_display(); // Make sure all the handlers are set up - foreach ($view->display as $display) { - if (!empty($display->handler) && $display->handler->has_path()) { - $one_path = $display->handler->get_option('path'); - if (empty($path_sort)) { - $path_sort = strtolower($one_path); - } - if (empty($view->disabled) && strpos($one_path, '%') === FALSE) { - $all_paths[] = l($one_path, $one_path); - } - else { - $all_paths[] = check_plain($one_path); - } - } - } - } - - return array_unique($all_paths); -} + switch ($view->type) { + case t('Default'): + default: + $type = t('In code'); + break; -/** - * Helper function to get a list of displays included in a view. - * - * @param $view - * The view. - * - * @return - * An array of display types that this view includes. - */ -function _views_ui_get_displays_list($view) { - $displays = array(); - foreach ($view->display as $display) { - if (!empty($display->handler->definition['admin'])) { - $displays[$display->handler->definition['admin']] = TRUE; - } - } + case t('Normal'): + $type = t('In database'); + break; - if ($displays) { - ksort($displays); - $displays = array_keys($displays); + case t('Overridden'): + $type = t('Database overriding code'); } - return $displays; -} - -/** - * Theme function; returns basic administrative information about a view. - * - * TODO: template + preprocess - */ -function theme_views_ui_view_info($variables) { - $title = empty($variables['title']) ? '' . t('No title') . '' : $variables['title']; - $paths = empty($variables['paths']) ? t('None') : format_plural(count($variables['paths']), 'Path', 'Paths') . ": " . implode(", ", $variables['paths']); - $displays = empty($variables['displays']) ? t('None') : format_plural(count($variables['displays']), 'Display', 'Displays') . ': ' . '' . implode(', ', $variables['displays']) . ''; $output = ''; $output .= '
' . $title . "
\n"; $output .= '
' . $displays . "
\n"; - $output .= '
' . $paths . "
\n"; + $output .= '
'. $type . "
\n"; + $output .= '
' . t('Type') . ': ' . $variables['base']. "
\n"; return $output; } -/** - * Page to delete a view. - */ -function views_ui_delete_confirm($form, &$form_state, $view) { - $form_state['view'] = &$view; - $form = array(); - - $cancel = 'admin/structure/views'; - if (!empty($_REQUEST['cancel'])) { - $cancel = $_REQUEST['cancel']; - } - - if ($view->type == t('Overridden')) { - $title = t('Are you sure you want to revert the view %name?', array('%name' => $view->name)); - $desc = t('Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered.'); - $button = t('Revert'); - } - else { - $title = t('Are you sure you want to delete the view %name?', array('%name' => $view->name)); - $desc = t('Deleting a view cannot be undone.'); - $button = t('Delete'); - } - - return confirm_form($form, - $title, - $cancel, - $desc, - $button, - t('Cancel')); -} - -/** - * Submit handler to delete a view. - */ -function views_ui_delete_confirm_submit(&$form, &$form_state) { - $form_state['view']->delete(); - ctools_object_cache_clear('view', $form_state['view']->name); - if ($form_state['view']->type == t('Overridden')) { - drupal_set_message(t('The view has been reverted.')); - } - else { - drupal_set_message(t('The view has been deleted.')); - } - $form_state['redirect'] = 'admin/structure/views'; -} - /** * Page to delete a view. */ @@ -958,7 +718,7 @@ function views_ui_edit_form($form, &$form_state, $view, $display_id = NULL) { '#id' => 'edit-displays-preview-fieldset', '#attributes' => array('class' => array('box-padding')), ); - + // Add the preview button $form['displays']['preview_controls']['preview_fieldset']['button'] = array( '#type' => 'submit', @@ -1096,7 +856,7 @@ function views_ui_edit_form_submit_undo_delete_display($form, &$form_state) { // Store in cache views_ui_cache_set($form_state['view']); - + // Redirect to the top-level edit page. $form_state['redirect'] = 'admin/structure/views/view/' . $form_state['view']->name . '/edit/' . $id; } @@ -1394,21 +1154,6 @@ function views_ui_pre_render_add_fieldset_markup($form) { return $form; } -/** - * Export a view for cut & paste. - */ -function views_ui_export_page($form, &$form_state, $view) { - $code = $view->export(); - $lines = substr_count($code, "\n"); - $form['code'] = array( - '#type' => 'textarea', - '#title' => $view->name, - '#default_value' => $code, - '#rows' => $lines, - ); - return $form; -} - /** * Import a view from cut & paste. */ @@ -3875,42 +3620,6 @@ function views_ui_get_roles() { return $roles; } -/** - * Page callback for the Views enable page. - */ -function views_ui_enable_page($view) { - if (isset($_GET['token']) && drupal_valid_token($_GET['token'], 'views-enable')) { - $views_status = variable_get('views_defaults', array()); - $views_status[$view->name] = FALSE; // FALSE is enabled - variable_set('views_defaults', $views_status); - views_invalidate_cache(); - menu_rebuild(); - drupal_set_message(t('The view has been enabled.')); - drupal_goto('admin/structure/views'); - } - else { - return drupal_access_denied(); - } -} - -/** - * Page callback for the Views enable page - */ -function views_ui_disable_page($view) { - if (isset($_GET['token']) && drupal_valid_token($_GET['token'], 'views-disable')) { - $views_status = variable_get('views_defaults', array()); - $views_status[$view->name] = TRUE; // True is disabled - variable_set('views_defaults', $views_status); - views_invalidate_cache(); - menu_rebuild(); - drupal_set_message(t('The view has been disabled.')); - drupal_goto('admin/structure/views'); - } - else { - return drupal_access_denied(); - } -} - /** * Form builder for the admin display settings page. */ diff --git a/includes/handlers.inc b/includes/handlers.inc index 284f801ae8f8ba24f3b5c7694b8f58a042b689f5..a007b0a78803250a81120055774deff8a5d908f0 100644 --- a/includes/handlers.inc +++ b/includes/handlers.inc @@ -133,7 +133,7 @@ function views_get_table_join($table, $base_table) { class views_handler extends views_object { /** * The top object of a view. - * + * * @var view */ var $view = NULL; @@ -1448,51 +1448,3 @@ class views_join { * @} */ -// Declare API compatibility on behalf of core modules: - -/** - * Implements hook_views_api(). - * - * This one is used as the base to reduce errors when updating. - */ -function views_views_api() { - return array( - // in your modules do *not* use views_api_version()!!! - 'api' => views_api_version(), - 'path' => drupal_get_path('module', 'views') . '/modules', - ); -} - -function aggregator_views_api() { return views_views_api(); } - -function book_views_api() { return views_views_api(); } - -function comment_views_api() { return views_views_api(); } - -function locale_views_api() { return views_views_api(); } - -function field_views_api() { return views_views_api(); } - -function filter_views_api() { return views_views_api(); } - -function node_views_api() { return views_views_api(); } - -function poll_views_api() { return views_views_api(); } - -function profile_views_api() { return views_views_api(); } - -function search_views_api() { return views_views_api(); } - -function statistics_views_api() { return views_views_api(); } - -function system_views_api() { return views_views_api(); } - -function taxonomy_views_api() { return views_views_api(); } - -function translation_views_api() { return views_views_api(); } - -function upload_views_api() { return views_views_api(); } - -function user_views_api() { return views_views_api(); } - -function contact_views_api() { return views_views_api(); } diff --git a/includes/view.inc b/includes/view.inc index 8b495b2e0dd8a078c84f8643ae6a0641e78516cf..86ae727ddbacb148b900d2e210c801519dab5ac0 100644 --- a/includes/view.inc +++ b/includes/view.inc @@ -1363,7 +1363,6 @@ class view extends views_db_object { static function load_views() { $result = db_query("SELECT DISTINCT v.* FROM {views_view} v"); $views = array(); - $vids = array(); // Load all the views. foreach ($result as $data) { @@ -1380,7 +1379,6 @@ class view extends views_db_object { return array(); } - $vids = implode(', ', array_keys($names)); // Now load all the subtables: foreach (view::db_objects() as $key) { $object_name = "views_$key"; @@ -1490,7 +1488,7 @@ class view extends views_db_object { foreach ($this->display as $id => $display) { $output .= "\n" . $indent . "/* Display: $display->display_title */\n"; - $output .= $indent . '$handler = $view->new_display(' . views_var_export($display->display_plugin, $indent) . ', ' . views_var_export($display->display_title, $indent) . ', \'' . $id . "');\n"; + $output .= $indent . '$handler = $view->new_display(' . ctools_var_export($display->display_plugin, $indent) . ', ' . ctools_var_export($display->display_title, $indent) . ', \'' . $id . "');\n"; if (empty($display->handler)) { // @todo -- probably need a method of exporting broken displays as // they may simply be broken because a module is not installed. That @@ -1830,6 +1828,8 @@ class views_db_object { * An optional indentation for prettifying nested code. */ function export_row($identifier = NULL, $indent = '') { + ctools_include('export'); + if (!$identifier) { $identifier = $this->db_table; } @@ -1864,7 +1864,7 @@ class views_db_object { } } - $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . views_var_export($value, $indent) . ";\n"; + $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n"; } return $output; } diff --git a/views.install b/views.install index 63185372f2833f98ed3583cf349901db2e2c1251..391a0a852b97623d343e02b87c09e3b36f089e82 100644 --- a/views.install +++ b/views.install @@ -89,6 +89,30 @@ function views_schema($caller_function = FALSE) { function views_schema_6000() { $schema['views_view'] = array( 'description' => 'Stores the general data for a view.', + 'export' => array( + 'identifier' => 'view', + 'bulk export' => TRUE, + 'primary key' => 'vid', + 'default hook' => 'views_default_views', + 'admin_title' => 'human_name', + 'admin_description' => 'description', + 'api' => array( + 'owner' => 'views', + 'api' => 'views_default', + 'minimum_version' => '2', + 'current_version' => '3.0', + ), + 'object' => 'view', + // the callback to load the displays + 'subrecords callback' => 'views_load_display_records', + // the variable that holds enabled/disabled status + 'status' => 'views_defaults', + // CRUD callbacks + 'create callback' => 'views_new_view', + 'save callback' => 'views_save_view', + 'delete callback' => 'views_delete_view', + 'export callback' => 'views_export_view', + ), 'fields' => array( 'vid' => array( 'type' => 'serial', diff --git a/views.module b/views.module index 7a62276570fcbcf4dac25e17c14bec2513ca58e8..909a57679ff0598ae0580fc19f922053e9416395 100644 --- a/views.module +++ b/views.module @@ -133,7 +133,7 @@ function views_theme($existing, $type, $theme, $path) { * The existing cache of theme hooks to test against. * @param $path * The path to search. - * + * * @see drupal_find_theme_templates */ function _views_find_module_templates($cache, $path) { @@ -1104,6 +1104,68 @@ function views_get_view($name, $reset = FALSE) { return $view->clone_view(); } +/** + * Export callback to load the view subrecords, which are the displays. + */ +function views_load_display_records(&$views) { + // Get vids from the views. + $names = array(); + foreach ($views as $view) { + if (empty($view->display)) { + $names[$view->vid] = $view->name; + } + } + + if (empty($names)) { + return; + } + + foreach (view::db_objects() as $key) { + $object_name = "views_$key"; + $result = db_query("SELECT * FROM {{$object_name}} WHERE vid IN (:vids) ORDER BY vid, position", + array(':vids' => array_keys($names))); + + foreach ($result as $data) { + $object = new $object_name(FALSE); + $object->load_row($data); + + // Because it can get complicated with this much indirection, + // make a shortcut reference. + $location = &$views[$names[$object->vid]]->$key; + + // If we have a basic id field, load the item onto the view based on + // this ID, otherwise push it on. + if (!empty($object->id)) { + $location[$object->id] = $object; + } + else { + $location[] = $object; + } + } + } +} + +/** + * Export CRUD callback to save a view. + */ +function views_save_view(&$view) { + return $view->save(); +} + +/** + * Export CRUD callback to export a view. + */ +function views_delete_view(&$view) { + return $view->delete(TRUE); +} + +/** + * Export CRUD callback to export a view. + */ +function views_export_view(&$view, $indent = '') { + return $view->export($indent); +} + // ------------------------------------------------------------------ // Views debug helper functions @@ -1272,7 +1334,7 @@ function views_exposed_form_submit(&$form, &$form_state) { $exclude = array('q', 'submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', ''); $exposed_form_plugin = $form_state['exposed_form_plugin']; $exposed_form_plugin->exposed_form_submit($form, $form_state, $exclude); - + foreach ($form_state['values'] as $key => $value) { if (!in_array($key, $exclude)) { $form_state['view']->exposed_raw_input[$key] = $value; @@ -1598,3 +1660,56 @@ function views_trim_text($alter, $value) { return $value; } + +function views_views_default_hook_name() { + return 'views_api'; +} + +// Declare API compatibility on behalf of core modules: + +/** + * Implements hook_views_api(). + * + * This one is used as the base to reduce errors when updating. + */ +function views_views_api() { + return array( + // in your modules do *not* use views_api_version()!!! + 'api' => views_api_version(), + 'path' => drupal_get_path('module', 'views') . '/modules', + ); +} + +function aggregator_views_api() { return views_views_api(); } + +function book_views_api() { return views_views_api(); } + +function comment_views_api() { return views_views_api(); } + +function locale_views_api() { return views_views_api(); } + +function field_views_api() { return views_views_api(); } + +function filter_views_api() { return views_views_api(); } + +function node_views_api() { return views_views_api(); } + +function poll_views_api() { return views_views_api(); } + +function profile_views_api() { return views_views_api(); } + +function search_views_api() { return views_views_api(); } + +function statistics_views_api() { return views_views_api(); } + +function system_views_api() { return views_views_api(); } + +function taxonomy_views_api() { return views_views_api(); } + +function translation_views_api() { return views_views_api(); } + +function upload_views_api() { return views_views_api(); } + +function user_views_api() { return views_views_api(); } + +function contact_views_api() { return views_views_api(); } diff --git a/views_ui.module b/views_ui.module index d10f1239c726a8780952d8e72e1d3a04073a0223..5da6a7e801b4702be151ec1ecfbce27f573d0ea3 100644 --- a/views_ui.module +++ b/views_ui.module @@ -21,29 +21,12 @@ function views_ui_menu() { ); // Top-level Views module pages (not tied to a particular View). - $items['admin/structure/views'] = array( - 'title' => 'Views', - 'description' => 'Manage customized lists of content.', - 'page callback' => 'views_ui_list_enabled_views', - ) + $base; - $items['admin/structure/views/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => '-1' - ) + $base; $items['admin/structure/views/add'] = array( 'title' => 'Add new view', 'page callback' => 'views_ui_add_page', 'type' => MENU_LOCAL_ACTION, ) + $base; - $items['admin/structure/views/templates'] = array( - 'title' => 'Add view from template', - 'page callback' => 'views_ui_list_disabled_views', - 'type' => MENU_LOCAL_ACTION, - ) + $base; - // Copy the "Add view" item so that it will also appear as a local action on - // the view templates page. - $items['admin/structure/views/templates/add'] = $items['admin/structure/views/add']; + $items['admin/structure/views/import'] = array( 'title' => 'Import view from code', 'page callback' => 'drupal_get_form', @@ -51,6 +34,7 @@ function views_ui_menu() { 'access callback' => 'views_import_access', 'type' => MENU_LOCAL_ACTION, ) + $base; + $items['admin/structure/views/settings'] = array( 'title' => 'Settings', 'page callback' => 'drupal_get_form', @@ -102,42 +86,27 @@ function views_ui_menu() { 'page arguments' => array(FALSE, 4), 'type' => MENU_LOCAL_TASK, ) + $base; + /* $items['admin/structure/views/view/%views_ui_cache/export'] = array( 'title' => 'Export', 'page callback' => 'drupal_get_form', 'page arguments' => array('views_ui_export_page', 4), 'type' => MENU_LOCAL_ACTION, ) + $base; + $items['admin/structure/views/view/%views_ui_cache/clone'] = array( 'title' => 'Clone', 'page callback' => 'views_ui_clone_page', 'page arguments' => array(4), 'type' => MENU_LOCAL_ACTION, ) + $base; +*/ $items['admin/structure/views/view/%views_ui_cache/break-lock'] = array( 'title' => 'Break lock', 'page callback' => 'drupal_get_form', 'page arguments' => array('views_ui_break_lock_confirm', 4), 'type' => MENU_CALLBACK, ) + $base; - $items['admin/structure/views/view/%views_ui_default/enable'] = array( - 'title' => 'Enable', - 'page callback' => 'views_ui_enable_page', - 'page arguments' => array(4), - 'type' => MENU_CALLBACK, - ) + $base; - $items['admin/structure/views/view/%views_ui_default/disable'] = array( - 'title' => 'Disable', - 'page callback' => 'views_ui_disable_page', - 'page arguments' => array(4), - 'type' => MENU_CALLBACK, - ) + $base; - $items['admin/structure/views/view/%views_ui_cache/delete'] = array( - 'title' => 'Delete', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('views_ui_delete_confirm', 4), - 'type' => MENU_CALLBACK, - ) + $base; // NoJS/AJAX callbacks that can use the default Views AJAX form system. $items['admin/structure/views/nojs/%/%views_ui_cache'] = array( @@ -264,7 +233,7 @@ function views_ui_theme() { // list views 'views_ui_view_info' => array( - 'variables' => array('title' => '', 'paths' => array(), 'displays' => array()), + 'variables' => array('view' => NULL, 'base' => NULL), 'file' => "includes/admin.inc", ), @@ -547,7 +516,7 @@ function views_ui_view_preview_section_display_category_links($view, $type, $tit 'attributes' => array('class' => array('views-ajax-link')), ), ); - + return $links; } @@ -573,7 +542,7 @@ function views_ui_view_preview_section_rows_links($view) { * Views UI provides wizard plugins on behalf of core base tables. */ function views_ui_ctools_plugin_directory($module, $plugin) { - if ($module == 'views_ui') { + if ($module == 'views_ui' || ($module == 'ctools' && $plugin == 'export_ui')) { return 'plugins/' . $plugin; } } @@ -774,3 +743,65 @@ function views_ui_ajax_get_form($form_id) { return $callback($form, $form_state); } } +// @todo move these when we can + + +/** + * Helper function to get a list of paths assigned to a view. + * + * @param $view + * The view. + * + * @return + * An array of links to this view's display paths. + */ +function _views_ui_get_paths($view) { + $all_paths = array(); + if (empty($view->display)) { + $all_paths[] = t('Edit this view to add a display.'); + } + else { + $view->init_display(); // Make sure all the handlers are set up + foreach ($view->display as $display) { + if (!empty($display->handler) && $display->handler->has_path()) { + $one_path = $display->handler->get_option('path'); + if (empty($path_sort)) { + $path_sort = strtolower($one_path); + } + if (empty($view->disabled) && strpos($one_path, '%') === FALSE) { + $all_paths[] = l($one_path, $one_path); + } + else { + $all_paths[] = check_plain($one_path); + } + } + } + } + + return array_unique($all_paths); +} + +/** + * Helper function to get a list of displays included in a view. + * + * @param $view + * The view. + * + * @return + * An array of display types that this view includes. + */ +function _views_ui_get_displays_list($view) { + $displays = array(); + foreach ($view->display as $display) { + if (!empty($display->handler->definition['admin'])) { + $displays[$display->handler->definition['admin']] = TRUE; + } + } + + if ($displays) { + ksort($displays); + $displays = array_keys($displays); + } + return $displays; +} +