/**
  * Handle the persisting of the currently loaded model.
  *
  * @return void
  */
 private function doPersist()
 {
     if (!$this->model->getMeta(ModelInterface::IS_CHANGED)) {
         return;
     }
     $this->handlePrePersist();
     // FIXME: manual sorting property handling is not enabled here as it originates from the backend defininiton.
     // Save the model.
     $dataProvider = $this->environment->getDataProvider($this->model->getProviderName());
     $dataProvider->save($this->model);
     $this->handlePostPersist();
     $this->storeVersion($this->model);
 }
Ejemplo n.º 2
0
 /**
  * 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.
  *
  * @SuppressWarnings(PHPMD.LongVariable)
  */
 public function execute()
 {
     $environment = $this->getEnvironment();
     $definition = $this->getDataDefinition();
     $dataProvider = $environment->getDataProvider($this->model->getProviderName());
     $dataProviderDefinition = $definition->getDataProviderDefinition();
     $dataProviderInformation = $dataProviderDefinition->getInformation($this->model->getProviderName());
     $inputProvider = $environment->getInputProvider();
     $palettesDefinition = $definition->getPalettesDefinition();
     $blnSubmitted = $inputProvider->getValue('FORM_SUBMIT') === $definition->getName();
     $blnIsAutoSubmit = $inputProvider->getValue('SUBMIT_TYPE') === 'auto';
     $widgetManager = new ContaoWidgetManager($environment, $this->model);
     $this->checkEditable($this->model);
     $this->checkCreatable($this->model);
     $environment->getEventDispatcher()->dispatch(PreEditModelEvent::NAME, new PreEditModelEvent($environment, $this->model));
     $environment->getEventDispatcher()->dispatch(DcGeneralEvents::ENFORCE_MODEL_RELATIONSHIP, new EnforceModelRelationshipEvent($this->getEnvironment(), $this->model));
     // Pass 1: Get the palette for the values stored in the model.
     $palette = $palettesDefinition->findPalette($this->model);
     $propertyValues = $this->processInput($widgetManager);
     if ($blnSubmitted && $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->getEnvironment()->getController()->updateModelFromPropertyBag($this->model, $propertyValues);
     }
     $fieldSets = $this->buildFieldSet($widgetManager, $palette, $propertyValues);
     if (!$blnIsAutoSubmit && $blnSubmitted && empty($this->errors)) {
         if ($this->doPersist()) {
             $this->handleSubmit($this->model);
         }
     }
     $objTemplate = new ContaoBackendViewTemplate('dcbe_general_edit');
     $objTemplate->setData(array('fieldsets' => $fieldSets, 'versions' => $dataProviderInformation->isVersioningEnabled() ? $dataProvider->getVersions($this->model->getId()) : null, 'subHeadline' => $this->getHeadline(), 'table' => $definition->getName(), 'enctype' => 'multipart/form-data', 'error' => $this->errors, 'editButtons' => $this->getEditButtons(), 'noReload' => (bool) $this->errors, 'breadcrumb' => $this->breadcrumb));
     if (in_array('ContaoCommunityAlliance\\DcGeneral\\Data\\MultiLanguageDataProviderInterface', class_implements($environment->getDataProvider($this->model->getProviderName())))) {
         /** @var MultiLanguageDataProviderInterface $dataProvider */
         $langsNative = array();
         require TL_ROOT . '/system/config/languages.php';
         $objTemplate->set('languages', $environment->getController()->getSupportedLanguages($this->model->getId()))->set('language', $dataProvider->getCurrentLanguage())->set('languageHeadline', $langsNative[$dataProvider->getCurrentLanguage()]);
     } else {
         $objTemplate->set('languages', null)->set('languageHeadline', '');
     }
     return $objTemplate->parse();
 }
 /**
  * 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();
 }
 /**
  * Retrieve children of a given model.
  *
  * @param ModelInterface $model           The model for which the children shall be retrieved.
  *
  * @param string|null    $sortingProperty The property name to use for sorting.
  *
  * @return CollectionInterface
  *
  * @throws DcGeneralRuntimeException When not in hierarchical mode.
  */
 protected function assembleChildrenFor(ModelInterface $model, $sortingProperty = null)
 {
     $environment = $this->getEnvironment();
     $definition = $environment->getDataDefinition();
     $provider = $environment->getDataProvider($model->getProviderName());
     $config = $environment->getBaseConfigRegistry()->getBaseConfig();
     $relationships = $definition->getModelRelationshipDefinition();
     if ($definition->getBasicDefinition()->getMode() !== BasicDefinitionInterface::MODE_HIERARCHICAL) {
         throw new DcGeneralRuntimeException('Unable to retrieve children in non hierarchical mode.');
     }
     $condition = $relationships->getChildCondition($model->getProviderName(), $model->getProviderName());
     $config->setFilter($condition->getFilter($model));
     if ($sortingProperty) {
         $config->setSorting(array((string) $sortingProperty => 'ASC'));
     }
     $siblings = $provider->fetchAll($config);
     return $siblings;
 }
Ejemplo n.º 5
0
 /**
  * Determine if the passed model is expanded.
  *
  * @param ModelInterface $model The model to check.
  *
  * @return bool
  */
 protected function isModelOpen($model)
 {
     $openModels = $this->getOpenElements();
     if (isset($openModels['all']) && $openModels['all'] == 1) {
         return true;
     }
     if (isset($openModels[$model->getProviderName()][$model->getID()]) && $openModels[$model->getProviderName()][$model->getID()]) {
         return true;
     }
     return false;
 }
Ejemplo n.º 6
0
 /**
  * Add the parent filtering to the given data config if any defined.
  *
  * @param ConfigInterface $config      The data config.
  *
  * @param ModelInterface  $parentModel The parent model.
  *
  * @return void
  *
  * @throws \RuntimeException When the parent provider does not match.
  */
 private function addParentFilter(ConfigInterface $config, ModelInterface $parentModel)
 {
     $environment = $this->getEnvironment();
     $definition = $environment->getDataDefinition();
     $basicDefinition = $definition->getBasicDefinition();
     $relationships = $definition->getModelRelationshipDefinition();
     if ($basicDefinition->getParentDataProvider() !== $parentModel->getProviderName()) {
         throw new \RuntimeException(sprintf('Parent provider mismatch: %s vs. %s', $basicDefinition->getParentDataProvider(), $parentModel->getProviderName()));
     }
     if (!$basicDefinition->getParentDataProvider()) {
         return;
     }
     // Apply parent filtering, do this only for root elements.
     if ($parentCondition = $relationships->getChildCondition($basicDefinition->getParentDataProvider(), $basicDefinition->getRootDataProvider())) {
         $baseFilter = $config->getFilter();
         $filter = $parentCondition->getFilter($parentModel);
         if ($baseFilter) {
             $filter = array_merge($baseFilter, $filter);
         }
         $config->setFilter($filter);
     }
 }
Ejemplo n.º 7
0
 /**
  * Determine the toggle state of a toggle command.
  *
  * @param ToggleCommandInterface $command The toggle command.
  *
  * @param ModelInterface         $model   The model in scope.
  *
  * @return bool
  */
 private function isTogglerInActiveState($command, $model)
 {
     $dataProvider = $this->environment->getDataProvider($model->getProviderName());
     if ($command instanceof TranslatedToggleCommandInterface && $dataProvider instanceof MultiLanguageDataProviderInterface) {
         $language = $dataProvider->getCurrentLanguage();
         $dataProvider->setCurrentLanguage($command->getLanguage());
         $propModel = $dataProvider->fetch($dataProvider->getEmptyConfig()->setId($model->getId())->setFields($command->getToggleProperty()));
         $dataProvider->setCurrentLanguage($language);
     } else {
         $propModel = $model;
     }
     if ($command->isInverse()) {
         return !$propModel->getProperty($command->getToggleProperty());
     }
     return (bool) $propModel->getProperty($command->getToggleProperty());
 }
Ejemplo n.º 8
0
 /**
  * Retrieve the MetaModel the given model is attached to.
  *
  * @param ModelInterface $model The input screen model for which to retrieve the MetaModel.
  *
  * @return IMetaModel
  *
  * @throws DcGeneralInvalidArgumentException When an invalid model has been passed or the model does not have an id.
  */
 protected function getMetaModelFromModel(ModelInterface $model)
 {
     if (!($model->getProviderName() == 'tl_metamodel_dcasetting' && $model->getProperty('pid'))) {
         throw new DcGeneralInvalidArgumentException(sprintf('Model must originate from tl_metamodel_dcasetting and be saved, this one originates from %s and ' . 'has pid %s', $model->getProviderName(), $model->getProperty('pid')));
     }
     $metaModelId = $this->getDatabase()->prepare('SELECT pid FROM tl_metamodel_dca WHERE id=?')->execute($model->getProperty('pid'));
     return $this->getMetaModelById($metaModelId->pid);
 }
Ejemplo n.º 9
0
 /**
  * Get the headline for the template.
  *
  * @param ModelInterface $model The model.
  *
  * @return string
  */
 protected function getHeadline($model)
 {
     $translator = $this->getEnvironment()->getTranslator();
     $headline = $translator->translate('MSC.showRecord', $model->getProviderName(), array('ID ' . $model->getId()));
     if ($headline !== 'MSC.showRecord') {
         return $headline;
     }
     return $translator->translate('MSC.showRecord', null, array('ID ' . $model->getId()));
 }
Ejemplo n.º 10
0
 /**
  * Create an instance from a model.
  *
  * @param ModelInterface $model The model.
  *
  * @return IdSerializer
  */
 public static function fromModel(ModelInterface $model)
 {
     return self::fromValues($model->getProviderName(), $model->getId());
 }
Ejemplo n.º 11
0
 /**
  * Retrieve the formatter for the given model.
  *
  * @param ModelInterface $model    The model for which the formatter shall be retrieved.
  * @param bool           $treeMode Flag if we are running in tree mode or not.
  *
  * @return ModelFormatterConfigInterface
  */
 protected function getFormatter(ModelInterface $model, $treeMode)
 {
     /** @var ListingConfigInterface $listing */
     $definition = $this->getEnvironment()->getDataDefinition();
     $listing = $definition->getDefinition(Contao2BackendViewDefinitionInterface::NAME)->getListingConfig();
     if ($listing->hasLabelFormatter($model->getProviderName())) {
         return $listing->getLabelFormatter($model->getProviderName());
     }
     // If not in tree mode and custom label has been defined, use it.
     if (!$treeMode && $this->itemLabel) {
         $label = $this->itemLabel;
         $formatter = new DefaultModelFormatterConfig();
         $formatter->setPropertyNames($label['fields']);
         $formatter->setFormat($label['format']);
         $formatter->setMaxLength($label['maxCharacters']);
         return $formatter;
     }
     // If no label has been defined, use some default.
     $properties = array();
     foreach ($definition->getPropertiesDefinition()->getProperties() as $property) {
         if ($property->getWidgetType() == 'text') {
             $properties[] = $property->getName();
         }
     }
     $formatter = new DefaultModelFormatterConfig();
     $formatter->setPropertyNames($properties);
     $formatter->setFormat(str_repeat('%s ', count($properties)));
     return $formatter;
 }
Ejemplo n.º 12
0
 /**
  * Render a command button.
  *
  * @param CommandInterface $objCommand           The command to render the button for.
  *
  * @param ModelInterface   $objModel             The model to which the command shall get applied.
  *
  * @param bool             $blnCircularReference Determinator if there exists a circular reference between the model
  *                                               and the model(s) contained in the clipboard.
  *
  * @param array            $arrChildRecordIds    List of the ids of all child models of the current model.
  *
  * @param ModelInterface   $previous             The previous model in the collection.
  *
  * @param ModelInterface   $next                 The next model in the collection.
  *
  * @return string
  */
 protected function buildCommand($objCommand, $objModel, $blnCircularReference, $arrChildRecordIds, $previous, $next)
 {
     $environment = $this->getEnvironment();
     $inputProvider = $environment->getInputProvider();
     $dispatcher = $environment->getEventDispatcher();
     $dataDefinitionName = $environment->getDataDefinition()->getName();
     $commandName = $objCommand->getName();
     $parameters = (array) $objCommand->getParameters();
     $extra = (array) $objCommand->getExtra();
     $extraAttributes = !empty($extra['attributes']) ? $extra['attributes'] : null;
     $attributes = '';
     // Set basic information.
     $opLabel = $objCommand->getLabel();
     if (strlen($opLabel)) {
         $label = $opLabel;
     } else {
         $label = $commandName;
     }
     $label = $this->translate($label, $dataDefinitionName);
     if (is_array($label)) {
         $label = $label[0];
     }
     $opDesc = $this->translate($objCommand->getDescription(), $dataDefinitionName);
     if (strlen($opDesc)) {
         $title = sprintf($opDesc, $objModel->getID());
     } else {
         $title = sprintf('%s id %s', $label, $objModel->getID());
     }
     // Toggle has to trigger the javascript.
     if ($objCommand instanceof ToggleCommandInterface) {
         $parameters['act'] = $commandName;
         $icon = $extra['icon'];
         $iconDisabled = isset($extra['icon_disabled']) ? $extra['icon_disabled'] : 'invisible.gif';
         $attributes = sprintf('onclick="Backend.getScrollOffset(); return BackendGeneral.toggleVisibility(this, \'%s\', \'%s\');"', $icon, $iconDisabled);
         $dataProvider = $this->getEnvironment()->getDataProvider($objModel->getProviderName());
         if ($objCommand instanceof TranslatedToggleCommandInterface && $dataProvider instanceof MultiLanguageDataProviderInterface) {
             $language = $dataProvider->getCurrentLanguage();
             $dataProvider->setCurrentLanguage($objCommand->getLanguage());
             $propModel = $dataProvider->fetch($dataProvider->getEmptyConfig()->setId($objModel->getId())->setFields($objCommand->getToggleProperty()));
             $dataProvider->setCurrentLanguage($language);
         } else {
             $propModel = $objModel;
         }
         $state = $objCommand->isInverse() ? !$propModel->getProperty($objCommand->getToggleProperty()) : $propModel->getProperty($objCommand->getToggleProperty());
         if (!$state) {
             $extra['icon'] = $iconDisabled ?: 'invisible.gif';
         }
     }
     if ($extraAttributes) {
         $attributes .= ltrim(sprintf($extraAttributes, $objModel->getID()));
     }
     $serializedModelId = ModelId::fromModel($objModel)->getSerialized();
     // Cut needs some special information.
     if ($objCommand instanceof CutCommandInterface) {
         $parameters = array();
         $parameters['act'] = $commandName;
         // If we have a pid add it, used for mode 4 and all parent -> current views.
         if ($inputProvider->hasParameter('pid')) {
             $parameters['pid'] = $inputProvider->getParameter('pid');
         }
         // Source is the id of the element which should move.
         $parameters['source'] = $serializedModelId;
     } elseif ($objCommand instanceof CopyCommandInterface) {
         // The copy operation.
         $parameters = array();
         $parameters['act'] = $commandName;
         // If we have a pid add it, used for mode 4 and all parent -> current views.
         if ($inputProvider->hasParameter('pid')) {
             $parameters['pid'] = $inputProvider->getParameter('pid');
         }
         // Source is the id of the element which should move.
         $parameters['source'] = $serializedModelId;
     } else {
         // TODO: Shall we interface this option?
         $idParam = isset($extra['idparam']) ? $extra['idparam'] : null;
         if ($idParam) {
             $parameters[$idParam] = $serializedModelId;
         } else {
             $parameters['id'] = $serializedModelId;
         }
     }
     $strHref = '';
     foreach ($parameters as $key => $value) {
         $strHref .= sprintf('&%s=%s', $key, $value);
     }
     /** @var AddToUrlEvent $event */
     $event = $dispatcher->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, new AddToUrlEvent($strHref));
     $strHref = $event->getUrl();
     $buttonEvent = new GetOperationButtonEvent($this->getEnvironment());
     $buttonEvent->setCommand($objCommand)->setObjModel($objModel)->setAttributes($attributes)->setLabel($label)->setTitle($title)->setHref($strHref)->setChildRecordIds($arrChildRecordIds)->setCircularReference($blnCircularReference)->setPrevious($previous)->setNext($next)->setDisabled($objCommand->isDisabled());
     $dispatcher->dispatch(GetOperationButtonEvent::NAME, $buttonEvent);
     // If the event created a button, use it.
     if ($buttonEvent->getHtml() !== null) {
         return trim($buttonEvent->getHtml());
     }
     $icon = $extra['icon'];
     if ($buttonEvent->isDisabled()) {
         /** @var GenerateHtmlEvent $event */
         $event = $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, new GenerateHtmlEvent(substr_replace($icon, '_1', strrpos($icon, '.'), 0), $buttonEvent->getLabel()));
         return $event->getHtml();
     }
     /** @var GenerateHtmlEvent $event */
     $event = $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, new GenerateHtmlEvent($icon, $buttonEvent->getLabel()));
     return sprintf(' <a href="%s" title="%s" %s>%s</a>', $buttonEvent->getHref(), specialchars($buttonEvent->getTitle()), $buttonEvent->getAttributes(), $event->getHtml());
 }
Ejemplo n.º 13
0
 /**
  * Format a model accordingly to the current configuration.
  *
  * Returns either an array when in tree mode or a string in (parented) list mode.
  *
  * @param ModelInterface $model The model that shall be formatted.
  *
  * @return array
  */
 public function formatModel(ModelInterface $model)
 {
     $listing = $this->getViewSection()->getListingConfig();
     $properties = $this->getDataDefinition()->getPropertiesDefinition();
     $formatter = $listing->getLabelFormatter($model->getProviderName());
     $sorting = array_keys((array) $listing->getDefaultSortingFields());
     $firstSorting = reset($sorting);
     $args = array();
     foreach ($formatter->getPropertyNames() as $propertyName) {
         if ($properties->hasProperty($propertyName)) {
             $property = $properties->getProperty($propertyName);
             $args[$propertyName] = (string) $this->getReadableFieldValue($property, $model, $model->getProperty($propertyName));
         } else {
             $args[$propertyName] = '-';
         }
     }
     $event = new ModelToLabelEvent($this->getEnvironment(), $model);
     $event->setArgs($args)->setLabel($formatter->getFormat())->setFormatter($formatter);
     $this->getEnvironment()->getEventPropagator()->propagate($event::NAME, $event, array($this->getEnvironment()->getDataDefinition()->getName()));
     $arrLabel = array();
     // Add columns.
     if ($listing->getShowColumns()) {
         $fields = $formatter->getPropertyNames();
         $args = $event->getArgs();
         if (!is_array($args)) {
             $arrLabel[] = array('colspan' => count($fields), 'class' => 'tl_file_list col_1', 'content' => $args);
         } else {
             foreach ($fields as $j => $propertyName) {
                 $arrLabel[] = array('colspan' => 1, 'class' => 'tl_file_list col_' . $j . ($propertyName == $firstSorting ? ' ordered_by' : ''), 'content' => $args[$propertyName] != '' ? $args[$propertyName] : '-');
             }
         }
     } else {
         if (!is_array($event->getArgs())) {
             $string = $event->getArgs();
         } else {
             $string = vsprintf($event->getLabel(), $event->getArgs());
         }
         if ($formatter->getMaxLength() !== null && strlen($string) > $formatter->getMaxLength()) {
             $string = substr($string, 0, $formatter->getMaxLength());
         }
         $arrLabel[] = array('colspan' => null, 'class' => 'tl_file_list', 'content' => $string);
     }
     return $arrLabel;
 }
Ejemplo n.º 14
0
 /**
  * Render a given model.
  *
  * @param ModelInterface $objModel    The model to render.
  *
  * @param string         $strToggleID The id of the toggler.
  *
  * @return string
  */
 protected function parseModel($objModel, $strToggleID)
 {
     $event = new FormatModelLabelEvent($this->environment, $objModel);
     $this->environment->getEventDispatcher()->dispatch(DcGeneralEvents::FORMAT_MODEL_LABEL, $event);
     $objModel->setMeta($objModel::LABEL_VALUE, $event->getLabel());
     $objTemplate = $this->getTemplate('dcbe_general_treeview_entry');
     if ($objModel->getMeta($objModel::SHOW_CHILDREN)) {
         $toggleTitle = $this->getEnvironment()->getTranslator()->translate('collapseNode', 'MSC');
     } else {
         $toggleTitle = $this->getEnvironment()->getTranslator()->translate('expandNode', 'MSC');
     }
     $toggleScript = sprintf('Backend.getScrollOffset(); return BackendGeneral.loadSubTree(this, ' . '{\'toggler\':\'%s\', \'id\':\'%s\', \'providerName\':\'%s\', \'level\':\'%s\', \'mode\':\'%s\'});', $strToggleID, $objModel->getId(), $objModel->getProviderName(), $objModel->getMeta('dc_gen_tv_level'), 6);
     $toggleUrlEvent = new AddToUrlEvent('ptg=' . $objModel->getId() . '&amp;provider=' . $objModel->getProviderName());
     $this->getEnvironment()->getEventDispatcher()->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, $toggleUrlEvent);
     $this->addToTemplate('environment', $this->getEnvironment(), $objTemplate)->addToTemplate('objModel', $objModel, $objTemplate)->addToTemplate('select', $this->isSelectModeActive(), $objTemplate)->addToTemplate('intMode', 6, $objTemplate)->addToTemplate('strToggleID', $strToggleID, $objTemplate)->addToTemplate('toggleUrl', $toggleUrlEvent->getUrl(), $objTemplate)->addToTemplate('toggleTitle', $toggleTitle, $objTemplate)->addToTemplate('toggleScript', $toggleScript, $objTemplate);
     return $objTemplate->parse();
 }
Ejemplo n.º 15
0
 /**
  * Determine if the passed model is expanded.
  *
  * @param ModelInterface $model The model to check.
  *
  * @return bool
  */
 protected function isModelOpen($model)
 {
     return $this->getTreeNodeStates()->isModelOpen($model->getProviderName(), $model->getID());
 }
Ejemplo n.º 16
0
 /**
  * Copy each children.
  *
  * @param ModelIdInterface     $modelId     The model id.
  * @param ModelInterface       $copiedModel The copied model.
  * @param EnvironmentInterface $environment The environment.
  *
  * @return void
  *
  * @SuppressWarnings(PHPMD.LongVariableName)
  */
 protected function copyEachChilds(ModelIdInterface $modelId, ModelInterface $copiedModel, EnvironmentInterface $environment)
 {
     $childDataProviderName = $environment->getInputProvider()->getParameter('ctable');
     $dataProvider = $environment->getDataProvider();
     $childDataProvider = $environment->getDataProvider($childDataProviderName);
     $modelRelationship = $environment->getParentDataDefinition()->getModelRelationshipDefinition();
     $childCondition = $modelRelationship->getChildCondition($copiedModel->getProviderName(), $childDataProviderName);
     if (!$childCondition) {
         return;
     }
     $parentModel = $dataProvider->fetch($dataProvider->getEmptyConfig()->setId($modelId->getId()));
     $parentFilters = $childCondition->getFilter($parentModel);
     $copiedFilters = $childCondition->getFilter($copiedModel);
     $filter = array();
     // Todo can many filter has operation equal
     foreach ($parentFilters as $index => $parentFilter) {
         if ($parentFilter['operation'] !== '=') {
             continue;
         }
         $filter = array('parent' => $parentFilter, 'copied' => $copiedFilters[$index]);
     }
     $childModels = $childDataProvider->fetchAll($childDataProvider->getEmptyConfig()->setFilter(array($filter['parent'])));
     if ($childModels->count() < 1) {
         return;
     }
     foreach ($childModels->getModelIds() as $index => $modelId) {
         $childModel = $childModels->get($index);
         $copyModelId = ModelId::fromModel($childModel);
         $copiedChildModel = null;
         if ($environment->getDataDefinition()->getName() !== $copyModelId->getDataProviderName()) {
             $copiedChildModel = $this->copyParent($copyModelId, $environment);
         }
         if ($environment->getDataDefinition()->getName() === $copyModelId->getDataProviderName() && !$copiedChildModel) {
             $copiedChildModel = $this->copyHandler($copyModelId, $environment);
         }
         $copiedChildModel->setProperty($filter['copied']['property'], $filter['copied']['value']);
         $childDataProvider->save($copiedChildModel);
     }
 }