Пример #1
0
 protected function performSave()
 {
     // there are two situation here, an orthodox form submittal and a ajax one:
     // - the orthodox will send a json string
     // - the ajax version will send an array
     $var = \Input::get($this->name);
     if (is_string($var)) {
         $var = json_decode($var, true);
     }
     if (!$var) {
         // the client submitted an empty tree, there's nothing to move
         return;
     }
     $movements = [];
     $subtreeId = $this->source->getKey();
     // We now invert the order of movements and group/sort them by
     // depth. This is done to avoid the situation where a node wants
     // to become the descendant of one of its own descendants.
     // This kind of sort will prevent the issue ensuring all the descendants
     // are moved first.
     $this->sortMovementsByDepth($var, $movements, $subtreeId);
     ksort($movements);
     $movements = call_user_func_array('array_merge', $movements);
     $movements = Collection::make($movements)->keyBy('id');
     /** @var \Baum\Extensions\Eloquent\Collection $nodes */
     $root = $this->source->getRoot();
     // store depth and left ot the root, to build upon when
     // we will rebuild the tree.
     $rootDepth = $root->depth;
     $rootLeft = $root->lft;
     // now we read the entire tree. We need to do that because
     // of the nested set way workings: Baum provides handy methods
     // to move the nodes, but they trigger an awful lot of queries.
     // We'd rather read the whole tree once instead, and perform all
     // the calculations in-memory.
     $nodes = $root->getDescendantsAndSelf([$this->source->getKeyName(), 'lft', 'rgt', 'depth', 'parent_id']);
     // the ids of all the moved elements
     $movedIds = $movements->keys()->toArray();
     // index the elements by primary key for speedy retrieval
     $dictionary = $nodes->getDictionary();
     // the elements of the bigger tree that did not change their
     // parent_id
     $unmoved = new \Baum\Extensions\Eloquent\Collection();
     foreach ($dictionary as $n) {
         if (!in_array($n->getKey(), $movedIds)) {
             $unmoved[] = $n;
         }
     }
     // the elements that were moved to a different parent
     $moved = new \Baum\Extensions\Eloquent\Collection();
     foreach ($movedIds as $i) {
         $moved[] = $dictionary[$i];
     }
     // this is the column that Baum uses to order the tree
     // the default is `lft`
     $orderColumn = $this->source->getOrderColumnName();
     // we backup the order column, because we have to mess with
     // it later and we want to be able to restore it so we can
     // still use `$node->isDirty()` to see if the the node needs
     // to be updated or not.
     foreach ($dictionary as $n) {
         $n->__order = $n->{$orderColumn};
     }
     // what now? We put all the moved nodes before the rest of the
     // tree. This way they'll be put before their unmoved siblings
     // shall they exist.
     $orderedNodes = $moved->merge($unmoved);
     // shady stuff going on here: Baum collections build the hierarchy
     // based on parent id AND the order column (lft). We thus update the
     // order column with an incremental value to be sure the siblings
     // order is preserved.
     $order = 1;
     foreach ($orderedNodes as $n) {
         $n->{$orderColumn} = $order++;
         if (isset($movements[$n->getKey()])) {
             // is the parent_id changed? If so, let's update it
             $n->parent_id = $movements[$n->getKey()]['parent_id'];
         }
     }
     // let Baum build the new tree
     $newTree = $orderedNodes->toHierarchy();
     // lets restore the order column and delete the previous backup,
     // so we can use `$node->isDirty` later
     foreach ($dictionary as $n) {
         $n->{$orderColumn} = $n->__order;
         unset($n->__order);
     }
     // if everything worked correctly we should have a nested collection
     // with only one root element. The root ID should be unchanged.
     $newRoot = $newTree->first();
     if ($newRoot->getKey() != $root->getKey() || count($newTree) != 1) {
         throw new \LogicException("Invalid tree");
     }
     // now we take the new tree and recursively recalculate the left, right
     // and depth fields.
     $left = $rootLeft - 1;
     $depth = $rootDepth;
     $reindex = function ($tree, $reindex, $depth) use(&$left) {
         foreach ($tree as $node) {
             $left++;
             $node->lft = $left;
             $node->depth = $depth;
             $reindex($node->getRelation('children'), $reindex, $depth + 1);
             $left++;
             $node->rgt = $left;
         }
     };
     $reindex($newTree, $reindex, $depth);
     // compute the changes and only save the changed ones!
     $bulk = [];
     foreach ($dictionary as $n) {
         if ($n->isDirty()) {
             $bulk[$n->getKey()] = ['lft' => $n->lft, 'rgt' => $n->rgt, 'depth' => $n->depth, 'parent_id' => $n->parent_id];
         }
     }
     foreach ($bulk as $id => $fields) {
         \DB::table($this->source->getTable())->where($this->source->getKeyName(), $id)->update($fields);
     }
 }
Пример #2
0
                <ul class="nav nav-tabs">
                    @foreach($application_settings as $key=>$section)
                        <li class='{{ @$i ? "":"active"}}'><a href="#tab-{{$key?$key:"Settings"}}" data-toggle="tab">{{$key?$key:"Settings"}}</a></li>
                        <?php 
$i = 1;
?>
                    @endforeach
                </ul>
                {!! Form::model($application, array('method' => 'POST', 'files'=>true, 'class'=>'main-form',  'action' => array('\Bootleg\Cms\ApplicationController@anyUpdate'))) !!}
                <div class='tab-content'>
                @foreach($application_settings as $key=>$section)
                <?php 
//we need to group this correctly.. I think there is a bug in Laravel that prevents
//nested groups working correctly. TODO: Probably look at this again later
$fields = "";
$model = new Baum\Extensions\Eloquent\Collection();
if (count($section) > 1) {
    foreach ($section as $flds) {
        $model->push($flds);
    }
    $fields = $model->groupBy('name');
}
?>
                    <div class="tab-pane fade {{!@$j?'active in':''}} edit-content-tab" id="tab-{{$key?$key:"Settings"}}">
                        <ul>
                            @if(!@$j)
                                <li class="form-group">
                                    {!! Form::label('name', 'Name:') !!}
                                    {!! Form::text('name', null, array('class'=>'form-control')) !!}
                                </li>
                                <?php