From 4addda038c0bce0c711209d9f4e2ee216b33e92f Mon Sep 17 00:00:00 2001
From: Tim Plunkett <git@plnktt.com>
Date: Mon, 24 Sep 2012 20:47:35 -0400
Subject: [PATCH] Issue #1760284 by tim.plunkett: Update the Views copy of the
 core Entity List API.

---
 lib/Drupal/views/ViewListController.php       | 105 +++--------
 lib/Drupal/views/ViewStorage.php              |  10 +
 views_ui.module                               |  67 +++++++
 .../views_ui_listing/EntityListController.php | 153 +++++++++++++++
 .../EntityListControllerBase.php              | 177 ------------------
 .../EntityListControllerInterface.php         |  63 +++----
 .../Tests/ConfigEntityListingTest.php         |  70 -------
 .../ConfigTestListController.php              |  55 ------
 .../views_ui_listing_test.info                |   5 -
 .../views_ui_listing_test.module              |   1 -
 views_ui_listing/views_ui_listing.module      |  88 ++-------
 11 files changed, 304 insertions(+), 490 deletions(-)
 create mode 100644 views_ui_listing/lib/Drupal/views_ui_listing/EntityListController.php
 delete mode 100644 views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerBase.php
 delete mode 100644 views_ui_listing/lib/Drupal/views_ui_listing/Tests/ConfigEntityListingTest.php
 delete mode 100644 views_ui_listing/tests/views_ui_listing_test/lib/Drupal/views_ui_listing_test/ConfigTestListController.php
 delete mode 100644 views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.info
 delete mode 100644 views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.module

diff --git a/lib/Drupal/views/ViewListController.php b/lib/Drupal/views/ViewListController.php
index c43bba173f14..a6976ef7a347 100644
--- a/lib/Drupal/views/ViewListController.php
+++ b/lib/Drupal/views/ViewListController.php
@@ -7,68 +7,20 @@
 
 namespace Drupal\views;
 
-use Drupal\views_ui_listing\EntityListControllerBase;
+use Drupal\views_ui_listing\EntityListController;
 use Drupal\Core\Entity\EntityInterface;
 
 /**
  * Provides a listing of Views.
  */
-class ViewListController extends EntityListControllerBase {
-
-  public function __construct($entity_type, $entity_info = FALSE) {
-    parent::__construct($entity_type, $entity_info);
-  }
+class ViewListController extends EntityListController {
 
   /**
-   * Overrides Drupal\views_ui_listing\EntityListControllerBase::hookMenu();
+   * Overrides Drupal\views_ui_listing\EntityListController::load();
    */
-  public function hookMenu() {
-    // Find the path and the number of path arguments.
-    $path = $this->entityInfo['list path'];
-    $path_count = count(explode('/', $path));
-
-    $items = parent::hookMenu();
-    // Override the access callback.
-    // @todo Probably won't need to specify user access.
-    $items[$path]['title'] = 'Views';
-    $items[$path]['description'] = 'Manage customized lists of content.';
-    $items[$path]['access callback'] = 'user_access';
-    $items[$path]['access arguments'] = array('administer views');
-
-    // Add a default local task, so we have tabs.
-    $items["$path/list"] = array(
-      'title' => 'List',
-      'weight' => -10,
-      'type' => MENU_DEFAULT_LOCAL_TASK,
-    );
-
-    // Set up the base for AJAX callbacks.
-    $ajax_base = array(
-      'page callback' => 'views_ui_listing_ajax_callback',
-      'page arguments' => array($this, $path_count + 1, $path_count + 2),
-      'access callback' => 'user_access',
-      'access arguments' => array('administer views'),
-      'type' => MENU_CALLBACK,
-    );
-
-    // Add an enable link.
-    $items["$path/view/%views_ui/enable"] = array(
-      'title' => 'Enable a view',
-    ) + $ajax_base;
-    // Add a disable link.
-    $items["$path/view/%views_ui/disable"] = array(
-      'title' => 'Disable a view',
-    ) + $ajax_base;
-
-    return $items;
-  }
-
-  /**
-   * Overrides Drupal\views_ui_listing\EntityListControllerBase::getList();
-   */
-  public function getList() {
-    $list = parent::getList();
-    uasort($list, function ($a, $b) {
+  public function load() {
+    $entities = parent::load();
+    uasort($entities, function ($a, $b) {
       $a_enabled = $a->isEnabled();
       $b_enabled = $b->isEnabled();
       if ($a_enabled != $b_enabled) {
@@ -76,14 +28,14 @@ public function getList() {
       }
       return $a->id() > $b->id();
     });
-    return $list;
+    return $entities;
   }
 
   /**
-   * Overrides Drupal\views_ui_listing\EntityListControllerBase::getRowData();
+   * Overrides Drupal\views_ui_listing\EntityListController::buildRow();
    */
-  public function getRowData(EntityInterface $view) {
-    $operations = $this->buildActionLinks($view);
+  public function buildRow(EntityInterface $view) {
+    $operations = $this->buildOperations($view);
     $operations['#theme'] = 'links__ctools_dropbutton';
     return array(
       'data' => array(
@@ -99,9 +51,9 @@ public function getRowData(EntityInterface $view) {
   }
 
   /**
-   * Overrides Drupal\views_ui_listing\EntityListControllerBase::getRowData();
+   * Overrides Drupal\views_ui_listing\EntityListController::buildHeader();
    */
-  public function getHeaderData() {
+  public function buildHeader() {
     return array(
       'view_name' => array(
         'data' => t('View name'),
@@ -119,7 +71,7 @@ public function getHeaderData() {
         'data' => t('Path'),
         'class' => array('views-ui-path'),
       ),
-      'actions' => array(
+      'operations' => array(
         'data' => t('Operations'),
         'class' => array('views-ui-operations'),
       ),
@@ -127,30 +79,33 @@ public function getHeaderData() {
   }
 
   /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::defineActionLinks();
+   * Implements Drupal\views_ui_listing\EntityListController::getOperations();
    */
-  public function defineActionLinks(EntityInterface $view) {
-    $path = $this->entityInfo['list path'] . '/view/' . $view->id();
-    $enabled = $view->isEnabled();
+  public function getOperations(EntityInterface $view) {
+    $uri = $view->uri();
+    $path = $uri['path'] . '/view/' . $view->id();
 
-    if (!$enabled) {
+    $definition['edit'] = array(
+      'title' => t('Edit'),
+      'href' => "$path/edit",
+      'weight' => -5,
+    );
+    if (!$view->isEnabled()) {
       $definition['enable'] = array(
         'title' => t('Enable'),
         'ajax' => TRUE,
         'token' => TRUE,
         'href' => "$path/enable",
+        'weight' => -10,
       );
     }
-    $definition['edit'] = array(
-      'title' => t('Edit'),
-      'href' => "$path/edit",
-    );
-    if ($enabled) {
+    else {
       $definition['disable'] = array(
         'title' => t('Disable'),
         'ajax' => TRUE,
         'token' => TRUE,
         'href' => "$path/disable",
+        'weight' => 0,
       );
     }
     // This property doesn't exist yet.
@@ -158,22 +113,24 @@ public function defineActionLinks(EntityInterface $view) {
       $definition['revert'] = array(
         'title' => t('Revert'),
         'href' => "$path/revert",
+        'weight' => 5,
       );
     }
     else {
       $definition['delete'] = array(
         'title' => t('Delete'),
         'href' => "$path/delete",
+        'weight' => 10,
       );
     }
     return $definition;
   }
 
   /**
-   * Overrides Drupal\views_ui_listing\EntityListControllerBase::renderList();
+   * Overrides Drupal\views_ui_listing\EntityListController::render();
    */
-  public function renderList() {
-    $list = parent::renderList();
+  public function render() {
+    $list = parent::render();
     $list['#attached']['css'] = views_ui_get_admin_css();
     return $list;
   }
diff --git a/lib/Drupal/views/ViewStorage.php b/lib/Drupal/views/ViewStorage.php
index 676855ea0626..9694e758128e 100644
--- a/lib/Drupal/views/ViewStorage.php
+++ b/lib/Drupal/views/ViewStorage.php
@@ -161,6 +161,16 @@ public function getModule() {
     return $this->module;
   }
 
+  /**
+   * Overrides Drupal\Core\Entity\EntityInterface::uri().
+   */
+  public function uri() {
+    $info = $this->entityInfo();
+    return array(
+      'path' => $info['list path'],
+    );
+  }
+
   /**
    * Overrides Drupal\Core\Entity\EntityInterface::id().
    */
diff --git a/views_ui.module b/views_ui.module
index c6dfae173a35..d6e19c6e5468 100644
--- a/views_ui.module
+++ b/views_ui.module
@@ -7,6 +7,7 @@
 
 use Drupal\views\ViewExecutable;
 use Drupal\views\ViewUI;
+use Drupal\Core\Entity\EntityInterface;
 
 /**
  * Implements hook_menu().
@@ -20,6 +21,12 @@ function views_ui_menu() {
     'access arguments' => array('administer views'),
     'file' => 'includes/admin.inc',
   );
+  // Set up the base for AJAX callbacks.
+  $ajax_base = array(
+    'page callback' => 'views_ui_ajax_callback',
+    'page arguments' => array(4, 5),
+    'type' => MENU_CALLBACK,
+  ) + $base;
 
   // Top-level Views module pages (not tied to a particular View).
   $items['admin/structure/views/add'] = array(
@@ -28,6 +35,26 @@ function views_ui_menu() {
     'type' => MENU_LOCAL_ACTION,
   ) + $base;
 
+  $items['admin/structure/views'] = array(
+    'title' => 'Views',
+    'description' => 'Manage customized lists of content.',
+    'page callback' => 'views_ui_list_page',
+  ) + $base;
+
+  $items['admin/structure/views/list'] = array(
+    'title' => 'List',
+    'weight' => -10,
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  ) + $base;
+
+  $items['admin/structure/views/view/%views_ui/enable'] = array(
+    'title' => 'Enable a view',
+  ) + $ajax_base;
+
+  $items['admin/structure/views/view/%views_ui/disable'] = array(
+    'title' => 'Disable a view',
+  ) + $ajax_base;
+
   /*
   // Top-level Views module pages (not tied to a particular View).
   $items['admin/structure/views/add-template'] = array(
@@ -752,3 +779,43 @@ function views_ui_truncate($string, $length) {
 function views_ui_load($name) {
   return views_get_view($name);
 }
+
+/**
+ * Page callback: Calls a method on a view and reloads the listing page.
+ *
+ * @param Drupal\views\ViewExectuable $view
+ *   The config entity being acted upon.
+ * @param string $op
+ *   The operation to perform, e.g., 'enable' or 'disable'.
+ *
+ * @return mixed
+ *   Either returns the listing page as JSON, or calls drupal_goto() to
+ *   redirect back to the listing page.
+ */
+function views_ui_ajax_callback(ViewExecutable $view, $op) {
+  $controller = views_ui_entity_list_controller('view');
+  // Perform the operation.
+  $view->storage->$op();
+
+  // If the request is via AJAX, return the rendered list as JSON.
+  if (drupal_container()->get('request')->request->get('js')) {
+    return $controller->renderListAJAX();
+  }
+  // Otherwise, redirect back to the page.
+  else {
+    drupal_goto($controller->getPath());
+  }
+}
+
+/**
+ * Page callback: Lists all of the views.
+ *
+ * @return array
+ *   A render array for a page containing a list of views.
+ *
+ * @see views_ui_menu()
+ */
+function views_ui_list_page() {
+  $controller = views_ui_entity_list_controller('view');
+  return $controller->render();
+}
diff --git a/views_ui_listing/lib/Drupal/views_ui_listing/EntityListController.php b/views_ui_listing/lib/Drupal/views_ui_listing/EntityListController.php
new file mode 100644
index 000000000000..6f297f0c7a71
--- /dev/null
+++ b/views_ui_listing/lib/Drupal/views_ui_listing/EntityListController.php
@@ -0,0 +1,153 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views_ui_listing\EntityListController.
+ */
+
+namespace Drupal\views_ui_listing;
+
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Provides a generic implementation of an entity list controller.
+ */
+class EntityListController implements EntityListControllerInterface {
+
+  /**
+   * The entity storage controller class.
+   *
+   * @var Drupal\Core\Entity\EntityStorageControllerInterface
+   */
+  protected $storage;
+
+  /**
+   * The entity type name.
+   *
+   * @var string
+   */
+  protected $entityType;
+
+  /**
+   * The entity info array.
+   *
+   * @var array
+   *
+   * @see entity_get_info()
+   */
+  protected $entityInfo;
+
+  /**
+   * Constructs a new EntityListController object.
+   *
+   * @param string $entity_type.
+   *   The type of entity to be listed.
+   */
+  public function __construct($entity_type) {
+    $this->entityType = $entity_type;
+    $this->storage = entity_get_controller($this->entityType);
+    $this->entityInfo = entity_get_info($this->entityType);
+  }
+
+  /**
+   * Implements Drupal\views_ui_listing\EntityListControllerInterface::getStorageController().
+   */
+  public function getStorageController() {
+    return $this->storage;
+  }
+
+  /**
+   * Implements Drupal\views_ui_listing\EntityListControllerInterface::load().
+   */
+  public function load() {
+    return $this->storage->load();
+  }
+
+  /**
+   * Implements Drupal\views_ui_listing\EntityListControllerInterface::getOperations().
+   */
+  public function getOperations(EntityInterface $entity) {
+    $uri = $entity->uri();
+    $operations['edit'] = array(
+      'title' => t('Edit'),
+      'href' => $uri['path'] . '/edit',
+      'options' => $uri['options'],
+      'weight' => 10,
+    );
+    $operations['delete'] = array(
+      'title' => t('Delete'),
+      'href' => $uri['path'] . '/delete',
+      'options' => $uri['options'],
+      'weight' => 100,
+    );
+    return $operations;
+  }
+
+  /**
+   * Retrieves the entity list path from the entity information.
+   *
+   * @return string
+   *   The internal system path where the entity list will be rendered.
+   *
+   * @todo What is this method for, other than fetching the list path? Is this
+   *  for http://drupal.org/node/1783964 ? Should it be on the interface?
+   */
+  public function getPath() {
+    return $this->entityInfo['list path'];
+  }
+
+  /**
+   * Implements Drupal\views_ui_listing\EntityListControllerInterface::buildHeader().
+   */
+  public function buildHeader() {
+    $row['label'] = t('Label');
+    $row['id'] = t('Machine name');
+    $row['operations'] = t('Operations');
+    return $row;
+  }
+
+  /**
+   * Implements Drupal\views_ui_listing\EntityListControllerInterface::buildRow().
+   */
+  public function buildRow(EntityInterface $entity) {
+    $row['label'] = $entity->label();
+    $row['id'] = $entity->id();
+    $operations = $this->buildOperations($entity);
+    $row['operations'] = drupal_render($operations);
+    return $row;
+  }
+
+  /**
+   * Implements Drupal\views_ui_listing\EntityListControllerInterface::buildOperations().
+   */
+  public function buildOperations(EntityInterface $entity) {
+    // Retrieve and sort operations.
+    $operations = $this->getOperations($entity);
+    uasort($operations, 'drupal_sort_weight');
+    $build = array(
+      '#theme' => 'links',
+      '#links' => $operations,
+    );
+    return $build;
+  }
+
+  /**
+   * Implements Drupal\views_ui_listing\EntityListControllerInterface::render().
+   */
+  public function render() {
+    $build = array(
+      '#theme' => 'table',
+      '#header' => $this->buildHeader(),
+      '#rows' => array(),
+      '#empty' => t('There is no @label yet. <a href="@add-url">Add one</a>.', array(
+        '@label' => $this->entityInfo['label'],
+        '@add-url' => url($this->getPath() . '/add'),
+      )),
+    );
+    foreach ($this->load() as $entity) {
+      $build['#rows'][$entity->id()] = $this->buildRow($entity);
+    }
+    return $build;
+  }
+
+}
diff --git a/views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerBase.php b/views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerBase.php
deleted file mode 100644
index cc042243444c..000000000000
--- a/views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerBase.php
+++ /dev/null
@@ -1,177 +0,0 @@
-<?php
-
-/**
- * Definition of Drupal\views_ui_listing\EntityListControllerBase.
- */
-
-namespace Drupal\views_ui_listing;
-
-use Drupal\Core\Entity\EntityInterface;
-use Symfony\Component\HttpFoundation\JsonResponse;
-
-/**
- * Abstract base class for config entity listing plugins.
- */
-abstract class EntityListControllerBase implements EntityListControllerInterface {
-
-  /**
-   * The Config storage controller class.
-   *
-   * @var Drupal\config\ConfigStorageController
-   */
-  protected $storage;
-
-  /**
-   * The Config entity type.
-   *
-   * @var string
-   */
-  protected $entityType;
-
-  /**
-   * The Config entity info.
-   *
-   * @var array
-   */
-  protected $entityInfo;
-
-  /**
-   * If ajax links are used on the listing page.
-   *
-   * @var bool
-   */
-  protected $usesAJAX;
-
-  public function __construct($entity_type, $entity_info = FALSE) {
-    $this->entityType = $entity_type;
-    $this->storage = entity_get_controller($entity_type);
-    if (!$entity_info) {
-      $entity_info = entity_get_info($entity_type);
-    }
-    $this->entityInfo = $entity_info;
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::getList();
-   */
-  public function getList() {
-    return $this->storage->load();
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::getStorageController();
-   */
-  public function getStorageController() {
-    return $this->storage;
-  }
-
-  public function getPath() {
-    return $this->entityInfo['list path'];
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::hookMenu();
-   */
-  public function hookMenu() {
-    $items = array();
-    $items[$this->entityInfo['list path']] = array(
-      'page callback' => 'views_ui_listing_entity_listing_page',
-      'page arguments' => array($this->entityType),
-      // @todo Add a proper access callback here.
-      'access callback' => TRUE,
-    );
-    return $items;
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::getRowData();
-   */
-  public function getRowData(EntityInterface $entity) {
-    $row = array();
-
-    $row['id'] = $entity->id();
-    $row['label'] = $entity->label();
-    $actions = $this->buildActionLinks($entity);
-    $row['actions'] = drupal_render($actions);
-
-    return $row;
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::getHeaderData();
-   */
-  public function getHeaderData() {
-    $row = array();
-    $row['id'] = t('ID');
-    $row['label'] = t('Label');
-    $row['actions'] = t('Actions');
-    return $row;
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::buildActionLinks();
-   */
-  public function buildActionLinks(EntityInterface $entity) {
-    $links = array();
-
-    foreach ($this->defineActionLinks($entity) as $definition) {
-      $attributes = array();
-
-      if (!empty($definition['ajax'])) {
-        $attributes['class'][] = 'use-ajax';
-        // Set this to true if we haven't already.
-        if (!isset($this->usesAJAX)) {
-          $this->usesAJAX = TRUE;
-        }
-      }
-
-      $links[] = array(
-        'title' => $definition['title'],
-        'href' => $definition['href'],
-        'attributes' => $attributes,
-      );
-    }
-
-    return array(
-      '#theme' => 'links',
-      '#links' => $links,
-    );
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::renderList();
-   */
-  public function renderList() {
-    $rows = array();
-
-    foreach ($this->getList() as $entity) {
-      $rows[] = $this->getRowData($entity);
-    }
-
-    // Add core AJAX library if we need to.
-    if (!empty($this->usesAJAX)) {
-      drupal_add_library('system', 'drupal.ajax');
-    }
-
-    return array(
-      '#theme' => 'table',
-      '#header' => $this->getHeaderData(),
-      '#rows' => $rows,
-      '#attributes' => array(
-        'id' => 'config-entity-listing',
-      ),
-    );
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::renderList();
-   */
-  public function renderListAJAX() {
-    $list = $this->renderList();
-    $commands = array();
-    $commands[] = ajax_command_replace('#config-entity-listing', drupal_render($list));
-
-    return new JsonResponse(ajax_render($commands));
-  }
-
-}
diff --git a/views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerInterface.php b/views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerInterface.php
index 1b9b592b9f13..9a80dec96c11 100644
--- a/views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerInterface.php
+++ b/views_ui_listing/lib/Drupal/views_ui_listing/EntityListControllerInterface.php
@@ -10,38 +10,37 @@
 use Drupal\Core\Entity\EntityInterface;
 
 /**
- * Defines an interface for Configuration entity listing plugins.
+ * Defines an interface for entity list controllers.
  */
 interface EntityListControllerInterface {
 
-  /*
-   * Returns a list of all available config entites of this type.
-   */
-  public function getList();
-
   /**
-   * Gets the ConfigEntityController.
+   * Gets the entity storage controller.
    *
-   * @todo Put in correct namespace and docs here.
+   * @return Drupal\Core\Entity\EntityStorageControllerInterface
+   *   The storage controller used by this list controller.
    */
   public function getStorageController();
 
   /**
-   * Gets the hook_menu array item.
+   * Loads entities of this type from storage for listing.
    *
-   * @todo Put in correct docs here.
+   * @return array
+   *   An array of entities implementing Drupal\Core\Entity\EntityInterface.
    */
-  public function hookMenu();
+  public function load();
 
   /**
-   * Builds an array of data for each row.
+   * Provides an array of information to render the operation links.
    *
-   * @param EntityInterface $entity
+   * @param Drupal\Core\Entity\EntityInterface $entity
+   *   The entity the operations are for.
    *
    * @return array
-   *   An array of fields to use for this entity.
+   *   A array of operation link data to use in
+   *   EntityListControllerInterface::buildOperations().
    */
-  public function getRowData(EntityInterface $entity);
+  public function getOperations(EntityInterface $entity);
 
   /**
    * Builds the header row.
@@ -49,36 +48,36 @@ public function getRowData(EntityInterface $entity);
    * @return array
    *   An array of header strings.
    */
-  public function getHeaderData();
+  public function buildHeader();
 
   /**
-   * Renders the list page markup to be output.
+   * Builds an array of data for each row.
    *
-   * @return string
-   *   The output markup for the listing page.
-   */
-  public function renderList();
-
-  /**
-   * Returns the list page as JSON.
+   * @param Drupal\Core\Entity\EntityInterface $entity
+   *   The entity for this row of the list.
    *
-   * @return Symfony\Component\HttpFoundation\JsonResponse
-   *   AJAX commands to render the list.
+   * @return array
+   *   An array of fields to use for this entity.
    */
-  public function renderListAJAX();
+  public function buildRow(EntityInterface $entity);
 
   /**
-   * Renders a list of action links.
+   * Renders a list of operation links.
+   *
+   * @param Drupal\Core\Entity\EntityInterface $entity
+   *   The entity on which the linked operations will be performed.
    *
    * @return array
+   *   A renderable array of operation links.
    */
-  public function buildActionLinks(EntityInterface $entity);
+  public function buildOperations(EntityInterface $entity);
 
   /**
-   * Provides an array of information to render action links.
+   * Renders the list page markup to be output.
    *
-   * @return array
+   * @return string
+   *   The output markup for the listing page.
    */
-  public function defineActionLinks(EntityInterface $entity);
+  public function render();
 
 }
diff --git a/views_ui_listing/lib/Drupal/views_ui_listing/Tests/ConfigEntityListingTest.php b/views_ui_listing/lib/Drupal/views_ui_listing/Tests/ConfigEntityListingTest.php
deleted file mode 100644
index b2aeae377323..000000000000
--- a/views_ui_listing/lib/Drupal/views_ui_listing/Tests/ConfigEntityListingTest.php
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\views_ui_listing\Tests\ConfigEntityListingTest.
- */
-
-namespace Drupal\views_ui_listing\Tests;
-
-use Drupal\simpletest\WebTestBase;
-use Drupal\config\ConfigEntityBase;
-
-/**
- * Tests configuration entities.
- */
-class ConfigEntityListingTest extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('views_ui_listing_test');
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Views configuration entity listing',
-      'description' => 'Tests configuration entity listing plugins.',
-      'group' => 'Views',
-    );
-  }
-
-  /**
-   * Tests basic listing plugin functionilty.
-   */
-  function testListingPlugin() {
-    $controller = views_ui_listing_get_list_controller('config_test');
-
-    // Get a list of Config entities.
-    $list = $controller->getList();
-    $this->assertEqual(count($list), 1, 'Correct number of plugins found.');
-    $this->assertTrue(!empty($list['default']), '"Default" config entity key found in list.');
-    $this->assertTrue($list['default'] instanceof ConfigEntityBase, '"Default" config entity is an instance of ConfigEntityBase');
-  }
-
-  /**
-   * Tests the listing UI.
-   */
-  function testListingUI() {
-    $page = $this->drupalGet('config-listing-test');
-
-    // Test that the page exists.
-    $this->assertText('Config test', 'Config test listing page title found.');
-
-    // Check we have the default id and label on the page too.
-    $this->assertText('default', '"default" ID found.');
-    $this->assertText('Default', '"Default" label found');
-
-    // Check each link.
-    foreach (array('edit', 'add', 'delete') as $link) {
-      $this->drupalSetContent($page);
-      $this->assertLink($link);
-      $this->clickLink($link);
-      $this->assertResponse(200);
-    }
-
-    // @todo Test AJAX links.
-  }
-
-}
diff --git a/views_ui_listing/tests/views_ui_listing_test/lib/Drupal/views_ui_listing_test/ConfigTestListController.php b/views_ui_listing/tests/views_ui_listing_test/lib/Drupal/views_ui_listing_test/ConfigTestListController.php
deleted file mode 100644
index b5467595062d..000000000000
--- a/views_ui_listing/tests/views_ui_listing_test/lib/Drupal/views_ui_listing_test/ConfigTestListController.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * Definition of Drupal\views_ui_listing_test\ConfigTestListController.
- */
-
-namespace Drupal\views_ui_listing_test;
-
-use Drupal\views_ui_listing\EntityListControllerBase;
-use Drupal\Core\Entity\EntityInterface;
-
-/**
- * Views config entity listing controller.
- */
-class ConfigTestListController extends EntityListControllerBase {
-
-  /**
-   * Overrides Drupal\views_ui_listing\EntityListControllerBase::hookMenu();
-   */
-  public function hookMenu() {
-    $path = $this->entityInfo['list path'];
-
-    $items = parent::hookMenu();
-    $items[$path]['title'] = 'Config test';
-    $items[$path]['description'] = 'Config test listing page.';
-    return $items;
-  }
-
-  /**
-   * Implements Drupal\views_ui_listing\EntityListControllerInterface::actionLinkMappings().
-   */
-  public function defineActionLinks(EntityInterface $entity) {
-    $id = $entity->id();
-
-    // @todo Add AJAX link to test.
-    return array(
-      'edit' => array(
-        'title' => 'edit',
-        'href' => "admin/structure/config_test/manage/$id/edit",
-        'ajax' => FALSE,
-      ),
-      'add' => array(
-        'title' => 'add',
-        'href' => "admin/structure/config_test/add",
-        'ajax' => FALSE,
-      ),
-      'delete' => array(
-        'title' => 'delete',
-        'href' => "admin/structure/config_test/manage/$id/delete",
-        'ajax' => FALSE,
-      ),
-    );
-  }
-
-}
diff --git a/views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.info b/views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.info
deleted file mode 100644
index 703ba6ce930a..000000000000
--- a/views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.info
+++ /dev/null
@@ -1,5 +0,0 @@
-name = Views UI listing test module
-package = Views
-dependencies[] = views_ui
-dependencies[] = config_test
-hidden = TRUE
diff --git a/views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.module b/views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.module
deleted file mode 100644
index b3d9bbc7f371..000000000000
--- a/views_ui_listing/tests/views_ui_listing_test/views_ui_listing_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/views_ui_listing/views_ui_listing.module b/views_ui_listing/views_ui_listing.module
index bb08f93e1990..ba58087e5bf8 100644
--- a/views_ui_listing/views_ui_listing.module
+++ b/views_ui_listing/views_ui_listing.module
@@ -1,86 +1,22 @@
 <?php
 
-use Drupal\views_ui_listing\EntityListControllerInterface;
-use Drupal\config\ConfigEntityInterface;
-use Drupal\views\ViewExecutable;
-
 /**
- * Implements hook_menu().
- */
-function views_ui_listing_menu() {
-  $items = array();
-  foreach (entity_get_info() as $entity_type => $type_info) {
-    if (isset($type_info['list controller class'])) {
-      $controller = views_ui_listing_get_list_controller($entity_type);
-      $items += $controller->hookMenu();
-    }
-  }
-  return $items;
-}
-
-/**
- * Gets the entity list controller class for an entity type.
+ * Returns an entity list controller for a given entity type.
+ *
+ * @param string $entity_type
+ *   The type of the entity.
  *
- * @return Drupal\entity\EntityListControllerInterface
+ * @return Drupal\Core\Entity\EntityListControllerInterface
+ *   An entity list controller.
+ *
+ * @see hook_entity_info()
  */
-function views_ui_listing_get_list_controller($entity_type) {
+function views_ui_entity_list_controller($entity_type) {
   $controllers = &drupal_static(__FUNCTION__, array());
-  if (!isset($controllers[$entity_type])) {
-    $type_info = entity_get_info($entity_type);
-    $class = $type_info['list controller class'];
+  if (!isset($instances[$entity_type])) {
+    $info = entity_get_info($entity_type);
+    $class = $info['list controller class'];
     $controllers[$entity_type] = new $class($entity_type);
   }
   return $controllers[$entity_type];
 }
-
-/**
- * Page callback: Displays a config listing page.
- *
- * @param string $entity_id
- *   The entity type.
- *
- * @return string
- *   The page markup for the page.
- */
-function views_ui_listing_entity_listing_page($entity_id) {
-  $controller = views_ui_listing_get_list_controller($entity_id);
-  return $controller->renderList();
-}
-
-/**
- * Page callback: Calls a method on a config entity and reloads the listing page.
- *
- * @param Drupal\views_ui_listing\EntityListControllerInterface $controller
- *   The list controller for this entity.
- * @param Drupal\views\ViewExecutable $entity
- *   The config entity being acted upon.
- * @param string $op
- *   The action to perform, e.g., 'enable' or 'disable'.
- *
- * @return mixed
- *   Either returns the listing page as JSON, or calls drupal_goto() to
- *   redirect back to the listing page.
- */
-function views_ui_listing_ajax_callback(EntityListControllerInterface $controller, ViewExecutable $entity, $op) {
-  // Perform the operation.
-  $entity->storage->$op();
-
-  // If the request is via AJAX, return the rendered list as JSON.
-  if (drupal_container()->get('request')->request->get('js')) {
-    return $controller->renderListAJAX();
-  }
-  // Otherwise, redirect back to the page.
-  else {
-    drupal_goto($controller->getPath());
-  }
-}
-
-/**
- * Implements hook_entity_info_alter().
- */
-function views_ui_listing_entity_info_alter(&$entity_info) {
-  if (isset($entity_info['config_test'])) {
-    $entity_info['config_test']['list path'] = 'config-listing-test';
-    $entity_info['config_test']['list controller class'] = 'Drupal\views_ui_listing_test\ConfigTestListController';
-  }
-}
-- 
GitLab