Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/hierarchy_manager
  • issue/hierarchy_manager-3188871
  • issue/hierarchy_manager-3188833
  • issue/hierarchy_manager-3191599
  • issue/hierarchy_manager-3191605
  • issue/hierarchy_manager-3205538
  • issue/hierarchy_manager-3217994
  • issue/hierarchy_manager-3230813
  • issue/hierarchy_manager-3241543
  • issue/hierarchy_manager-3243559
  • issue/hierarchy_manager-3243579
  • issue/hierarchy_manager-3278219
  • issue/hierarchy_manager-3341369
  • issue/hierarchy_manager-3344493
  • issue/hierarchy_manager-3343978
  • issue/hierarchy_manager-3347488
  • issue/hierarchy_manager-3347499
  • issue/hierarchy_manager-3343297
  • issue/hierarchy_manager-3451974
  • issue/hierarchy_manager-3467198
20 results
Show changes
Commits on Source (4)
Showing
with 260 additions and 141 deletions
hmconfig
hmsetup
Jsoneditor
jsoneditor
Jstree
jstree
Mingsong
pluginable
\ No newline at end of file
################
# GitLabCI template for Drupal projects.
#
# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification.
# It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained.
# As long as you include the project, ref and three files below, any future updates added by the Drupal Association will be used in your
# pipelines automatically. However, you can modify this template if you have additional needs for your project.
# The full documentation is on https://project.pages.drupalcode.org/gitlab_templates/
################
# For information on alternative values for 'ref' see https://project.pages.drupalcode.org/gitlab_templates/info/templates-version/
# To test a Drupal 7 project, change the first include filename from .main.yml to .main-d7.yml
include:
- project: $_GITLAB_TEMPLATES_REPO
ref: $_GITLAB_TEMPLATES_REF
file:
- "/includes/include.drupalci.main.yml"
- "/includes/include.drupalci.variables.yml"
- "/includes/include.drupalci.workflows.yml"
################
# Pipeline configuration variables are defined with default values and descriptions in the file
# https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes/include.drupalci.variables.yml
# Uncomment the lines below if you want to override any of the variables. The following is just an example.
################
variables:
SKIP_ESLINT: '1'
SKIP_PHPSTAN: '1'
# OPT_IN_TEST_NEXT_MAJOR: '1'
# _CURL_TEMPLATES_REF: 'main'
...@@ -10,18 +10,33 @@ CONTENTS OF THIS FILE ...@@ -10,18 +10,33 @@ CONTENTS OF THIS FILE
INTRODUCTION INTRODUCTION
------------ ------------
Drupal provides a draggable table to manage the hierarchy of menu links and taxonomy terms. The Drupal draggable table is not able to present a massive hierarchy in one page. Drupal provides a draggable table to manage the hierarchy of menu links
and taxonomy terms.
The Drupal draggable table is not able to present a massive hierarchy
in one page.
This module provides a plugin architecture to delivery a flexibility of managing hierarchy for taxonomy terms, menu links and others. There are two out of box plugins, taxonomy hierarchy management plugin and menu hierarchy plugin. The front-end JavaScript libraries is also pluginable. The out of box display plugin using jsTree to render the hierarchy tree with filter. The hierarchy tree is draggable which means you can update the hierarchy by dragging a node in the tree. This module provides a plugin architecture to delivery a flexibility
of managing hierarchy for taxonomy terms,
menu links and others. There are two out of box plugins,
taxonomy hierarchy management plugin and menu hierarchy plugin.
The front-end JavaScript libraries is also pluginable.
The out of box display plugin using jsTree to render
the hierarchy tree with filter.
The hierarchy tree is draggable which means you can update
the hierarchy by dragging a node in the tree.
Other modules can define their own management plugin to manage hierarchy for any other entities or display plugin to render the hierarchy tree by a JavaScript library other than jsTree. Other modules can define their own management plugin to manage
hierarchy for any other entities or display plugin to render
the hierarchy tree by a JavaScript library other than jsTree.
REQUIREMENTS REQUIREMENTS
------------ ------------
This module requires the following library: This module requires the following library:
* jsTree JS (This module will automatically load this library from romte CDN if it wasn't hosted locally under /libraries/jquery.jstree/3.3.8/ folder) * jsTree JS (This module will automatically load this library
from remote CDN if it wasn't hosted locally under
/libraries/jquery.jstree/3.3.8/ folder)
INSTALLATION INSTALLATION
------------ ------------
...@@ -31,13 +46,23 @@ INSTALLATION ...@@ -31,13 +46,23 @@ INSTALLATION
CONFIGURATION CONFIGURATION
------------- -------------
* Go the hierarchy manage display management page (/admin/structure/hm_display_profile) under the Structure menu to create a display profile * Go the hierarchy manage display management page
(/admin/structure/hm_display_profile) under
the Structure menu to create a display profile
* Go to the hierarchy management configuration page (/admin/config/user-interface/hierarchy_manager/config) to enable hierarchy management plugins, such as taxonomy plugin, and specify a display profile created in step above. * Go to the hierarchy management configuration page
(/admin/config/user-interface/hierarchy_manager/config) to
enable hierarchy management plugins, such as taxonomy plugin,
and specify a display profile created in step above.
* Once a hierarchy mange plugin is enabled, the related edit form should be replaced with a hierarchy tree form. For instance, the taxonomy term edit form (/admin/structure/taxonomy/manage/{tid}/overview) will be replaced with a hierarchy tree implemented by the taxonomy hierarchy manage plugin. * Once a hierarchy mange plugin is enabled, the related edit form
should be replaced with a hierarchy tree form.
For instance, the taxonomy term edit form
(/admin/structure/taxonomy/manage/{tid}/overview)
will be replaced with a hierarchy tree implemented by
the taxonomy hierarchy manage plugin.
MAINTAINERS MAINTAINERS
----------- -----------
Mingsong Hu (Mingsong) - https://www.drupal.org/u/mingsong Mingsong Hu (Mingsong) - https://www.drupal.org/u/mingsong
\ No newline at end of file
hierarchy_manager:
hierarchy_manager.hmconfig:
type: config_object
label: 'Hierarchy Manager Configuration'
mapping:
allowed_setup_plugins:
type: sequence
label: 'Allowed Setup Plugins'
sequence:
type: string
label: 'Setup Plugin ID'
setup_plugin_settings:
label: 'TFA validation plugin configuration'
type: sequence
sequence:
type: hierarchy_manager.HmSetupPlugin.plugin.config.[%key]
hierarchy_manager.HmSetupPlugin.plugin.config.hm_setup_taxonomy:
type: mapping
label: 'HM Setup Taxonomy Settings'
mapping:
display_profile:
type: string
label: 'Display Profile'
bundle:
type: sequence
label: 'Bundle'
sequence:
type: string
label: 'Bundle Name'
hierarchy_manager.HmSetupPlugin.plugin.config.hm_setup_menu:
type: mapping
label: 'HM Setup Menu Settings'
mapping:
display_profile:
type: string
label: 'Display Profile'
bundle:
type: sequence
label: 'Bundle'
sequence:
type: string
label: 'Bundle Item'
hierarchy_manager.hm_display_profile.*:
type: config_entity
label: 'Hierarchy Manager Display Profile'
mapping:
id:
type: string
label: 'ID'
label:
type: string
label: 'Label'
plugin:
type: string
label: 'Plugin'
config:
type: string
label: 'Config'
confirm:
type: boolean
label: 'Confirm'
hierarchy_manager.hm_display_profile.*:
type: config_entity
label: 'HM Display Profile Entity config'
mapping:
id:
type: string
label: 'ID'
label:
type: label
label: 'Label'
uuid:
type: string
plugin:
type: string
label: 'Display plugin'
config:
type: text
label: 'Configuration'
confirm:
type: boolean
label: 'Confirm'
/* HM Tree item status (unpublished/disabled) */ /* HM Tree item status (unpublished/disabled) */
.jstree-default .jstree-node.hm-tree-node-disabled > a { .jstree-default .jstree-node.hm-tree-node-disabled > a {
color: grey; color: gray;
background-color: #fff4f4; background-color: #fff4f4;
} }
......
name: Hierarchy Manager name: Hierarchy Manager
description: Provides API and plugins to build hierarchy views for entites such as taxonomy or menu. description: Provides API and plugins to build hierarchy views for entities such as taxonomy or menu.
package: Administration package: Administration
type: module type: module
core_version_requirement: ^9.2.0 || ^10 core_version_requirement: ^9.2.0 || ^10 || ^11
configure: hierarchy_manager.hm_config_form configure: hierarchy_manager.hm_config_form
...@@ -16,7 +16,7 @@ function hierarchy_manager_update_8001() { ...@@ -16,7 +16,7 @@ function hierarchy_manager_update_8001() {
if (!empty($allowed_setup_plugins['hm_setup_menu'])) { if (!empty($allowed_setup_plugins['hm_setup_menu'])) {
$menus = Menu::loadMultiple(); $menus = Menu::loadMultiple();
$bundles = []; $bundles = [];
/** @var Menu $menu */ /** @var \Drupal\system\Entity\Menu $menu */
foreach ($menus as $menu) { foreach ($menus as $menu) {
$id = $menu->id(); $id = $menu->id();
$bundles[$id] = $id; $bundles[$id] = $id;
......
...@@ -17,7 +17,7 @@ function hierarchy_manager_help($route_name, RouteMatchInterface $route_match) { ...@@ -17,7 +17,7 @@ function hierarchy_manager_help($route_name, RouteMatchInterface $route_match) {
$output = '<h3>' . t('About') . '</h3>'; $output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Hierarchy Manager module provides a flexible solution for managing hierarchies of menu links and taxonomy terms. Unlike the default Drupal draggable table, this module supports massive hierarchies and offers a plugin architecture for customization.') . '</p>'; $output .= '<p>' . t('Hierarchy Manager module provides a flexible solution for managing hierarchies of menu links and taxonomy terms. Unlike the default Drupal draggable table, this module supports massive hierarchies and offers a plugin architecture for customization.') . '</p>';
$output .= '<p>' . t('Out of the box, the module comes with two plugins: a taxonomy hierarchy management plugin and a menu hierarchy plugin. The front-end JavaScript libraries are also pluginable, with an out-of-the-box display plugin using jsTree to render the hierarchy tree with a filter. The hierarchy tree is draggable, allowing you to easily update the hierarchy by dragging a node in the tree.') . '</p>'; $output .= '<p>' . t('Out of the box, the module comes with two plugins: a taxonomy hierarchy management plugin and a menu hierarchy plugin. The front-end JavaScript libraries are also pluginable, with an out-of-the-box display plugin using jsTree to render the hierarchy tree with a filter. The hierarchy tree is draggable, allowing you to easily update the hierarchy by dragging a node in the tree.') . '</p>';
return $output; return $output;
} }
} }
...@@ -42,12 +42,12 @@ function hierarchy_manager_library_info_alter(array &$libraries, $module) { ...@@ -42,12 +42,12 @@ function hierarchy_manager_library_info_alter(array &$libraries, $module) {
if ($cdn_library) { if ($cdn_library) {
$libraries['libraries.jquery.jstree.default-dark']['css']['component'] = $cdn_library; $libraries['libraries.jquery.jstree.default-dark']['css']['component'] = $cdn_library;
} }
// jsoneditor min js. // Jsoneditor min js.
$cdn_library = _hierarchy_manager_use_cdn($libraries, 'libraries.jsoneditor', 'js'); $cdn_library = _hierarchy_manager_use_cdn($libraries, 'libraries.jsoneditor', 'js');
if ($cdn_library) { if ($cdn_library) {
$libraries['libraries.jsoneditor']['js'] = $cdn_library; $libraries['libraries.jsoneditor']['js'] = $cdn_library;
} }
// jsoneditor default theme. // Jsoneditor default theme.
$cdn_library = _hierarchy_manager_use_cdn($libraries, 'libraries.jsoneditor.default-theme', 'css'); $cdn_library = _hierarchy_manager_use_cdn($libraries, 'libraries.jsoneditor.default-theme', 'css');
if ($cdn_library) { if ($cdn_library) {
$libraries['libraries.jsoneditor.default-theme']['css']['component'] = $cdn_library; $libraries['libraries.jsoneditor.default-theme']['css']['component'] = $cdn_library;
...@@ -56,15 +56,12 @@ function hierarchy_manager_library_info_alter(array &$libraries, $module) { ...@@ -56,15 +56,12 @@ function hierarchy_manager_library_info_alter(array &$libraries, $module) {
} }
/** /**
* Implement hook_entity_type_alter(). * Implements hook_entity_type_alter().
*
* @param array $entity_types
* Entity type information array.
*/ */
function hierarchy_manager_entity_type_alter(array &$entity_types) { function hierarchy_manager_entity_type_alter(array &$entity_types) {
// Override the menu edit form. // Override the menu edit form.
$entity_types['menu'] $entity_types['menu']
->setFormClass('edit', 'Drupal\hierarchy_manager\Form\HmMenuForm'); ->setFormClass('edit', 'Drupal\hierarchy_manager\Form\HmMenuForm');
} }
/** /**
......
...@@ -2,19 +2,22 @@ ...@@ -2,19 +2,22 @@
namespace Drupal\hierarchy_manager\Controller; namespace Drupal\hierarchy_manager\Controller;
use Drupal\Core\Url;
use Drupal\Core\Access\CsrfTokenGenerator; use Drupal\Core\Access\CsrfTokenGenerator;
use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityRepository; use Drupal\Core\Entity\EntityRepository;
use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Menu\MenuLinkTreeInterface;
use Drupal\Core\Menu\MenuLinkManagerInterface; use Drupal\Core\Menu\MenuLinkManagerInterface;
use Drupal\Core\Menu\MenuLinkTreeInterface;
use Drupal\Core\Menu\MenuTreeParameters; use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Menu item feeding controller.
*/
class HmMenuController extends ControllerBase { class HmMenuController extends ControllerBase {
/** /**
...@@ -60,7 +63,7 @@ class HmMenuController extends ControllerBase { ...@@ -60,7 +63,7 @@ class HmMenuController extends ControllerBase {
protected $menuLinkManager; protected $menuLinkManager;
/** /**
* The entity repository object * The entity repository object.
* *
* @var \Drupal\Core\Entity\EntityRepository * @var \Drupal\Core\Entity\EntityRepository
*/ */
...@@ -129,7 +132,7 @@ class HmMenuController extends ControllerBase { ...@@ -129,7 +132,7 @@ class HmMenuController extends ControllerBase {
$tree = $this->loadMenuTree($mid, $parent, $depth, $destination); $tree = $this->loadMenuTree($mid, $parent, $depth, $destination);
// menu access check done. // Menu access check done.
$request->attributes->set('_menu_admin', FALSE); $request->attributes->set('_menu_admin', FALSE);
if ($tree) { if ($tree) {
...@@ -160,8 +163,8 @@ class HmMenuController extends ControllerBase { ...@@ -160,8 +163,8 @@ class HmMenuController extends ControllerBase {
* *
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Symfony\Component\HttpFoundation\Request $request
* Http request object. * Http request object.
* @param string $vid * @param string $mid
* Vocabulary ID. * Menu ID.
*/ */
public function updateMenuLinks(Request $request, string $mid) { public function updateMenuLinks(Request $request, string $mid) {
// Access token. // Access token.
...@@ -188,8 +191,8 @@ class HmMenuController extends ControllerBase { ...@@ -188,8 +191,8 @@ class HmMenuController extends ControllerBase {
} }
if (empty($parent_links)) { if (empty($parent_links)) {
// The parent menu doesn't exist. // The parent menu doesn't exist.
return new JsonResponse(['result' => 'fail']); return new JsonResponse(['result' => 'fail']);
} }
if (empty($children)) { if (empty($children)) {
...@@ -231,7 +234,8 @@ class HmMenuController extends ControllerBase { ...@@ -231,7 +234,8 @@ class HmMenuController extends ControllerBase {
/** /**
* Get a display plugin instance. * Get a display plugin instance.
* *
* @return NULL|object * @return null|object
* The display plugin instance.
*/ */
protected function getDisplayPlugin() { protected function getDisplayPlugin() {
$display_profile = $this->hmPluginTypeManager->getDisplayProfile('hm_setup_menu'); $display_profile = $this->hmPluginTypeManager->getDisplayProfile('hm_setup_menu');
...@@ -244,13 +248,13 @@ class HmMenuController extends ControllerBase { ...@@ -244,13 +248,13 @@ class HmMenuController extends ControllerBase {
* @param string $mid * @param string $mid
* The menu ID. * The menu ID.
* @param string $parent * @param string $parent
* parent id * Parent id.
* @param int $depth * @param int $depth
* The max depth loaded. * The max depth loaded.
* @param string $destination * @param string $destination
* The destination of edit link. * The destination of edit link.
*/ */
protected function loadMenuTree(string $mid, string $parent, int $depth = 0, string $destination = '') { protected function loadMenuTree(string $mid, string $parent, int $depth = 0, string $destination = '') {
$tree = $this->loadMenuLinkObjs($mid, $parent, $depth); $tree = $this->loadMenuLinkObjs($mid, $parent, $depth);
// Load all menu links into one array. // Load all menu links into one array.
$tree = $this->buildMenuLinkArray($tree); $tree = $this->buildMenuLinkArray($tree);
...@@ -278,13 +282,11 @@ class HmMenuController extends ControllerBase { ...@@ -278,13 +282,11 @@ class HmMenuController extends ControllerBase {
* @param string $mid * @param string $mid
* The menu ID. * The menu ID.
* @param string $parent * @param string $parent
* parent id * Parent id.
* @param int $depth * @param int $depth
* The max depth loaded. * The max depth loaded.
* @param string $destination
* The destination of edit link.
*/ */
protected function loadMenuLinkObjs(string $mid, string $parent, int $depth = 0) { protected function loadMenuLinkObjs(string $mid, string $parent, int $depth = 0) {
$menu_para = new MenuTreeParameters(); $menu_para = new MenuTreeParameters();
if (!empty($depth)) { if (!empty($depth)) {
$menu_para->setMaxDepth($depth); $menu_para->setMaxDepth($depth);
...@@ -311,10 +313,9 @@ class HmMenuController extends ControllerBase { ...@@ -311,10 +313,9 @@ class HmMenuController extends ControllerBase {
* The menu links array. * The menu links array.
*/ */
protected function buildMenuLinkArray($tree) { protected function buildMenuLinkArray($tree) {
// $tree_access_cacheability = new CacheableMetadata(); // $tree_access_cacheability = new CacheableMetadata();
foreach ($tree as $element) { foreach ($tree as $element) {
// $tree_access_cacheability = $tree_access_cacheability->merge(CacheableMetadata::createFromObject($element->access)); // $tree_access_cacheability = $tree_access_cacheability->merge(CacheableMetadata::createFromObject($element->access));
// Only load accessible links. // Only load accessible links.
if (!$element->access->isAllowed()) { if (!$element->access->isAllowed()) {
continue; continue;
...@@ -363,5 +364,5 @@ class HmMenuController extends ControllerBase { ...@@ -363,5 +364,5 @@ class HmMenuController extends ControllerBase {
return $this->overviewTree; return $this->overviewTree;
} }
}
}
...@@ -10,12 +10,12 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; ...@@ -10,12 +10,12 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Term;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
/** /**
* Taxononmy controller class. * Taxonomy feeding controller class.
*/ */
class HmTaxonomyController extends ControllerBase { class HmTaxonomyController extends ControllerBase {
...@@ -32,7 +32,7 @@ class HmTaxonomyController extends ControllerBase { ...@@ -32,7 +32,7 @@ class HmTaxonomyController extends ControllerBase {
* @var \Drupal\taxonomy\TermStorageInterface * @var \Drupal\taxonomy\TermStorageInterface
*/ */
protected $storageController; protected $storageController;
/** /**
* The hierarchy manager plugin type manager. * The hierarchy manager plugin type manager.
* *
...@@ -71,14 +71,13 @@ class HmTaxonomyController extends ControllerBase { ...@@ -71,14 +71,13 @@ class HmTaxonomyController extends ControllerBase {
); );
} }
/** /**
* Access check callback for taxonomy tree json. * Access check callback for taxonomy tree json.
* *
* @param \Drupal\Core\Session\AccountInterface $account * @param \Drupal\Core\Session\AccountInterface $account
* User account. * User account.
* @param string $vid * @param string $vid
* Vocabulary ID. * Vocabulary ID.
*/ */
public function access(AccountInterface $account, string $vid) { public function access(AccountInterface $account, string $vid) {
if ($account->hasPermission('administer taxonomy')) { if ($account->hasPermission('administer taxonomy')) {
...@@ -102,7 +101,7 @@ class HmTaxonomyController extends ControllerBase { ...@@ -102,7 +101,7 @@ class HmTaxonomyController extends ControllerBase {
$term_array = []; $term_array = [];
// Store the number of each term id present. // Store the number of each term id present.
$ids = []; $ids = [];
// Store terms that have ambiguous paretns. // Store terms that have ambiguous parents.
$am_terms = []; $am_terms = [];
// Store all terms only have single ancestor. // Store all terms only have single ancestor.
$single_parent = []; $single_parent = [];
...@@ -113,8 +112,8 @@ class HmTaxonomyController extends ControllerBase { ...@@ -113,8 +112,8 @@ class HmTaxonomyController extends ControllerBase {
$parent = $request->get('parent') ?: 0; $parent = $request->get('parent') ?: 0;
$depth = $request->get('depth'); $depth = $request->get('depth');
$destination = $request->get('destination'); $destination = $request->get('destination');
if(!empty($depth)) { if (!empty($depth)) {
$depth = intval($depth); $depth = intval($depth);
} }
...@@ -139,10 +138,10 @@ class HmTaxonomyController extends ControllerBase { ...@@ -139,10 +138,10 @@ class HmTaxonomyController extends ControllerBase {
if ($ids[$id] === 0 && isset($single_parent[$id])) { if ($ids[$id] === 0 && isset($single_parent[$id])) {
// Update previous term in the term array // Update previous term in the term array
// which has the same ID. Make it not draggable. // which has the same ID. Make it not draggable.
$term_array[$single_parent[$id]]['draggable'] = false; $term_array[$single_parent[$id]]['draggable'] = FALSE;
} }
$ids[$id]++; $ids[$id]++;
$term_id = $id . '_' . $ids[$id]; $term_id = $id . '_' . $ids[$id];
} }
else { else {
$ids[$id] = 0; $ids[$id] = 0;
...@@ -152,22 +151,22 @@ class HmTaxonomyController extends ControllerBase { ...@@ -152,22 +151,22 @@ class HmTaxonomyController extends ControllerBase {
// It will present multiple times under different parents. // It will present multiple times under different parents.
// So the term id will be duplicated. // So the term id will be duplicated.
// The solution is to format the term id as following, // The solution is to format the term id as following,
// {term_id}_{parent_index} // {term_id}_{parent_index}.
if ( $count_parent > 1) { if ($count_parent > 1) {
$draggable = false; $draggable = FALSE;
// This term has an ancestor with multiple parents. // This term has an ancestor with multiple parents.
if ($ids[$id] === $count_parent) { if ($ids[$id] === $count_parent) {
// Put into the ambiguous array. // Put into the ambiguous array.
// Will solve it later. // Will solve it later.
$am_terms[] = [ $am_terms[] = [
'solved' => false, 'solved' => FALSE,
'id' => $term_id, 'id' => $term_id,
'label' => $term->label(), 'label' => $term->label(),
'parent' => $term_parent, 'parent' => $term_parent,
'url' => $url, 'url' => $url,
'publish' => $term->isPublished(), 'publish' => $term->isPublished(),
'weight' => $term->getWeight(), 'weight' => $term->getWeight(),
'draggable' => false, 'draggable' => FALSE,
]; ];
continue; continue;
} }
...@@ -177,12 +176,12 @@ class HmTaxonomyController extends ControllerBase { ...@@ -177,12 +176,12 @@ class HmTaxonomyController extends ControllerBase {
if ($ids[$id]) { if ($ids[$id]) {
// The parent has multiple grandparent. // The parent has multiple grandparent.
$parent_id = $term_parent[0] . '_' . $ids[$id]; $parent_id = $term_parent[0] . '_' . $ids[$id];
$draggable = false; $draggable = FALSE;
} }
else { else {
// The parent doesn't have multiple grandparent. // The parent doesn't have multiple grandparent.
$parent_id = $term_parent[0]; $parent_id = $term_parent[0];
$draggable = true; $draggable = TRUE;
// At this point, we still don't know // At this point, we still don't know
// if this term has multiple ancestors or not. // if this term has multiple ancestors or not.
// So keep the index of term array for later update // So keep the index of term array for later update
...@@ -205,7 +204,7 @@ class HmTaxonomyController extends ControllerBase { ...@@ -205,7 +204,7 @@ class HmTaxonomyController extends ControllerBase {
} }
// Figure out the parent id for terms in the ambiguous term array. // Figure out the parent id for terms in the ambiguous term array.
do { do {
$found = false; $found = FALSE;
foreach ($am_terms as $key => $term) { foreach ($am_terms as $key => $term) {
if ($term['solved']) { if ($term['solved']) {
continue; continue;
...@@ -223,15 +222,15 @@ class HmTaxonomyController extends ControllerBase { ...@@ -223,15 +222,15 @@ class HmTaxonomyController extends ControllerBase {
$term['weight'], $term['weight'],
$term['draggable'] $term['draggable']
); );
$found = true; $found = TRUE;
// Remove this parent from ids array. // Remove this parent from ids array.
$ids[$id]--; $ids[$id]--;
$am_terms[$key]['solved'] = true; $am_terms[$key]['solved'] = TRUE;
continue 2; continue 2;
} }
} }
} }
}while ($found); } while ($found);
// Display profile. // Display profile.
$display_profile = $this->hmPluginTypeManager->getDisplayProfile('hm_setup_taxonomy'); $display_profile = $this->hmPluginTypeManager->getDisplayProfile('hm_setup_taxonomy');
...@@ -294,7 +293,7 @@ class HmTaxonomyController extends ControllerBase { ...@@ -294,7 +293,7 @@ class HmTaxonomyController extends ControllerBase {
if (!empty($children)) { if (!empty($children)) {
// The parent term has children. // The parent term has children.
$target_position = intval($target_position); $target_position = intval($target_position);
foreach ($children as $child) { foreach ($children as $child) {
$all_siblings[$child->tid] = (int) $child->weight; $all_siblings[$child->tid] = (int) $child->weight;
} }
......
...@@ -67,10 +67,10 @@ class HmDisplayProfile extends ConfigEntityBase implements HmDisplayProfileInter ...@@ -67,10 +67,10 @@ class HmDisplayProfile extends ConfigEntityBase implements HmDisplayProfileInter
* @var string * @var string
*/ */
protected $plugin; protected $plugin;
/** /**
* The configurations * The configurations.
* *
* @var string * @var string
*/ */
protected $config; protected $config;
...@@ -81,4 +81,5 @@ class HmDisplayProfile extends ConfigEntityBase implements HmDisplayProfileInter ...@@ -81,4 +81,5 @@ class HmDisplayProfile extends ConfigEntityBase implements HmDisplayProfileInter
* @var bool * @var bool
*/ */
protected $confirm = FALSE; protected $confirm = FALSE;
} }
...@@ -2,14 +2,12 @@ ...@@ -2,14 +2,12 @@
namespace Drupal\hierarchy_manager\Form; namespace Drupal\hierarchy_manager\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\hierarchy_manager\Plugin\HmSetupPluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
* Class HMConfigForm. * Hierarchy Manager configuration form.
*/ */
class HMConfigForm extends ConfigFormBase { class HMConfigForm extends ConfigFormBase {
...@@ -20,25 +18,13 @@ class HMConfigForm extends ConfigFormBase { ...@@ -20,25 +18,13 @@ class HMConfigForm extends ConfigFormBase {
*/ */
protected $pluginManagerHmSetup; protected $pluginManagerHmSetup;
/**
* Constructs a new HMConfigForm object.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
HmSetupPluginManager $plugin_manager_hm_hmsetup
) {
parent::__construct($config_factory);
$this->pluginManagerHmSetup = $plugin_manager_hm_hmsetup;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
return new static( $instance = parent::create($container);
$container->get('config.factory'), $instance->pluginManagerHmSetup = $container->get('plugin.manager.hm.hmsetup');
$container->get('plugin.manager.hm.hmsetup') return $instance;
);
} }
/** /**
...@@ -90,7 +76,7 @@ class HMConfigForm extends ConfigFormBase { ...@@ -90,7 +76,7 @@ class HMConfigForm extends ConfigFormBase {
$form['setup_plugin_settings'] = [ $form['setup_plugin_settings'] = [
'#type' => 'fieldset', '#type' => 'fieldset',
'#title' => $this->t('Setup Plugin Settings'), '#title' => $this->t('Setup Plugin Settings'),
'#descrption' => $this->t('Setup plugin advanced settings.'), '#description' => $this->t('Setup plugin advanced settings.'),
'#tree' => TRUE, '#tree' => TRUE,
]; ];
foreach ($setup_plugins_labels as $key => $val) { foreach ($setup_plugins_labels as $key => $val) {
......
...@@ -5,11 +5,11 @@ namespace Drupal\hierarchy_manager\Form; ...@@ -5,11 +5,11 @@ namespace Drupal\hierarchy_manager\Form;
use Drupal\Component\Utility\Xss; use Drupal\Component\Utility\Xss;
use Drupal\Core\Entity\EntityForm; use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\hierarchy_manager\Plugin\HmDisplayPluginManager; use Drupal\hierarchy_manager\Plugin\HmDisplayPluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
* Class HmDisplayProfileForm. * HmDisplayProfile entity form class.
*/ */
class HmDisplayProfileForm extends EntityForm { class HmDisplayProfileForm extends EntityForm {
...@@ -24,8 +24,8 @@ class HmDisplayProfileForm extends EntityForm { ...@@ -24,8 +24,8 @@ class HmDisplayProfileForm extends EntityForm {
* Constructs a new HmDisplayProfileForm object. * Constructs a new HmDisplayProfileForm object.
*/ */
public function __construct( public function __construct(
HmDisplayPluginManager $plugin_manager_hm_display HmDisplayPluginManager $plugin_manager_hm_display,
) { ) {
$this->pluginManagerHmDisplay = $plugin_manager_hm_display; $this->pluginManagerHmDisplay = $plugin_manager_hm_display;
} }
...@@ -83,14 +83,14 @@ class HmDisplayProfileForm extends EntityForm { ...@@ -83,14 +83,14 @@ class HmDisplayProfileForm extends EntityForm {
'#description' => $this->t('Display plugin that is in charge of rendering the hierarchy view.'), '#description' => $this->t('Display plugin that is in charge of rendering the hierarchy view.'),
'#required' => TRUE, '#required' => TRUE,
]; ];
$form['config'] = array( $form['config'] = [
'#type' => 'hidden', '#type' => 'hidden',
'#value' => $hm_display_profile->get('config'), '#value' => $hm_display_profile->get('config'),
'#attributes' => [ '#attributes' => [
'id' => 'config-value', 'id' => 'config-value',
], ],
); ];
$form['json_editor'] = [ $form['json_editor'] = [
'#type' => 'html_tag', '#type' => 'html_tag',
'#tag' => 'div', '#tag' => 'div',
...@@ -103,7 +103,7 @@ class HmDisplayProfileForm extends EntityForm { ...@@ -103,7 +103,7 @@ class HmDisplayProfileForm extends EntityForm {
'hierarchy_manager/libraries.jsoneditor', 'hierarchy_manager/libraries.jsoneditor',
'hierarchy_manager/feature.hm.jsoneditor', 'hierarchy_manager/feature.hm.jsoneditor',
'hierarchy_manager/libraries.jsoneditor.default-theme', 'hierarchy_manager/libraries.jsoneditor.default-theme',
] ],
], ],
]; ];
} }
...@@ -131,7 +131,7 @@ class HmDisplayProfileForm extends EntityForm { ...@@ -131,7 +131,7 @@ class HmDisplayProfileForm extends EntityForm {
$hm_display_profile = $this->entity; $hm_display_profile = $this->entity;
// User input. // User input.
$input = $form_state->getUserInput(); $input = $form_state->getUserInput();
if (isset($input['config'])) { if (isset($input['config'])) {
// Sanitize the user input. // Sanitize the user input.
$input['config'] = Xss::filter($input['config']); $input['config'] = Xss::filter($input['config']);
...@@ -142,7 +142,7 @@ class HmDisplayProfileForm extends EntityForm { ...@@ -142,7 +142,7 @@ class HmDisplayProfileForm extends EntityForm {
if (isset($input['confirm'])) { if (isset($input['confirm'])) {
$hm_display_profile->set('confirm', $input['confirm']); $hm_display_profile->set('confirm', $input['confirm']);
} }
$status = $hm_display_profile->save(); $status = $hm_display_profile->save();
switch ($status) { switch ($status) {
......
...@@ -2,17 +2,20 @@ ...@@ -2,17 +2,20 @@
namespace Drupal\hierarchy_manager\Form; namespace Drupal\hierarchy_manager\Form;
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\menu_ui\MenuForm; use Drupal\menu_ui\MenuForm;
use Drupal\system\MenuInterface; use Drupal\system\MenuInterface;
/**
* Hierarchy manager menu plugin configuration form.
*/
class HmMenuForm extends MenuForm { class HmMenuForm extends MenuForm {
/** /**
* The indicator if the menu hierarchy manager is enabled. * The indicator if the menu hierarchy manager is enabled.
* *
* @var bool|NULL * @var bool|null
*/ */
private $isEnabled = NULL; private $isEnabled = NULL;
...@@ -37,7 +40,7 @@ class HmMenuForm extends MenuForm { ...@@ -37,7 +40,7 @@ class HmMenuForm extends MenuForm {
if (!$menu->isNew() || $menu->isLocked()) { if (!$menu->isNew() || $menu->isLocked()) {
// We are removing the menu link overview form // We are removing the menu link overview form
// and using our own hierarchy manager tree instead. // and using our own hierarchy manager tree instead.
// The overview form implemented by Drupal Menu UI module // The overview form implemented by Drupal Menu UI module.
// @see \Drupal\menu_ui\MenuForm::form() // @see \Drupal\menu_ui\MenuForm::form()
unset($form['links']); unset($form['links']);
$form['hm_links'] = $this->buildOverviewTree([], $form_state); $form['hm_links'] = $this->buildOverviewTree([], $form_state);
...@@ -66,9 +69,11 @@ class HmMenuForm extends MenuForm { ...@@ -66,9 +69,11 @@ class HmMenuForm extends MenuForm {
* *
* @param array $form * @param array $form
* Parent form array. * Parent form array.
* @param FormStateInterface $form_state * @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state object. * Form state object.
* @return NULL|array *
* @return null|array
* The tree elements.
*/ */
protected function buildOverviewTree(array $form, FormStateInterface $form_state) { protected function buildOverviewTree(array $form, FormStateInterface $form_state) {
...@@ -94,9 +99,20 @@ class HmMenuForm extends MenuForm { ...@@ -94,9 +99,20 @@ class HmMenuForm extends MenuForm {
else { else {
$destination = '/'; $destination = '/';
} }
// Urls // Urls.
$source_url = Url::fromRoute('hierarchy_manager.menu.tree.json', ['mid' => $mid], ['query' => ['token' => $token, 'destination' => $destination]])->toString(); $source_url = Url::fromRoute('hierarchy_manager.menu.tree.json',
$update_url = Url::fromRoute('hierarchy_manager.menu.tree.update', ['mid' => $mid], ['query' => ['token' => $token]])->toString(); ['mid' => $mid],
[
'query' =>
[
'token' => $token,
'destination' => $destination,
],
])->toString();
$update_url = Url::fromRoute('hierarchy_manager.menu.tree.update',
['mid' => $mid],
['query' => ['token' => $token]]
)->toString();
$config = $display_profile->get("config"); $config = $display_profile->get("config");
$confirm = $display_profile->get("confirm"); $confirm = $display_profile->get("confirm");
return $display_plugin_instance->getForm($source_url, $update_url, $form, $form_state, $config, $confirm); return $display_plugin_instance->getForm($source_url, $update_url, $form, $form_state, $config, $confirm);
...@@ -110,6 +126,7 @@ class HmMenuForm extends MenuForm { ...@@ -110,6 +126,7 @@ class HmMenuForm extends MenuForm {
* Create a hierarchy manager plugin manager. * Create a hierarchy manager plugin manager.
* *
* @return \Drupal\hierarchy_manager\PluginTypeManager * @return \Drupal\hierarchy_manager\PluginTypeManager
* The plugin manager instance.
*/ */
protected function loadPluginManager() { protected function loadPluginManager() {
if (empty($this->hmPluginTypeManager)) { if (empty($this->hmPluginTypeManager)) {
...@@ -125,7 +142,7 @@ class HmMenuForm extends MenuForm { ...@@ -125,7 +142,7 @@ class HmMenuForm extends MenuForm {
* @param \Drupal\system\MenuInterface $menu * @param \Drupal\system\MenuInterface $menu
* The menu entity. * The menu entity.
* *
* @return boolean|NULL * @return bool|null
* Return TRUE if the menu plugin is enabled, * Return TRUE if the menu plugin is enabled,
* otherwise return FALSE. * otherwise return FALSE.
*/ */
...@@ -151,4 +168,5 @@ class HmMenuForm extends MenuForm { ...@@ -151,4 +168,5 @@ class HmMenuForm extends MenuForm {
return $this->isEnabled; return $this->isEnabled;
} }
} }
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
namespace Drupal\hierarchy_manager\Form; namespace Drupal\hierarchy_manager\Form;
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\taxonomy\VocabularyInterface; use Drupal\Core\Url;
use Drupal\taxonomy\Form\OverviewTerms; use Drupal\taxonomy\Form\OverviewTerms;
use Drupal\taxonomy\VocabularyInterface;
/** /**
* Taxonomy overview form class. * Taxonomy overview form class.
...@@ -61,8 +61,19 @@ class HmOverviewTerms extends OverviewTerms { ...@@ -61,8 +61,19 @@ class HmOverviewTerms extends OverviewTerms {
$destination = '/'; $destination = '/';
} }
// Urls. // Urls.
$source_url = Url::fromRoute('hierarchy_manager.taxonomy.tree.json', ['vid' => $vid], ['query' => ['token' => $token, 'destination' => $destination]])->toString(); $source_url = Url::fromRoute('hierarchy_manager.taxonomy.tree.json',
$update_url = Url::fromRoute('hierarchy_manager.taxonomy.tree.update', ['vid' => $vid], ['query' => ['token' => $token]])->toString(); ['vid' => $vid],
[
'query' => [
'token' => $token,
'destination' => $destination,
],
]
)->toString();
$update_url = Url::fromRoute('hierarchy_manager.taxonomy.tree.update',
['vid' => $vid],
['query' => ['token' => $token]]
)->toString();
$config = $display_profile->get("config"); $config = $display_profile->get("config");
$confirm = $display_profile->get('confirm'); $confirm = $display_profile->get('confirm');
return $instance->getForm($source_url, $update_url, $form, $form_state, $config, $confirm); return $instance->getForm($source_url, $update_url, $form, $form_state, $config, $confirm);
......
...@@ -6,8 +6,8 @@ use Drupal\Component\Serialization\Json; ...@@ -6,8 +6,8 @@ use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Xss; use Drupal\Component\Utility\Xss;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\hierarchy_manager\Plugin\HmDisplayPluginInterface;
use Drupal\hierarchy_manager\Plugin\HmDisplayPluginBase; use Drupal\hierarchy_manager\Plugin\HmDisplayPluginBase;
use Drupal\hierarchy_manager\Plugin\HmDisplayPluginInterface;
/** /**
* JsTree display plugin. * JsTree display plugin.
...@@ -20,7 +20,7 @@ use Drupal\hierarchy_manager\Plugin\HmDisplayPluginBase; ...@@ -20,7 +20,7 @@ use Drupal\hierarchy_manager\Plugin\HmDisplayPluginBase;
class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInterface { class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInterface {
use StringTranslationTrait; use StringTranslationTrait;
/* /**
* Build the tree form. * Build the tree form.
*/ */
public function getForm(string $url_source, string $url_update, array &$form = [], FormStateInterface &$form_state = NULL, $options = NULL, $confirm = FALSE) { public function getForm(string $url_source, string $url_update, array &$form = [], FormStateInterface &$form_state = NULL, $options = NULL, $confirm = FALSE) {
...@@ -44,12 +44,12 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte ...@@ -44,12 +44,12 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte
$form['search'] = [ $form['search'] = [
'#type' => 'textfield', '#type' => 'textfield',
'#title' => $this '#title' => $this
->t('Search'), ->t('Search'),
'#description' => $this->t('Type in the search keyword here to filter the tree below. Multiple keywords separated by spaces. Empty the keyword to reset the tree.'), '#description' => $this->t('Type in the search keyword here to filter the tree below. Multiple keywords separated by spaces. Empty the keyword to reset the tree.'),
'#attributes' => [ '#attributes' => [
'name' => 'jstree-search', 'name' => 'jstree-search',
'id' => isset($parent_id) ? 'hm-jstree-search-' . $parent_id : 'hm-jstree-search', 'id' => isset($parent_id) ? 'hm-jstree-search-' . $parent_id : 'hm-jstree-search',
'parent-id' => isset($parent_id) ? $parent_id : '', 'parent-id' => $parent_id ?? '',
'class' => [ 'class' => [
'hm-jstree-search', 'hm-jstree-search',
], ],
...@@ -68,7 +68,7 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte ...@@ -68,7 +68,7 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte
'hm-jstree', 'hm-jstree',
], ],
'id' => isset($parent_id) ? 'hm-jstree-' . $parent_id : 'hm-jstree', 'id' => isset($parent_id) ? 'hm-jstree-' . $parent_id : 'hm-jstree',
'parent-id' => isset($parent_id) ? $parent_id : '', 'parent-id' => $parent_id ?? '',
'options' => $options, 'options' => $options,
'confirm' => $confirm, 'confirm' => $confirm,
'data-source' => $url_source, 'data-source' => $url_source,
...@@ -113,7 +113,7 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte ...@@ -113,7 +113,7 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte
'width' => '960', 'width' => '960',
'title' => $this->t('Edit') . ' ' . preg_replace('~<span(.*?)</span>~Usi', '', $tree_node['text']), 'title' => $this->t('Edit') . ' ' . preg_replace('~<span(.*?)</span>~Usi', '', $tree_node['text']),
]; ];
// Custom data // Custom data.
$jstree_node['a_attr'] = [ $jstree_node['a_attr'] = [
'href' => $jstree_node['edit_url'], 'href' => $jstree_node['edit_url'],
'class' => 'use-ajax', 'class' => 'use-ajax',
...@@ -122,7 +122,7 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte ...@@ -122,7 +122,7 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte
]; ];
$jstree_node['data'] = [ $jstree_node['data'] = [
'weight' => $tree_node['weight'], 'weight' => $tree_node['weight'],
'draggable' => $tree_node['draggable'] 'draggable' => $tree_node['draggable'],
]; ];
unset($jstree_node['edit_url']); unset($jstree_node['edit_url']);
// Add this node into the data array. // Add this node into the data array.
...@@ -131,4 +131,5 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte ...@@ -131,4 +131,5 @@ class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInte
return $jstree_data; return $jstree_data;
} }
} }
...@@ -10,13 +10,14 @@ use Drupal\Core\Form\FormStateInterface; ...@@ -10,13 +10,14 @@ use Drupal\Core\Form\FormStateInterface;
*/ */
interface HmDisplayPluginInterface extends PluginInspectionInterface { interface HmDisplayPluginInterface extends PluginInspectionInterface {
/* /**
* Build the tree form. * Build the tree form.
*/ */
public function getForm(string $url_source, string $url_update, array &$form = [], FormStateInterface &$form_state = NULL, $options = NULL); public function getForm(string $url_source, string $url_update, array &$form = [], FormStateInterface &$form_state = NULL, $options = NULL);
/** /**
* Build the data array that JS library accepts. * Build the data array that JS library accepts.
*/ */
public function treeData(array $data); public function treeData(array $data);
} }
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
namespace Drupal\hierarchy_manager\Plugin; namespace Drupal\hierarchy_manager\Plugin;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
/** /**
* Provides the Hierarchy manager display plugin plugin manager. * Provides the Hierarchy manager display plugin plugin manager.
......