/**
  * Save a model to the database.
  *
  * In general, this method fetches the solely property "rows" from the model and updates the local table against
  * these contents.
  *
  * The parent id (id of the model) will get checked and reflected also for new items.
  *
  * When rows with duplicate ids are encountered (like from MCW for example), the dupes are inserted as new rows.
  *
  * @param ModelInterface $objItem   The model to save.
  *
  * @param bool           $recursive Ignored as not relevant in this data provider.
  *
  * @return ModelInterface The passed Model.
  *
  * @throws DcGeneralException When the passed model does not contain a property named "rows", an Exception is
  *                            thrown.
  *
  * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  */
 public function save(ModelInterface $objItem, $recursive = false)
 {
     $arrData = $objItem->getProperty('rows');
     if (!($objItem->getID() && $arrData)) {
         throw new DcGeneralException('invalid input data in model.', 1);
     }
     $arrKeep = array();
     foreach ($arrData as $arrRow) {
         $arrSQL = $arrRow;
         // Update all.
         $intId = intval($arrRow['id']);
         // Work around the fact that multicolumnwizard does not clear any hidden fields when copying a dataset.
         // therefore we do consider any dupe as new dataset and save it accordingly.
         if (in_array($intId, $arrKeep)) {
             $intId = 0;
             unset($arrSQL['id']);
         }
         if ($intId > 0) {
             $this->objDatabase->prepare(sprintf('UPDATE %s %%s WHERE id=? AND %s=?', $this->strSource, $this->strGroupCol))->set($arrSQL)->execute($intId, $objItem->getId());
             $arrKeep[] = $intId;
         } else {
             // Force group col value.
             $arrSQL[$this->strGroupCol] = $objItem->getId();
             $arrKeep[] = $this->objDatabase->prepare(sprintf('INSERT INTO %s %%s', $this->strSource))->set($arrSQL)->execute()->insertId;
         }
     }
     // House keeping, kill the rest.
     $this->objDatabase->prepare(sprintf('DELETE FROM  %s WHERE %s=? AND id NOT IN (%s)', $this->strSource, $this->strGroupCol, implode(',', $arrKeep)))->execute($objItem->getId());
     return $objItem;
 }
示例#2
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;
 }
示例#3
0
 /**
  * Render a command button.
  *
  * @param CommandInterface $command             The command to render the button for.
  *
  * @param ModelInterface   $model               The model to which the command shall get applied.
  *
  * @param ModelInterface   $previous            The previous model in the collection.
  *
  * @param ModelInterface   $next                The next model in the collection.
  *
  * @param bool             $isCircularReference Determinator if there exists a circular reference between the model
  *                                              and the model(s) contained in the clipboard.
  *
  * @param string[]         $childIds            The ids of all child models.
  *
  * @return string
  */
 private function buildCommand($command, $model, $previous, $next, $isCircularReference, $childIds)
 {
     $extra = (array) $command->getExtra();
     $attributes = '';
     if (!empty($extra['attributes'])) {
         $attributes .= sprintf($extra['attributes'], $model->getID());
     }
     $label = $this->getCommandLabel($command);
     $title = sprintf($this->translate($command->getDescription()), $model->getID());
     $icon = $extra['icon'];
     if ($command instanceof ToggleCommandInterface) {
         $iconDisabled = isset($extra['icon_disabled']) ? $extra['icon_disabled'] : 'invisible.gif';
         $attributes .= sprintf(' onclick="Backend.getScrollOffset(); return BackendGeneral.toggleVisibility(this, \'%s\', \'%s\');"', $icon, $iconDisabled);
         if (!$this->isTogglerInActiveState($command, $model)) {
             $icon = $iconDisabled;
         }
     }
     $href = $this->calculateHref($command, $model);
     $buttonEvent = new GetOperationButtonEvent($this->environment);
     $buttonEvent->setCommand($command)->setObjModel($model)->setAttributes($attributes)->setLabel($label)->setTitle($title)->setHref($href)->setChildRecordIds($childIds)->setCircularReference($isCircularReference)->setPrevious($previous)->setNext($next)->setDisabled($command->isDisabled());
     $this->eventDispatcher->dispatch(GetOperationButtonEvent::NAME, $buttonEvent);
     if (null !== ($html = $buttonEvent->getHtml())) {
         // If the event created a button, use it.
         return trim($html);
     }
     if ($buttonEvent->isDisabled()) {
         return $this->renderImageAsHtml(substr_replace($icon, '_1', strrpos($icon, '.'), 0), $buttonEvent->getLabel());
     }
     return sprintf(' <a href="%s" title="%s" %s>%s</a>', $buttonEvent->getHref(), specialchars($buttonEvent->getTitle()), ltrim($buttonEvent->getAttributes()), $this->renderImageAsHtml($icon, $buttonEvent->getLabel()));
 }
 /**
  * Save a new version of a row.
  *
  * @param ModelInterface $objModel    The model for which a new version shall be created.
  *
  * @param string         $strUsername The username to attach to the version as creator.
  *
  * @return void
  */
 public function saveVersion(ModelInterface $objModel, $strUsername)
 {
     $objCount = $this->objDatabase->prepare('SELECT count(*) as mycount FROM tl_version WHERE pid=? AND fromTable = ?')->execute($objModel->getID(), $this->strSource);
     $mixNewVersion = intval($objCount->mycount) + 1;
     $mixData = $objModel->getPropertiesAsArray();
     $mixData['id'] = $objModel->getID();
     $arrInsert = array();
     $arrInsert['pid'] = $objModel->getID();
     $arrInsert['tstamp'] = time();
     $arrInsert['version'] = $mixNewVersion;
     $arrInsert['fromTable'] = $this->strSource;
     $arrInsert['username'] = $strUsername;
     $arrInsert['data'] = serialize($mixData);
     $this->objDatabase->prepare('INSERT INTO tl_version %s')->set($arrInsert)->execute();
     $this->setVersionActive($objModel->getID(), $mixNewVersion);
 }
示例#5
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());
 }
示例#6
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());
 }