Issue #2056513 by tim.plunkett: Remove PluginUI subsystem, provide block plugins UI as one-off.

8.0.x
webchick 2013-08-07 12:49:26 -07:00
parent c5f524fa61
commit b435b703d6
27 changed files with 323 additions and 582 deletions

View File

@ -61,14 +61,14 @@ function block_help($path, $arg) {
$output .= '<dd>' . t('Blocks can be configured to be visible only on certain pages, only to users of certain roles, or only on pages displaying certain <a href="@content-type">content types</a>. Some dynamic blocks, such as those generated by modules, will be displayed only on certain pages.', array('@content-type' => url('admin/structure/types'), '@user' => url('user'))) . '</dd>';
if (module_exists('custom_block')) {
$output .= '<dt>' . t('Creating custom blocks') . '</dt>';
$output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can <a href="@block-add">add custom blocks</a>, which are then listed on the <a href="@blocks">Blocks administration page</a>. Once created, custom blocks behave just like default and module-generated blocks.', array('@blocks' => url('admin/structure/block'), '@block-add' => url('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add/custom_blocks'))) . '</dd>';
$output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can <a href="@block-add">add custom blocks</a>, which are then listed on the <a href="@blocks">Blocks administration page</a>. Once created, custom blocks behave just like default and module-generated blocks.', array('@blocks' => url('admin/structure/block'), '@block-add' => url('admin/structure/block/list/' . config('system.theme')->get('default') . '/add/custom_blocks'))) . '</dd>';
}
$output .= '</dl>';
return $output;
}
if ($arg[0] == 'admin' && $arg[1] == 'structure' && $arg['2'] == 'block' && (empty($arg[3]) || $arg[3] == 'list') && empty($arg[5])) {
if (!empty($arg[4])) {
list(, $demo_theme) = explode(':', $arg[4]);
$demo_theme = $arg[4];
}
else {
$demo_theme = config('system.theme')->get('default');
@ -136,28 +136,28 @@ function block_menu() {
// and plugin IDs to decouple the routes from these dependencies and allow
// hook_menu_local_tasks() to check for the untranslated tab_parent path.
// @see http://drupal.org/node/1067408
$themes = list_themes();
foreach (drupal_container()->get('plugin.manager.system.plugin_ui')->getDefinitions() as $plugin_id => $plugin) {
list($plugin_base, $key) = explode(':', $plugin_id);
if ($plugin_base == 'block_plugin_ui') {
$theme = $themes[$key];
$items['admin/structure/block/list/' . $plugin_id] = array(
'title' => check_plain($theme->info['name']),
'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'route_name' => 'block_admin_display.' . $plugin_id
);
$items['admin/structure/block/demo/' . $key] = array(
'title' => check_plain($theme->info['name']),
'page callback' => 'block_admin_demo',
'page arguments' => array($key),
'type' => MENU_CALLBACK,
'access callback' => '_block_themes_access',
'access arguments' => array($key),
'theme callback' => '_block_custom_theme',
'theme arguments' => array($key),
'file' => 'block.admin.inc',
);
}
foreach (list_themes() as $key => $theme) {
$items["admin/structure/block/list/$key"] = array(
'title' => check_plain($theme->info['name']),
'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'route_name' => "block_admin_display.$key",
);
$items["admin/structure/block/list/$key/add"] = array(
'title' => 'Place blocks',
'type' => MENU_LOCAL_ACTION,
'route_name' => "block_plugin_ui.$key",
);
$items["admin/structure/block/demo/$key"] = array(
'title' => check_plain($theme->info['name']),
'page callback' => 'block_admin_demo',
'page arguments' => array($key),
'type' => MENU_CALLBACK,
'access callback' => '_block_themes_access',
'access arguments' => array($key),
'theme callback' => '_block_custom_theme',
'theme arguments' => array($key),
'file' => 'block.admin.inc',
);
}
return $items;
}

View File

@ -26,3 +26,10 @@ block_admin_add:
_content: '\Drupal\block\Controller\BlockAddController::blockAddConfigureForm'
requirements:
_permission: 'administer blocks'
block_autocomplete:
pattern: '/block/autocomplete'
defaults:
_controller: '\Drupal\block\Controller\BlockAutocompleteController::autocomplete'
requirements:
_permission: 'administer blocks'

View File

@ -13,7 +13,6 @@ services:
class: Drupal\block\Routing\RouteSubscriber
tags:
- { name: event_subscriber}
arguments: ['@plugin.manager.system.plugin_ui']
block.theme_access_check:
class: Drupal\block\Access\BlockThemeAccessCheck
tags:

View File

@ -283,7 +283,7 @@ class BlockFormController extends EntityFormController implements EntityControll
drupal_set_message(t('The block configuration has been saved.'));
cache_invalidate_tags(array('content' => TRUE));
$form_state['redirect'] = 'admin/structure/block/list/block_plugin_ui:' . $entity->get('theme');
$form_state['redirect'] = 'admin/structure/block/list/' . $entity->get('theme');
}
/**

View File

@ -0,0 +1,78 @@
<?php
/**
* @file
* Contains \Drupal\block\Controller\BlockAutocompleteController.
*/
namespace Drupal\block\Controller;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Component\Utility\Tags;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Controller\ControllerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* Provides an autocomplete for blocks.
*/
class BlockAutocompleteController implements ControllerInterface {
/**
* The block plugin manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected $manager;
/**
* Constructs a new BlockAutocompleteController object.
*
* @param \Drupal\Component\Plugin\PluginManagerInterface $manager
* The block plugin manager.
*/
public function __construct(PluginManagerInterface $manager) {
$this->manager = $manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('plugin.manager.block')
);
}
/**
* Autocompletes a block plugin ID.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The matched plugins as JSON.
*/
public function autocomplete(Request $request) {
$string_typed = $request->query->get('q');
// The passed string may be comma or space separated.
$string_typed = Tags::explode($string_typed);
// Take the last result and lowercase it.
$string = Unicode::strtolower(array_pop($string_typed));
$matches = array();
if ($string) {
$titles = array();
// Gather all block plugins and their admin titles.
foreach($this->manager->getDefinitions() as $plugin_id => $plugin) {
$titles[$plugin_id] = $plugin['admin_label'];
}
// Find any matching block plugin IDs.
$matches = preg_grep("/\b". $string . "/i", $titles);
}
return new JsonResponse($matches);
}
}

View File

@ -18,17 +18,15 @@ class BlockListController extends EntityListController {
/**
* Shows the block administration page.
*
* @param string $entity_type
* Entity type of list page.
* @param string|null $theme
* Theme key of block list.
*
* @return array
* A render array as expected by drupal_render().
*/
public function listing($entity_type, $theme = NULL) {
$default_theme = $theme ?: $this->config('system.theme')->get('default');
return $this->entityManager()->getListController($entity_type)->render($default_theme);
public function listing($theme = NULL) {
$theme = $theme ?: $this->config('system.theme')->get('default');
return $this->entityManager()->getListController('block')->render($theme);
}
}

View File

@ -0,0 +1,157 @@
<?php
/**
* @file
* Contains \Drupal\block\Form\PlaceBlocksForm.
*/
namespace Drupal\block\Form;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Component\Utility\String;
use Drupal\Core\Controller\ControllerInterface;
use Drupal\Core\Form\FormInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides the 'Place blocks' form.
*/
class PlaceBlocksForm implements FormInterface, ControllerInterface {
/**
* The block plugin manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected $manager;
/**
* The theme this block will be placed into.
*
* @var string
*/
protected $theme;
/**
* Constructs a new PlaceBlocksForm object.
*
* @param \Drupal\Component\Plugin\PluginManagerInterface $manager
* The block plugin manager.
*/
public function __construct(PluginManagerInterface $manager) {
$this->manager = $manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('plugin.manager.block')
);
}
/**
* {@inheritdoc}
*/
public function getFormID() {
return 'block_plugin_ui';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, array &$form_state, $theme = NULL, $category = NULL) {
$this->theme = $theme;
$form['#theme'] = 'system_plugin_ui_form';
$rows = array();
$categories = array();
foreach ($this->manager->getDefinitions() as $plugin_id => $plugin_definition) {
if (empty($category) || $plugin_definition['category'] == $category) {
$rows[$plugin_id] = $this->row($plugin_id, $plugin_definition);
}
$categories[$plugin_definition['category']] = array(
'title' => $plugin_definition['category'],
'href' => 'admin/structure/block/list/' . $this->theme . '/add/' . $plugin_definition['category'],
);
}
$form['right']['block'] = array(
'#type' => 'textfield',
'#title' => t('Search'),
'#autocomplete_path' => 'block/autocomplete',
);
$form['right']['submit'] = array(
'#type' => 'submit',
'#button_type' => 'primary',
'#value' => t('Next'),
);
$form['right']['all_plugins'] = array(
'#type' => 'link',
'#title' => t('All blocks'),
'#href' => 'admin/structure/block/list/' . $this->theme . '/add',
);
if (!empty($categories)) {
$form['right']['categories'] = array(
'#theme' => 'links',
'#heading' => array(
'text' => t('Categories'),
'level' => 'h3',
),
'#links' => $categories,
);
}
// Sort rows alphabetically.
asort($rows);
$form['left']['plugin_library'] = array(
'#theme' => 'table',
'#header' => array(t('Subject'), t('Operations')),
'#rows' => $rows,
);
return $form;
}
/**
* Generates the row data for a single block plugin.
*
* @param string $plugin_id
* The plugin ID.
* @param array $plugin_definition
* The plugin definition.
*
* @return array
* The row data for a single block plugin.
*/
protected function row($plugin_id, array $plugin_definition) {
$row = array();
$row[] = String::checkPlain($plugin_definition['admin_label']);
$row[] = array('data' => array(
'#type' => 'operations',
'#links' => array(
'configure' => array(
'title' => t('Place block'),
'href' => 'admin/structure/block/add/' . $plugin_id . '/' . $this->theme,
),
),
));
return $row;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, array &$form_state) {
if (!$this->manager->getDefinition($form_state['values']['block'])) {
form_set_error('block', t('You must select a valid block.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, array &$form_state) {
$form_state['redirect'] = 'admin/structure/block/add/' . $form_state['values']['block'] . '/' . $this->theme;
}
}

View File

@ -1,29 +0,0 @@
<?php
/**
* Contains \Drupal\block\Plugin\Derivative\BlockPluginUI.
*/
namespace Drupal\block\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DerivativeBase;
/**
* Provides block plugin UI plugin definitions for all themes.
*
* @todo Add documentation to this class.
*
* @see \Drupal\block\Plugin\system\plugin_ui\BlockPluginUI
*/
class BlockPluginUI extends DerivativeBase {
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions(array $base_plugin_definition) {
// Provide a derivative of the plugin UI for each theme.
foreach (list_themes() as $key => $theme) {
$this->derivatives[$key] = $base_plugin_definition;
}
return parent::getDerivativeDefinitions($base_plugin_definition);
}
}

View File

@ -1,229 +0,0 @@
<?php
/**
* Contains \Drupal\block\Plugin\PluginUI\BlockPluginUI.
*/
namespace Drupal\block\Plugin\PluginUI;
use Drupal\system\Plugin\PluginUIBase;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
/**
* Defines an overrideable UI for block selection, configuration, and placement.
*
* @Plugin(
* id = "block_plugin_ui",
* module = "block",
* all_plugins = @Translation("All Blocks"),
* config_path = "admin/structure/block/add",
* default_task = TRUE,
* derivative = "Drupal\block\Plugin\Derivative\BlockPluginUI",
* facets = {
* "module" = @Translation("Modules")
* },
* link_title = @Translation("Place block"),
* manager = "plugin.manager.block",
* menu = TRUE,
* path = "admin/structure/block/list",
* suffix = "add",
* task_suffix = "library",
* task_title = @Translation("Library"),
* title = @Translation("Place blocks"),
* title_attribute = "admin_label",
* type = MENU_LOCAL_ACTION
* )
*/
class BlockPluginUI extends PluginUIBase {
/**
* Overrides \Drupal\system\Plugin\PluginUIBase::form().
*
* @todo Add inline documentation to this method.
*/
public function form($form, &$form_state, $facet = NULL) {
// @todo Add an inline comment here.
list($plugin, $theme) = explode(':', $this->getPluginId());
$plugin_definition = $this->getPluginDefinition();
// @todo Find out how to let the manager be injected into the class.
$manager = drupal_container()->get($plugin_definition['manager']);
$plugins = $manager->getDefinitions();
$form['#theme'] = 'system_plugin_ui_form';
$form['theme'] = array(
'#type' => 'value',
'#value' => $theme,
);
$form['manager'] = array(
'#type' => 'value',
'#value' => $manager,
);
$form['instance'] = array(
'#type' => 'value',
'#value' => $this,
);
$form['right']['block'] = array(
'#type' => 'textfield',
'#title' => t('Search'),
'#autocomplete_path' => 'system/autocomplete/' . $this->getPluginId(),
);
$form['right']['submit'] = array(
'#type' => 'submit',
'#value' => t('Next'),
);
$rows = array();
foreach ($plugins as $plugin_id => $display_plugin_definition) {
if (empty($facet) || $this->facetCompare($facet, $display_plugin_definition)) {
$rows[$plugin_id] = $this->row($plugin_id, $display_plugin_definition);
}
foreach ($plugin_definition['facets'] as $key => $title) {
$facets[$key][$display_plugin_definition[$key]] = $this->facetLink($key, $plugin_id, $display_plugin_definition);
}
$form['right']['all_plugins'] = array(
'#type' => 'link',
'#title' => $plugin_definition['all_plugins'],
'#href' => $this->allPluginsUrl($plugin_id, $display_plugin_definition),
);
foreach ($facets as $group => $values) {
$form['right'][$group] = array(
'#theme' => 'links',
'#heading' => array(
'text' => $plugin_definition['facets'][$group],
'level' => 'h3',
),
'#links' => $values,
);
}
}
// Sort rows alphabetically.
asort($rows);
$form['left']['plugin_library'] = array(
'#theme' => 'table',
'#header' => $this->tableHeader(),
'#rows' => $rows,
);
return $form;
}
/**
* Overrides \Drupal\system\Plugin\PluginUIBase::formValidate().
*/
public function formValidate($form, &$form_state) {
$definitions = $form_state['values']['manager']->getDefinitions();
if (!isset($definitions[$form_state['values']['block']])) {
form_set_error('block', t('You must select a valid block.'));
}
}
/**
* Overrides \Drupal\system\Plugin\PluginUIBase::formSubmit().
*/
public function formSubmit($form, &$form_state) {
$form_state['redirect'] = 'admin/structure/block/add/' . $form_state['values']['block'] . '/' . $form_state['values']['theme'];
}
/**
* Overrides \Drupal\system\Plugin\PluginUIBase::access().
*/
public function access() {
list($plugin, $theme) = explode(':', $this->getPluginId());
return _block_themes_access($theme);
}
/**
* Overrides \Drupal\system\Plugin\PluginUIBase::tableHeader().
*/
public function tableHeader() {
return array(t('Subject'), t('Operations'));
}
/**
* Overrides \Drupal\system\Plugin\PluginUIBase::row().
*/
public function row($display_plugin_id, array $display_plugin_definition) {
$plugin_definition = $this->getPluginDefinition();
list($plugin, $theme) = explode(':', $this->getPluginId());
$row = array();
$row[] = check_plain($display_plugin_definition['admin_label']);
$row[] = array('data' => array(
'#type' => 'operations',
'#links' => array(
'configure' => array(
'title' => $plugin_definition['link_title'],
'href' => $plugin_definition['config_path'] . '/' . $display_plugin_id . '/' . $theme,
),
),
));
return $row;
}
/**
* Creates a facet link for a given facet of a display plugin.
*
* Provides individually formatted links for the faceting that happens within
* the user interface. Since this is a faceting style procedure, each plugin
* may be parsed multiple times in order to extract all facets and their
* appropriate labels.
*
* The $display_plugin_id and $display_plugin_definition are provided for
* convenience when overriding this method.
*
* @param string $facet
* A simple string indicating what element of the $display_plugin_definition
* to utilize for faceting.
* @param string $display_plugin_id
* The plugin ID of the plugin we are currently parsing a facet link from.
* @param array $display_plugin_definition
* The plugin definition we are parsing.
*
* @return array
* Returns a row array comaptible with theme_links().
*/
protected function facetLink($facet, $display_plugin_id, array $display_plugin_definition) {
$plugin_definition = $this->getPluginDefinition();
return array(
'title' => $display_plugin_definition[$facet],
'href' => $plugin_definition['path'] . '/' . $this->getPluginId() . '/' . $facet . ':' . $display_plugin_definition[$facet],
);
}
/**
* Determines whether a given facet should be displayed for a plugin.
*
* Compares a given plugin definition with the selected facet to determine if
* the plugin should be displayed in the user interface.
*
* @param string $facet
* A colon separated string representing the key/value paring of a selected
* facet.
* @param array $display_plugin_definition
* The plugin definition to be compared.
*
* @return bool
* Returns TRUE if the selected facet matches this plugin.
*/
protected function facetCompare($facet, $display_plugin_definition) {
list($facet_type, $option) = explode(':', $facet);
return $option == $display_plugin_definition[$facet_type];
}
/**
* Provides an "all" style link to reset the facets.
*
* The $display_plugin_id and $display_plugin_definition are provided for
* convenience when overriding this method.
*
* @param string $display_plugin_id
* The plugin ID of the plugin we are currently parsing a facet link from.
* @param array $display_plugin_definition
* The plugin definition we are parsing.
*
* @return string
* Returns a simple URL string for use within l().
*/
protected function allPluginsUrl($display_plugin_id, $display_plugin_definition) {
$plugin_definition = $this->getPluginDefinition();
return $plugin_definition['path'] . '/' . $this->getPluginId() . '/add';
}
}

View File

@ -1,6 +1,7 @@
<?php
/**
* @file
* Contains \Drupal\block\Plugin\Type\BlockManager.
*/
@ -10,6 +11,7 @@ use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Plugin\DefaultPluginManager;
/**
* Manages discovery and instantiation of block plugins.
*
@ -37,4 +39,17 @@ class BlockManager extends DefaultPluginManager {
$this->alterInfo($module_handler, 'block');
$this->setCacheBackend($cache_backend, $language_manager, 'block_plugins');
}
/**
* {@inheritdoc}
*/
public function processDefinition(&$definition, $plugin_id) {
parent::processDefinition($definition, $plugin_id);
// Ensure that every block has a category.
$definition += array(
'category' => $definition['provider'],
);
}
}

View File

@ -1,4 +1,5 @@
<?php
/**
* @file
* Contains \Drupal\block\Routing\RouteSubscriber.
@ -11,31 +12,12 @@ use Drupal\Core\Routing\RoutingEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
/**
* Listens to the dynamic route events.
*/
class RouteSubscriber implements EventSubscriberInterface {
/**
* The injection plugin manager that should be passed into the route.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected $pluginManager;
/**
* Constructs a RouteSubscriber object.
*
* @param \Drupal\Component\Plugin\PluginManagerInterface $plugin_manager
* The service container this object should use.
*/
public function __construct(PluginManagerInterface $plugin_manager) {
$this->pluginManager = $plugin_manager;
}
/**
* Implements EventSubscriberInterface::getSubscribedEvents().
*/
@ -55,18 +37,32 @@ class RouteSubscriber implements EventSubscriberInterface {
*/
public function routes(RouteBuildEvent $event) {
$collection = $event->getRouteCollection();
foreach ($this->pluginManager->getDefinitions() as $plugin_id => $plugin) {
list($plugin_base, $key) = explode(':', $plugin_id);
if ($plugin_base == 'block_plugin_ui') {
$route = new Route('admin/structure/block/list/' . $plugin_id, array(
foreach (list_themes(TRUE) as $key => $theme) {
// The block entity listing page.
$route = new Route(
"admin/structure/block/list/$key",
array(
'_controller' => '\Drupal\block\Controller\BlockListController::listing',
'entity_type' => 'block',
'theme' => $key,
), array(
),
array(
'_block_themes_access' => 'TRUE',
));
$collection->add('block_admin_display.' . $plugin_id, $route);
}
)
);
$collection->add("block_admin_display.$key", $route);
// The block plugin listing page.
$route = new Route(
"admin/structure/block/list/$key/add/{category}",
array(
'_form' => '\Drupal\block\Form\PlaceBlocksForm',
'category' => NULL,
'theme' => $key,
),
array('_block_themes_access' => 'TRUE')
);
$collection->add("block_plugin_ui.$key", $route);
}
}
}

View File

@ -38,14 +38,14 @@ class BlockAdminThemeTest extends WebTestBase {
$this->drupalLogin($admin_user);
// Ensure that access to block admin page is denied when theme is disabled.
$this->drupalGet('admin/structure/block/list/block_plugin_ui:bartik');
$this->drupalGet('admin/structure/block/list/bartik');
$this->assertResponse(403);
// Enable admin theme and confirm that tab is accessible.
theme_enable(array('bartik'));
$edit['admin_theme'] = 'bartik';
$this->drupalPost('admin/appearance', $edit, t('Save configuration'));
$this->drupalGet('admin/structure/block/list/block_plugin_ui:bartik');
$this->drupalGet('admin/structure/block/list/bartik');
$this->assertResponse(200);
}
}

View File

@ -49,11 +49,11 @@ class BlockLibrarySearchTest extends WebTestBase {
*/
function testBlockLibrarySearch() {
// Check that the block plugin is valid.
$this->drupalPost('admin/structure/block/list/block_plugin_ui:stark/add', array('block' => 'invalid_block'), t('Next'));
$this->drupalPost('admin/structure/block/list/stark/add', array('block' => 'invalid_block'), t('Next'));
$this->assertText('You must select a valid block.');
// Check that the block search form redirects to the correct block form.
$this->drupalPost('admin/structure/block/list/block_plugin_ui:stark/add', array('block' => 'system_main_block'), t('Next'));
$this->drupalPost('admin/structure/block/list/stark/add', array('block' => 'system_main_block'), t('Next'));
$this->assertUrl('admin/structure/block/add/system_main_block/stark');
}

View File

@ -274,7 +274,7 @@ class BlockTest extends BlockTestBase {
}
// Ensure that the disabled module's block plugin is no longer available.
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add');
$this->drupalGet('admin/structure/block/list/' . config('system.theme')->get('default') . '/add');
$this->assertNoText(t('Test block caching'));
// Confirm that the block is no longer displayed on the front page.

View File

@ -45,7 +45,7 @@ class BlockTitleXSSTest extends WebTestBase {
$this->drupalLogin($this->drupalCreateUser(array('administer blocks', 'access administration pages')));
$default_theme = config('system.theme')->get('default');
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . $default_theme . '/add');
$this->drupalGet('admin/structure/block/list/' . $default_theme . '/add');
$this->assertNoRaw("<script>alert('XSS subject');</script>", 'The block title was properly sanitized in Block Plugin UI Admin page.');
}

View File

@ -110,7 +110,7 @@ class BlockUiTest extends WebTestBase {
*/
function testBlockSearch() {
$block = t('Administration');
$blocks = drupal_json_decode($this->drupalGet('system/autocomplete/block_plugin_ui:stark', array('query' => array('q' => $block))));
$blocks = drupal_json_decode($this->drupalGet('block/autocomplete', array('query' => array('q' => $block))));
$this->assertEqual($blocks['system_menu_block:menu-admin'], $block, t('Can search for block with name !block.', array('!block' => $block)));
}

View File

@ -34,7 +34,7 @@ class NonDefaultBlockAdminTest extends WebTestBase {
$this->drupalLogin($admin_user);
$new_theme = 'bartik';
theme_enable(array($new_theme));
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . $new_theme);
$this->drupalGet('admin/structure/block/list/' . $new_theme);
$this->assertText('Bartik(' . t('active tab') . ')', 'Tab for non-default theme found.');
}
}

View File

@ -161,7 +161,7 @@ class MenuTest extends MenuWebTestBase {
// Enable the custom menu block.
$menu_name = 'menu-' . $menu_name; // Drupal prepends the name with 'menu-'.
// Confirm that the custom menu block is available.
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add');
$this->drupalGet('admin/structure/block/list/' . config('system.theme')->get('default') . '/add');
$this->assertText($label);
// Enable the block.
@ -379,7 +379,7 @@ class MenuTest extends MenuWebTestBase {
// Make sure menu shows up with new name in block addition.
$default_theme = variable_get('theme_default', 'stark');
$this->drupalget('admin/structure/block/list/block_plugin_ui:' . $default_theme . '/add');
$this->drupalget('admin/structure/block/list/' . $default_theme . '/add');
$this->assertText($edit['label']);
}

View File

@ -1,55 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\system\Access\SystemPluginUiCheck.
*/
namespace Drupal\system\Access;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Access\AccessCheckInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
/**
* Access check for system routes.
*/
class SystemPluginUiCheck implements AccessCheckInterface {
/**
* The plugin UI manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected $pluginUiManager;
/**
* Constructs a SystemController object.
*
* @param \Drupal\Component\Plugin\PluginManagerInterface $plugin_ui_manager
* The plugin UI manager.
*/
public function __construct(PluginManagerInterface $plugin_ui_manager) {
$this->pluginUiManager = $plugin_ui_manager;
}
/**
* {@inheritdoc}
*/
public function applies(Route $route) {
return array_key_exists('_access_system_plugin_ui', $route->getRequirements());
}
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
if ($request->attributes->get('plugin_id')) {
// Checks access for a given plugin using the plugin's access() method.
$plugin_ui = $this->pluginUiManager->createInstance($request->attributes->get('plugin_id'), array());
return $plugin_ui->access(NULL) ? static::ALLOW : static::DENY;
}
}
}

View File

@ -1,56 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\system\Controller\SystemController.
*/
namespace Drupal\system\Controller;
use Drupal\Component\Utility\Tags;
use Drupal\Component\Utility\Unicode;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* Returns responses for System routes.
*/
class SystemController extends ContainerAware {
/**
* Autocompletes any plugin system tied to a plugin UI plugin.
*
* The passed plugin_id indicates the specific plugin_ui plugin that is in use
* here. The documentation within the annotation of that plugin will contain a
* manager for the plugins that need to be autocompleted allowing this
* function to autocomplete plugins for any plugin type.
*
* @param string $plugin_id
* The plugin id for the calling plugin.
* @param Request $request
* The request object that contains the typed tags.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The matched plugins as json.
*/
public function autocomplete($plugin_id, Request $request) {
$string_typed = $request->query->get('q');
$string_typed = Tags::explode($string_typed);
$string = Unicode::strtolower(array_pop($string_typed));
$matches = array();
if ($string) {
$plugin_ui = $this->container->get('plugin.manager.system.plugin_ui')->getDefinition($plugin_id);
$manager = $this->container->get($plugin_ui['manager']);
$titles = array();
foreach($manager->getDefinitions() as $plugin_id => $plugin) {
$titles[$plugin_id] = $plugin[$plugin_ui['title_attribute']];
}
$matches = preg_grep("/\b". $string . "/i", $titles);
}
return new JsonResponse($matches);
}
}

View File

@ -1,51 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\system\Plugin\Type\PluginUIManager.
*/
namespace Drupal\system\Plugin\Type;
use Drupal\Component\Plugin\PluginManagerBase;
use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
use Drupal\Core\Plugin\Discovery\AlterDecorator;
use Drupal\Core\Plugin\Discovery\CacheDecorator;
use Drupal\Component\Plugin\Factory\DefaultFactory;
/**
* Manages discovery and instantiation of Plugin UI plugins.
*
* @todo This class needs @see references and/or more documentation.
*/
class PluginUIManager extends PluginManagerBase {
/**
* Constructs a \Drupal\system\Plugin\Type\PluginUIManager object.
*
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations,
*/
public function __construct(\Traversable $namespaces) {
$this->discovery = new AnnotatedClassDiscovery('Plugin/PluginUI', $namespaces);
$this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
$this->discovery = new AlterDecorator($this->discovery, 'plugin_ui');
$this->discovery = new CacheDecorator($this->discovery, 'plugin_ui');
$this->factory = new DefaultFactory($this->discovery);
}
/**
* Overrides \Drupal\Component\Plugin\PluginManagerBase::processDefinition().
*/
public function processDefinition(&$definition, $plugin_id) {
$definition += array(
'default_task' => TRUE,
'task_title' => t('View'),
'task_suffix' => 'view',
'access_callback' => 'user_access',
);
}
}

View File

@ -964,83 +964,9 @@ function system_menu() {
);
}
foreach (drupal_container()->get('plugin.manager.system.plugin_ui')->getDefinitions() as $plugin_id => $plugin) {
if ($plugin['menu'] === TRUE) {
$items[$plugin['path'] . '/' . $plugin_id . '/' . $plugin['suffix']] = array(
'title' => $plugin['title'],
'page callback' => 'drupal_get_form',
'page arguments' => array($plugin['id'], $plugin_id),
'access callback' => 'system_plugin_ui_access',
'access arguments' => array($plugin_id),
'type' => $plugin['type'],
);
if (!empty($plugin['default_task'])) {
$items[$plugin['path'] . '/' . $plugin_id . '/' . $plugin['suffix'] . '/' . $plugin['task_suffix']] = array(
'title' => $plugin['task_title'],
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
}
$items[$plugin['path'] . '/' . $plugin_id . '/%'] = array(
'title' => $plugin['title'],
'page callback' => 'drupal_get_form',
'page arguments' => array($plugin['id'], $plugin_id, (count(explode('/', $plugin['path'])) + 1)),
'access callback' => 'system_plugin_ui_access',
'access arguments' => array($plugin_id, (count(explode('/', $plugin['path'])) + 1)),
'type' => MENU_CALLBACK,
);
if (!empty($plugin['file'])) {
$items[$plugin['path'] . '/' . $plugin_id . '/' . $plugin['suffix']]['file'] = $plugin['file'];
$items[$plugin['path'] . '/' . $plugin_id . '/%']['file'] = $plugin['file'];
if (!empty($plugin['file_path'])) {
$items[$plugin['path'] . '/' . $plugin_id . '/' . $plugin['suffix']]['file path'] = $plugin['file_path'];
$items[$plugin['path'] . '/' . $plugin_id . '/%']['file path'] = $plugin['file_path'];
}
}
}
}
return $items;
}
/**
* Proxies to the plugin class' form method.
*
* @todo This needs more explanation, an @see or two, and parameter
* documentation. Also "proxies" is a weird word to use.
*/
function system_plugin_ui_form($form, &$form_state, $plugin, $facet = NULL) {
$plugin_ui = drupal_container()->get('plugin.manager.system.plugin_ui')->createInstance($plugin);
$form = $plugin_ui->form($form, $form_state, $facet);
$form['#validate'][] = array($plugin_ui, 'formValidate');
$form['#submit'][] = array($plugin_ui, 'formSubmit');
return $form;
}
/**
* Checks access for a given plugin using the plugin's access() method.
*
* @todo This needs more explanation, some @see, and parameter documentation.
* @todo What the heck kind of parameter name is "facet"?
*/
function system_plugin_ui_access($plugin, $facet = NULL) {
$plugin_ui = drupal_container()->get('plugin.manager.system.plugin_ui')->createInstance($plugin);
return $plugin_ui->access($facet);
}
/**
* Implements hook_forms().
*/
function system_forms() {
$forms = array();
foreach (drupal_container()->get('plugin.manager.system.plugin_ui')->getDefinitions() as $plugin_id => $plugin) {
if (empty($forms[$plugin['id']])) {
$forms[$plugin['id']]['callback'] = 'system_plugin_ui_form';
}
}
return $forms;
}
/**
* Theme callback for the default batch page.
*/

View File

@ -213,10 +213,3 @@ system_timezone:
_controller: '\Drupal\system\Controller\TimezoneController::getTimezone'
requirements:
_access: 'TRUE'
system_plugin_autocomplete:
pattern: '/system/autocomplete/{plugin_id}'
defaults:
_controller: 'Drupal\system\Controller\SystemController::autocomplete'
requirements:
_access_system_plugin_ui: 'TRUE'

View File

@ -3,14 +3,6 @@ services:
class: Drupal\system\Access\CronAccessCheck
tags:
- { name: access_check }
access_check.system_plugin_ui:
class: Drupal\system\Access\SystemPluginUiCheck
tags:
- { name: access_check }
arguments: ['@plugin.manager.system.plugin_ui']
plugin.manager.system.plugin_ui:
class: Drupal\system\Plugin\Type\PluginUIManager
arguments: ['@container.namespaces']
system.manager:
class: Drupal\system\SystemManager
arguments: ['@module_handler', '@database']

View File

@ -122,7 +122,7 @@ class BasicTest extends WizardTestBase {
$this->assertLinkByHref(url($view3['page[path]']));
// Confirm that the block is available in the block administration UI.
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add');
$this->drupalGet('admin/structure/block/list/' . config('system.theme')->get('default') . '/add');
$this->assertText('View: ' . $view3['label']);
// Place the block.

View File

@ -75,7 +75,7 @@ class ItemsPerPageTest extends WizardTestBase {
$this->assertTrue($pos5 < $pos4 && $pos4 < $pos3 && $pos3 < $pos2, 'The nodes appear in the expected order in the page display.');
// Confirm that the block is listed in the block administration UI.
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add');
$this->drupalGet('admin/structure/block/list/' . config('system.theme')->get('default') . '/add');
$this->assertText('View: ' . $view['label']);
// Place the block, visit a page that displays the block, and check that the

View File

@ -54,7 +54,7 @@ class OverrideDisplaysTest extends UITestBase {
$this->assertText($original_title);
// Confirm that the view block is available in the block administration UI.
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add');
$this->drupalGet('admin/structure/block/list/' . config('system.theme')->get('default') . '/add');
$this->assertText('View: ' . $view['label']);
// Place the block.
@ -112,7 +112,7 @@ class OverrideDisplaysTest extends UITestBase {
$this->assertNoText($view['block[title]']);
// Confirm that the block is available in the block administration UI.
$this->drupalGet('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add');
$this->drupalGet('admin/structure/block/list/' . config('system.theme')->get('default') . '/add');
$this->assertText('View: ' . $view['label']);
// Put the block into the first sidebar region, and make sure it will not