Commit 1b817a60 authored by Igor Biki's avatar Igor Biki
Browse files

Merge branch '8.x-1.x-ISTWCMS-3830-content-management-block' into 8.x-1.x

parents 7cdc49b8 a4a82f68
.content-management-block-table > tbody > tr > td:first-child {
width: 75%;
}
.flex-container > div {
display: flex;
}
.flex-container > div > fieldset {
flex-grow: 1;
flex-basis: 0;
}
<?php
namespace Drupal\uw_dashboard\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuLinkTreeInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Class ContentManagementMenuBlock.
*
* @package Drupal\uw_dashboard\Plugin\Block
*
* @Block(
* id = "uw_content_management_menu_block",
* admin_label = "Content management menu",
* )
*/
class ContentManagementMenuBlock extends BlockBase implements ContainerFactoryPluginInterface {
/** @var \Drupal\Core\Menu\MenuLinkTree */
protected $menuLinkTree;
/**
* {@inheritDoc}
*/
public function build() {
$build = [];
if (isset($this->configuration['selected_menus'])) {
// Load configured menu, and un-serialize it.
$configured = unserialize($this->configuration['selected_menus']);
if ($configured) {
// Need menu hierarchy and flatten for key validations.
$primary_menu = $this->getContentMenuItems();
// Iterate primary (level 1) menu items.
foreach ($primary_menu as $primary_menu_item) {
$id = $primary_menu_item->link->getPluginId();
// Get secondary (level 2) menu items.
$secondary_menu = $this->processMenuTree($primary_menu_item->subtree);
$selected_secondary = [];
// Check if user has access to any submenu items. If not, skip.
if (!empty($secondary_menu)) {
// If sub menu exists for primary menu item, use it as default, but
// also append new menu items (items that are added after block has
// been configured. If not (else block) use secondary menu by default.
if (isset($configured[$id])) {
$selected_secondary = array_keys(array_filter($configured[$id] + $secondary_menu));
}
else {
$selected_secondary = array_keys($secondary_menu);
}
}
// Run only if there are menus to display for secondary menu.
if (!empty($selected_secondary)) {
$build[$id] = [
'#markup' => '<h2>' . $primary_menu_item->link->getTitle() . '</h2>',
];
$build[$id]['table'] = [
'#type' => 'table',
'#attributes' => [
'class' => ['content-management-block-table'],
],
'#headers' => [
$this->t($primary_menu_item->link->getTitle()),
$this->t('Operations'),
],
];
foreach ($primary_menu_item->subtree as $item) {
$sec_id = $item->link->getPluginId();
if (in_array($sec_id, $selected_secondary)) {
$build[$id]['table'][$sec_id]['label'] = [
'#plain_text' => $item->link->getTitle(),
];
$build[$id]['table'][$sec_id]['operations'] = [
'#type' => 'operations',
'#links' => [],
];
$build[$id]['table'][$sec_id]['operations']['#links']['add'] = [
'title' => t('Add'),
'url' => $item->link->getUrlObject(),
];
foreach ($item->subtree as $sub_item) {
$build[$id]['table'][$sec_id]['operations']['#links'][$sub_item->link->getPluginId()] = [
'title' => $this->t($sub_item->link->getTitle()),
'url' => $sub_item->link->getUrlObject(),
];
}
}
}
}
}
}
$build['#attached']['library'][] = 'uw_dashboard/uw-styles';
}
return $build;
}
/**
* {@inheritDoc}
*/
public static function create(
ContainerInterface $container,
array $configuration,
$plugin_id,
$plugin_definition
) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('menu.link_tree')
);
}
/**
* ContentManagementMenuBlock constructor.
*
* @param array $configuration
* @param $plugin_id
* @param $plugin_definition
* @param \Drupal\Core\Menu\MenuLinkTreeInterface $menuLinkTree
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
MenuLinkTreeInterface $menuLinkTree
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->menuLinkTree = $menuLinkTree;
}
/**
* {@inheritDoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
// Use configuration if exists, otherwise select all available. Using
// serialize because dot is not supported as array key, exception will be
// thrown from ConfigBase.php:211.
$selected_menus = unserialize($this->configuration['selected_menus']);
$form['#attached']['library'][] = 'uw_dashboard/uw-styles';
// Get all content menu items, load them.
$menu_first_level = $this->getContentMenuItems();
$form['details'] = [
'#type' => 'fieldset',
'#title' => $this->t('Menus to display'),
'#attributes' => [
'class' => ['flex-container'],
],
];
foreach ($menu_first_level as $item_first_level) {
$sub_tree = $this->processMenuTree($item_first_level->subtree);
if (!empty($sub_tree)) {
$primary = $item_first_level->link;
$primary_id = $primary->getPluginId();
// Merging two arrays to ensure new menu items are selected by default.
// Using plus(+) instead of array_merge because don't want to update
// array values for keys found in both arrays.
if (isset($selected_menus[$primary_id])) {
$default_value = array_keys(array_filter($selected_menus[$primary_id] + $sub_tree));
}
else {
$default_value = array_keys($sub_tree);
}
$form['details'][$primary_id] = [
'#type' => 'checkboxes',
'#title' => $primary->getTitle(),
'#options' => $sub_tree,
'#default_value' => $default_value,
];
}
}
return $form;
}
/**
* {@inheritDoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$menu_first_level = $this->getContentMenuItems();
// Storing all menu items, even not selected ones. This is needed because
// if new menu items are added those items need to be enabled.
$values = $form_state->cleanValues()->getValues();
$selected_menus = [];
foreach ($menu_first_level as $item) {
$menu_id = $item->link->getPluginId();
if (isset($values['details'][$menu_id])) {
$selected_menus[$menu_id] = $values['details'][$menu_id];
}
}
$this->configuration['selected_menus'] = serialize($selected_menus);
parent::submitConfigurationForm($form, $form_state);
}
/**
* Loads Content menu items.
*
* @param bool $flatten
* If FALSE return will ne multilevel associative array. If TRUE array will
* be flatten, meaning only first level items.
*
* @return array
* Entire menu tree as array, could be flat or multilevel depending on arg.
*/
protected function getContentMenuItems(bool $flatten = FALSE) {
// Load menu tree with children items.
$menu = $this->menuLinkTree->load('uw-menu-content-management', new MenuTreeParameters());
// Run trough transform, to append access and sort.
$tree = $this->menuLinkTree->transform($menu, [
['callable' => 'menu.default_tree_manipulators:checkAccess'],
['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
]);
return $flatten ? $this->processMenuTree($tree) : $tree;
}
/**
* Process menu tree, setting key to be plugin id, and value to be title.
*
* @param $tree
* Tree to be processed, access level checked.
*
* @return array
* Array where key is plugin id, and title is the value.
*/
protected function processMenuTree($tree) {
$menu = [];
foreach ($tree as $menu_item) {
if ($menu_item->access->isAllowed()) {
$menu[$menu_item->link->getPluginId()] = $menu_item->link->getTitle();
}
}
return $menu;
}
}
# UW Dashboard libraries
uw-styles:
version: 1.x
weight: 50
css:
theme:
css/uw_dashboard.css: {}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment