/**
  * Generate backend output if TL_MODE is set to BE
  *
  * @return string|null Backend output or null
  */
 public function rsceGetBackendOutput()
 {
     if (TL_MODE !== 'BE') {
         return null;
     }
     $config = CustomElements::getConfigByType($this->type) ?: array();
     // Handle newsletter output the same way as the frontend
     if (!empty($config['isNewsletter'])) {
         if (\Input::get('do') === 'newsletter') {
             return null;
         }
         foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $entry) {
             $method = $entry['class'] . '::' . $entry['function'];
             if ($entry['file'] === TL_ROOT . '/system/modules/newsletter/classes/Newsletter.php' || $entry['file'] === TL_ROOT . '/vendor/contao/newsletter-bundle/src/Resources/contao/classes/Newsletter.php' || $method === 'Contao\\Newsletter::send' || $method === 'tl_newsletter::listNewsletters') {
                 return null;
             }
         }
     }
     if (!empty($config['beTemplate'])) {
         $this->strTemplate = $config['beTemplate'];
         return null;
     }
     if (in_array($this->type, $GLOBALS['TL_WRAPPERS']['start']) || in_array($this->type, $GLOBALS['TL_WRAPPERS']['stop']) || in_array($this->type, $GLOBALS['TL_WRAPPERS']['separator'])) {
         return '';
     }
     return null;
 }
 /**
  * Create one DCA field with the specified parameters
  *
  * This function calls itself recursively for nested data structures
  *
  * @param  string         $fieldPrefix    Field prefix, e.g. "rsce_field_"
  * @param  string         $fieldName      Field name
  * @param  array          $fieldConfig    Field configuration array
  * @param  array          $paletteFields  Reference to the list of all fields
  * @param  \DataContainer $dc             Data container
  * @param  boolean        $createFromPost Whether to create the field structure from post data or not
  * @return void
  */
 protected function createDcaItem($fieldPrefix, $fieldName, $fieldConfig, &$paletteFields, $dc, $createFromPost)
 {
     if (!is_string($fieldConfig) && !is_array($fieldConfig)) {
         throw new \Exception('Field config must be of type array or string.');
     }
     if (strpos($fieldName, '__') !== false) {
         throw new \Exception('Field name must not include "__" (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
     }
     if (strpos($fieldName, 'rsce_field_') !== false) {
         throw new \Exception('Field name must not include "rsce_field_" (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
     }
     if (substr($fieldName, 0, 1) === '_' || substr($fieldName, -1) === '_') {
         throw new \Exception('Field name must not start or end with "_" (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
     }
     if (!is_string($fieldName)) {
         $fieldName = 'unnamed_' . $fieldName;
     }
     if (is_string($fieldConfig)) {
         $fieldConfig = array('inputType' => 'group', 'label' => array($fieldConfig, ''));
     }
     if (!\BackendUser::getInstance()->hasAccess($dc->table . '::rsce_data', 'alexf') && $fieldConfig['inputType'] !== 'standardField') {
         return;
     }
     if (isset($fieldConfig['label'])) {
         $fieldConfig['label'] = static::getLabelTranslated($fieldConfig['label']);
     }
     if (isset($fieldConfig['reference']) && is_array($fieldConfig['reference']) && count(array_filter($fieldConfig['reference'], 'is_array'))) {
         $fieldConfig['reference'] = array_map(function ($label) {
             return \MadeYourDay\Contao\CustomElements::getLabelTranslated($label);
         }, $fieldConfig['reference']);
     }
     if ($fieldConfig['inputType'] === 'list') {
         if (isset($fieldConfig['elementLabel'])) {
             $fieldConfig['elementLabel'] = static::getLabelTranslated($fieldConfig['elementLabel']);
         }
         $fieldConfig['minItems'] = isset($fieldConfig['minItems']) ? (int) $fieldConfig['minItems'] : 0;
         $fieldConfig['maxItems'] = isset($fieldConfig['maxItems']) ? (int) $fieldConfig['maxItems'] : null;
         if ($fieldConfig['maxItems'] && $fieldConfig['maxItems'] < $fieldConfig['minItems']) {
             throw new \Exception('maxItems must not be higher than minItems (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
         }
         $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '_rsce_list_start'] = array('label' => $fieldConfig['label'], 'inputType' => 'rsce_list_start', 'eval' => array('minItems' => $fieldConfig['minItems'], 'maxItems' => $fieldConfig['maxItems']));
         $paletteFields[] = $fieldPrefix . $fieldName . '_rsce_list_start';
         $hasFields = false;
         foreach ($fieldConfig['fields'] as $fieldConfig2) {
             if (isset($fieldConfig2['inputType']) && $fieldConfig2['inputType'] !== 'list') {
                 $hasFields = true;
             }
         }
         if (!$hasFields) {
             // add an empty field
             $fieldConfig['fields']['rsce_empty'] = array('inputType' => 'text', 'eval' => array('tl_class' => 'hidden'));
         }
         $this->createDcaItemListDummy($fieldPrefix, $fieldName, $fieldConfig, $paletteFields, $dc, $createFromPost);
         $fieldData = $this->getNestedValue($fieldPrefix . $fieldName);
         for ($dataKey = 0; $dataKey < $fieldConfig['minItems'] || ($createFromPost ? $this->wasListFieldSubmitted($fieldPrefix . $fieldName, $dataKey) : isset($fieldData[$dataKey])); $dataKey++) {
             if (is_int($fieldConfig['maxItems']) && $dataKey > $fieldConfig['maxItems'] - 1) {
                 break;
             }
             $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_start'] = array('inputType' => 'rsce_list_item_start', 'label' => array(sprintf($fieldConfig['elementLabel'], $dataKey + 1)), 'eval' => array('label_template' => $fieldConfig['elementLabel']));
             $paletteFields[] = $fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_start';
             foreach ($fieldConfig['fields'] as $fieldName2 => $fieldConfig2) {
                 $this->createDcaItem($fieldPrefix . $fieldName . '__' . $dataKey . '__', $fieldName2, $fieldConfig2, $paletteFields, $dc, $createFromPost);
             }
             $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_stop'] = array('inputType' => 'rsce_list_item_stop');
             $paletteFields[] = $fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_stop';
         }
         $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '_rsce_list_stop'] = array('inputType' => 'rsce_list_stop');
         $paletteFields[] = $fieldPrefix . $fieldName . '_rsce_list_stop';
     } else {
         if ($fieldConfig['inputType'] === 'standardField') {
             if ($fieldPrefix !== 'rsce_field_') {
                 throw new \Exception('Input type "standardField" is not allowed inside lists.');
             }
             if (isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName])) {
                 if (isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName]['eval']) && is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName]['eval']) && isset($fieldConfig['eval']) && is_array($fieldConfig['eval'])) {
                     $fieldConfig['eval'] = array_merge($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName]['eval'], $fieldConfig['eval']);
                 }
                 unset($fieldConfig['inputType']);
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName] = array_merge($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName], $fieldConfig);
                 $paletteFields[] = $fieldName;
             }
         } else {
             if ($fieldConfig['inputType'] === 'group') {
                 $fieldConfig['inputType'] = 'rsce_group_start';
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName] = $fieldConfig;
                 $paletteFields[] = $fieldPrefix . $fieldName;
             } else {
                 if ($fieldConfig['inputType'] === 'url') {
                     $fieldConfig['inputType'] = 'text';
                     $fieldConfig['wizard'] = array(array('MadeYourDay\\Contao\\CustomElements', 'pagePicker'));
                     $fieldConfig['eval']['tl_class'] = (isset($fieldConfig['eval']['tl_class']) ? $fieldConfig['eval']['tl_class'] . ' ' : '') . 'wizard';
                     if (!isset($fieldConfig['eval']['fieldType'])) {
                         $fieldConfig['eval']['fieldType'] = 'radio';
                     }
                     if (!isset($fieldConfig['eval']['filesOnly'])) {
                         $fieldConfig['eval']['filesOnly'] = true;
                     }
                 }
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName] = $fieldConfig;
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['eval']['alwaysSave'] = true;
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['eval']['doNotSaveEmpty'] = true;
                 if (!is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['load_callback'])) {
                     $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['load_callback'] = array();
                 }
                 array_unshift($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['load_callback'], array('MadeYourDay\\Contao\\CustomElements', 'loadCallback'));
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['save_callback'][] = array('MadeYourDay\\Contao\\CustomElements', 'saveCallback');
                 $paletteFields[] = $fieldPrefix . $fieldName;
             }
         }
     }
 }