Overview

Namespaces

  • DcGeneral
    • Clipboard
    • Contao
      • Callback
      • Compatibility
      • DataDefinition
        • Definition
      • Dca
        • Builder
          • Legacy
        • Definition
        • Palette
        • Populator
      • Event
      • View
        • Contao2BackendView
          • Event
    • Controller
    • Data
    • DataDefinition
      • Builder
      • Definition
        • Properties
        • View
          • Panel
      • ModelRelationship
      • Palette
        • Builder
          • Event
        • Condition
          • Palette
          • Property
    • EnvironmentPopulator
    • Event
    • Exception
    • Factory
      • Event
    • Panel
    • View
      • Event

Classes

  • Ajax
  • Ajax2X
  • Ajax3X
  • DefaultController

Interfaces

  • ControllerInterface
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
   1: <?php
   2: /**
   3:  * PHP version 5
   4:  * @package    generalDriver
   5:  * @author     Christian Schiffler <c.schiffler@cyberspectrum.de>
   6:  * @author     Stefan Heimes <stefan_heimes@hotmail.com>
   7:  * @author     Tristan Lins <tristan.lins@bit3.de>
   8:  * @copyright  The MetaModels team.
   9:  * @license    LGPL.
  10:  * @filesource
  11:  */
  12: 
  13: namespace DcGeneral\Controller;
  14: 
  15: use DcGeneral\Contao\BackendBindings;
  16: use DcGeneral\Data\CollectionInterface;
  17: use DcGeneral\Data\ConfigInterface;
  18: use DcGeneral\Data\DataProviderInterface;
  19: use DcGeneral\Data\DCGE;
  20: use DcGeneral\Data\LanguageInformationInterface;
  21: use DcGeneral\Data\ModelInterface;
  22: use DcGeneral\Data\PropertyValueBagInterface;
  23: use DcGeneral\DataContainerInterface;
  24: use DcGeneral\DataDefinition\Definition\BasicDefinitionInterface;
  25: use DcGeneral\EnvironmentInterface;
  26: use DcGeneral\Exception\DcGeneralRuntimeException;
  27: 
  28: class DefaultController implements ControllerInterface
  29: {
  30:     /**
  31:      * Current DC General.
  32:      *
  33:      * @var DataContainerInterface
  34:      *
  35:      * @deprecated
  36:      */
  37:     protected $objDC = null;
  38: 
  39:     /**
  40:      * The attached environment.
  41:      *
  42:      * @var EnvironmentInterface
  43:      */
  44:     protected $environment;
  45: 
  46:     /**
  47:      * A list with all current IDs.
  48:      *
  49:      * @var array
  50:      */
  51:     protected $arrInsertIDs = array();
  52: 
  53:     /**
  54:      * Error message.
  55:      *
  56:      * @var string
  57:      */
  58:     protected $notImplMsg = "<div style='text-align:center; font-weight:bold; padding:40px;'>The function/view &quot;%s&quot; is not implemented.<br />Please <a target='_blank' style='text-decoration:underline' href='http://now.metamodel.me/en/sponsors/become-one#payment'>support us</a> to add this important feature!</div>";
  59: 
  60:     /**
  61:      * Field for the function sortCollection.
  62:      *
  63:      * @var string $arrColSort
  64:      */
  65:     protected $arrColSort;
  66: 
  67:     /**
  68:      * Throw an exception that an unknown method has been called.
  69:      *
  70:      * @param string $name      Method name.
  71:      *
  72:      * @param array  $arguments Method arguments.
  73:      *
  74:      * @return void
  75:      *
  76:      * @throws DcGeneralRuntimeException Always.
  77:      */
  78:     public function __call($name, $arguments)
  79:     {
  80:         throw new DcGeneralRuntimeException('Error Processing Request: ' . $name, 1);
  81:     }
  82: 
  83:     /**
  84:      * Get DC General.
  85:      *
  86:      * @return DataContainerInterface;
  87:      *
  88:      * @deprecated
  89:      */
  90:     public function getDC()
  91:     {
  92:         return $this->objDC;
  93:     }
  94: 
  95:     /**
  96:      * Set DC General.
  97:      *
  98:      * @param DataContainerInterface $objDC The DC.
  99:      *
 100:      * @return void
 101:      *
 102:      * @deprecated
 103:      */
 104:     public function setDC($objDC)
 105:     {
 106:         $this->objDC = $objDC;
 107:         $this->setEnvironment($objDC->getEnvironment());
 108:     }
 109: 
 110:     /**
 111:      * {@inheritDoc}
 112:      */
 113:     public function setEnvironment(EnvironmentInterface $environment)
 114:     {
 115:         $this->environment = $environment;
 116: 
 117:         return $this;
 118:     }
 119: 
 120:     /**
 121:      * {@inheritDoc}
 122:      */
 123:     public function getEnvironment()
 124:     {
 125:         return $this->environment;
 126:     }
 127: 
 128:     /**
 129:      * {@inheritDoc}
 130:      */
 131:     public function assembleAllChildrenFrom($objModel, $strDataProvider = '')
 132:     {
 133:         if ($strDataProvider == '')
 134:         {
 135:             $strDataProvider = $objModel->getProviderName();
 136:         }
 137: 
 138:         $arrIds = array();
 139: 
 140:         if ($strDataProvider == $objModel->getProviderName())
 141:         {
 142:             $arrIds = array($objModel->getId());
 143:         }
 144: 
 145:         // Check all data providers for children of the given element.
 146:         $conditions = $this
 147:             ->getEnvironment()
 148:             ->getDataDefinition()
 149:             ->getModelRelationshipDefinition()
 150:             ->getChildConditions($objModel->getProviderName());
 151:         foreach ($conditions as $objChildCondition)
 152:         {
 153:             $objDataProv = $this->getEnvironment()->getDataProvider($objChildCondition->getDestinationName());
 154:             $objConfig   = $objDataProv->getEmptyConfig();
 155:             $objConfig->setFilter($objChildCondition->getFilter($objModel));
 156: 
 157:             foreach ($objDataProv->fetchAll($objConfig) as $objChild)
 158:             {
 159:                 /** @var ModelInterface $objChild */
 160:                 if ($strDataProvider == $objChild->getProviderName())
 161:                 {
 162:                     $arrIds[] = $objChild->getId();
 163:                 }
 164: 
 165:                 $arrIds = array_merge($arrIds, $this->assembleAllChildrenFrom($objChild, $strDataProvider));
 166:             }
 167:         }
 168: 
 169:         return $arrIds;
 170:     }
 171: 
 172:     /**
 173:      * {@inheritDoc}
 174:      */
 175:     public function updateModelFromPropertyBag($model, $propertyValues)
 176:     {
 177:         $environment = $this->getEnvironment();
 178:         if (!$propertyValues)
 179:         {
 180:             return $this;
 181:         }
 182: 
 183:         // Callback to tell visitors that we have just updated the model.
 184:         // $environment->getCallbackHandler()->onModelBeforeUpdateCallback($model);
 185: 
 186:         foreach ($propertyValues as $property => $value)
 187:         {
 188:             try
 189:             {
 190:                 $model->setProperty($property, $value);
 191:                 $model->setMeta(DCGE::MODEL_IS_CHANGED, true);
 192:             }
 193:             catch (\Exception $exception)
 194:             {
 195:                 $propertyValues->markPropertyValueAsInvalid($property, $exception->getMessage());
 196:             }
 197:         }
 198: 
 199:         $basicDefinition = $environment->getDataDefinition()->getBasicDefinition();
 200: 
 201:         if (($basicDefinition->getMode() & (
 202:                 BasicDefinitionInterface::MODE_PARENTEDLIST
 203:                 | BasicDefinitionInterface::MODE_HIERARCHICAL))
 204:             // FIXME: dependency injection.
 205:             && (strlen(\Input::getInstance()->get('pid')) > 0)
 206:         )
 207:         {
 208:             $providerName       = $basicDefinition->getDataProvider();
 209:             $parentProviderName = $basicDefinition->getParentDataProvider();
 210:             $objParentDriver    = $environment->getDataProvider($parentProviderName);
 211:             $objParentModel     = $objParentDriver->fetch(
 212:                 $objParentDriver
 213:                     ->getEmptyConfig()
 214:                     ->setId(\Input::getInstance()->get('pid'))
 215:             );
 216: 
 217:             $relationship = $environment
 218:                 ->getDataDefinition()
 219:                 ->getModelRelationshipDefinition()
 220:                 ->getChildCondition($parentProviderName, $providerName);
 221: 
 222:             if ($relationship && $relationship->getSetters())
 223:             {
 224:                 $relationship->applyTo($objParentModel, $model);
 225:             }
 226:         }
 227: 
 228:         // Callback to tell visitors that we have just updated the model.
 229:         // $environment->getCallbackHandler()->onModelUpdateCallback($model);
 230: 
 231:         return $this;
 232:     }
 233: 
 234:     /**
 235:      * Add the filter for the item with the given id from the parent data provider to the given config.
 236:      *
 237:      * @param mixed           $idParent The id of the parent item.
 238:      *
 239:      * @param ConfigInterface $config   The config to add the filter to.
 240:      *
 241:      * @return \DcGeneral\Data\ConfigInterface
 242:      *
 243:      * @throws DcGeneralRuntimeException When the parent item is not found.
 244:      */
 245:     protected function addParentFilter($idParent, $config)
 246:     {
 247:         $environment        = $this->getEnvironment();
 248:         $definition         = $environment->getDataDefinition();
 249:         $providerName       = $definition->getBasicDefinition()->getDataProvider();
 250:         $parentProviderName = $definition->getBasicDefinition()->getParentDataProvider();
 251:         $parentProvider     = $environment->getDataProvider($parentProviderName);
 252: 
 253:         if ($parentProvider)
 254:         {
 255:             $objParent = $parentProvider->fetch($parentProvider->getEmptyConfig()->setId($idParent));
 256:             if (!$objParent)
 257:             {
 258:                 throw new DcGeneralRuntimeException('Parent item ' . $idParent . ' not found in ' . $parentProviderName);
 259:             }
 260: 
 261:             $condition = $definition->getModelRelationshipDefinition()->getChildCondition($parentProviderName, $providerName);
 262: 
 263:             if ($condition)
 264:             {
 265:                 $arrBaseFilter = $config->getFilter();
 266:                 $arrFilter     = $condition->getFilter($objParent);
 267: 
 268:                 if ($arrBaseFilter)
 269:                 {
 270:                     $arrFilter = array_merge($arrBaseFilter, $arrFilter);
 271:                 }
 272: 
 273:                 $config->setFilter(array(array(
 274:                     'operation' => 'AND',
 275:                     'children'    => $arrFilter,
 276:                 )));
 277:             }
 278:         }
 279: 
 280:         return $config;
 281:     }
 282: 
 283:     /**
 284:      * Return all supported languages from the default data data provider.
 285:      *
 286:      * @param mixed $mixID The id of the item for which to retrieve the valid languages.
 287:      *
 288:      * @return array
 289:      */
 290:     public function getSupportedLanguages($mixID)
 291:     {
 292:         $environment     = $this->getEnvironment();
 293:         $objDataProvider = $environment->getDataProvider();
 294: 
 295:         // Check if current data provider supports multi language.
 296:         if (in_array('DcGeneral\Data\MultiLanguageDataProviderInterface', class_implements($objDataProvider)))
 297:         {
 298:             /** @var \DcGeneral\Data\MultiLanguageDataProviderInterface $objDataProvider */
 299:             $objLanguagesSupported = $objDataProvider->getLanguages($mixID);
 300:         }
 301:         else
 302:         {
 303:             $objLanguagesSupported = null;
 304:         }
 305: 
 306:         // Check if we have some languages.
 307:         if ($objLanguagesSupported == null)
 308:         {
 309:             return array();
 310:         }
 311: 
 312:         // Make an array from the collection.
 313:         $arrLanguage = array();
 314:         $translator  = $environment->getTranslator();
 315:         foreach ($objLanguagesSupported as $value)
 316:         {
 317:             /** @var LanguageInformationInterface $value */
 318:             $arrLanguage[$value->getLocale()] = $translator->translate('LNG.' . $value->getLocale(), 'languages');
 319:         }
 320: 
 321:         return $arrLanguage;
 322:     }
 323: 
 324:     /**
 325:      * Cut and paste.
 326:      *
 327:      * <p>
 328:      * -= GET Parameter =-<br/>
 329:      * act      - Mode like cut | copy | and co <br/>
 330:      * <br/>
 331:      * after    - ID of target element to insert after <br/>
 332:      * into     - ID of parent element to insert into <br/>
 333:      * <br/>
 334:      * id       - Parent child ID used for redirect <br/>
 335:      * pid      - ID of the parent used in list mode 4,5 <br/>
 336:      * source   - ID of the element which should moved <br/>
 337:      * <br/>
 338:      * pdp      - Parent Data Provider real name <br/>
 339:      * cdp      - Current Data Provider real name <br/>
 340:      * <br/>
 341:      * -= Deprecated =-<br/>
 342:      * mode     - 1 Insert after | 2 Insert into (NEVER USED AGAIN - Deprecated) <br/>
 343:      * </p>
 344:      */
 345:     public function cut()
 346:     {
 347:         $this->checkIsWritable();
 348: 
 349:         $mixAfter  = \Input::getInstance()->get('after');
 350:         $mixInto   = \Input::getInstance()->get('into');
 351:         $intId     = \Input::getInstance()->get('id');
 352:         $mixPid    = \Input::getInstance()->get('pid');
 353:         $mixSource = \Input::getInstance()->get('source');
 354:         $strPDP    = \Input::getInstance()->get('pdp');
 355:         $strCDP    = \Input::getInstance()->get('cdp');
 356: 
 357:         // Deprecated
 358:         $intMode  = \Input::getInstance()->get('mode');
 359:         $mixChild = \Input::getInstance()->get('child');
 360: 
 361:         // Check basic vars
 362:         if (empty($mixSource) || ( is_null($mixAfter) && is_null($mixInto) ) || empty($strCDP))
 363:         {
 364:             BackendBindings::log('Missing parameter for cut in ' . $this->getDC()->getTable(), __CLASS__ . ' - ' . __FUNCTION__, TL_ERROR);
 365:             BackendBindings::redirect('contao/main.php?act=error');
 366:         }
 367: 
 368:         // Get current DataProvider
 369:         if (!empty($strCDP))
 370:         {
 371:             $objCurrentDataProvider = $this->getEnvironment()->getDataProvider($strCDP);
 372:         }
 373:         else
 374:         {
 375:             $objCurrentDataProvider = $this->getEnvironment()->getDataProvider();
 376:         }
 377: 
 378:         if ($objCurrentDataProvider == null)
 379:         {
 380:             throw new DcGeneralRuntimeException('Could not load current data provider in ' . __CLASS__ . ' - ' . __FUNCTION__);
 381:         }
 382: 
 383:         // Get parent DataProvider, if set
 384:         $objParentDataProvider = null;
 385:         if (!empty($strPDP))
 386:         {
 387:             $objParentDataProvider = $this->getEnvironment()->getDataProvider($strPDP);
 388: 
 389:             if ($objCurrentDataProvider == null)
 390:             {
 391:                 throw new DcGeneralRuntimeException('Could not load parent data provider ' . $strPDP . ' in ' . __CLASS__ . ' - ' . __FUNCTION__);
 392:             }
 393:         }
 394: 
 395:         // Load the source model
 396:         $objSrcModel = $objCurrentDataProvider->fetch($objCurrentDataProvider->getEmptyConfig()->setId($mixSource));
 397: 
 398:         // Check mode
 399:         switch ($this->getDC()->arrDCA['list']['sorting']['mode'])
 400:         {
 401:             case 0:
 402:                 $this->getNewPosition($objCurrentDataProvider, $objParentDataProvider, $objSrcModel, ($mixAfter == DCGE::INSERT_AFTER_START) ? 0 : $mixAfter, null, 'cut');
 403:                 break;
 404:             case 1:
 405:             case 2:
 406:             case 3:
 407:             case 4:
 408:                 $this->getNewPosition($objCurrentDataProvider, $objParentDataProvider, $objSrcModel, $mixAfter, $mixInto, 'cut');
 409:                 break;
 410: 
 411:             case 5:
 412:                 switch ($intMode)
 413:                 {
 414:                     case 1: // insert after
 415:                         // we want a new item in $strCDP having an optional parent in $strPDP (with pid item $mixPid) just after $mixAfter (in child tree conditions).
 416:                         // sadly, with our complex rules an getParent() is IMPOSSIBLE (or in other words way too costly as we would be forced to iterate through all items and check if this item would end up in their child collection).
 417:                         // therefore we get the child we want to be next of and set all fields to the same values as in the sibling to end up in the same parent.
 418:                         $objOtherChild = $objCurrentDataProvider->fetch($objCurrentDataProvider->getEmptyConfig()->setId($mixAfter));
 419:                         $this->getDC()->setSameParent($objSrcModel, $objOtherChild, $strCDP);
 420: 
 421:                         // Update sorting.
 422:                         $this->getNewPosition($objCurrentDataProvider, $objParentDataProvider, $objSrcModel, $mixAfter, $mixInto, 'cut');
 423:                         break;
 424: 
 425:                     case 2: // insert into
 426:                         // we want a new item in $strCDP having an optional parent in $strPDP (with pid item $mixPid) just as child of $mixAfter (in child tree conditions).
 427:                         // now check if we want to be inserted as root in our own condition - this means either no "after".
 428:                         if (($mixAfter == 0))
 429:                         {
 430:                             $this->setRoot($objSrcModel, 'self');
 431:                         }
 432:                         else
 433:                         {
 434:                             // enforce the child condition from our parent.
 435:                             $objMyParent = $objCurrentDataProvider->fetch($objCurrentDataProvider->getEmptyConfig()->setId($mixAfter));
 436:                             $this->setParent($objSrcModel, $objMyParent, 'self');
 437:                         }
 438: 
 439:                         // Update sorting.
 440:                         $this->getNewPosition($objCurrentDataProvider, $objParentDataProvider, $objSrcModel, $mixAfter, $mixInto, 'cut');
 441:                         break;
 442:                     default:
 443:                         BackendBindings::log('Unknown create mode for copy in ' . $this->getDC()->getTable(), 'DC_General - DefaultController - copy()', TL_ERROR);
 444:                         BackendBindings::redirect('contao/main.php?act=error');
 445:                         break;
 446:                 }
 447:                 break;
 448: 
 449:             default:
 450:                 return vsprintf($this->notImplMsg, 'cut - Mode ' . $this->getDC()->arrDCA['list']['sorting']['mode']);
 451:         }
 452: 
 453:         // Save new sorting
 454:         $objCurrentDataProvider->save($objSrcModel);
 455: 
 456:         // Reset clipboard + redirect
 457:         $this->getEnvironment()->getClipboard()->clear();
 458:         $this->redirectHome();
 459:     }
 460: 
 461:     /**
 462:      * Copy an entry and all children.
 463:      *
 464:      * @return string error msg for an unknown mode
 465:      */
 466:     public function copy()
 467:     {
 468:         // Check
 469:         $this->checkIsWritable();
 470:         switch ($this->getDC()->arrDCA['list']['sorting']['mode'])
 471:         {
 472:             case 0:
 473:             case 1:
 474:             case 2:
 475:             case 3:
 476:                 $intId = $this->Input->get('id');
 477:                 $intPid = (strlen($this->Input->get('pid')) != 0)? $this->Input->get('pid') : 0;
 478: 
 479:                 if (strlen($intId) == 0)
 480:                 {
 481:                     BackendBindings::log('Missing parameter for copy in ' . $this->getDC()->getTable(), 'DC_General - DefaultController - copy()', TL_ERROR);
 482:                     BackendBindings::redirect('contao/main.php?act=error');
 483:                 }
 484: 
 485:                 // Check
 486:                 $this->checkIsWritable();
 487:                 $this->checkLanguage($this->getDC());
 488: 
 489:                 // Check if we have fields
 490:                 if (!$this->getEnvironment()->getDataDefinition()->hasEditableProperties())
 491:                 {
 492:                     BackendBindings::redirect($this->getReferer());
 493:                 }
 494: 
 495:                 // Load something
 496:                 $this->getDC()->preloadTinyMce();
 497: 
 498:                 // Load record from data provider - Load the source model
 499:                 $objDataProvider = $this->getEnvironment()->getDataProvider();
 500:                 $objSrcModel = $objDataProvider->fetch($objDataProvider->getEmptyConfig()->setId($intId));
 501: 
 502:                 $objDBModel = clone $objSrcModel;
 503:                 $objDBModel->setMeta(DCGE::MODEL_IS_CHANGED, true);
 504: 
 505:                 $this->getDC()->setCurrentModel($objDBModel);
 506: 
 507:                 // Check if we have a auto submit
 508:                 $this->getDC()->updateModelFromPOST();
 509: 
 510:                 // Check submit
 511:                 if ($this->getDC()->isSubmitted() == true)
 512:                 {
 513:                     if (isset($_POST["save"]))
 514:                     {
 515:                         // process input and update changed properties.
 516:                         if ($this->doSave() !== false)
 517:                         {
 518:                             $this->reload();
 519:                         }
 520:                     }
 521:                     else if (isset($_POST["saveNclose"]))
 522:                     {
 523:                         // process input and update changed properties.
 524:                         if ($this->doSave() !== false)
 525:                         {
 526:                             setcookie('BE_PAGE_OFFSET', 0, 0, '/');
 527: 
 528:                             $_SESSION['TL_INFO'] = '';
 529:                             $_SESSION['TL_ERROR'] = '';
 530:                             $_SESSION['TL_CONFIRM'] = '';
 531: 
 532:                             BackendBindings::redirect($this->getReferer());
 533:                         }
 534:                     }
 535:                     // Maybe Callbacks ? Yes, this is the first version of an simple
 536:                     // button callback system like dc_memory.
 537:                     else
 538:                     {
 539:                         $arrButtons = $this->getDC()->arrDCA['buttons'];
 540: 
 541:                         if (is_array($arrButtons))
 542:                         {
 543:                             foreach ($arrButtons as $arrButton)
 544:                             {
 545:                                 if (empty($arrButton) || !is_array($arrButton))
 546:                                 {
 547:                                     continue;
 548:                                 }
 549: 
 550:                                 if (array_key_exists($arrButton['formkey'], $_POST))
 551:                                 {
 552:                                     $strClass = $arrButton['button_callback'][0];
 553:                                     $strMethod = $arrButton['button_callback'][1];
 554: 
 555:                                     $this->import($strClass);
 556: 
 557:                                     $this->$strClass->$strMethod($this->getDC());
 558: 
 559:                                     break;
 560:                                 }
 561:                             }
 562:                         }
 563: 
 564:                         if (Input::getInstance()->post('SUBMIT_TYPE') !== 'auto')
 565:                         {
 566:                             $this->reload();
 567:                         }
 568:                     }
 569:                 }
 570: 
 571:                 return;
 572: 
 573:             case 5:
 574:                 // Init Vars
 575:                 $intMode = $this->Input->get('mode');
 576:                 $intPid = $this->Input->get('pid');
 577:                 $intId = $this->Input->get('id');
 578:                 $intChilds = $this->Input->get('childs');
 579: 
 580:                 if (strlen($intMode) == 0 || strlen($intPid) == 0 || strlen($intId) == 0)
 581:                 {
 582:                     BackendBindings::log('Missing parameter for copy in ' . $this->getDC()->getTable(), 'DC_General - DefaultController - copy()', TL_ERROR);
 583:                     BackendBindings::redirect('contao/main.php?act=error');
 584:                 }
 585: 
 586:                 // Get the join field
 587:                 $arrJoinCondition = $this->getDC()->getJoinConditions('self');
 588: 
 589:                 // Insert the copy
 590:                 $this->insertCopyModel($intId, $intPid, $intMode, $intChilds, $arrJoinCondition[0]['srcField'], $arrJoinCondition[0]['dstField'], $arrJoinCondition[0]['operation']);
 591:                 break;
 592: 
 593:             default:
 594:                 return vsprintf($this->notImplMsg, 'copy - Mode ' . $this->getDC()->arrDCA['list']['sorting']['mode']);
 595:                 break;
 596:         }
 597: 
 598:         // Reset clipboard + redirect
 599:         $this->resetClipboard(true);
 600:     }
 601: 
 602:     /**
 603:      * Recurse through all children in mode 5 and return their Ids.
 604:      *
 605:      * @param ModelInterface $objParentModel The parent model to fetch children for.
 606:      *
 607:      * @param bool           $blnRecurse     Boolean flag determining if the collection shall recurse into sub levels.
 608:      *
 609:      * @return array
 610:      */
 611:     protected function fetchMode5ChildrenOf($objParentModel, $blnRecurse = true)
 612:     {
 613:         $environment      = $this->getEnvironment();
 614:         $definition       = $environment->getDataDefinition();
 615:         $objChildCondition = $definition->getChildCondition($objParentModel->getProviderName(), $definition->getName());
 616: 
 617:         // Build filter
 618:         $objChildConfig = $environment->getDataProvider()->getEmptyConfig();
 619:         $objChildConfig->setFilter($objChildCondition->getFilter($objParentModel));
 620: 
 621:         // Get child collection
 622:         $objChildCollection = $environment->getDataProvider()->fetchAll($objChildConfig);
 623: 
 624:         $arrIDs = array();
 625:         foreach ($objChildCollection as $objChildModel)
 626:         {
 627:             /** @var ModelInterface $objChildModel */
 628:             $arrIDs[] = $objChildModel->getId();
 629:             if ($blnRecurse)
 630:             {
 631:                 $arrIDs = array_merge($arrIDs, $this->fetchMode5ChildrenOf($objChildModel, true));
 632:             }
 633:         }
 634:         return $arrIDs;
 635:     }
 636: 
 637:     public function getBaseConfig()
 638:     {
 639:         $objConfig     = $this->getEnvironment()->getDataProvider()->getEmptyConfig();
 640:         $objDefinition = $this->getEnvironment()->getDataDefinition();
 641:         $arrAdditional = $objDefinition->getBasicDefinition()->getAdditionalFilter();
 642: 
 643:         // Custom filter common for all modes.
 644:         if ($arrAdditional)
 645:         {
 646:             $objConfig->setFilter($arrAdditional);
 647:         }
 648: 
 649:         // Special filter for certain modes.
 650:         if ($objDefinition->getBasicDefinition()->getMode() == BasicDefinitionInterface::MODE_PARENTEDLIST)
 651:         {
 652:             $this->addParentFilter(
 653:                 $this->getEnvironment()->getInputProvider()->getParameter('pid'),
 654:                 $objConfig
 655:             );
 656:         }
 657: 
 658:         return $objConfig;
 659:     }
 660: 
 661:     /**
 662:      * Loads the current model from the data provider and overrides the selector
 663:      *
 664:      * @param type $strSelector the name of the checkbox toggling the palette.
 665:      */
 666:     public function generateAjaxPalette($strSelector)
 667:     {
 668:         // Check
 669:         $this->checkIsWritable();
 670:         $this->checkLanguage($this->getDC());
 671: 
 672:         // Check if we have fields
 673:         if (!$this->getEnvironment()->getDataDefinition()->hasEditableProperties())
 674:         {
 675:             $this->redirect($this->getReferer());
 676:         }
 677: 
 678:         // Load something
 679:         $this->getDC()->preloadTinyMce();
 680: 
 681:         $objDataProvider = $this->getEnvironment()->getDataProvider();
 682: 
 683:         // Load record from data provider
 684:         $objDBModel = $objDataProvider->fetch($objDataProvider->getEmptyConfig()->setId($this->getDC()->getId()));
 685:         if ($objDBModel == null)
 686:         {
 687:             $objDBModel = $objDataProvider->getEmptyModel();
 688:         }
 689: 
 690:         $this->getDC()->setCurrentModel($objDBModel);
 691: 
 692:         // override the setting from POST now.
 693:         $objDBModel->setProperty($strSelector, intval($this->Input->post('state')));
 694:     }
 695: 
 696:     /**
 697:      * Calculate the new position of an element
 698:      *
 699:      * Warning this function needs the cdp (current data provider).
 700:      *
 701:      * Warning this function needs the pdp (parent data provider).
 702:      *
 703:      * Based on backbone87 PR - "creating items in parent modes generates sorting value of 0"
 704:      *
 705:      * @param DataProviderInterface $objCDP             Current data provider
 706:      * @param DataProviderInterface $objPDP             Parent data provider
 707:      * @param ModelInterface  $objDBModel         Model of element which should moved
 708:      * @param mixed           $mixAfter           Target element
 709:      * @param                 $mixInto
 710:      * @param string          $strMode            Mode like cut | create and so on
 711:      * @param mixed           $mixParentID        Parent ID of table or element
 712:      * @param integer         $intInsertMode      Insert Mode => 1 After | 2 Into
 713:      * @param bool            $blnWithoutReorder
 714:      *
 715:      * @throws \RuntimeException
 716:      *
 717:      * @return void
 718:      */
 719:     protected function getNewPosition($objCDP, $objPDP, $objDBModel, $mixAfter, $mixInto, $strMode, $mixParentID = null, $intInsertMode = null, $blnWithoutReorder = false)
 720:     {
 721:         if (!$objDBModel)
 722:         {
 723:             throw new DcGeneralRuntimeException('No model provided!');
 724:         }
 725: 
 726:         $environment = $this->getEnvironment();
 727:         $definition  = $environment->getDataDefinition();
 728: 
 729:         // Check if we have a sorting field, if not skip here.
 730:         if (!$objCDP->fieldExists('sorting'))
 731:         {
 732:             return;
 733:         }
 734: 
 735:         // Load default DataProvider.
 736:         if (is_null($objCDP))
 737:         {
 738:             $objCDP = $this->getEnvironment()->getDataProvider();
 739:         }
 740: 
 741:         if ($mixAfter === DCGE::INSERT_AFTER_START)
 742:         {
 743:             $mixAfter = 0;
 744:         }
 745: 
 746:         // Search for the highest sorting. Default - Add to end off all.
 747:         // ToDo: We have to check the child <=> parent condition . To get all sortings for one level.
 748:         // If we get a after 0, add to top.
 749:         if ($mixAfter === 0) {
 750: 
 751:             // Build filter for conditions
 752:             $arrFilter = array();
 753: 
 754:             if (in_array($this->getDC()->arrDCA['list']['sorting']['mode'], array(4, 5, 6)))
 755:             {
 756:                 $arrConditions = $definition->getRootCondition()->getFilter();
 757: 
 758:                 if ($arrConditions)
 759:                 {
 760:                     foreach ($arrConditions as $arrCondition)
 761:                     {
 762:                         if (array_key_exists('remote', $arrCondition))
 763:                         {
 764:                             $arrFilter[] = array(
 765:                                 'value'      => Input::getInstance()->get($arrCondition['remote']),
 766:                                 'property'   => $arrCondition['property'],
 767:                                 'operation'  => $arrCondition['operation']
 768:                             );
 769:                         }
 770:                         else if (array_key_exists('remote_value', $arrCondition))
 771:                         {
 772:                             $arrFilter[] = array(
 773:                                 'value'      => Input::getInstance()->get($arrCondition['remote_value']),
 774:                                 'property'   => $arrCondition['property'],
 775:                                 'operation'  => $arrCondition['operation']
 776:                             );
 777:                         }
 778:                         else
 779:                         {
 780:                             $arrFilter[] = array(
 781:                                 'value'      => $arrCondition['value'],
 782:                                 'property'   => $arrCondition['property'],
 783:                                 'operation'  => $arrCondition['operation']
 784:                             );
 785:                         }
 786:                     }
 787:                 }
 788:             }
 789: 
 790:             // Build config
 791:             $objConfig = $objCDP->getEmptyConfig();
 792:             $objConfig->setFields(array('sorting'));
 793:             $objConfig->setSorting(array('sorting' => DCGE::MODEL_SORTING_ASC));
 794:             $objConfig->setAmount(1);
 795:             $objConfig->setFilter($arrFilter);
 796: 
 797:             $objCollection = $objCDP->fetchAll($objConfig);
 798: 
 799:             if ($objCollection->length())
 800:             {
 801:                 $intLowestSorting    = $objCollection->get(0)->getProperty('sorting');
 802:                 $intNextSorting      = round($intLowestSorting / 2);
 803:             }
 804:             else
 805:             {
 806:                 $intNextSorting = 256;
 807:             }
 808: 
 809:             // FIXME: lowest sorting is uninitialized here - stefan heimes, what to do?
 810:             // Check if we have a valide sorting.
 811:             if (($intLowestSorting < 2 || $intNextSorting <= 2) && !$blnWithoutReorder)
 812:             {
 813:                 // ToDo: Add child <=> parent config.
 814:                 $objConfig = $objCDP->getEmptyConfig();
 815:                 $objConfig->setFilter($arrFilter);
 816: 
 817:                 $this->reorderSorting($objConfig);
 818:                 $this->getNewPosition($objCDP, $objPDP, $objDBModel, $mixAfter, $mixInto, $strMode, $mixParentID, $intInsertMode, true);
 819:                 return;
 820:             }
 821:             // Fallback to valid sorting.
 822:             else if ($intNextSorting <= 2)
 823:             {
 824:                 $intNextSorting = 256;
 825:             }
 826: 
 827:             $objDBModel->setProperty('sorting', $intNextSorting);
 828:         }
 829:         // If we get a after, search for the right value.
 830:         else if (!empty($mixAfter))
 831:         {
 832:             // Init some vars.
 833:             $intAfterSorting = 0;
 834:             $intNextSorting = 0;
 835: 
 836:             // Get "after" sorting value value.
 837:             $objAfterConfig = $objCDP->getEmptyConfig();
 838:             $objAfterConfig->setAmount(1);
 839:             $objAfterConfig->setFilter(array(array(
 840:                 'value'      => $mixAfter,
 841:                 'property'   => 'id',
 842:                 'operation'  => '='
 843:             )));
 844: 
 845:             $objAfterCollection = $objCDP->fetchAll($objAfterConfig);
 846: 
 847:             if ($objAfterCollection->length())
 848:             {
 849:                 $intAfterSorting = $objAfterCollection->get(0)->getProperty('sorting');
 850:             }
 851: 
 852:             // Get "next" sorting value value.
 853:             $objNextConfig = $objCDP->getEmptyConfig();
 854:             $objNextConfig->setFields(array('sorting'));
 855:             $objNextConfig->setAmount(1);
 856:             $objNextConfig->setSorting(array('sorting' => DCGE::MODEL_SORTING_ASC));
 857: 
 858:             $arrFilterSettings = array(array(
 859:                 'value'      => $intAfterSorting,
 860:                 'property'   => 'sorting',
 861:                 'operation'  => '>'
 862:             ));
 863: 
 864: 
 865:             $arrFilterChildCondition = array();
 866: 
 867:             // If we have mode 4, 5, 6 build the child <=> parent condition.
 868:             if (in_array($this->getDC()->arrDCA['list']['sorting']['mode'], array(4, 5, 6)))
 869:             {
 870:                 $arrChildCondition   = $this->objDC->getParentChildCondition($objAfterCollection->get(0), $objCDP->getEmptyModel()->getProviderName());
 871:                 $arrChildCondition   = $arrChildCondition['setOn'];
 872: 
 873:                 if ($arrChildCondition)
 874:                 {
 875:                     foreach ($arrChildCondition as $arrOperation)
 876:                     {
 877:                         if (array_key_exists('to_field', $arrOperation))
 878:                         {
 879:                             $arrFilterChildCondition[] = array(
 880:                                 'value'      => $objAfterCollection->get(0)->getProperty($arrOperation['to_field']),
 881:                                 'property'   => $arrOperation['to_field'],
 882:                                 'operation'  => '='
 883:                             );
 884:                         }
 885:                         else
 886:                         {
 887:                             $arrFilterChildCondition[] = array(
 888:                                 'value'      => $arrOperation['property'],
 889:                                 'property'   => $arrOperation['to_field'],
 890:                                 'operation'  => '='
 891:                             );
 892:                         }
 893:                     }
 894:                 }
 895:             }
 896: 
 897:             $objNextConfig->setFilter(array_merge($arrFilterSettings, $arrFilterChildCondition));
 898: 
 899:             $objNextCollection = $objCDP->fetchAll($objNextConfig);
 900: 
 901:             if ($objNextCollection->length())
 902:             {
 903:                 $intNextSorting = $objNextCollection->get(0)->getProperty('sorting');
 904:             }
 905:             else
 906:             {
 907:                 $intNextSorting = $intAfterSorting + (2 * 256);
 908:             }
 909: 
 910:             // Check if we have a valide sorting.
 911:             if (($intAfterSorting < 2 || $intNextSorting < 2 || round(($intNextSorting - $intAfterSorting) / 2) <= 2) && !$blnWithoutReorder)
 912:             {
 913:                 // ToDo: Add child <=> parent config.
 914:                 $objConfig = $objCDP->getEmptyConfig();
 915:                 $objConfig->setFilter($arrFilterChildCondition);
 916: 
 917:                 $this->reorderSorting($objConfig);
 918:                 $this->getNewPosition($objCDP, $objPDP, $objDBModel, $mixAfter, $mixInto, $strMode, $mixParentID, $intInsertMode, true);
 919:                 return;
 920:             }
 921:             // Fallback to valid sorting.
 922:             else if ($intNextSorting <= 2)
 923:             {
 924:                 $intNextSorting = 256;
 925:             }
 926: 
 927:             // Get sorting between these two values.
 928:             $intNewSorting = $intAfterSorting + round(($intNextSorting - $intAfterSorting) / 2);
 929: 
 930:             // Save in model.
 931:             $objDBModel->setProperty('sorting', $intNewSorting);
 932: 
 933:         }
 934:         // Else use the highest value. Fallback.
 935:         else
 936:         {
 937:             $objConfig = $objCDP->getEmptyConfig();
 938:             $objConfig->setFields(array('sorting'));
 939:             $objConfig->setSorting(array('sorting' => DCGE::MODEL_SORTING_DESC));
 940:             $objConfig->setAmount(1);
 941: 
 942:             $objCollection = $objCDP->fetchAll($objConfig);
 943: 
 944:             $intHighestSorting = 0;
 945: 
 946:             if ($objCollection->length())
 947:             {
 948:                 $intHighestSorting = $objCollection->get(0)->getProperty('sorting') + 256;
 949:             }
 950: 
 951:             $objDBModel->setProperty('sorting', $intHighestSorting);
 952:         }
 953:     }
 954: 
 955:     /**
 956:      * Reorder all sortings for one table.
 957:      *
 958:      * @param ConfigInterface $objConfig
 959:      *
 960:      * @return void
 961:      */
 962:     protected function reorderSorting($objConfig)
 963:     {
 964:         $objCurrentDataProvider = $this->getEnvironment()->getDataProvider();
 965: 
 966:         if ($objConfig == null)
 967:         {
 968:             $objConfig = $objCurrentDataProvider->getEmptyConfig();
 969:         }
 970: 
 971:         // Search for the lowest sorting
 972:         $objConfig->setFields(array('sorting'));
 973:         $objConfig->setSorting(array('sorting' => DCGE::MODEL_SORTING_ASC, 'id' => DCGE::MODEL_SORTING_ASC));
 974:         $arrCollection = $objCurrentDataProvider->fetchAll($objConfig);
 975: 
 976:         $i = 1;
 977:         $intCount = 256;
 978: 
 979:         foreach ($arrCollection as $value)
 980:         {
 981:             $value->setProperty('sorting', $intCount * $i++);
 982:             $objCurrentDataProvider->save($value);
 983:         }
 984:     }
 985: 
 986:     /* /////////////////////////////////////////////////////////////////////
 987:      * ---------------------------------------------------------------------
 988:      * Copy modes
 989:      * ---------------------------------------------------------------------
 990:      * ////////////////////////////////////////////////////////////////// */
 991: 
 992:     /**
 993:      * @todo Make it fine
 994:      *
 995:      * @param type $intSrcID
 996:      * @param type $intDstID
 997:      * @param type $intMode
 998:      * @param type $blnChilds
 999:      * @param type $strDstField
1000:      * @param type $strSrcField
1001:      * @param type $strOperation
1002:      */
1003:     protected function insertCopyModel($intIdSource, $intIdTarget, $intMode, $blnChilds, $strFieldId, $strFieldPid, $strOperation)
1004:     {
1005:         // Get dataprovider
1006:         $objDataProvider = $this->getEnvironment()->getDataProvider();
1007: 
1008:         // Load the source model
1009:         $objSrcModel = $objDataProvider->fetch($objDataProvider->getEmptyConfig()->setId($intIdSource));
1010: 
1011:         // Create a empty model for the copy
1012:         $objCopyModel = clone $objSrcModel;
1013: 
1014: //      // Load all params
1015: //      $arrProperties = $objSrcModel->getPropertiesAsArray();
1016: //
1017: //      // Clear some fields, see dca
1018: //      foreach ($arrProperties as $key => $value)
1019: //      {
1020: //          // If the field is not known, remove it
1021: //          if (!key_exists($key, $this->getDC()->arrDCA['fields']))
1022: //          {
1023: //              continue;
1024: //          }
1025: //
1026: //          // Check doNotCopy
1027: //          if ($this->getDC()->arrDCA['fields'][$key]['eval']['doNotCopy'] == true)
1028: //          {
1029: //              unset($arrProperties[$key]);
1030: //              continue;
1031: //          }
1032: //
1033: //          // Check fallback
1034: //          if ($this->getDC()->arrDCA['fields'][$key]['eval']['fallback'] == true)
1035: //          {
1036: //              $objDataProvider->resetFallback($key);
1037: //          }
1038: //
1039: //          // Check unique
1040: //          if ($this->getDC()->arrDCA['fields'][$key]['eval']['unique'] == true && $objDataProvider->isUniqueValue($key, $value))
1041: //          {
1042: //              throw new DcGeneralRuntimeException(vsprintf($GLOBALS['TL_LANG']['ERR']['unique'], $key));
1043: //          }
1044: //      }
1045: //
1046: //      // Add the properties to the empty model
1047: //      $objCopyModel->setPropertiesAsArray($arrProperties);
1048: 
1049:         $intListMode = $this->getDC()->arrDCA['list']['sorting']['mode'];
1050: 
1051:         //Insert After => Get the parent from he target id
1052:         if (in_array($intListMode, array(0, 1, 2, 3)))
1053:         {
1054:             // ToDo: reset sorting for new entry
1055:         }
1056:         //Insert After => Get the parent from he target id
1057:         else if (in_array($intListMode, array(5)) && $intMode == 1)
1058:         {
1059:             $this->setParent($objCopyModel, $this->getParent('self', null, $intIdTarget), 'self');
1060:         }
1061:         // Insert Into => use the pid
1062:         else if (in_array($intListMode, array(5)) && $intMode == 2)
1063:         {
1064:             if ($this->isRootEntry('self', $intIdTarget))
1065:             {
1066:                 $this->setRoot($objCopyModel, 'self');
1067:             }
1068:             else
1069:             {
1070:                 $objParentConfig = $this->getEnvironment()->getDataProvider()->getEmptyConfig();
1071:                 $objParentConfig->setId($intIdTarget);
1072: 
1073:                 $objParentModel = $this->getEnvironment()->getDataProvider()->fetch($objParentConfig);
1074: 
1075:                 $this->setParent($objCopyModel, $objParentModel, 'self');
1076:             }
1077:         }
1078:         else
1079:         {
1080:             BackendBindings::log('Unknown create mode for copy in ' . $this->getDC()->getTable(), 'DC_General - DefaultController - copy()', TL_ERROR);
1081:             BackendBindings::redirect('contao/main.php?act=error');
1082:         }
1083: 
1084:         $objDataProvider->save($objCopyModel);
1085: 
1086:         $this->arrInsertIDs[$objCopyModel->getID()] = true;
1087: 
1088:         if ($blnChilds == true)
1089:         {
1090:             $strFilter = $strFieldPid . $strOperation . $objSrcModel->getProperty($strFieldId);
1091:             $objChildConfig = $objDataProvider->getEmptyConfig()->setFilter(array($strFilter));
1092:             $objChildCollection = $objDataProvider->fetchAll($objChildConfig);
1093: 
1094:             foreach ($objChildCollection as $key => $value)
1095:             {
1096:                 if (array_key_exists($value->getID(), $this->arrInsertIDs))
1097:                 {
1098:                     continue;
1099:                 }
1100: 
1101:                 $this->insertCopyModel($value->getID(), $objCopyModel->getID(), 2, $blnChilds, $strFieldId, $strFieldPid, $strOperation);
1102:             }
1103:         }
1104:     }
1105: 
1106:     protected function calcLabelPattern($strTable)
1107:     {
1108:         if ($strTable == $this->getDC()->getTable())
1109:         {
1110:             // easy, take from DCA.
1111:             return $this->getDC()->arrDCA['list']['label']['format'];
1112:         }
1113: 
1114:         $arrChildDef = $this->getDC()->arrDCA['dca_config']['child_list'];
1115:         if (is_array($arrChildDef) && array_key_exists($strTable, $arrChildDef) && isset($arrChildDef[$strTable]['format']))
1116:         {
1117:             // check if defined in child conditions.
1118:             return $arrChildDef[$strTable]['format'];
1119:         }
1120:         else if (($strTable == 'self') && array_key_exists('self', $arrChildDef) && $arrChildDef['self']['format'])
1121:         {
1122:             return $arrChildDef['self']['format'];
1123:         }
1124:     }
1125: 
1126:     /**
1127:      * Get a list with all needed fields for the models.
1128:      *
1129:      * @param ModelInterface $objModel
1130:      * @param string $strDstTable
1131:      *
1132:      * @return array A list with all needed values.
1133:      */
1134:     protected function calcNeededFields(ModelInterface $objModel, $strDstTable)
1135:     {
1136:         $arrFields = $this->calcLabelFields($strDstTable);
1137:         $arrChildCond = $this->getDC()->getChildCondition($objModel, $strDstTable);
1138:         foreach ($arrChildCond as $arrCond)
1139:         {
1140:             if ($arrCond['property'])
1141:             {
1142:                 $arrFields[] = $arrCond['property'];
1143:             }
1144:         }
1145: 
1146:         // Add some default values, if we have this values in DB.
1147:         if($this->getEnvironment()->getDataProvider($strDstTable)->fieldExists('enabled'))
1148:         {
1149:             $arrFields [] = 'enabled';
1150:         }
1151: 
1152:         return $arrFields;
1153:     }
1154: 
1155:     /**
1156:      * {@inheritDoc}
1157:      */
1158:     public function isRootModel(ModelInterface $model)
1159:     {
1160:         if ($this
1161:             ->getEnvironment()
1162:             ->getDataDefinition()
1163:         ->getBasicDefinition()
1164:         ->getMode() !== BasicDefinitionInterface::MODE_HIERARCHICAL)
1165:         {
1166:             return false;
1167:         }
1168: 
1169:         return $this
1170:             ->getEnvironment()
1171:             ->getDataDefinition()
1172:             ->getModelRelationshipDefinition()
1173:             ->getRootCondition()
1174:             ->matches($model);
1175:     }
1176: 
1177:     /**
1178:      * {@inheritDoc}
1179:      */
1180:     public function setRootModel(ModelInterface $model)
1181:     {
1182:         $rootCondition = $this
1183:             ->getEnvironment()
1184:             ->getDataDefinition()
1185:             ->getModelRelationshipDefinition()
1186:             ->getRootCondition();
1187: 
1188:         $rootCondition->applyTo($model);
1189: 
1190:         return $this;
1191:     }
1192: 
1193:     /**
1194:      * {@inheritDoc}
1195:      *
1196:      * @throws \DcGeneral\Exception\DcGeneralRuntimeException
1197:      */
1198:     public function setParent(ModelInterface  $childModel, ModelInterface  $parentModel)
1199:     {
1200:         $this
1201:             ->getEnvironment()
1202:             ->getDataDefinition($childModel->getProviderName())
1203:             ->getModelRelationshipDefinition()
1204:             ->getChildCondition($parentModel->getProviderName(), $childModel->getProviderName())
1205:             ->applyTo($parentModel, $childModel);
1206:     }
1207: 
1208:     /**
1209:      * {@inheritDoc}
1210:      */
1211:     public function setSameParent(ModelInterface $receivingModel, ModelInterface $sourceModel, $parentTable)
1212:     {
1213:         if ($this->isRootModel($sourceModel))
1214:         {
1215:             $this->setRootModel($receivingModel);
1216:         }
1217:         else
1218:         {
1219:             $this
1220:                 ->getEnvironment()
1221:                 ->getDataDefinition()
1222:                 ->getModelRelationshipDefinition()
1223:                 ->getChildCondition($parentTable, $receivingModel->getProviderName())
1224:                 ->copyFrom($sourceModel, $receivingModel);
1225:         }
1226:     }
1227: 
1228:     public function sortCollection(ModelInterface $a, ModelInterface $b)
1229:     {
1230:         if ($a->getProperty($this->arrColSort['field']) == $b->getProperty($this->arrColSort['field']))
1231:         {
1232:             return 0;
1233:         }
1234: 
1235:         if (!$this->arrColSort['reverse'])
1236:         {
1237:             return ($a->getProperty($this->arrColSort['field']) < $b->getProperty($this->arrColSort['field'])) ? -1 : 1;
1238:         }
1239:         else
1240:         {
1241:             return ($a->getProperty($this->arrColSort['field']) < $b->getProperty($this->arrColSort['field'])) ? 1 : -1;
1242:         }
1243:     }
1244: 
1245:     public function executePostActions()
1246:     {
1247:         if (version_compare(VERSION, '3.0', '>='))
1248:         {
1249:             $objHandler = new Ajax3X();
1250:         }
1251:         else
1252:         {
1253:             $objHandler = new Ajax2X();
1254:         }
1255:         $objHandler->executePostActions($this->getDC());
1256:     }
1257: 
1258: }
1259: 
contao-community-alliance/dc-general API documentation generated by ApiGen 2.8.0