Reorder Menu tree.

@param Menu $menu
@param string $field
@return bool
175172
public function reorder(Menu $menu, $field = 'position')
    {
        $roots = $this->menuItemRepository->getRootNodes();
        $rootItem = null;

        foreach ($roots as $root) {
            if ($root->getMenu() == $menu) {
                $rootItem = $root;
            }
        }

        if ($rootItem) {
            $this->menuItemRepository->reorder($rootItem, $field);
            return true;
        }

        return false;
    }
277842
public function createMenuItemAction(Request $request, Menu $menu)
    {
        $entity = new MenuItem();
        $entity->setMenu($menu);
        $form = $this->createMenuItemCreateForm($entity);
        $form->handleRequest($request);
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            if($entity->getPage()){
                $entity->setPageSlug($entity->getPage());
            }

            $em->persist($entity);

            $this->get('amulen.page.service.menu')->reorder($menu);
            $em->flush();

            $availableLangs = $this->container->getParameter('flowcode_page.available_languages');
            foreach ($availableLangs as $key => $value) {
                $menuItemLabel = new MenuItemLabel();
                $menuItemLabel->setLang($key);
                $menuItemLabel->setContent($entity->getName());
                $menuItemLabel->setMenuItem($entity);
                $em->persist($menuItemLabel);
            }
            $em->flush();

            return $this->redirect($this->generateUrl('admin_menu_items', array('id' => $menu->getId())));
        }

        return array(
            'entity' => $entity,
            'form' => $form->createView(),
        );
    }
36150
public function handleReorder(ReorderEvent $event)
    {
        $document = $event->getDocument();

        if (!$document instanceof OrderBehavior) {
            return;
        }

        $parentDocument = $this->documentInspector->getParent($document);

        if (null === $parentDocument) {
            return;
        }

        $count = 1;
        foreach ($this->documentInspector->getChildren($parentDocument) as $childDocument) {
            if (!$childDocument instanceof OrderBehavior) {
                continue;
            }

            $order = $count * 10;
            $childDocument->setSuluOrder($order);

            // TODO move to NodeHelper once integrated in sulu/sulu?
            $childNode = $this->documentInspector->getNode($childDocument);
            $childNode->setProperty($this->propertyEncoder->systemName(static::FIELD), $order);

            ++$count;
        }
    }
112040
public function addMenu(Menu $menu)
    {
        $menu->setArticle($this);
        $this->menus[] = $menu;

        return $this;
    }
377567
public function populateSelectField($field)
    {
        $menus = \Municipio\Helper\Navigation::getMenuList();
        $field['choices'] = array();

        foreach ($menus as $menu) {
            $field['choices'][$menu->term_id] = $menu->name . ' (ID: ' . $menu->term_id . ')';
        }

        return $field;
    }
192083
public function update(Menu $menu, FormRequest $request)
    {
        $this->repository->update($request->id, $request->all());

        return $this->redirect($request, $menu);
    }
853997
public function orderBy($field, $order = 'asc'){
        $this->model = $this->model->orderBy(...func_get_args());
        return $this;
    }
1175912
public function updateSort()
    {
        if ($this->validate()) {
            $srcMenuModels = DpAdminMenu::find()
                ->andFilterWhere(['in', 'menu_id', $this->menu_ids])
                ->orderBy([new Expression('field(menu_id, ' . join(',', $this->menu_ids) . ')')])
                ->all();
            $targetMenuModel = DpAdminMenu::find()
                ->findByMenuId($this->target_menu_id)
                ->one();
            $menuModels = DpAdminMenu::find()
                ->findByParentId($targetMenuModel->parent_id)
                ->defaultOrder()
                ->all();
            $srcMenuIds = ArrayHelper::getColumn($srcMenuModels, 'menu_id');
            if ($srcMenuModels && $targetMenuModel && $menuModels) {
                if (static::POSITION_BEFORE == $this->position) {
                    $displayOrder = -1;
                    $transaction = Yii::$app->db->beginTransaction();
                    foreach ($menuModels as $itemMenuModel) {
                        if (in_array($itemMenuModel->menu_id, $srcMenuIds)) {
                            continue;
                        }
                        $displayOrder++;
                        if ($targetMenuModel->menu_id == $itemMenuModel->menu_id) {
                            // before
                            foreach ($srcMenuModels as $itemSrcMenuMode) {
                                $itemSrcMenuMode->display_order = $displayOrder;
                                $itemSrcMenuMode->parent_id = $targetMenuModel->parent_id;
                                if (!$itemSrcMenuMode->save()) {
                                    $transaction->rollBack();
                                    $this->addErrors($itemSrcMenuMode->errors);
                                    return false;
                                }
                                $displayOrder++;
                            }
                            // target
                            $targetMenuModel->display_order = $displayOrder;
                            if (!$targetMenuModel->save()) {
                                $transaction->rollBack();
                                $this->addErrors($targetMenuModel->errors);
                                return false;
                            }
                            continue;
                        }
                        $itemMenuModel->display_order = $displayOrder;
                        if (!$itemMenuModel->save()) {
                            $transaction->rollBack();
                            $this->addErrors($itemMenuModel->errors);
                            return false;
                        }
                    }
                    $transaction->commit();
                    return true;
                } elseif (static::POSITION_AFTER == $this->position) {
                    $displayOrder = -1;
                    $transaction = Yii::$app->db->beginTransaction();
                    foreach ($menuModels as $itemMenuModel) {
                        if (in_array($itemMenuModel->menu_id, $srcMenuIds)) {
                            continue;
                        }
                        $displayOrder++;
                        if ($targetMenuModel->menu_id == $itemMenuModel->menu_id) {
                            // target
                            $targetMenuModel->display_order = $displayOrder;
                            if (!$targetMenuModel->save()) {
                                $transaction->rollBack();
                                $this->addErrors($targetMenuModel->errors);
                                return false;
                            }
                            $displayOrder++;
                            // after
                            foreach ($srcMenuModels as $itemSrcMenuMode) {
                                $itemSrcMenuMode->display_order = $displayOrder;
                                $itemSrcMenuMode->parent_id = $targetMenuModel->parent_id;
                                if (!$itemSrcMenuMode->save()) {
                                    $transaction->rollBack();
                                    $this->addErrors($itemSrcMenuMode->errors);
                                    return false;
                                }
                                $displayOrder++;
                            }
                            continue;
                        }
                        $itemMenuModel->display_order = $displayOrder;
                        if (!$itemMenuModel->save()) {
                            $transaction->rollBack();
                            $this->addErrors($itemMenuModel->errors);
                            return false;
                        }
                    }
                    $transaction->commit();
                    return true;
                } elseif (static::POSITION_APPEND == $this->position) {
                    $menuModels = DpAdminMenu::find()
                        ->findByParentId($targetMenuModel->menu_id)
                        ->defaultOrder()
                        ->all();
                    if ($menuModels) {
                        // 将目标菜单设置成该目标元素下的最后一个元素
                        $targetParentMenuModels = DpAdminMenu::find()->findByParentId($targetMenuModel->menu_id)->defaultOrder()->all();
                        $targetMenuModel = array_pop($targetParentMenuModels);

                        $displayOrder = -1;
                        $transaction = Yii::$app->db->beginTransaction();
                        foreach ($menuModels as $itemMenuModel) {
                            if (in_array($itemMenuModel->menu_id, $srcMenuIds)) {
                                continue;
                            }
                            $displayOrder++;
                            if ($targetMenuModel->menu_id == $itemMenuModel->menu_id) {
                                // target
                                $targetMenuModel->display_order = $displayOrder;
                                if (!$targetMenuModel->save()) {
                                    $transaction->rollBack();
                                    $this->addErrors($targetMenuModel->errors);
                                    return false;
                                }
                                $displayOrder++;
                                // after
                                foreach ($srcMenuModels as $itemSrcMenuMode) {
                                    $itemSrcMenuMode->display_order = $displayOrder;
                                    $itemSrcMenuMode->parent_id = $targetMenuModel->parent_id;
                                    if (!$itemSrcMenuMode->save()) {
                                        $transaction->rollBack();
                                        $this->addErrors($itemSrcMenuMode->errors);
                                        return false;
                                    }
                                    $displayOrder++;
                                }
                                continue;
                            }
                            $itemMenuModel->display_order = $displayOrder;
                            if (!$itemMenuModel->save()) {
                                $transaction->rollBack();
                                $this->addErrors($itemMenuModel->errors);
                                return false;
                            }
                        }
                    } else {
                        $displayOrder = 0;
                        // 菜单没有节点时
                        $transaction = Yii::$app->db->beginTransaction();
                        foreach ($srcMenuModels as $itemSrcMenuMode) {
                            $itemSrcMenuMode->display_order = $displayOrder;
                            $itemSrcMenuMode->parent_id = $targetMenuModel->menu_id;
                            if (!$itemSrcMenuMode->save()) {
                                $transaction->rollBack();
                                $this->addErrors($itemSrcMenuMode->errors);
                                return false;
                            }
                            $displayOrder++;
                        }
                    }
                    $transaction->commit();
                    return true;
                }
            }
        }

        return false;
    }
132635
public function setDefaultOrder($field)
    {
        $this->loadAvailableOrders();
        if (isset($this->availableOrder[$field])) {
            $this->orderField = $field;
        }

        return $this;
    }
1311603
public function orderBy($field, $direction = self::DESC) {
        if (is_array($field)) {
            foreach ($field as $key => $dir) {
                $this->orderBy($key, $dir);
            }

        } else if ($field === 'RAND') {
            $this->_orderBy[] = $this->func('RAND');

        } else if ($field instanceof Func) {
            $this->_orderBy[] = $field;

        } else {
            $direction = strtolower($direction);

            if ($direction != self::ASC && $direction != self::DESC) {
                throw new InvalidArgumentException(sprintf('Invalid order direction %s for field %s', $direction, $field));
            }

            $this->_orderBy[$field] = $direction;
        }

        return $this;
    }
153223
public function order($field, $order = 'desc')
    {
        $field = $this->model->field($field);
        $order = $this->normalizeOrder($order);

        $this->builder->addOrderBy($this->connection->quoteIdentifier($field->mappedName()), $order);

        return $this;
    }
213222
public static function link($menu, $text, array $options = [], array $fields = [])
    {
        if ($menu instanceof ActiveRecord) {

            if (!$fields) {
                $fields = self::$fields;
            }

            if ($menu->{$fields['page_blank']}) {
                $options['target'] = '_blank';
            }

            return Html::a($text, self::linkUrl(
                $menu->{$fields['page_id']},
                $menu->{$fields['page_url']}
            ), $options);
        }

        return false;
    }
999930
public function menu($id)
    {
        $this->loadModel('Menu.Menus');
        $menu = $this->Menus->get($id);
        $links = $this->Menus->MenuLinks->find()
            ->where(['menu_id' => $menu->id])
            ->order(['lft' => 'ASC'])
            ->all()
            ->map(function ($link) {
                $link->set('expanded', true);

                return $link;
            })
            ->nest('id', 'parent_id');

        if (!empty($this->request->data['tree_order'])) {
            $items = json_decode($this->request->data['tree_order']);

            if (!empty($items)) {
                unset($items[0]);
                $entities = [];

                foreach ($items as $key => $item) {
                    $link = $this->Menus->MenuLinks->get($item->item_id);
                    $link = $this->Menus->MenuLinks->patchEntity($link, [
                        'parent_id' => intval($item->parent_id),
                        'lft' => intval(($item->left - 1)),
                        'rght' => intval(($item->right - 1)),
                    ], ['validate' => false]);
                    $entities[] = $link;
                }

                $this->Menus->MenuLinks->connection()->transactional(function () use ($entities) {
                    foreach ($entities as $entity) {
                        $result = $this->Menus->MenuLinks->save($entity);
                        if (!$result) {
                            return false;
                        }
                    }

                    return true;
                });

                // don't trust "left" and "right" values coming from user's POST
                $this->Menus->MenuLinks->addBehavior('Tree', ['scope' => ['menu_id' => $menu->id]]);
                $this->Menus->MenuLinks->recover();
                $this->Flash->success(__d('menu', 'Menu has been reordered'));
            } else {
                $this->Flash->danger(__d('menu', 'Invalid information, check you have JavaScript enabled'));
            }

            $this->redirect($this->referer());
        }

        $disabledIds = $links
            ->match(['status' => false])
            ->extract('id')
            ->toArray();

        $this->title(__d('menu', 'Menu’s Links'));
        $this->set(compact('menu', 'links', 'disabledIds'));
        $this->Breadcrumb
            ->push('/admin/menu/manage')
            ->push(__d('menu', 'Editing menu'), ['plugin' => 'Menu', 'controller' => 'manage', 'action' => 'edit', $menu->id])
            ->push(__d('menu', 'Links'), '#');
    }
486952
protected function saveMenuItems(Menu $menu, $items)
    {
        $itemStorage  = $this->treeManager->getItemStorage();
        $currentTree  = $this->treeManager->buildTree($menu->getId(), false);
        $menuId       = $menu->getId();

        // First, get all elements so that we can delete those that are removed
        // @todo pri: sorry this is inneficient, but I need it
        $old = [];
        foreach ($currentTree->getAll() as $item) {
            $old[$item->getId()] = $item;
        }

        // FIXME, this is coming from javascript, we should really check access on nodes

        // Keep a list of processed elements
        $processed = [];
        $deleteItems = [];

        // Keep in mind that items ordered
        if (!empty($items)) {

            // Because they are ordered and a parent will be saved before a child,
            // thus modifying a child: we have to use a classic loop
            $itemsCount = count($items);

            // Keep track of latest root parent found, in order to reorder top
            // level item relative to each other.
            $latestRootParentId = null;

            for ($i = 0; $i < $itemsCount; $i++) {

                $item     = $items[$i];
                $nodeId   = $item['item_id'];
                $isNew    = substr($item['id'], 0, 4) == 'new_' || empty($item['id']);
                $title    = trim($item['title']);
                $itemId   = $isNew ? null : $item['id'];
                $parentId = empty($item['parent_id']) ? null : $item['parent_id'];

                if ($isNew) {
                    if ($parentId) {
                        $itemId = $itemStorage->insertAsChild($parentId, $nodeId, $title);
                    } else {
                        $itemId = $itemStorage->insert($menuId, $nodeId, $title);
                        // Move the new item, in root tree, right after the
                        // lastest processed root item
                        if ($latestRootParentId) {
                            $itemStorage->moveAfter($itemId, $latestRootParentId);
                        }
                    }
                    // New potential parent item inserted, replace potential children parent_id
                    foreach ($items as $index => $potentialChild) {
                        if ($potentialChild['parent_id'] === $item['id']) {
                            $items[$index]['parent_id'] = $itemId;
                        }
                    }
                } else {
                    if ($parentId) {
                        $itemStorage->moveAsChild($itemId, $parentId);
                    } else {
                        if ($latestRootParentId) {
                            $itemStorage->moveAfter($itemId, $latestRootParentId);
                        } else {
                            $itemStorage->moveToRoot($itemId);
                        }
                    }

                    // When inserting or moving an item in the root of the tree
                    // we must keep track of it for being able to properly place
                    // the item relatively to its previous sibling.
                    if (!$parentId) {
                        $latestRootParentId = $itemId;
                    }

                    // Update title if revelant
                    if ($title !== $currentTree->getItemById($itemId)->getTitle()) {
                        $itemStorage->update($itemId, null, $title);
                    }
                }

                $processed[$itemId] = true;
            }
        }

        $newTree = $this->treeManager->buildTree($menuId, false, false, true);

        // Remove elements not in the original array
        foreach (array_diff_key($old, $processed) as $itemId => $deleted) {
            $itemStorage->delete($itemId);
            $deleteItems[$itemId] = $deleted;
        }

        $this->dispatcher->dispatch(
            MenuEvent::EVENT_TREE,
            new MenuEvent(
                $menu->getName(),
                $newTree,
                $deleteItems,
                $menu->hasSiteId() ? $this->siteManager->getStorage()->findOne($menu->getSiteId()) : null
            )
        );
    }
717791
def reorder(self, fields_in_new_order):
        
        if not len(fields_in_new_order) == len(self.fields):
            raise Exception("Fields to reorder with are not the same length "
                            "(%s) as the original fields (%s)" %
                            (len(fields_in_new_order), len(self.fields)))
        if not set(fields_in_new_order) == set(self.fields):
            raise Exception("Fields to reorder with should be the same "
                            "as the original fields")
        new = OrderedDict()
        for field in fields_in_new_order:
            new[field] = self.__data[field]
        self.__data = new
208025
protected function mergeWithLastStack($menu)
    {
        $stack = array_pop($this->stack);
        $this->stack[] = array_merge_recursive($stack, $menu);
    }
725962
public function order($field, $order = null)
    {
        if (!empty($field)) {
            if (is_string($field)) {
                if (!empty($this->options['via'])) {
                    $field = $this->options['via'] . '.' . $field;
                }
                $field = empty($order) ? $field : [$field => $order];
            } elseif (!empty($this->options['via'])) {
                foreach ($field as $key => $val) {
                    if (is_numeric($key)) {
                        $field[$key] = $this->options['via'] . '.' . $val;
                    } else {
                        $field[$this->options['via'] . '.' . $key] = $val;
                        unset($field[$key]);
                    }
                }
            }
            if (!isset($this->options['order'])) {
                $this->options['order'] = [];
            }
            if (is_array($field)) {
                $this->options['order'] = array_merge($this->options['order'], $field);
            } else {
                $this->options['order'][] = $field;
            }
        }
        return $this;
    }