diff --git a/drush/views.drush.inc b/drush/views.drush.inc index 42aff0fb6d4..ef64b397924 100644 --- a/drush/views.drush.inc +++ b/drush/views.drush.inc @@ -2,24 +2,21 @@ /** * @file - * Drush integration of views. - * - * drush cache-clear views - Clears the views specific caches. - * views-revert - Drush command to revert views overridden in the system. + * Drush integration for views. */ use Drupal\views\Analyzer; +use Drupal\views\ViewStorage; /** - * Implement hook_drush_help(). + * Implements hook_drush_help(). */ function views_drush_help($section) { switch ($section) { - case 'drush:views-revert': - $help = dt('Reverts views in the drupal installation that have been overriden. '); - $help .= dt('If no view names are specified, you will be presented with a list of overridden views to choose from. '); - $help .= dt('To revert all views, do not specify any view names, and choose the option "All" from the options presented.'); - return $help; + case 'meta:views:title': + return dt('Views commands'); + case 'meta:views:summary': + return dt('Views drush commands.'); case 'drush:views-list': return dt('Show a list of available views with information about them.'); case 'drush:views-enable': @@ -30,59 +27,42 @@ function views_drush_help($section) { } /** - * Implement hook_drush_command(). + * Implements hook_drush_command(). */ function views_drush_command() { $items = array(); - $items['views-revert'] = array( - 'callback' => 'views_revert_views', - 'drupal dependencies' => array('views'), - 'description' => 'Revert overridden views to their default state. Make sure to backup first.', - 'arguments' => array( - 'views' => 'A space delimited list of view names.', - ), - 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL, - 'aliases' => array('vr'), - 'examples' => array( - 'drush vr archive' => 'Reverts the "archive" view.', - 'drush rln archive frontpage' => 'Reverts the "archive" and "frontpage" view.', - 'drush vr' => 'Will present you with a list of overridden views to choose from, and an option to revert all overridden views.', - ), - ); $items['views-dev'] = array( 'callback' => 'views_development_settings', 'drupal dependencies' => array('views'), 'description' => 'Set the Views settings to more developer-oriented values.', - 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL, 'aliases' => array('vd'), ); $items['views-list'] = array( 'drupal dependencies' => array('views'), 'description' => 'Get a list of all views in the system.', - 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL, 'aliases' => array('vl'), 'options' => array( 'name' => 'String contained in view\'s name by which filter the results.', 'tags' => 'A comma-separated list of views tags by which to filter the results.', 'status' => 'Status of the views by which to filter the results. Choices: enabled, disabled.', - 'type' => 'Type of the views by which to filter the results. Choices: normal, default or overridden.', ), 'examples' => array( 'drush vl' => 'Show a list of all available views.', 'drush vl --name=blog' => 'Show a list of views which names contain "blog".', 'drush vl --tags=tag1,tag2' => 'Show a list of views tagged with "tag1" or "tag2".', 'drush vl --status=enabled' => 'Show a list of enabled views.', - 'drush vl --type=overridden' => 'Show a list of overridden views.', ), ); + $items['views-analyze'] = array( 'drupal dependencies' => array('views', 'views_ui'), - 'description' => 'Get a list of all Views analyze warnings', 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL, + 'description' => 'Get a list of all Views analyze warnings', 'aliases' => array('va'), ); + $items['views-enable'] = array( 'drupal dependencies' => array('views'), 'description' => 'Enable the specified views.', @@ -94,6 +74,7 @@ function views_drush_command() { 'drush ven frontpage taxonomy_term' => 'Enable the frontpage and taxonomy_term views.', ), ); + $items['views-disable'] = array( 'drupal dependencies' => array('views'), 'description' => 'Disable the specified views.', @@ -110,129 +91,9 @@ function views_drush_command() { } /** - * Callback function for views-revert command. - */ -function views_revert_views() { - $views = views_get_all_views(); - $i = 0; - // The provided views names specified in the command. - $viewnames = _convert_csv_to_array(func_get_args()); - - // Find all overridden views. - foreach ($views as $view) { - if ($view->disabled) { - continue; - } - if ($view->type == dt('Overridden')) { - $overridden[$view->storage->name] = $view->storage->name; - } - } - - // Return early if there are no overridden views in the system. - if (empty($overridden)) { - return drush_set_error(dt('There are no overridden views in the system.')); - } - - // If the user specified in the command the views to be overridden. - if (!empty($viewnames)) { - foreach ($viewnames as $key => $viewname) { - $is_overridden = key_exists($viewname, $overridden); - // Check if the provided view name is in the system - if ($viewname && !key_exists($viewname, $views)) { - drush_set_error(dt("'@viewname' view is not present in the system.", array('@viewname' => $viewname))); - } - // Check if the provided view is overridden. - elseif (!$is_overridden) { - drush_set_error(dt("The view specified '@viewname' is not overridden.", array('@viewname' => $viewname))); - } - // If the view is overriden, revert it. - elseif ($is_overridden) { - views_revert_view($views[$viewname]); - $i++; - } - // We should never get here but well... - else { - drush_set_error(dt("The view specified '@viewname' is not provided in code, and thus cannot be reverted.", array('@viewname' => $viewname))); - } - } - } - - // The user did not specify any views in the command, prompt the user - else { - // list of choices for the user - $overridden['all'] = dt('Revert all overridden views'); // add a choice at the end - $choice = drush_choice($overridden, 'Enter a number to choose which view to revert.', '!key'); // prompt the user - - if ($choice !== FALSE) { - // revert all views option - if ($choice == 'all') { - $i = views_revert_allviews($views); - } - // else the user specified a single view - else { - views_revert_view($views[$choice]); - $i++; - } - } - - } - - // final results output - if ($i == 0) { - drush_log(dt('No views were reverted.'), 'ok'); - } - else { - drush_log(dt('Reverted a total of @count views.', array('@count' => $i)), 'ok'); - } -} - -/** - * Reverts all views - * @param $views - * All views in the system as provided by views_get_all_views(). - */ -function views_revert_allviews($views) { - $i = 0; - foreach ($views as $view) { - if ($view->disabled) { - continue; - } - - if ($view->type == t('Overridden')) { - views_revert_view($view); - $i++; - } - } - return $i; -} - -/** - * Revert a specified view - * @param $view - * The view object to be reverted + * Drush views dev command. * - * Checks on wether or not the view is overridden is handled in views_revert_views_revert() - * We perform a check here anyway in case someone somehow calls this function on their own... - */ -function views_revert_view($view) { - // check anyway just in case - if ($view->type == t('Overridden')) { - // Revert the view. - $view->delete(); - // Clear its cache. - views_temp_store()->delete($view->storage->name); - // Give feedback. - $message = dt("Reverted the view '@viewname'", array('@viewname' => $view->storage->name)); - drush_log($message, 'success'); - // Reverted one more view. - } - else { - drush_set_error(dt("The view '@viewname' is not overridden.", array('@viewname' => $view->storage->name))); - } -} - -/** - * Change the settings to a more developer oriented value. + * Changes the settings to more developer oriented values. */ function views_development_settings() { config('views.settings') @@ -251,8 +112,7 @@ function views_development_settings() { ->set('ui.show.display_embed', TRUE) ->save(); - $message = dt('Setup the new views settings.'); - drush_log($message, 'success'); + drush_log(dt('New views configuration saved.'), 'success'); } /** @@ -263,235 +123,255 @@ function drush_views_list() { $rows = array(); $disabled_views = array(); $enabled_views = array(); - $overridden = 0; - $indb = 0; - $incode = 0; - $disabled = 0; - $total = 0; $views = views_get_all_views(); - // get the --name option - // TODO : take into account the case off a comma-separated list of names - $name = drush_get_option_list('name'); + // Get the --name option. + $name = array_filter(drush_get_option_list('name')); $with_name = !empty($name) ? TRUE : FALSE; - // get the --tags option - $tags = drush_get_option_list('tags'); + // Get the --tags option. + $tags = array_filter(drush_get_option_list('tags')); $with_tags = !empty($tags) ? TRUE : FALSE; - // get the --status option - // store user input appart to reuse it after - $status_opt = drush_get_option_list('status'); - // use the same logic than $view->disabled - if (in_array('disabled', $status_opt)) { - $status = TRUE; - $with_status = TRUE; - } - elseif (in_array('enabled', $status_opt)) { - $status = FALSE; - $with_status = TRUE; - } - else { - $status = NULL; - // wrong or empty --status option - $with_status = FALSE; + // Get the --status option. Store user input appart to reuse it after. + $status = drush_get_option('status', FALSE); + + // Throw an error if it's an invalid status. + if ($status && !in_array($status, array('enabled', 'disabled'))) { + return drush_set_error(dt('Invalid status: @status. Available options are "enabled" or "disabled"', array('@status' => $status))); } - // get the --type option - $type = drush_get_option_list('type'); - // use the same logic than $view->type - $with_type = FALSE; - if (in_array('normal', $type) || in_array('default', $type)|| in_array('overridden', $type)) { - $with_type = TRUE; - } - - // set the table headers + // Set the table headers. $header = array( dt('Machine name'), + dt('Human name'), dt('Description'), - dt('Type'), dt('Status'), dt('Tag'), ); - // setup a row for each view + // Setup a row for each view. foreach ($views as $id => $view) { - // if options were specified, check that first - // mismatch push the loop to the next view - if ($with_tags && !in_array($view->storage->tag, $tags)) { + // If options were specified, check that first mismatch push the loop to the + // next view. + if ($with_name && !stristr($view->name, $name[0])) { continue; } - if ($with_status && !$view->disabled == $status) { + if ($with_tags && !in_array($view->tag, $tags)) { continue; } - if ($with_type && strtolower($view->type) !== $type[0]) { - continue; - } - if ($with_name && !stristr($view->storage->name, $name[0])) { + + $status_bool = $status == 'enabled'; + if ($status && ($view->isEnabled() !== $status_bool)) { continue; } $row = array(); - // each row entry should be in the same order as the header - $row[] = $view->storage->name; - $row[] = $view->storage->description; - $row[] = $view->type; - $row[] = $view->storage->disabled ? dt('Disabled') : dt('Enabled'); - $row[] = $view->storage->tag; - // place the row in the appropiate array, - // so we can have disabled views at the bottom - if ($view->storage->disabled) { - $disabled_views[] = $row; + $row[] = $view->id(); + $row[] = $view->label(); + $row[] = $view->description; + $row[] = $view->isEnabled() ? dt('Enabled') : dt('Disabled'); + $row[] = $view->tag; + + // Place the row in the appropiate array, so we can have disabled views at + // the bottom. + if ($view->isEnabled()) { + $enabled_views[] = $row; } else{ - $enabled_views[] = $row; + $disabled_views[] = $row; } + unset($row); - - // gather some statistics - switch ($view->type) { - case dt('Normal'): - $indb++; - break; - - case dt('Overridden'): - $overridden++; - break; - - case dt('Default'): - $incode++; - break; - } - $total++; } $disabled = count($disabled_views); - // sort alphabeticaly + // Sort alphabeticaly. asort($disabled_views); asort($enabled_views); - // if options were used - $summary = ""; - if ($with_name || $with_tags || $with_status || $with_type) { - $summary = "Views"; + // If options were used. + $summary = ''; + if ($with_name || $with_tags || $status) { + $summary = dt('Views'); if ($with_name) { - $summary .= " named $name[0]"; + $summary .= ' ' . dt('named "@name"', array('@name' => $name[0])); } if ($with_tags) { - $tags = implode(" or ", $tags); - $summary .= " tagged $tags"; + $tags = implode(' or ', $tags); + $summary .= ' ' . dt('tagged with "@tags"', array('@tags' => $tags)); } - if ($with_status) { - $status_opt = implode("", $status_opt); - $summary .= " which status is '$status_opt'"; + if ($status) { + $summary .= ' ' . dt('with a status of "@status"', array('@status' => $status)); } - if ($with_type) { - $type = ucfirst($type[0]); - $summary .= " of type '$type'"; - } + drush_print($summary . ":\n"); } - if (!empty($summary)) { - drush_print($summary . "\n"); - } - - // print all rows as a table - if ($total > 0) { + // Print all rows as a table. + if (count($enabled_views) || count($disabled_views)) { $rows = array_merge($enabled_views, $disabled_views); - // put the headers as first row + $total = count($rows); + // Put the headers as first row. array_unshift($rows, $header); drush_print_table($rows, TRUE); + + // Print the statistics messages. + drush_print(dt('A total of @total views were found in this Drupal installation:', array('@total' => $total))); + drush_print(' ' . dt('@dis views are disabled', array('@dis' => $disabled)) . "\n"); + } + else { + drush_set_error(dt('No views found.')); } - // print the statistics messages - drush_print(dt("A total of @total views were found in this Drupal installation:", array('@total' => $total))); - drush_print(dt(" @indb views reside only in the database", array('@indb' => $indb ))); - drush_print(dt(" @over views are overridden", array('@over' => $overridden))); - drush_print(dt(" @incode views are in their default state", array('@incode' => $incode))); - drush_print(dt(" @dis views are disabled\n", array('@dis' => $disabled))); -} - -function drush_views_analyze() { - views_include('analyze'); - $messages_count = 0; - $total = 0; - - $analyzer = new Analyzer(); - foreach (views_get_all_views() as $view_name => $view) { - $total++; - $analyzer->setView($view); - if ($messages = $analyzer->getMessages($view)) { - drush_print($view_name); - foreach ($messages as $message) { - $messages_count++; - drush_print($message['type'] .': '. $message['message'], 2); - } - } - } - drush_log(dt('A total of @total views were analyzed and @messages problems were found.', array('@total' => $total, '@messages' => $messages_count)), 'ok'); } /** - * Enables views + * Drush views analyze command. + */ +function drush_views_analyze() { + $messages_count = 0; + + $views = views_get_all_views(); + + if (!empty($views)) { + $analyzer = new Analyzer(); + foreach ($views as $view_name => $view) { + $view = $view->getExecutable(); + $analyzer->setView($view); + if ($messages = $analyzer->getMessages($view)) { + drush_print($view_name); + foreach ($messages as $message) { + $messages_count++; + drush_print($message['type'] .': '. $message['message'], 2); + } + } + } + return drush_log(dt('A total of @total views were analyzed and @messages problems were found.', array('@total' => count($views), '@messages' => $messages_count)), 'ok'); + } + else { + return drush_set_error(dt('There are no views to analyze')); + } +} + +/** + * Drush views enable command. */ function drush_views_enable() { - $viewnames = _convert_csv_to_array(func_get_args()); + $view_names = func_get_args(); // Return early if no view names were specified. - if (empty($viewnames)) { - return drush_set_error(dt('Please specify a space delimited list of view names to enable')); + if (empty($view_names)) { + return drush_set_error(dt('Please specify a list of view names to enable')); } - _views_drush_changestatus($viewnames, FALSE); + _views_drush_op('enable', $view_names); } /** - * Disables views + * Drush views disable command. */ function drush_views_disable() { - $viewnames = _convert_csv_to_array(func_get_args()); + $view_names = func_get_args(); // Return early if no view names were specified. - if (empty($viewnames)) { - return drush_set_error(dt('Please specify a space delimited list of view names to disable')); + if (empty($view_names)) { + return drush_set_error(dt('Please specify a list of view names to disable')); } - _views_drush_changestatus($viewnames, TRUE); + _views_drush_op('disable', $view_names); } /** - * Helper function to enable / disable views - * @param $viewnames: array of viewnames to process - * @param $status: TRUE to disable or FALSE to enable the view + * Perform operations on view objects. + * + * @param string $op + * The operation to perform. + * @param array $view_names + * An array of view names to load and perform this operation on. */ -function _views_drush_changestatus($viewnames = array(), $status = NULL) { - if ($status !== NULL && !empty($viewnames)) { - $changed = FALSE; - $processed = $status ? dt('disabled') : dt('enabled'); - $views_status = variable_get('views_defaults', array()); +function _views_drush_op($op = '', array $view_names = array()) { + $op_types = _views_drush_op_types(); + if (!in_array($op, array_keys($op_types))) { + return drush_set_error(dt('Invalid op type')); + } - foreach ($viewnames as $key => $viewname) { - if ($views_status[$viewname] !== $status) { - $views_status[$viewname] = $status; - $changed = TRUE; - drush_log(dt("The view '!name' has been !processed", array('!name' => $viewname, '!processed' => $processed)), 'success'); + $view_names = drupal_map_assoc($view_names); + + if ($views = entity_load_multiple('view', $view_names)) { + foreach ($views as $view) { + $tokens = array('@view' => $view->id(), '@action' => $op_types[$op]['action']); + + if ($op_types[$op]['validate']($view)) { + $view->$op(); + drush_log(dt('View: @view has been @action', $tokens), 'success'); } else { - drush_set_error(dt("The view '!name' is already !processed", array('!name' => $viewname, '!processed' => $processed))); + drush_log(dt('View: @view is already @action', $tokens), 'notice'); } - } - // If we made changes to views status, save them and clear caches - if ($changed) { - variable_set('views_defaults', $views_status); - views_invalidate_cache(); - drush_log(dt("Views cache was cleared"), 'ok'); - drush_log(dt("Menu cache is set to be rebuilt on the next request."), 'ok'); + // Remove this view from the viewnames input list. + unset($view_names[$view->id()]); } } + else { + drush_set_error(dt('No views have been loaded')); + } + + // If we have some unmatched/leftover view names that weren't loaded. + if (!empty($view_names)) { + foreach ($view_names as $viewname) { + drush_log(dt('View: @view could not be found.', array('@view' => $viewname)), 'error'); + } + } + +} + +/** + * Returns an array of op types that can be performed on views. + * + * @return array + * An associative array keyed by op type => action name. + */ +function _views_drush_op_types() { + return array( + 'enable' => array( + 'action' => dt('enabled'), + 'validate' => '_views_drush_view_is_disabled', + ), + 'disable' => array( + 'action' => dt('disabled'), + 'validate' => '_views_drush_view_is_enabled', + ), + ); +} + +/** + * Returns whether a view is enabled. + * + * @param Drupal\views\ViewStorage $view + * The view object to check. + * + * @return bool + * TRUE if the View is enabled, FALSE otherwise. + */ +function _views_drush_view_is_enabled(ViewStorage $view) { + return $view->isEnabled(); +} + +/** + * Returns whether a view is disabled. + * + * @param Drupal\views\ViewStorage $view + * The view object to check. + * + * @return bool + * TRUE if the View is disabled, FALSE otherwise. + */ +function _views_drush_view_is_disabled(ViewStorage $view) { + return !$view->isEnabled(); } /** diff --git a/includes/analyze.inc b/includes/analyze.inc deleted file mode 100644 index 9338ec0e6d2..00000000000 --- a/includes/analyze.inc +++ /dev/null @@ -1,39 +0,0 @@ -display) < 2) { - $ret[] = Analyzer::formatMessage(t('This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display.'), 'warning'); - } - // You can give a page display the same path as an alias existing in the - // system, so the alias will not work anymore. Report this to the user, - // because he probably wanted something else. - foreach ($view->displayHandlers as $display) { - if (empty($display)) { - continue; - } - if ($display->hasPath() && $path = $display->getOption('path')) { - $normal_path = drupal_get_normal_path($path); - if ($path != $normal_path) { - $ret[] = Analyzer::formatMessage(t('You have configured display %display with a path which is an path alias as well. This might lead to unwanted effects so better use an internal path.', array('%display' => $display['display_title'])), 'warning'); - } - } - } - - return $ret; -} diff --git a/views_ui.module b/views_ui.module index d6e19c6e546..603f781d29f 100644 --- a/views_ui.module +++ b/views_ui.module @@ -7,6 +7,7 @@ use Drupal\views\ViewExecutable; use Drupal\views\ViewUI; +use Drupal\views\Analyzer; use Drupal\Core\Entity\EntityInterface; /** @@ -759,6 +760,37 @@ function views_ui_library_alter(&$libraries, $module) { } } +/** + * Implements hook_views_analyze(). + * + * This is the basic views analysis that checks for very minimal problems. + * There are other analysis tools in core specific sections, such as + * node.views.inc as well. + */ +function views_ui_views_analyze($view) { + $ret = array(); + // Check for something other than the default display: + if (count($view->displayHandlers) < 2) { + $ret[] = Analyzer::formatMessage(t('This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display.'), 'warning'); + } + // You can give a page display the same path as an alias existing in the + // system, so the alias will not work anymore. Report this to the user, + // because he probably wanted something else. + foreach ($view->displayHandlers as $display) { + if (empty($display)) { + continue; + } + if ($display->hasPath() && $path = $display->getOption('path')) { + $normal_path = drupal_get_normal_path($path); + if ($path != $normal_path) { + $ret[] = Analyzer::formatMessage(t('You have configured display %display with a path which is an path alias as well. This might lead to unwanted effects so better use an internal path.', array('%display' => $display['display_title'])), 'warning'); + } + } + } + + return $ret; +} + /** * Truncate strings to a set length and provide a ... if they truncated. *