/**

*

* @access public

* @param Array $categories

* @param \CCDNForum\ForumBundle\Entity\Category $categoryShift

* @param int $direction

* @return \CCDNForum\ForumBundle\Manager\BaseManagerInterface

*/

public function reorderCategories($categories, Category $categoryShift, $direction)

{

$categoryCount = (count($categories) - 1);

// Find category in collection to shift and use list order as array key for easier editing.

$sorted = array();

$shiftIndex = null;

foreach ($categories as $categoryIndex => $category) {

if ($categories[$categoryIndex]->getId() == $categoryShift->getId()) {

$shiftIndex = $categoryIndex;

}

$sorted[$categoryIndex] = $category;

}

$incrementKeysAfterIndex = function($index, $arr) {

$hydrated = array();

foreach ($arr as $key => $el) {

if ($key > $index) {

$hydrated[$key + 1] = $el;

} else {

$hydrated[$key] = $el;

}

}

return $hydrated;

};

$decrementKeysBeforeIndex = function($index, $arr) {

$hydrated = array();

foreach ($arr as $key => $el) {

if ($key < $index) {

$hydrated[$key - 1] = $el;

} else {

$hydrated[$key] = $el;

}

}

return $hydrated;

};

$shifted = array();

// First Category needs reordering??

if ($shiftIndex == 0) {

if ($direction) { // Down (move down 1)

$shifted = $sorted;

$shifted[$shiftIndex] = $sorted[$shiftIndex + 1];

$shifted[$shiftIndex + 1] = $sorted[$shiftIndex];

} else { // Up (send to bottom)

$shifted[$categoryCount] = $sorted[0];

unset($sorted[0]);

$shifted = array_merge($decrementKeysBeforeIndex($categoryCount + 1, $sorted), $shifted);

}

} else {

// Last category needs reordering??

if ($shiftIndex == $categoryCount) {

if ($direction) { // Down (send to top)

$shifted[0] = $sorted[$categoryCount];

unset($sorted[$categoryCount]);

$shifted = array_merge($shifted, $incrementKeysAfterIndex(-1, $sorted));

} else { // Up (move up 1)

$shifted = $sorted;

$shifted[$shiftIndex] = $sorted[$shiftIndex - 1];

$shifted[$shiftIndex - 1] = $sorted[$shiftIndex];

}

} else {

// Swap 2 categories not at beginning or end.

$shifted = $sorted;

if ($direction) { // Down (move down 1)

$shifted[$shiftIndex] = $sorted[$shiftIndex + 1];

$shifted[$shiftIndex + 1] = $sorted[$shiftIndex];

} else { // Up (move up 1)

$shifted[$shiftIndex] = $sorted[$shiftIndex - 1];

$shifted[$shiftIndex - 1] = $sorted[$shiftIndex];

}

}

}

// Set the order from the $index arranged prior and persist.

foreach ($shifted as $index => $category) {

$category->setListOrderPriority($index);

$this->persist($category);

}

$this->flush();

return $this;

}