/** * Update the sorting property values of all models. * * @return void */ private function updateSorting() { $ids = $this->getModelIds(); // If no "next" sibling, simply increment the sorting as we are at the end of the list. if (!$this->marker) { foreach ($this->results as $model) { $this->position += 128; /** @var ModelInterface $model */ $model->setProperty($this->getSortingProperty(), $this->position); } return; } $delta = $this->determineDelta(); // Loop over all models and increment sorting value. foreach ($this->results as $model) { $this->position += $delta; /** @var ModelInterface $model */ $model->setProperty($this->getSortingProperty(), $this->position); } // When the sorting exceeds the sorting of the "next" sibling, we need to push the remaining siblings to the // end of the list. if ($this->marker->getProperty($this->getSortingProperty()) <= $this->position) { do { // Skip models about to be pasted. if (in_array($this->marker->getId(), $ids)) { $this->marker = $this->siblingsCopy->shift(); continue; } $this->position += $delta; $this->marker->setProperty($this->getSortingProperty(), $this->position); $this->results->push($this->marker); $this->marker = $this->siblingsCopy->shift(); } while ($this->marker); } }
/** * Prepare the required collections from provided test data. * * @param array|ModelIdInterface[] $siblings List of all models. * @param array $resortingIds Resorting ids. * @param int|null $previousModelId Previous model ids. * @param CollectionInterface $siblingCollection The sibling collection. * @param CollectionInterface $modelCollection The model collection of models being moved. * @param ModelIdInterface|null $previousModel Optional previous model. * * @return void. */ protected function prepareCollections(array &$siblings, array $resortingIds, $previousModelId, $siblingCollection, $modelCollection, &$previousModel) { foreach ($siblings as $id => $sorting) { $model = new DefaultModel(); $model->setID($id); $model->setProperty('sorting', $sorting); $siblingCollection->push($model); $siblings[$id] = $model; if (in_array($id, $resortingIds)) { $modelCollection->push($model); } if ($id === $previousModelId) { $previousModel = $model; } } }
/** * Calculate the resulting list. * * @return void */ protected function calculate() { if (isset($this->results) || $this->models->length() == 0) { return; } $ids = $this->getModelIds(); $this->results = clone $this->models; $this->siblingsCopy = clone $this->siblings; $this->scanToDesiredPosition(); // If no "next" sibling, simply increment the sorting as we are at the end of the list. if (!$this->marker) { foreach ($this->results as $model) { $this->position += 128; /** @var ModelInterface $model */ $model->setProperty($this->getSortingProperty(), $this->position); } return; } // Determine delta value: ((next sorting - current sorting) / amount of insert models). $delta = ($this->marker->getProperty($this->getSortingProperty()) - $this->position) / $this->results->length(); // If delta too narrow, we need to make room. if ($delta < 2) { $delta = 128; } // Loop over all models and increment sorting value. foreach ($this->results as $model) { $this->position += $delta; /** @var ModelInterface $model */ $model->setProperty($this->getSortingProperty(), $this->position); } // When the sorting exceeds the sorting of the "next" sibling, we need to push the remaining siblings to the // end of the list. if ($this->marker->getProperty($this->getSortingProperty()) <= $this->position) { do { // Skip models about to be pasted. if (in_array($this->marker->getId(), $ids)) { $this->marker = $this->siblingsCopy->shift(); continue; } $this->position += $delta; $this->marker->setProperty($this->getSortingProperty(), $this->position); $this->results->push($this->marker); $this->marker = $this->siblingsCopy->shift(); } while ($this->marker); } }