<?php
function orderBeforeArray($name, $destination, $list)
{
// reindex the array so there are no gaps
$list = array_values($list);
$oldpos = array_search($name, $list);
if (false === $oldpos) {
throw new ItemNotFoundException("$name is not a child of this node");
}
if ($destination == null) {
// null means move to end
unset($list[$oldpos]);
$list[] = $name;
} else {
// insert before element $destination
$newpos = array_search($destination, $list);
if ($newpos === false) {
throw new ItemNotFoundException("$destination is not a child of this node");
}
if ($oldpos < $newpos) {
// we first unset, the position will change by one
$newpos--;
}
unset($list[$oldpos]);
array_splice($list, $newpos, 0, $name);
}
return $list;
}
$old = ['one', 'two', 'three', 'four'];
$new = ['one', 'three', 'two'];
$reorders = [];
//check for deleted items
$newIndex = array_flip($new);
foreach ($old as $key => $value) {
if (!isset($newIndex[$value])) {
unset($old[$key]);
}
}
// reindex the arrays to avoid holes in the indexes
$old = array_values($old);
$new = array_values($new);
$len = count($new) - 1;
$oldIndex = array_flip($old);
//go backwards on the new node order and arrange them this way
for ($i = $len; $i >= 0; $i--) {
//get the name of the child node
$current = $new[$i];
//check if it's not the last node
if (isset($new[$i + 1])) {
// get the name of the next node
$next = $new[$i + 1];
//if in the old order $c and next are not neighbors already, do the reorder command
if ($oldIndex[$current] + 1 != $oldIndex[$next]) {
$reorders[$current] = $next;
$old = orderBeforeArray($current, $next, $old);
$oldIndex = array_flip($old);
}
} else {
//check if it's not already at the end of the nodes
if ($oldIndex[$current] != $len) {
$reorders[$current] = null;
$old = orderBeforeArray($current, null, $old);
$oldIndex = array_flip($old);
}
}
}
var_dump($reorders);