TreeMoveTrait
Moves one node (with its subtree) through the "Move to..." modal and sorts children alphabetically.
Move: the row action moveModal! opens the shared admin
ModalWindow with the form moveForm:
the new parent (a Picker over the same grid: a suggest field with the path plus a modal in
picker mode; empty means the top level; the node itself and its subtree are excluded) and the
position (TreePosition). It is stored only through manager->moveSubtreeTo() with a
contract: oldParentId is the parent at the moment the modal opened, the neighbors come from
a snapshot of the target parent children (TreeMovePlan). A stale modal gets TREE_STALE
and nothing is written. The entity is never save()d, so the move carries no risk of saving
the whole form (collection overwrite, field validation). Success is a full navigation
(data-naja-force-redirect): flash, closed modal, the moved node highlighted. Failure shows
the message inside the modal (it overlays layout flashes) and refreshes the grid body.
Sort: sortChildren!(parentId) (0 is the root level or the children of the focused node) sorts
the direct children by label in the current language (Collator) and writes them in one
manager->reorderChildren() operation under the tree lock.
Both use the same gate as drag and drop: the edit privilege, a tree with a right bound,
drag and drop enabled (not flat), outside picker mode.
Table of Contents
Properties
- $moveNode : object|null
- Node being moved in this request (signal or modal submit).
- $moveNotices : array<int, array{key: string, type: string}>
- Messages inside the modal; per request, not a session flash, which would resurface on the next open.
- $pickerFactory : PickerFactory|null
- $treePositionFactory : TreePositionFactory|null
Methods
- canMoveNodes() : bool
- Tells whether "Move to..." is offered; same gate as drag and drop (a flat drag must not change the parent).
- canSortChildren() : bool
- Tells whether "sort children alphabetically" is offered.
- getMoveNotices() : array<int, array{key: string, type: string}>
- Returns the messages for the modal; the template translates them by the full grid domain key.
- handleMoveModal() : void
- Opens the "Move to..." modal for a node (AJAX; without JS it just returns to the list).
- handleSortChildren() : void
- Sorts the direct children of a parent by label (current language collation) in one operation under the tree lock. `parentId` 0 is the root level of the view (the real roots without focus).
- setTreeMoveFactories() : self
- Component factories of the modal, injected by {@see \App\UI\Admin\System\Components\DataGridComponent\DataGridFactory}.
- sortIdsByLabel() : array<int, int>
- Returns ids sorted by label using `Collator` (`strnatcasecmp` without intl). Equal labels keep their original order (stable sort), so sorting again changes nothing.
- createComponentMoveForm() : Form
- createComponentMoveParentPicker() : Picker
- Parent in the modal: a suggest field with the path plus a modal with the same grid in picker mode (without the node and its subtree).
- createComponentMovePosition() : TreePosition
- addMoveNotice() : void
- buildMoveTargetParams() : array<string, mixed>
- Builds the redirect parameters after success so that the moved node is highlighted and visible.
- findMoveChildren() : array<int, array{id: int, label: string}>
- findMoveNode() : object|null
- moveDialogErrorKey() : string
- processMoveForm() : void
- reloadMoveNodeFromForm() : void
- requireTreeMoveAllowed() : void
- resolveCollatorLocale() : string
- Returns the collation locale by the admin language (`cs` to `cs_CZ`), Czech by default.
- resolveMoveNode() : object|null
- Returns the node being moved: from the form value (submit) or from the signal parameter (open).
- resolveMoveParentLabel() : string|null
- resolveTreeLabelProperty() : string|null
- Returns the property of the indented column (node name), which the parent suggest searches by.
- showMoveModal() : void
- Fills and opens the shared modal with the current form state (idempotent).
- suggestMoveParents() : array<int, array{id: int, label: string}>
- Suggests parents: LIKE over the name column property, without the node and its subtree, with the path in the label so that equal names can be told apart.
Properties
$moveNode
Node being moved in this request (signal or modal submit).
private
object|null
$moveNode
= null
$moveNotices
Messages inside the modal; per request, not a session flash, which would resurface on the next open.
private
array<int, array{key: string, type: string}>
$moveNotices
= []
$pickerFactory
private
PickerFactory|null
$pickerFactory
= null
$treePositionFactory
private
TreePositionFactory|null
$treePositionFactory
= null
Methods
canMoveNodes()
Tells whether "Move to..." is offered; same gate as drag and drop (a flat drag must not change the parent).
public
canMoveNodes() : bool
Return values
boolcanSortChildren()
Tells whether "sort children alphabetically" is offered.
public
canSortChildren() : bool
Return values
boolgetMoveNotices()
Returns the messages for the modal; the template translates them by the full grid domain key.
public
getMoveNotices() : array<int, array{key: string, type: string}>
Return values
array<int, array{key: string, type: string}>handleMoveModal()
Opens the "Move to..." modal for a node (AJAX; without JS it just returns to the list).
public
handleMoveModal(int $id) : void
Parameters
- $id : int
handleSortChildren()
Sorts the direct children of a parent by label (current language collation) in one operation under the tree lock. `parentId` 0 is the root level of the view (the real roots without focus).
public
handleSortChildren([int $parentId = 0 ]) : void
Parameters
- $parentId : int = 0
Attributes
- #[Requires]
- $methods: 'POST'
setTreeMoveFactories()
Component factories of the modal, injected by {@see \App\UI\Admin\System\Components\DataGridComponent\DataGridFactory}.
public
setTreeMoveFactories(PickerFactory $pickerFactory, TreePositionFactory $treePositionFactory) : self
Parameters
- $pickerFactory : PickerFactory
- $treePositionFactory : TreePositionFactory
Return values
selfsortIdsByLabel()
Returns ids sorted by label using `Collator` (`strnatcasecmp` without intl). Equal labels keep their original order (stable sort), so sorting again changes nothing.
public
static sortIdsByLabel(array<int, string> $labels[, string $locale = 'cs_CZ' ]) : array<int, int>
Parameters
- $labels : array<int, string>
-
id => label in the current order
- $locale : string = 'cs_CZ'
Return values
array<int, int>createComponentMoveForm()
protected
createComponentMoveForm() : Form
Return values
FormcreateComponentMoveParentPicker()
Parent in the modal: a suggest field with the path plus a modal with the same grid in picker mode (without the node and its subtree).
protected
createComponentMoveParentPicker() : Picker
Return values
PickercreateComponentMovePosition()
protected
createComponentMovePosition() : TreePosition
Return values
TreePositionaddMoveNotice()
private
addMoveNotice(string $key, string $type) : void
Parameters
- $key : string
- $type : string
buildMoveTargetParams()
Builds the redirect parameters after success so that the moved node is highlighted and visible.
private
buildMoveTargetParams(int $id, int|null $newParentId) : array<string, mixed>
In a tree the path to the new parent is expanded; when it lies outside the focused subtree, the new parent is focused. A flat list (search) stays as it is.
Parameters
- $id : int
- $newParentId : int|null
Return values
array<string, mixed>findMoveChildren()
private
findMoveChildren(int|null $parentId) : array<int, array{id: int, label: string}>
Parameters
- $parentId : int|null
Return values
array<int, array{id: int, label: string}> —children of the parent in lft order (grid scope)
findMoveNode()
private
findMoveNode(int $id) : object|null
Parameters
- $id : int
Return values
object|nullmoveDialogErrorKey()
private
moveDialogErrorKey(Result $result) : string
Parameters
- $result : Result
Return values
stringprocessMoveForm()
private
processMoveForm(ArrayHash $values) : void
Parameters
- $values : ArrayHash
reloadMoveNodeFromForm()
private
reloadMoveNodeFromForm() : void
requireTreeMoveAllowed()
private
requireTreeMoveAllowed() : void
resolveCollatorLocale()
Returns the collation locale by the admin language (`cs` to `cs_CZ`), Czech by default.
private
resolveCollatorLocale() : string
Return values
stringresolveMoveNode()
Returns the node being moved: from the form value (submit) or from the signal parameter (open).
private
resolveMoveNode() : object|null
Return values
object|nullresolveMoveParentLabel()
private
resolveMoveParentLabel(int $id) : string|null
Parameters
- $id : int
Return values
string|nullresolveTreeLabelProperty()
Returns the property of the indented column (node name), which the parent suggest searches by.
private
resolveTreeLabelProperty() : string|null
Return values
string|nullshowMoveModal()
Fills and opens the shared modal with the current form state (idempotent).
private
showMoveModal() : void
suggestMoveParents()
Suggests parents: LIKE over the name column property, without the node and its subtree, with the path in the label so that equal names can be told apart.
private
suggestMoveParents(string $query, int|null $nodeId, int|null $lft, int|null $rgt) : array<int, array{id: int, label: string}>
Parameters
- $query : string
- $nodeId : int|null
- $lft : int|null
- $rgt : int|null