Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
hierarchy_manager-3343978
Manage
Activity
Members
Labels
Plan
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Issue forks
hierarchy_manager-3343978
Commits
10864436
Commit
10864436
authored
5 years ago
by
Mingsong Hu
Browse files
Options
Downloads
Patches
Plain Diff
Improve hierarchy update algorithm
parent
d2c9e782
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/Controller/HmMenuController.php
+30
-37
30 additions, 37 deletions
src/Controller/HmMenuController.php
src/Controller/HmTaxonomyController.php
+8
-21
8 additions, 21 deletions
src/Controller/HmTaxonomyController.php
src/PluginTypeManager.php
+89
-81
89 additions, 81 deletions
src/PluginTypeManager.php
with
127 additions
and
139 deletions
src/Controller/HmMenuController.php
+
30
−
37
View file @
10864436
...
...
@@ -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'
]);
}
...
...
This diff is collapsed.
Click to expand it.
src/Controller/HmTaxonomyController.php
+
8
−
21
View file @
10864436
...
...
@@ -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
();
}
}
...
...
This diff is collapsed.
Click to expand it.
src/PluginTypeManager.php
+
89
−
81
View file @
10864436
...
...
@@ -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
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment