/** * 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 * * @throws \RuntimeException When no sorting property has been defined. */ protected function calculate() { if (isset($this->results) || $this->models->length() == 0) { return; } if (!$this->getSortingProperty()) { throw new \RuntimeException('No sorting property defined for ' . $this->models->get(0)->getProviderName()); } $this->results = clone $this->models; $this->siblingsCopy = clone $this->siblings; $this->scanToDesiredPosition(); $this->updateSorting(); }
/** * 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); } }
/** * {@inheritDoc} * * @throws \RuntimeException When no models have been passed. */ public function pasteAfter(ModelInterface $previousModel, CollectionInterface $models, $sortedBy) { if ($models->length() == 0) { throw new \RuntimeException('No models passed to pasteAfter().'); } $environment = $this->getEnvironment(); if (in_array($environment->getDataDefinition()->getBasicDefinition()->getMode(), array(BasicDefinitionInterface::MODE_HIERARCHICAL, BasicDefinitionInterface::MODE_PARENTEDLIST))) { $parentModel = null; $parentModel = null; if (!$this->isRootModel($previousModel)) { $parentModel = $this->searchParentOf($previousModel); } foreach ($models as $model) { /** @var ModelInterface $model */ $this->setSameParent($model, $previousModel, $parentModel ? $parentModel->getProviderName() : null); } } // Enforce proper sorting now. $siblings = $this->assembleSiblingsFor($previousModel, $sortedBy); $sortManager = new SortingManager($models, $siblings, $sortedBy, $previousModel); $newList = $sortManager->getResults(); $environment->getDataProvider($previousModel->getProviderName())->saveEach($newList); }
/** * Render the operation buttons for the passed models. * * @param CollectionInterface $collection The collection containing the models. * * @return void */ public function renderButtonsForCollection(CollectionInterface $collection) { // Generate buttons. foreach ($collection as $i => $model) { $previous = $collection->get($i - 1); $next = $collection->get($i + 1); /** @var ModelInterface $model */ $this->renderButtonsFor($model, $previous, $next); } }
/** * Compute the union of this collection and the given collection. * * @param CollectionInterface $collection The collection to intersect. * * @return CollectionInterface */ public function union($collection) { $union = clone $this; /** @var ModelInterface $otherModel */ foreach ($collection->diff($this) as $otherModel) { $union->push($otherModel); } return $union; }
/** * Render the entries for parent view. * * @param CollectionInterface $collection The collection to render. * * @param array $groupingInformation The grouping information as retrieved via * BaseView::getGroupingMode(). * * @return void */ protected function renderEntries($collection, $groupingInformation) { $environment = $this->getEnvironment(); $view = $this->getViewSection(); $listing = $view->getListingConfig(); $remoteCur = null; $groupClass = 'tl_folder_tlist'; $eoCount = -1; $objConfig = $environment->getDataProvider()->getEmptyConfig(); $this->getPanel()->initialize($objConfig); // Run each model. $i = 0; foreach ($collection as $model) { /** @var ModelInterface $model */ $i++; // Add the group header. if ($groupingInformation) { $remoteNew = $this->formatCurrentValue($groupingInformation['property'], $model, $groupingInformation['mode'], $groupingInformation['length']); // Add the group header if it differs from the last header. if (!$listing->getShowColumns() && $groupingInformation['mode'] !== ListingConfigInterface::GROUP_NONE && ($remoteNew != $remoteCur || $remoteCur === null)) { $eoCount = -1; $model->setMeta($model::GROUP_VALUE, array('class' => $groupClass, 'value' => $remoteNew)); $groupClass = 'tl_folder_list'; $remoteCur = $remoteNew; } } if ($listing->getItemCssClass()) { $model->setMeta($model::CSS_CLASS, $listing->getItemCssClass()); } // Regular buttons. if (!$this->isSelectModeActive()) { $previous = !is_null($collection->get($i - 1)) ? $collection->get($i - 1) : null; $next = !is_null($collection->get($i + 1)) ? $collection->get($i + 1) : null; $buttons = $this->generateButtons($model, $previous, $next); $model->setMeta($model::OPERATION_BUTTONS, $buttons); } $event = new ParentViewChildRecordEvent($this->getEnvironment(), $model); $this->getEnvironment()->getEventPropagator()->propagate($event::NAME, $event, array($this->getEnvironment()->getDataDefinition()->getName(), $model->getId())); $model->setMeta($model::CSS_ROW_CLASS, ++$eoCount % 2 == 0 ? 'even' : 'odd'); if ($event->getHtml() !== null) { $information = array(array('colspan' => 1, 'class' => 'tl_file_list col_1', 'content' => $event->getHtml())); $model->setMeta($model::LABEL_VALUE, $information); } else { $model->setMeta($model::LABEL_VALUE, $this->formatModel($model)); } } }
/** * Render the entries for parent view. * * @param CollectionInterface $collection The collection to render. * * @param array $groupingInformation The grouping information as retrieved via * BaseView::getGroupingMode(). * * @return void */ protected function renderEntries($collection, $groupingInformation) { $environment = $this->getEnvironment(); $clipboard = $environment->getClipboard(); $view = $this->getViewSection(); $listing = $view->getListingConfig(); $remoteCur = null; $groupClass = 'tl_folder_tlist'; $eoCount = -1; $objConfig = $environment->getDataProvider()->getEmptyConfig(); $this->getPanel()->initialize($objConfig); // Run each model. $index = 0; foreach ($collection as $model) { /** @var ModelInterface $model */ $index++; // Add the group header. if ($groupingInformation) { $remoteNew = $this->formatCurrentValue($groupingInformation['property'], $model, $groupingInformation['mode'], $groupingInformation['length']); // Add the group header if it differs from the last header. if (!$listing->getShowColumns() && $groupingInformation['mode'] !== GroupAndSortingInformationInterface::GROUP_NONE && ($remoteNew != $remoteCur || $remoteCur === null)) { $eoCount = -1; $model->setMeta($model::GROUP_VALUE, array('class' => $groupClass, 'value' => $remoteNew)); $groupClass = 'tl_folder_list'; $remoteCur = $remoteNew; } } if ($listing->getItemCssClass()) { $model->setMeta($model::CSS_CLASS, $listing->getItemCssClass()); } // Regular buttons. if (!$this->isSelectModeActive()) { $previous = $collection->get($index - 1) !== null ? $collection->get($index - 1) : null; $next = $collection->get($index + 1) !== null ? $collection->get($index + 1) : null; $buttons = $this->generateButtons($model, $previous, $next); $model->setMeta($model::OPERATION_BUTTONS, $buttons); } $event = new ParentViewChildRecordEvent($this->getEnvironment(), $model); $environment->getEventDispatcher()->dispatch($event::NAME, $event); $cssClasses = array(++$eoCount % 2 == 0 ? 'even' : 'odd'); $modelId = IdSerializer::fromModel($model); if ($clipboard->hasId($modelId)) { $cssClasses[] = 'tl_folder_clipped'; } $model->setMeta($model::CSS_ROW_CLASS, implode(' ', $cssClasses)); if ($event->getHtml() !== null) { $information = array(array('colspan' => 1, 'class' => 'tl_file_list col_1', 'content' => $event->getHtml())); $model->setMeta($model::LABEL_VALUE, $information); } else { $event = new FormatModelLabelEvent($this->environment, $model); $this->environment->getEventDispatcher()->dispatch(DcGeneralEvents::FORMAT_MODEL_LABEL, $event); $model->setMeta($model::LABEL_VALUE, $event->getLabel()); } } }