Forked from
project / hierarchy_manager
58 commits behind the upstream repository.
-
Mingsong Hu authoredMingsong Hu authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
HmTaxonomyController.php 7.05 KiB
<?php
namespace Drupal\hierarchy_manager\Controller;
use Drupal\Core\Access\CsrfTokenGenerator;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\taxonomy\VocabularyInterface;
use Drupal\taxonomy\Entity\Term;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Taxononmy controller class.
*/
class HmTaxonomyController extends ControllerBase {
/**
* CSRF Token.
*
* @var \Drupal\Core\Access\CsrfTokenGenerator
*/
protected $csrfToken;
/**
* The term storage handler.
*
* @var \Drupal\taxonomy\TermStorageInterface
*/
protected $storageController;
/**
* Display plugin manager.
*
* @var \Drupal\hierarchy_manager\Plugin\HmDisplayPluginInterface
*/
protected $displayManager;
/**
* Setup plugin manager.
*
* @var \Drupal\hierarchy_manager\Plugin\HmSetupPluginManager
*/
protected $setupManager;
/**
* {@inheritdoc}
*/
public function __construct(CsrfTokenGenerator $csrfToken, EntityTypeManagerInterface $entity_type_manager, $display_manager, $setup_manager) {
$this->csrfToken = $csrfToken;
$this->entityTypeManager = $entity_type_manager;
$this->storageController = $entity_type_manager->getStorage('taxonomy_term');
$this->displayManager = $display_manager;
$this->setupManager = $setup_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('csrf_token'),
$container->get('entity_type.manager'),
$container->get('plugin.manager.hm.display_plugin'),
$container->get('plugin.manager.hm.hmsetup')
);
}
/**
* Callback for taxonomy tree json.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* Http request object.
* @param string $vid
* Vocabulary ID.
*/
public function taxonomyTreeJson(Request $request, string $vid) {
// Access token.
$token = $request->get('token');
// The term array will be returned.
$term_array = [];
if (empty($token) || !$this->csrfToken->validate($token, $vid)) {
return new Response($this->t('Access denied!'));
}
$parent = $request->get('parent') ?: 0;
$depth = $request->get('depth');
if(!empty($depth)) {
$depth = intval($depth);
}
$vocabulary_hierarchy = $this->storageController->getVocabularyHierarchyType($vid);
// Taxonomy tree must not be multiple parent tree.
if ($vocabulary_hierarchy !== VocabularyInterface::HIERARCHY_MULTIPLE) {
$tree = $this->storageController->loadTree($vid, $parent, $depth, TRUE);
$access_control_handler = $this->entityTypeManager->getAccessControlHandler('taxonomy_term');
foreach ($tree as $term) {
if ($term instanceof Term) {
// User can only access the terms that they can update.
if ($access_control_handler->access($term, 'update')) {
$term_array[] = [
'id' => $term->id(),
'text' => $term->label(),
'parent' => $term->parents[0],
'edit_url' => $term->toUrl('edit-form')->toString(),
];
}
}
}
}
// Taxonomy setup plugin instance.
$taxonomy_setup_plugin = $this->setupManager->createInstance('hm_setup_taxonomy');
// Display profile.
$display_profile = $this->entityTypeManager->getStorage('hm_display_profile')->load($taxonomy_setup_plugin->getDispalyProfileId());
// Display plugin ID.
$display_plugin_id = $display_profile->get("plugin");
// Display plugin instance.
$display_plugin = $this->displayManager->createInstance($display_plugin_id);
if (method_exists($display_plugin, 'treeData')) {
// Convert the tree data to the structure
// that display plugin accepts.
$tree_data = $display_plugin->treeData($term_array);
}
else {
$tree_data = $term_array;
}
return new JsonResponse($tree_data);
}
/**
* Callback for taxonomy tree json.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* Http request object.
* @param string $vid
* Vocabulary ID.
*/
public function updateTerms(Request $request, string $vid) {
// Access token.
$token = $request->get('token');
if (empty($token) || !$this->csrfToken->validate($token, $vid)) {
return new Response($this->t('Access denied!'));
}
$target_position = $request->get('target');
$parent_id = intval($request->get('parent'));
$updated_terms = $request->get('keys');
$success = FALSE;
if (is_array($updated_terms) && !empty($updated_terms)) {
// Taxonomy access control.
$access_control_handler = $this->entityTypeManager->getAccessControlHandler('taxonomy_term');
// Children of the parent term in weight and name alphabetically order.
$children = $this->storageController->loadTree($vid, $parent_id, 1);
if (empty($children)) {
if (Term::load($parent_id)) {
// The parent term hasn't had any children.
$weight = 0;
}
else {
// The parent term doesn't exist.
return new JsonResponse(['result' => 'fail']);
}
}
else {
// The parent term has children.
$target_position = intval($target_position);
$total = count($children);
// Move all terms after the target position forward.
if (isset($children[$target_position])) {
$weight = (int) $children[$target_position]->weight;
$tids = [];
$step = $weight + count($updated_terms);
for ($i = $target_position; $i < $total; $i++) {
if ($children[$i]->weight < $step++) {
$tids[] = $children[$i]->tid;
}
else {
// There is planty room, no need to move anymore.
break;
}
}
$step = $weight + count($updated_terms);
$term_siblings = Term::loadMultiple($tids);
foreach ($term_siblings as $term) {
$term->setWeight($step++);
$success = $term->save();
}
}
elseif ($target_position === $total) {
// Insert into the end.
$weight = intval(array_slice($children, -1)[0]->weight) + 1;
}
else {
return new JsonResponse(['result' => 'The term is not found.']);
}
}
// Load all terms needed to update.
$terms = Term::loadMultiple($updated_terms);
// Update all terms, the weight will be increased by 1,
// after inserting.
foreach ($terms as $term) {
if ($access_control_handler->access($term, 'update')) {
$term->set('parent', ['target_id' => $parent_id]);
$term->setWeight($weight++);
$success = $term->save();
}
}
}
if ($success) {
return new JsonResponse(['result' => 'success']);
}
return new JsonResponse(['result' => 'fail']);
}
}