/**
  * Create the edit mask.
  *
  * @return string
  *
  * @throws DcGeneralRuntimeException         If the data container is not editable, closed.
  *
  * @throws DcGeneralInvalidArgumentException If an unknown property is encountered in the palette.
  */
 public function execute()
 {
     $inputProvider = $this->environment->getInputProvider();
     $palettesDefinition = $this->definition->getPalettesDefinition();
     $isSubmitted = $inputProvider->getValue('FORM_SUBMIT') === $this->definition->getName();
     $isAutoSubmit = $inputProvider->getValue('SUBMIT_TYPE') === 'auto';
     $widgetManager = new WidgetManager($this->environment, $this->model);
     $this->dispatcher->dispatch(PreEditModelEvent::NAME, new PreEditModelEvent($this->environment, $this->model));
     $this->enforceModelRelationship();
     // Pass 1: Get the palette for the values stored in the model.
     $palette = $palettesDefinition->findPalette($this->model);
     $propertyValues = $this->processInput($widgetManager);
     if ($isSubmitted && $propertyValues) {
         // Pass 2: Determine the real palette we want to work on if we have some data submitted.
         $palette = $palettesDefinition->findPalette($this->model, $propertyValues);
         // Update the model - the model might add some more errors to the propertyValueBag via exceptions.
         $this->environment->getController()->updateModelFromPropertyBag($this->model, $propertyValues);
     }
     $fieldSets = $this->buildFieldSet($widgetManager, $palette, $propertyValues);
     $buttons = $this->getEditButtons();
     if (!$isAutoSubmit && $isSubmitted && empty($this->errors)) {
         $this->doPersist();
         $this->handleSubmit($buttons);
     }
     $template = new ViewTemplate('dcfe_general_edit');
     $template->setData(array('fieldsets' => $fieldSets, 'subHeadline' => $this->getHeadline(), 'table' => $this->definition->getName(), 'enctype' => 'multipart/form-data', 'error' => $this->errors, 'editButtons' => $buttons));
     return $template->parse();
 }
예제 #2
0
 /**
  * Create a controller instance in the environment if none has been defined yet.
  *
  * @param EnvironmentInterface $environment The environment to populate.
  *
  * @return void
  *
  * @internal
  */
 public function populateController(EnvironmentInterface $environment)
 {
     // Already populated, get out then.
     if ($environment->getController()) {
         return;
     }
     $controller = new DefaultController();
     $controller->setEnvironment($environment);
     $environment->setController($controller);
 }
 /**
  * Retrieve the instance of a widget for the given property.
  *
  * @param string           $property Name of the property for which the widget shall be retrieved.
  *
  * @param PropertyValueBag $valueBag The input values to use (optional).
  *
  * @return \Widget
  *
  * @throws DcGeneralRuntimeException         When No widget could be build.
  * @throws DcGeneralInvalidArgumentException When property is not defined in the property definitions.
  */
 public function getWidget($property, PropertyValueBag $valueBag = null)
 {
     $environment = $this->getEnvironment();
     $dispatcher = $environment->getEventDispatcher();
     $propertyDefinitions = $environment->getDataDefinition()->getPropertiesDefinition();
     if (!$propertyDefinitions->hasProperty($property)) {
         throw new DcGeneralInvalidArgumentException('Property ' . $property . ' is not defined in propertyDefinitions.');
     }
     $model = clone $this->model;
     $model->setId($this->model->getId());
     if ($valueBag) {
         $values = new PropertyValueBag($valueBag->getArrayCopy());
         $this->environment->getController()->updateModelFromPropertyBag($model, $values);
     }
     $propertyDefinition = $propertyDefinitions->getProperty($property);
     $event = new BuildWidgetEvent($environment, $model, $propertyDefinition);
     $dispatcher->dispatch(DcGeneralFrontendEvents::BUILD_WIDGET, $event);
     if (!$event->getWidget()) {
         throw new DcGeneralRuntimeException(sprintf('Widget was not build for property %s::%s.', $this->model->getProviderName(), $property));
     }
     return $event->getWidget();
 }
 /**
  * Create a controller instance in the environment if none has been defined yet.
  *
  * @param EnvironmentInterface $environment The environment to populate.
  *
  * @return void
  *
  * @internal
  */
 public function populateController(EnvironmentInterface $environment)
 {
     // Already populated, get out then.
     if ($environment->getController()) {
         return;
     }
     $definition = $environment->getDataDefinition();
     // If we encounter an extended definition, that one may override.
     if (!$definition->hasDefinition(ExtendedDca::NAME)) {
         return;
     }
     /** @var ExtendedDca $extendedDefinition */
     $extendedDefinition = $definition->getDefinition(ExtendedDca::NAME);
     $class = $extendedDefinition->getControllerClass();
     if (!$class) {
         return;
     }
     $controllerClass = new \ReflectionClass($class);
     /** @var ControllerInterface $controller */
     $controller = $controllerClass->newInstance();
     $controller->setEnvironment($environment);
     $environment->setController($controller);
 }
예제 #5
0
 /**
  * Retrieve the instance of a widget for the given property.
  *
  * @param string           $property    Name of the property for which the widget shall be retrieved.
  *
  * @param PropertyValueBag $inputValues The input values to use (optional).
  *
  * @throws DcGeneralInvalidArgumentException When an unknown property has been passed.
  *
  * @return \Widget
  */
 public function getWidget($property, PropertyValueBag $inputValues = null)
 {
     $environment = $this->getEnvironment();
     $defName = $environment->getDataDefinition()->getName();
     $propertyDefinitions = $environment->getDataDefinition()->getPropertiesDefinition();
     if (!$propertyDefinitions->hasProperty($property)) {
         throw new DcGeneralInvalidArgumentException('Property ' . $property . ' is not defined in propertyDefinitions.');
     }
     $event = new BuildWidgetEvent($environment, $this->model, $propertyDefinitions->getProperty($property));
     $environment->getEventPropagator()->propagate($event::NAME, $event, array($defName, $property));
     if ($event->getWidget()) {
         return $event->getWidget();
     }
     $propInfo = $propertyDefinitions->getProperty($property);
     $propExtra = $propInfo->getExtra();
     $varValue = $this->decodeValue($property, $this->model->getProperty($property));
     $xLabel = $this->getXLabel($propInfo);
     $strClass = $GLOBALS['BE_FFL'][$propInfo->getWidgetType()];
     if (!class_exists($strClass)) {
         return null;
     }
     // FIXME TEMPORARY WORKAROUND! To be fixed in the core: Controller::prepareForWidget(..).
     if (in_array($propExtra['rgxp'], array('date', 'time', 'datim')) && !$propExtra['mandatory'] && is_numeric($varValue) && $varValue == 0) {
         $varValue = '';
     }
     // OH: why not $required = $mandatory always? source: DataContainer 226.
     // OH: the whole prepareForWidget(..) thing is an only mess
     // Widgets should parse the configuration by themselves, depending on what they need.
     $propExtra['required'] = $varValue == '' && $propExtra['mandatory'];
     if ($inputValues) {
         $model = clone $this->model;
         $model->setId($this->model->getId());
         $this->environment->getController()->updateModelFromPropertyBag($model, $inputValues);
     } else {
         $model = $this->model;
     }
     $options = $propInfo->getOptions();
     $event = new GetPropertyOptionsEvent($environment, $model);
     $event->setPropertyName($property);
     $event->setOptions($options);
     $environment->getEventPropagator()->propagate($event::NAME, $event, $environment->getDataDefinition()->getName(), $property);
     if ($event->getOptions() !== $options) {
         $options = $event->getOptions();
     }
     $arrConfig = array('inputType' => $propInfo->getWidgetType(), 'label' => array($propInfo->getLabel(), $propInfo->getDescription()), 'options' => $options, 'eval' => $propExtra);
     if (isset($propExtra['reference'])) {
         $arrConfig['reference'] = $propExtra['reference'];
     }
     $event = new GetAttributesFromDcaEvent($arrConfig, $propInfo->getName(), $varValue, $property, $defName, new DcCompat($environment, $this->model, $property));
     $environment->getEventPropagator()->propagate(ContaoEvents::WIDGET_GET_ATTRIBUTES_FROM_DCA, $event, $environment->getDataDefinition()->getName(), $property);
     $arrPrepared = $event->getResult();
     // Bugfix CS: ajax subpalettes are really broken.
     // Therefore we reset to the default checkbox behaviour here and submit the entire form.
     // This way, the javascript needed by the widget (wizards) will be correctly evaluated.
     if ($arrConfig['inputType'] == 'checkbox' && is_array($GLOBALS['TL_DCA'][$defName]['subpalettes']) && in_array($property, array_keys($GLOBALS['TL_DCA'][$defName]['subpalettes'])) && $arrConfig['eval']['submitOnChange']) {
         $arrPrepared['onclick'] = $arrConfig['eval']['submitOnChange'] ? "Backend.autoSubmit('" . $defName . "')" : '';
     }
     $objWidget = new $strClass($arrPrepared);
     // OH: what is this? source: DataContainer 232.
     $objWidget->currentRecord = $this->model->getId();
     $objWidget->wizard .= $xLabel;
     $event = new ManipulateWidgetEvent($environment, $this->model, $propInfo, $objWidget);
     $environment->getEventPropagator()->propagate($event::NAME, $event, array($defName, $property));
     return $objWidget;
 }
예제 #6
0
 /**
  * Create a new instance.
  *
  * @param EnvironmentInterface $environment The environment.
  */
 public function __construct(EnvironmentInterface $environment)
 {
     $this->environment = $environment;
     $this->translator = $environment->getTranslator();
     $this->eventDispatcher = $environment->getEventDispatcher();
     $this->clipboardItems = $this->calculateClipboardItems();
     $dataDefinition = $environment->getDataDefinition();
     $basicDefinition = $dataDefinition->getBasicDefinition();
     $this->isHierarchical = $basicDefinition::MODE_HIERARCHICAL === $basicDefinition->getMode();
     $this->commands = $dataDefinition->getDefinition(Contao2BackendViewDefinitionInterface::NAME)->getModelCommands();
     $controller = $environment->getController();
     $this->clipboardModels = $controller->getModelsFromClipboardItems($this->clipboardItems);
     $this->circularModelIds = array();
     // We must only check for CUT operation here as pasting copy'ed parents is allowed.
     $cutItems = array_filter($this->clipboardItems, function ($item) {
         /** @var ItemInterface $item */
         return $item->getAction() === $item::CUT;
     });
     $cutModels = $controller->getModelsFromClipboardItems($cutItems);
     foreach ($cutModels as $model) {
         $providerName = $model->getProviderName();
         foreach ($controller->assembleAllChildrenFrom($model) as $subModel) {
             $this->circularModelIds[] = ModelId::fromValues($providerName, $subModel)->getSerialized();
         }
     }
     if (null !== ViewHelpers::getManualSortingProperty($environment)) {
         $this->hasPasteButtons = !empty($this->clipboardItems);
         $this->hasPasteNewButton = empty($this->clipboardItems) && !$this->isHierarchical;
     } else {
         $this->hasPasteButtons = false;
         $this->hasPasteNewButton = false;
     }
 }
예제 #7
0
 /**
  * Check if the language has been switched.
  *
  * If so, the value in the session will be updated and the page reloaded.
  *
  * @param EnvironmentInterface $environment The environment.
  *
  * @return void
  */
 private function checkLanguageSubmit($environment)
 {
     $sessionStorage = $environment->getSessionStorage();
     $inputProvider = $environment->getInputProvider();
     if ($inputProvider->getValue('FORM_SUBMIT') !== 'language_switch') {
         return;
     }
     $modelId = $inputProvider->getParameter('id') && $inputProvider->getParameter('id') ? IdSerializer::fromSerialized($inputProvider->getParameter('id'))->getId() : null;
     $languages = $environment->getController()->getSupportedLanguages($modelId);
     $providerName = $environment->getDataDefinition()->getName();
     // Get/Check the new language.
     if ($inputProvider->hasValue('language') && array_key_exists($inputProvider->getValue('language'), $languages)) {
         $session['ml_support'][$providerName][$modelId] = $inputProvider->getValue('language');
         $sessionStorage->set('dc_general', $session);
     }
     $environment->getEventDispatcher()->dispatch(ContaoEvents::CONTROLLER_RELOAD, new ReloadEvent());
 }
예제 #8
0
 /**
  * Create an empty model using the default values from the definition.
  *
  * @return ModelInterface
  *
  * @deprecated Use Controller::createEmptyModelWithDefaults() instead!
  */
 protected function createEmptyModelWithDefaults()
 {
     return $this->environment->getController()->createEmptyModelWithDefaults();
 }