diff --git a/core/modules/block/src/BlockListBuilder.php b/core/modules/block/src/BlockListBuilder.php index 37b2e8b..110111c 100644 --- a/core/modules/block/src/BlockListBuilder.php +++ b/core/modules/block/src/BlockListBuilder.php @@ -11,6 +11,7 @@ use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Form\FormInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Operations\OperationsProviderInterface; use Drupal\Core\Theme\ThemeManagerInterface; use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -345,6 +346,9 @@ public function getDefaultOperations(EntityInterface $entity) { if (isset($operations['delete'])) { $operations['delete']['title'] = $this->t('Remove'); } + if ($entity instanceof OperationsProviderInterface) { + $operations += $entity->getOperationLinks(); + } return $operations; } diff --git a/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php b/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php index e97e740..a102855 100644 --- a/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php +++ b/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php @@ -7,6 +7,7 @@ use Drupal\Core\Block\BlockManagerInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Operations\OperationsProviderInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\Session\AccountInterface; @@ -22,7 +23,7 @@ * deriver = "Drupal\block_content\Plugin\Derivative\BlockContent" * ) */ -class BlockContentBlock extends BlockBase implements ContainerFactoryPluginInterface { +class BlockContentBlock extends BlockBase implements ContainerFactoryPluginInterface, OperationsProviderInterface { /** * The Plugin Block Manager. @@ -185,4 +186,18 @@ protected function getEntity() { return $this->blockContent; } + /** + * {@inheritdoc} + */ + public function getOperationLinks() { + $entity = $this->getEntity(); + return [ + 'block-edit' => [ + 'title' => $this->t('Edit block'), + 'url' => $entity->toUrl('edit-form')->setOptions([]), + 'weight' => 50, + ], + ]; + } + } diff --git a/core/modules/block_content/tests/src/Kernel/BlockContentTest.php b/core/modules/block_content/tests/src/Kernel/BlockContentTest.php new file mode 100644 index 0000000..aeb1952 --- /dev/null +++ b/core/modules/block_content/tests/src/Kernel/BlockContentTest.php @@ -0,0 +1,81 @@ +installSchema('system', ['sequence']); + $this->installEntitySchema('user'); + $this->installEntitySchema('block_content'); + + $user = User::create([ + 'name' => 'tony', + 'mail' => 'tony@example.com', + ]); + $role = Role::create([ + 'label' => 'Views admin', + 'id' => 'views_admin', + ]); + $role->grantPermission('administer views'); + $role->save(); + $user->addRole($role->id()); + \Drupal::service('current_user')->setAccount($user); + } + + /** + * Tests the editing links for BlockContentBlock. + */ + public function testOperationLinks() { + // Create a block content type. + $block_content_type = BlockContentType::create([ + 'id' => 'spiffy', + 'label' => 'Mucho spiffy', + 'description' => "Provides a block type that increases your site's spiffiness by upto 11%", + ]); + $block_content_type->save(); + // And a block content entity. + $block_content = BlockContent::create([ + 'info' => 'Spiffy prototype', + 'type' => 'spiffy', + ]); + $block_content->save(); + $block = Block::create([ + 'plugin' => 'block_content' . PluginBase::DERIVATIVE_SEPARATOR . $block_content->uuid(), + 'region' => 'content', + 'id' => 'machinename', + 'theme' => 'stark', + ]); + + $links = $block->getOperationLinks(); + $block_link = [ + 'title' => 'Edit block', + 'url' => $block_content->toUrl('edit-form')->setOptions([]), + 'weight' => 50, + ]; + $this->assertEquals(['block-edit' => $block_link], $links); + } + +} diff --git a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php index 88af86e..263abb2 100644 --- a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php @@ -34,7 +34,7 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa /** * The module handler used to check whether menu_ui is installed. * - * @var \Drupal\Core\Extension\ModuleHandlerInterface. + * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected $moduleHandler; diff --git a/core/modules/views/src/Plugin/Block/ViewsBlockBase.php b/core/modules/views/src/Plugin/Block/ViewsBlockBase.php index 4e3020c..5036c64 100644 --- a/core/modules/views/src/Plugin/Block/ViewsBlockBase.php +++ b/core/modules/views/src/Plugin/Block/ViewsBlockBase.php @@ -4,8 +4,11 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Block\BlockBase; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Operations\OperationsProviderInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Url; use Drupal\views\ViewExecutableFactory; use Drupal\Core\Entity\EntityStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -14,7 +17,7 @@ /** * Base class for Views block plugins. */ -abstract class ViewsBlockBase extends BlockBase implements ContainerFactoryPluginInterface { +abstract class ViewsBlockBase extends BlockBase implements ContainerFactoryPluginInterface, OperationsProviderInterface { /** * The View executable object. @@ -45,6 +48,13 @@ protected $user; /** + * The module handler used to check whether menu_ui is installed. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** * Constructs a \Drupal\views\Plugin\Block\ViewsBlockBase object. * * @param array $configuration @@ -59,8 +69,10 @@ * The views storage. * @param \Drupal\Core\Session\AccountInterface $user * The current user. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler used to check whether views_ui is installed. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, ViewExecutableFactory $executable_factory, EntityStorageInterface $storage, AccountInterface $user) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, ViewExecutableFactory $executable_factory, EntityStorageInterface $storage, AccountInterface $user, ModuleHandlerInterface $module_handler) { $this->pluginId = $plugin_id; $delta = $this->getDerivativeId(); list($name, $this->displayID) = explode('-', $delta, 2); @@ -69,6 +81,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->view = $executable_factory->get($view); $this->displaySet = $this->view->setDisplay($this->displayID); $this->user = $user; + $this->moduleHandler = $module_handler; parent::__construct($configuration, $plugin_id, $plugin_definition); } @@ -81,7 +94,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, $container->get('views.executable'), $container->get('entity.manager')->getStorage('view'), - $container->get('current_user') + $container->get('current_user'), + $container->get('module_handler') ); } @@ -206,4 +220,24 @@ protected function addContextualLinks(&$output, $block_type = 'block') { } } + /** + * {@inheritdoc} + */ + public function getOperationLinks() { + $delta = $this->getDerivativeId(); + list($view, $display_id) = explode('-', $delta, 2); + $links = []; + if ($this->moduleHandler->moduleExists('views_ui')) { + $links['view-edit'] = [ + 'title' => $this->t('Edit view'), + 'url' => Url::fromRoute('entity.view.edit_display_form', [ + 'view' => $view, + 'display_id' => $display_id, + ]), + 'weight' => 50, + ]; + } + return $links; + } + } diff --git a/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php b/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php index 879f6d4..5e42d78 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php @@ -2,6 +2,10 @@ namespace Drupal\Tests\views\Kernel\Plugin; +use Drupal\block\Entity\Block; +use Drupal\Core\Url; +use Drupal\user\Entity\Role; +use Drupal\user\Entity\User; use Drupal\views\Plugin\Block\ViewsBlock; use Drupal\views\Tests\ViewTestData; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; @@ -19,7 +23,7 @@ class ViewsBlockTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = ['block', 'block_test_views']; + public static $modules = ['block', 'block_test_views', 'views_ui']; /** * Views used by this test. @@ -34,6 +38,19 @@ class ViewsBlockTest extends ViewsKernelTestBase { protected function setUp($import_test_views = TRUE) { parent::setUp(); + $user = User::create([ + 'name' => 'tony', + 'mail' => 'tony@example.com', + ]); + $role = Role::create([ + 'label' => 'Views admin', + 'id' => 'views_admin', + ]); + $role->grantPermission('administer views'); + $role->save(); + $user->addRole($role->id()); + \Drupal::service('current_user')->setAccount($user); + ViewTestData::createTestViews(get_class($this), ['block_test_views']); } @@ -127,4 +144,27 @@ public function testBuildWithTitleOverride() { $this->assertEquals('Overridden title', $build['#title']['#markup']); } + /** + * Tests the editing links for ViewsBlockBase. + */ + public function testOperationLinks() { + $block = Block::create([ + 'plugin' => 'views_block:test_view_block-block_1', + 'region' => 'content', + 'id' => 'machinename', + 'theme' => 'stark', + ]); + + $links = $block->getOperationLinks(); + $view_link = [ + 'title' => 'Edit view', + 'url' => Url::fromRoute('entity.view.edit_display_form', [ + 'view' => 'test_view_block', + 'display_id' => 'block_1', + ]), + 'weight' => 50, + ]; + $this->assertEquals(['view-edit' => $view_link], $links); + } + }