diff --git a/src/Controller/HmMenuController.php b/src/Controller/HmMenuController.php index 9f2793a10c27ac5d47bd0821be594fe44998b812..d101c2eda3ccdffbc96430cdea0f4416a5ab246b 100644 --- a/src/Controller/HmMenuController.php +++ b/src/Controller/HmMenuController.php @@ -168,6 +168,8 @@ class HmMenuController extends ControllerBase { $updated_links = $request->get('keys'); //$after = $request->get('after'); $before = $request->get('before'); + $all_siblings = []; + $insert_after = TRUE; if (is_array($updated_links) && !empty($updated_links)) { if (empty($parent)) { @@ -186,48 +188,39 @@ class HmMenuController extends ControllerBase { // The parent menu doesn't exist. return new JsonResponse(['result' => 'fail']); } - else { - if (empty($children)) { - $parent_link = reset($parent_links); - $children = $parent_link->subtree; - } - if ($children) { - // The parent menu has children. - $target_position = intval($target_position); - $all_siblings = []; - $insert_after = TRUE; - $position = 0; - foreach ($children as $child) { - $link = $child->link; - $link_id = $link->getPLuginId(); - // Figure out if the new links are inserted - // after the target position. - if ($position++ == $target_position && $link_id !== $before) { - $insert_after = FALSE; - } - - $all_siblings[$link_id] = (int) $link->getWeight(); + if (empty($children)) { + $parent_link = reset($parent_links); + $children = $parent_link->subtree; + } + + if ($children) { + // The parent menu has children. + $target_position = intval($target_position); + + $position = 0; + foreach ($children as $child) { + $link = $child->link; + $link_id = $link->getPLuginId(); + // Figure out if the new links are inserted + // after the target position. + if ($position++ == $target_position && $link_id !== $before) { + $insert_after = FALSE; } - $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_links, $insert_after); - $weight = $new_hierarchy['start_weight']; - $moving_siblings = $new_hierarchy['moving_siblings']; - - // Update all sibling links needed to update. - foreach ($moving_siblings as $link_id => $link_weight) { - $this->menuLinkManager->updateDefinition($link_id, ['weight' => $link_weight]); - } - } - else { - // The parent link doesn't have children. - $weight = 0; - } - // Move all links updated. - foreach ($updated_links as $link_id) { - $this->menuLinkManager->updateDefinition($link_id, ['weight' => $weight++, 'parent' => $parent]); + $all_siblings[$link_id] = (int) $link->getWeight(); } } + else { + // The parent link doesn't have children. + + } + + $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_links, $insert_after); + // Update all links need to update. + foreach ($new_hierarchy as $link_id => $link_weight) { + $this->menuLinkManager->updateDefinition($link_id, ['weight' => $link_weight, 'parent' => $parent]); + } return new JsonResponse(['result' => 'success']); } diff --git a/src/Controller/HmTaxonomyController.php b/src/Controller/HmTaxonomyController.php index 68cc884c34e87b50a28be4fdf4fdd4d5d809e0f2..536b1f4c9fa2792d9958d49922763cb131e000f2 100644 --- a/src/Controller/HmTaxonomyController.php +++ b/src/Controller/HmTaxonomyController.php @@ -146,6 +146,8 @@ class HmTaxonomyController extends ControllerBase { //$after = $request->get('after'); $before = $request->get('before'); $success = FALSE; + $insert_after = TRUE; + $all_siblings = []; if (is_array($updated_terms) && !empty($updated_terms)) { // Taxonomy access control. @@ -156,7 +158,6 @@ class HmTaxonomyController extends ControllerBase { 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. @@ -166,8 +167,6 @@ class HmTaxonomyController extends ControllerBase { else { // The parent term has children. $target_position = intval($target_position); - $all_siblings = []; - $insert_after = TRUE; $position = 0; foreach ($children as $child) { @@ -179,30 +178,18 @@ class HmTaxonomyController extends ControllerBase { $all_siblings[$child->tid] = (int) $child->weight; } - - $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_terms, $insert_after); - $weight = $new_hierarchy['start_weight']; - $moving_siblings = $new_hierarchy['moving_siblings']; - $tids = array_keys($moving_siblings); - - if (!empty($tids)) { - // Update siblings. - $term_siblings = Term::loadMultiple($tids); - foreach ($term_siblings as $term) { - $term->setWeight($moving_siblings[$term->id()]); - $success = $term->save(); - } - } } + $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_terms, $insert_after); + $tids = array_keys($new_hierarchy); + // Load all terms needed to update. - $terms = Term::loadMultiple($updated_terms); - // Update all terms, the weight will be increased by 1, - // after inserting. + $terms = Term::loadMultiple($tids); + // Update all terms. foreach ($terms as $term) { if ($access_control_handler->access($term, 'update')) { $term->set('parent', ['target_id' => $parent_id]); - $term->setWeight($weight++); + $term->setWeight($new_hierarchy[$term->id()]); $success = $term->save(); } } diff --git a/src/PluginTypeManager.php b/src/PluginTypeManager.php index a6a5a8b3d0f6b5fe23a6b0430ff17ea10f72ca8b..315d523f0cea7cb1aebf038c28534a7d1ba5de3e 100644 --- a/src/PluginTypeManager.php +++ b/src/PluginTypeManager.php @@ -97,107 +97,115 @@ class PluginTypeManager { * IDs of new items inserted. * @param int|bool $after * Indicator if new items are inserted after target position. + * @param int $weight + * The initial weight. * * @return array * All siblings needed to move and their new weights. */ - public function updateHierarchy(int $target_position, array $all_siblings, array $updated_items, $after) { - $filtered_moving_siblings = []; + public function updateHierarchy(int $target_position, array $all_siblings, array $updated_items, $after, int $weight = 0) { + $new_hierarchy = []; $first_half = TRUE; - - $total = count($all_siblings); - if ($target_position === 0) { - // The insert postion is the first position. - // we don't need to move any siblings. - $weight = (int) reset($all_siblings) - 1; - } - elseif ($target_position >= $total - 1) { - // The insert postion is the end, - // we don't need to move any siblings. - $last_item= array_slice($all_siblings, -1, 1, TRUE); - $weight = (int) reset($last_item) + 1; - } - else { - $target_item = array_slice($all_siblings, $target_position, 1, TRUE); - $weight = (int) reset($target_item); - // If the target position is in the second half, - // we will move all siblings - // after the target position forward. - // Otherwise, we will move siblings - // before the target position backwards. - if ($target_position >= $total / 2) { - $first_half = FALSE; - - if ($after) { - // Insert after the target position. - // The target stay where it is. - $weight += 1; - $moving_siblings = array_slice($all_siblings, $target_position + 1, NULL, TRUE); - } - else { - // Insert before the target position. - // The target need to move forwards. - $moving_siblings = array_slice($all_siblings, $target_position, NULL, TRUE); - } - $step = $weight + count($updated_items); + + if (!empty($all_siblings)) { + $total = count($all_siblings); + if ($target_position === 0) { + // The insert postion is the first position. + // we don't need to move any siblings. + $weight = (int) reset($all_siblings) - 1; + } + elseif ($target_position >= $total - 1) { + // The insert postion is the end, + // we don't need to move any siblings. + $last_item= array_slice($all_siblings, -1, 1, TRUE); + $weight = (int) reset($last_item) + 1; } else { - if ($after) { - // Insert after the target position. - // The target need to move backwards. - $moving_siblings = array_slice($all_siblings, 0, $target_position + 1, TRUE); + $target_item = array_slice($all_siblings, $target_position, 1, TRUE); + $weight = (int) reset($target_item); + // If the target position is in the second half, + // we will move all siblings + // after the target position forward. + // Otherwise, we will move siblings + // before the target position backwards. + if ($target_position >= $total / 2) { + $first_half = FALSE; + + if ($after) { + // Insert after the target position. + // The target stay where it is. + $weight += 1; + $moving_siblings = array_slice($all_siblings, $target_position + 1, NULL, TRUE); + } + else { + // Insert before the target position. + // The target need to move forwards. + $moving_siblings = array_slice($all_siblings, $target_position, NULL, TRUE); + } + $step = $weight + count($updated_items); } else { - // Insert before the target position. - // The target stay where it is. - $weight -= 1; - $moving_siblings = array_slice($all_siblings, 0, $target_position, TRUE); - } - $weight = $step = $weight - count($updated_items); - // Reverse the siblings_moved array - // as we will decrease the weight - // starting from the first element - // and the new weight should be in - // an opposite order. - $moving_siblings = array_reverse($moving_siblings, TRUE); - } - - // Move all siblings that need to move. - foreach($moving_siblings as $item_id => $item_weight) { - // Skip all links in the updated array. They will be moved later. - if (in_array($item_id, $updated_items)) { - continue; - } - if ($first_half) { - // While moving the first half of the siblings, - // all moving siblings' weight are decreased, - // if they are greater than the step. - if ((int)$item_weight < --$step) { - // There is planty room, no need to move anymore. - break; + if ($after) { + // Insert after the target position. + // The target need to move backwards. + $moving_siblings = array_slice($all_siblings, 0, $target_position + 1, TRUE); } else { - // Update the weight. - $filtered_moving_siblings[$item_id] = $step; + // Insert before the target position. + // The target stay where it is. + $weight -= 1; + $moving_siblings = array_slice($all_siblings, 0, $target_position, TRUE); } + $weight = $step = $weight - count($updated_items); + // Reverse the siblings_moved array + // as we will decrease the weight + // starting from the first element + // and the new weight should be in + // an opposite order. + $moving_siblings = array_reverse($moving_siblings, TRUE); } - else { - // While moving the second half of the siblings, - // all moving siblings' weight are increased, - // if they are less than the step. - if ((int)$item_weight < ++$step) { - // Update the weight. - $filtered_moving_siblings[$item_id] = $step; + + // Move all siblings that need to move. + foreach($moving_siblings as $item_id => $item_weight) { + // Skip all links in the updated array. They will be moved later. + if (in_array($item_id, $updated_items)) { + continue; + } + if ($first_half) { + // While moving the first half of the siblings, + // all moving siblings' weight are decreased, + // if they are greater than the step. + if ((int)$item_weight < --$step) { + // There is planty room, no need to move anymore. + break; + } + else { + // Update the weight. + $new_hierarchy[$item_id] = $step; + } } else { - // There is planty room, no need to move anymore. - break; + // While moving the second half of the siblings, + // all moving siblings' weight are increased, + // if they are less than the step. + if ((int)$item_weight < ++$step) { + // Update the weight. + $new_hierarchy[$item_id] = $step; + } + else { + // There is planty room, no need to move anymore. + break; + } } } } } - return ['start_weight' => $weight, 'moving_siblings' => $filtered_moving_siblings]; + foreach ($updated_items as $item) { + $new_hierarchy[$item] = $weight++; + } + + return $new_hierarchy; } }