/** * Fetch actions from the clipboard. * * @param FilterInterface|null $filter The clipboard filter. * @param ModelIdInterface $parentModelId The parent id. * * @return array */ private function fetchModelsFromClipboard(FilterInterface $filter = null, ModelIdInterface $parentModelId = null) { $environment = $this->getEnvironment(); $dataDefinition = $environment->getDataDefinition(); if (!$filter) { $filter = new Filter(); } $basicDefinition = $dataDefinition->getBasicDefinition(); $modelProviderName = $basicDefinition->getDataProvider(); $filter->andModelIsFromProvider($modelProviderName); if ($parentModelId) { $filter->andParentIsFromProvider($parentModelId->getDataProviderName()); } else { $filter->andHasNoParent(); } $environment = $this->getEnvironment(); $clipboard = $environment->getClipboard(); $items = $clipboard->fetch($filter); $actions = array(); foreach ($items as $item) { $model = null; if (!$item->isCreate() && $item->getModelId()) { $modelId = $item->getModelId(); $dataProvider = $environment->getDataProvider($item->getDataProviderName()); $config = $dataProvider->getEmptyConfig()->setId($modelId->getId()); $model = $dataProvider->fetch($config); } $actions[] = array('model' => $model, 'item' => $item); } return $actions; }
/** * Calculate all clipboard items for the current view. * * @return ItemInterface[] */ private function calculateClipboardItems() { $dataDefinition = $this->environment->getDataDefinition(); $basicDefinition = $dataDefinition->getBasicDefinition(); $clipboard = $this->environment->getClipboard(); $filter = new Filter(); $filter->andModelIsFromProvider($basicDefinition->getDataProvider()); if ($parentDataProviderName = $basicDefinition->getParentDataProvider()) { $filter->andParentIsFromProvider($parentDataProviderName); } else { $filter->andHasNoParent(); } return $clipboard->fetch($filter); }
/** * Handle view. * * @param ViewEvent $event The view event. * * @return void */ public function handleView(ViewEvent $event) { if (DcGeneralViews::CLIPBOARD !== $event->getViewName()) { return; } $environment = $event->getEnvironment(); $input = $environment->getInputProvider(); $clipboard = $environment->getClipboard(); $eventDispatcher = $environment->getEventDispatcher(); $basicDefinition = $environment->getDataDefinition()->getBasicDefinition(); $modelProviderName = $basicDefinition->getDataProvider(); $parentProviderName = $basicDefinition->getParentDataProvider(); $filter = new Filter(); $filter->andModelIsFromProvider($modelProviderName); if ($parentProviderName) { $filter->andParentIsFromProvider($parentProviderName); } else { $filter->andHasNoParent(); } $options = array(); foreach ($clipboard->fetch($filter) as $item) { $modelId = $item->getModelId(); $dataProvider = $environment->getDataProvider($item->getDataProviderName()); if ($modelId) { $config = $dataProvider->getEmptyConfig(); $config->setId($modelId->getId()); $model = $dataProvider->fetch($config); // The model might have been deleted meanwhile. if (!$model) { continue; } $formatModelLabelEvent = new FormatModelLabelEvent($environment, $model); $eventDispatcher->dispatch(DcGeneralEvents::FORMAT_MODEL_LABEL, $formatModelLabelEvent); $label = $formatModelLabelEvent->getLabel(); $label = array_shift($label); $label = $label['content']; } else { $model = $dataProvider->getEmptyModel(); $label = $environment->getTranslator()->translate('new.0', $item->getDataProviderName()); } $options[$item->getClipboardId()] = array('item' => $item, 'model' => $model, 'label' => $label); } $addToUrlEvent = new AddToUrlEvent('act=clear-clipboard&original-act=' . $input->getParameter('act')); $eventDispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, $addToUrlEvent); $clearUrl = $addToUrlEvent->getUrl(); $addToUrlEvent = new AddToUrlEvent('clipboard-item=%id%&act=clear-clipboard&original-act=' . $input->getParameter('act')); $eventDispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, $addToUrlEvent); $clearItemUrl = $addToUrlEvent->getUrl(); $template = new \BackendTemplate('dcbe_general_clipboard'); $template->setData(array('environment' => $environment, 'options' => $options, 'clearUrl' => $clearUrl, 'clearItemUrl' => $clearItemUrl)); $event->setResponse($template->parse()); }
/** * Create the "new" button. * * @return null|Command */ protected function getCreateModelCommand() { $environment = $this->getEnvironment(); $definition = $environment->getDataDefinition(); $basicDefinition = $definition->getBasicDefinition(); $providerName = $environment->getDataDefinition()->getName(); $mode = $basicDefinition->getMode(); $config = $this->getEnvironment()->getBaseConfigRegistry()->getBaseConfig(); if ($serializedPid = $environment->getInputProvider()->getParameter('pid')) { $pid = ModelId::fromSerialized($serializedPid); } else { $pid = null; } if (!$basicDefinition->isCreatable()) { return null; } $command = new Command(); $parameters = $command->getParameters(); $extra = $command->getExtra(); $extra['class'] = 'header_new'; $extra['accesskey'] = 'n'; $extra['attributes'] = 'onclick="Backend.getScrollOffset();"'; $command->setName('button_new')->setLabel($this->translate('new.0', $providerName))->setDescription($this->translate('new.1', $providerName)); $this->getPanel()->initialize($config); // Add new button. if ($mode == BasicDefinitionInterface::MODE_PARENTEDLIST || $mode == BasicDefinitionInterface::MODE_HIERARCHICAL) { $filter = new Filter(); $filter->andModelIsFromProvider($basicDefinition->getDataProvider()); if ($parentDataProviderName = $basicDefinition->getParentDataProvider()) { $filter->andParentIsFromProvider($parentDataProviderName); } else { $filter->andHasNoParent(); } if ($environment->getClipboard()->isNotEmpty($filter)) { return null; } } $parameters['act'] = 'create'; // Add new button. if ($pid) { $parameters['pid'] = $pid->getSerialized(); } return $command; }
/** * Test andHasNoParent filter. */ public function testAndHasNoParent() { $filter = new Filter(); $parentId = new ModelId('dummy-provider', 5); $item = new MockedAbstractItem(ItemInterface::CREATE, $parentId); $item2 = new MockedAbstractItem(ItemInterface::CREATE); $filter->andSub(new MockedFilter(true)); $filter->andHasNoParent(); $this->assertEquals(false, $filter->accepts($item)); $this->assertEquals(true, $filter->accepts($item2)); }
/** * Retrieve a list of html buttons to use in the top panel (submit area). * * @param ModelInterface $parentModel The parent model. * * @return string */ protected function getHeaderButtons($parentModel) { $environment = $this->getEnvironment(); $definition = $environment->getDataDefinition(); $clipboard = $environment->getClipboard(); $basicDefinition = $definition->getBasicDefinition(); $headerButtons = array(); if (!$this->isSelectModeActive()) { return ''; } $dispatcher = $environment->getEventDispatcher(); $objConfig = $this->getEnvironment()->getBaseConfigRegistry()->getBaseConfig(); $this->getPanel()->initialize($objConfig); $sorting = $objConfig->getSorting(); $headerButtons['editHeader'] = $this->getHeaderEditButtons($parentModel); $filter = new Filter(); $filter->andModelIsFromProvider($basicDefinition->getDataProvider()); if ($parentDataProviderName = $basicDefinition->getParentDataProvider()) { $filter->andParentIsFromProvider($parentDataProviderName); } else { $filter->andHasNoParent(); } if ($sorting && $clipboard->isEmpty($filter) && $basicDefinition->isCreatable()) { /** @var AddToUrlEvent $urlEvent */ $urlEvent = $dispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, new AddToUrlEvent('act=edit&pid=' . ModelId::fromModel($parentModel)->getSerialized())); /** @var GenerateHtmlEvent $imageEvent */ $imageEvent = $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, new GenerateHtmlEvent('new.gif', $this->translate('pastenew.0', $definition->getName()))); $headerButtons['pasteNew'] = sprintf('<a href="%s" title="%s" onclick="Backend.getScrollOffset()">%s</a>', $urlEvent->getUrl(), specialchars($this->translate('pastenew.1', $definition->getName())), $imageEvent->getHtml()); } $filter = new Filter(); $filter->andModelIsFromProvider($basicDefinition->getDataProvider()); $filter->andParentIsFromProvider($basicDefinition->getParentDataProvider()); if ($sorting && $clipboard->isNotEmpty($filter)) { $allowPasteTop = ViewHelpers::getManualSortingProperty($this->environment); if (!$allowPasteTop) { $subFilter = new Filter(); $subFilter->andActionIsNotIn(array(ItemInterface::COPY, ItemInterface::DEEP_COPY)); $subFilter->andParentIsNot(ModelId::fromModel($parentModel)); $subFilter->orActionIsIn(array(ItemInterface::COPY, ItemInterface::DEEP_COPY)); $filter = new Filter(); $filter->andModelIsFromProvider($basicDefinition->getDataProvider()); $filter->andParentIsFromProvider($basicDefinition->getParentDataProvider()); $filter->andSub($subFilter); $allowPasteTop = (bool) $clipboard->fetch($filter); } if ($allowPasteTop) { /** @var AddToUrlEvent $urlEvent */ $urlEvent = $dispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, new AddToUrlEvent('act=paste' . '&pid=' . ModelId::fromModel($parentModel)->getSerialized())); /** @var GenerateHtmlEvent $imageEvent */ $imageEvent = $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, new GenerateHtmlEvent('pasteafter.gif', $this->translate('pasteafter.0', $definition->getName()), 'class="blink"')); $headerButtons['pasteAfter'] = sprintf('<a href="%s" title="%s" onclick="Backend.getScrollOffset()">%s</a>', $urlEvent->getUrl(), specialchars($this->translate('pasteafter.0', $definition->getName())), $imageEvent->getHtml()); } else { /** @var GenerateHtmlEvent $imageEvent */ $imageEvent = $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, new GenerateHtmlEvent('pasteafter_.gif', $this->translate('pasteafter.0', $definition->getName()), 'class="blink"')); $headerButtons['pasteAfter'] = $imageEvent->getHtml(); } } return implode(' ', $headerButtons); }
/** * Compile buttons from the table configuration array and return them as HTML. * * @param ModelInterface $model The model for which the buttons shall be generated for. * @param ModelInterface $previous The previous model in the collection. * @param ModelInterface $next The next model in the collection. * * @return string */ protected function generateButtons(ModelInterface $model, ModelInterface $previous = null, ModelInterface $next = null) { $environment = $this->getEnvironment(); $dataDefinition = $environment->getDataDefinition(); $basicDefinition = $dataDefinition->getBasicDefinition(); $commands = $this->getViewSection()->getModelCommands(); $clipboard = $environment->getClipboard(); $dispatcher = $environment->getEventDispatcher(); $filter = new Filter(); $filter->andModelIsFromProvider($basicDefinition->getDataProvider()); if ($parentDataProviderName = $basicDefinition->getParentDataProvider()) { $filter->andParentIsFromProvider($parentDataProviderName); } else { $filter->andHasNoParent(); } if ($clipboard->isNotEmpty($filter)) { $circularIds = $clipboard->getCircularIds(); $isCircular = in_array(ModelId::fromModel($model)->getSerialized(), $circularIds); } else { $circularIds = array(); $isCircular = false; } $arrButtons = array(); foreach ($commands->getCommands() as $command) { $arrButtons[$command->getName()] = $this->buildCommand($command, $model, $isCircular, $circularIds, $previous, $next); } if (ViewHelpers::getManualSortingProperty($this->environment)) { $clipboardIsEmpty = $clipboard->isEmpty($filter); if ($clipboardIsEmpty && BasicDefinitionInterface::MODE_HIERARCHICAL !== $basicDefinition->getMode()) { /** @var AddToUrlEvent $urlEvent */ $urlEvent = $dispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, new AddToUrlEvent('act=create&after=' . ModelId::fromModel($model)->getSerialized())); /** @var GenerateHtmlEvent $imageEvent */ $imageEvent = $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, new GenerateHtmlEvent('new.gif', $this->translate('pastenew.0', $this->getDataDefinition()->getName()))); $arrButtons['pasteNew'] = sprintf('<a href="%s" title="%s" onclick="Backend.getScrollOffset()">%s</a>', $urlEvent->getUrl(), specialchars($this->translate('pastenew.1', $this->getDataDefinition()->getName())), $imageEvent->getHtml()); } // Add paste into/after icons. if (!$clipboardIsEmpty) { if ($clipboard->isCreate()) { // Add ext. information. $add2UrlAfter = sprintf('act=create&after=%s&', ModelId::fromModel($model)->getSerialized()); $add2UrlInto = sprintf('act=create&into=%s&', ModelId::fromModel($model)->getSerialized()); } else { // Add ext. information. $add2UrlAfter = sprintf('act=paste&after=%s&', ModelId::fromModel($model)->getSerialized()); $add2UrlInto = sprintf('act=paste&into=%s&', ModelId::fromModel($model)->getSerialized()); } /** @var AddToUrlEvent $urlAfter */ $urlAfter = $dispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, new AddToUrlEvent($add2UrlAfter)); /** @var AddToUrlEvent $urlInto */ $urlInto = $dispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, new AddToUrlEvent($add2UrlInto)); $models = $this->environment->getController()->getModelsFromClipboard($parentDataProviderName ? IdSerializer::fromValues($parentDataProviderName, null) : null); $buttonEvent = new GetPasteButtonEvent($this->getEnvironment()); $buttonEvent->setModel($model)->setCircularReference($isCircular)->setPrevious($previous)->setNext($next)->setHrefAfter($urlAfter->getUrl())->setHrefInto($urlInto->getUrl())->setPasteAfterDisabled($clipboard->isCut() && $isCircular)->setPasteIntoDisabled($clipboard->isCut() && $isCircular)->setContainedModels($models); $this->getEnvironment()->getEventDispatcher()->dispatch(GetPasteButtonEvent::NAME, $buttonEvent); $arrButtons['pasteafter'] = $this->renderPasteAfterButton($buttonEvent); if ($this->getDataDefinition()->getBasicDefinition()->getMode() == BasicDefinitionInterface::MODE_HIERARCHICAL) { $arrButtons['pasteinto'] = $this->renderPasteIntoButton($buttonEvent); } } } return implode(' ', $arrButtons); }
/** * Render the tree view. * * @param CollectionInterface $collection The collection of items. * * @return string */ protected function viewTree($collection) { $definition = $this->getDataDefinition(); $listing = $this->getViewSection()->getListingConfig(); $basicDefinition = $definition->getBasicDefinition(); $environment = $this->getEnvironment(); $dispatcher = $environment->getEventDispatcher(); // Init some Vars switch (6) { case 6: $treeClass = 'tree_xtnd'; break; default: $treeClass = 'tree'; } // Label + Icon. if (strlen($listing->getRootLabel()) == 0) { $strLabelText = 'DC General Tree BackendView Ultimate'; } else { $strLabelText = $listing->getRootLabel(); } if (strlen($listing->getRootIcon()) == 0) { $strLabelIcon = 'pagemounts.gif'; } else { $strLabelIcon = $listing->getRootIcon(); } $filter = new Filter(); $filter->andModelIsFromProvider($basicDefinition->getDataProvider()); if ($parentDataProviderName = $basicDefinition->getParentDataProvider()) { $filter->andParentIsFromProvider($parentDataProviderName); } else { $filter->andHasNoParent(); } // Root paste into. if ($environment->getClipboard()->isNotEmpty($filter)) { /** @var AddToUrlEvent $urlEvent */ $urlEvent = $dispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, new AddToUrlEvent(sprintf('act=paste&into=%s::0', $definition->getName()))); $buttonEvent = new GetPasteRootButtonEvent($this->getEnvironment()); $buttonEvent->setHref($urlEvent->getUrl())->setPasteDisabled(false); $dispatcher->dispatch($buttonEvent::NAME, $buttonEvent); $strRootPasteInto = $this->renderPasteRootButton($buttonEvent); } else { $strRootPasteInto = ''; } /** @var GenerateHtmlEvent $imageEvent */ $imageEvent = $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, new GenerateHtmlEvent($strLabelIcon)); // Build template. $objTemplate = $this->getTemplate('dcbe_general_treeview'); $objTemplate->treeClass = 'tl_' . $treeClass; $objTemplate->tableName = $definition->getName(); $objTemplate->strLabelIcon = $imageEvent->getHtml(); $objTemplate->strLabelText = $strLabelText; $objTemplate->strHTML = $this->generateTreeView($collection, $treeClass); $objTemplate->strRootPasteinto = $strRootPasteInto; $objTemplate->select = $this->isSelectModeActive(); $objTemplate->selectButtons = $this->getSelectButtons(); $objTemplate->intMode = 6; // Add breadcrumb, if we have one. $strBreadcrumb = $this->breadcrumb(); if ($strBreadcrumb != null) { $objTemplate->breadcrumb = $strBreadcrumb; } return $objTemplate->parse(); }