예제 #1
0
    /**
     * Render a row of a box and return it as HTML string
     *
     * @param string $strPalette
     *
     * @return string
     *
     * @throws \Exception
     */
    protected function row($strPalette = null)
    {
        $arrData = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField];
        // Redirect if the field is excluded
        if ($arrData['exclude']) {
            $this->log('Field "' . $this->strField . '" of table "' . $this->strTable . '" was excluded from being edited', __METHOD__, TL_ERROR);
            $this->redirect('contao/main.php?act=error');
        }
        $xlabel = '';
        // Toggle line wrap (textarea)
        if ($arrData['inputType'] == 'textarea' && !isset($arrData['eval']['rte'])) {
            $xlabel .= ' ' . \Image::getHtml('wrap.gif', $GLOBALS['TL_LANG']['MSC']['wordWrap'], 'title="' . specialchars($GLOBALS['TL_LANG']['MSC']['wordWrap']) . '" class="toggleWrap" onclick="Backend.toggleWrap(\'ctrl_' . $this->strInputName . '\')"');
        }
        // Add the help wizard
        if ($arrData['eval']['helpwizard']) {
            $xlabel .= ' <a href="contao/help.php?table=' . $this->strTable . '&amp;field=' . $this->strField . '" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['helpWizard']) . '" onclick="Backend.openModalIframe({\'width\':735,\'height\':405,\'title\':\'' . specialchars(str_replace("'", "\\'", $arrData['label'][0])) . '\',\'url\':this.href});return false">' . \Image::getHtml('about.gif', $GLOBALS['TL_LANG']['MSC']['helpWizard'], 'style="vertical-align:text-bottom"') . '</a>';
        }
        // Add a custom xlabel
        if (is_array($arrData['xlabel'])) {
            foreach ($arrData['xlabel'] as $callback) {
                if (is_array($callback)) {
                    $this->import($callback[0]);
                    $xlabel .= $this->{$callback}[0]->{$callback}[1]($this);
                } elseif (is_callable($callback)) {
                    $xlabel .= $callback($this);
                }
            }
        }
        // Input field callback
        if (is_array($arrData['input_field_callback'])) {
            $this->import($arrData['input_field_callback'][0]);
            return $this->{$arrData}['input_field_callback'][0]->{$arrData}['input_field_callback'][1]($this, $xlabel);
        } elseif (is_callable($arrData['input_field_callback'])) {
            return $arrData['input_field_callback']($this, $xlabel);
        }
        /** @var \Widget $strClass */
        $strClass = $GLOBALS['BE_FFL'][$arrData['inputType']];
        // Return if the widget class does not exists
        if (!class_exists($strClass)) {
            return '';
        }
        $arrData['eval']['required'] = false;
        // Use strlen() here (see #3277)
        if ($arrData['eval']['mandatory']) {
            if (is_array($this->varValue)) {
                if (empty($this->varValue)) {
                    $arrData['eval']['required'] = true;
                }
            } else {
                if (!strlen($this->varValue)) {
                    $arrData['eval']['required'] = true;
                }
            }
        }
        // Convert insert tags in src attributes (see #5965)
        if (isset($arrData['eval']['rte']) && strncmp($arrData['eval']['rte'], 'tiny', 4) === 0) {
            $this->varValue = \StringUtil::insertTagToSrc($this->varValue);
        }
        /** @var \Widget $objWidget */
        $objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $this->strInputName, $this->varValue, $this->strField, $this->strTable, $this));
        $objWidget->xlabel = $xlabel;
        $objWidget->currentRecord = $this->intId;
        // Validate the field
        if (\Input::post('FORM_SUBMIT') == $this->strTable) {
            $key = \Input::get('act') == 'editAll' ? 'FORM_FIELDS_' . $this->intId : 'FORM_FIELDS';
            // Calculate the current palette
            $postPaletteFields = implode(',', \Input::post($key));
            $postPaletteFields = array_unique(trimsplit('[,;]', $postPaletteFields));
            // Compile the palette if there is none
            if ($strPalette === null) {
                $newPaletteFields = trimsplit('[,;]', $this->getPalette());
            } else {
                // Use the given palette ($strPalette is an array in editAll mode)
                $newPaletteFields = is_array($strPalette) ? $strPalette : trimsplit('[,;]', $strPalette);
                // Re-check the palette if the current field is a selector field
                if (isset($GLOBALS['TL_DCA'][$this->strTable]['palettes']['__selector__']) && in_array($this->strField, $GLOBALS['TL_DCA'][$this->strTable]['palettes']['__selector__'])) {
                    // If the field value has changed, recompile the palette
                    if ($this->varValue != \Input::post($this->strInputName)) {
                        $newPaletteFields = trimsplit('[,;]', $this->getPalette());
                    }
                }
            }
            // Adjust the names in editAll mode
            if (\Input::get('act') == 'editAll') {
                foreach ($newPaletteFields as $k => $v) {
                    $newPaletteFields[$k] = $v . '_' . $this->intId;
                }
                if ($this->User->isAdmin) {
                    $newPaletteFields['pid'] = 'pid_' . $this->intId;
                    $newPaletteFields['sorting'] = 'sorting_' . $this->intId;
                }
            }
            $paletteFields = array_intersect($postPaletteFields, $newPaletteFields);
            // Validate and save the field
            if (in_array($this->strInputName, $paletteFields) || \Input::get('act') == 'overrideAll') {
                $objWidget->validate();
                if ($objWidget->hasErrors()) {
                    // Skip mandatory fields on auto-submit (see #4077)
                    if (\Input::post('SUBMIT_TYPE') != 'auto' || !$objWidget->mandatory || $objWidget->value != '') {
                        $this->noReload = true;
                    }
                } elseif ($objWidget->submitInput()) {
                    $varValue = $objWidget->value;
                    // Sort array by key (fix for JavaScript wizards)
                    if (is_array($varValue)) {
                        ksort($varValue);
                        $varValue = serialize($varValue);
                    }
                    // Convert file paths in src attributes (see #5965)
                    if ($varValue && isset($arrData['eval']['rte']) && strncmp($arrData['eval']['rte'], 'tiny', 4) === 0) {
                        $varValue = \StringUtil::srcToInsertTag($varValue);
                    }
                    // Save the current value
                    try {
                        $this->save($varValue);
                    } catch (\Exception $e) {
                        $this->noReload = true;
                        $objWidget->addError($e->getMessage());
                    }
                }
            }
        }
        $wizard = '';
        $strHelpClass = '';
        // Date picker
        if ($arrData['eval']['datepicker']) {
            $rgxp = $arrData['eval']['rgxp'];
            $format = \Date::formatToJs(\Config::get($rgxp . 'Format'));
            switch ($rgxp) {
                case 'datim':
                    $time = ",\n      timePicker:true";
                    break;
                case 'time':
                    $time = ",\n      pickOnly:\"time\"";
                    break;
                default:
                    $time = '';
                    break;
            }
            $wizard .= ' <img src="assets/mootools/datepicker/' . $GLOBALS['TL_ASSETS']['DATEPICKER'] . '/icon.gif" width="20" height="20" alt="" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['datepicker']) . '" id="toggle_' . $objWidget->id . '" style="vertical-align:-6px;cursor:pointer">
  <script>
    window.addEvent("domready", function() {
      new Picker.Date($("ctrl_' . $objWidget->id . '"), {
        draggable: false,
        toggle: $("toggle_' . $objWidget->id . '"),
        format: "' . $format . '",
        positionOffset: {x:-211,y:-209}' . $time . ',
        pickerClass: "datepicker_bootstrap",
        useFadeInOut: !Browser.ie,
        startDay: ' . $GLOBALS['TL_LANG']['MSC']['weekOffset'] . ',
        titleFormat: "' . $GLOBALS['TL_LANG']['MSC']['titleFormat'] . '"
      });
    });
  </script>';
        }
        // Color picker
        if ($arrData['eval']['colorpicker']) {
            // Support single fields as well (see #5240)
            $strKey = $arrData['eval']['multiple'] ? $this->strField . '_0' : $this->strField;
            $wizard .= ' ' . \Image::getHtml('pickcolor.gif', $GLOBALS['TL_LANG']['MSC']['colorpicker'], 'style="vertical-align:top;cursor:pointer" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['colorpicker']) . '" id="moo_' . $this->strField . '"') . '
  <script>
    window.addEvent("domready", function() {
      new MooRainbow("moo_' . $this->strField . '", {
        id: "ctrl_' . $strKey . '",
        startColor: ((cl = $("ctrl_' . $strKey . '").value.hexToRgb(true)) ? cl : [255, 0, 0]),
        imgPath: "assets/mootools/colorpicker/' . $GLOBALS['TL_ASSETS']['COLORPICKER'] . '/images/",
        onComplete: function(color) {
          $("ctrl_' . $strKey . '").value = color.hex.replace("#", "");
        }
      });
    });
  </script>';
        }
        // Add a custom wizard
        if (is_array($arrData['wizard'])) {
            foreach ($arrData['wizard'] as $callback) {
                if (is_array($callback)) {
                    $this->import($callback[0]);
                    $wizard .= $this->{$callback}[0]->{$callback}[1]($this);
                } elseif (is_callable($callback)) {
                    $wizard .= $callback($this);
                }
            }
        }
        $objWidget->wizard = $wizard;
        // Set correct form enctype
        if ($objWidget instanceof \uploadable) {
            $this->blnUploadable = true;
        }
        // Mark floated single checkboxes
        if ($arrData['inputType'] == 'checkbox' && !$arrData['eval']['multiple'] && strpos($arrData['eval']['tl_class'], 'w50') !== false) {
            $arrData['eval']['tl_class'] .= ' cbx';
        } elseif ($arrData['inputType'] == 'text' && $arrData['eval']['multiple'] && strpos($arrData['eval']['tl_class'], 'wizard') !== false) {
            $arrData['eval']['tl_class'] .= ' inline';
        }
        // No 2-column layout in "edit all" mode
        if (\Input::get('act') == 'editAll' || \Input::get('act') == 'overrideAll') {
            $arrData['eval']['tl_class'] = str_replace(array('w50', 'clr', 'wizard', 'long', 'm12', 'cbx'), '', $arrData['eval']['tl_class']);
        }
        $updateMode = '';
        // Replace the textarea with an RTE instance
        if (!empty($arrData['eval']['rte'])) {
            list($file, $type) = explode('|', $arrData['eval']['rte'], 2);
            if (!file_exists(TL_ROOT . '/system/config/' . $file . '.php')) {
                throw new \Exception(sprintf('Cannot find editor configuration file "%s.php"', $file));
            }
            $selector = 'ctrl_' . $this->strInputName;
            $language = \Backend::getTinyMceLanguage();
            // backwards compatibility
            ob_start();
            include TL_ROOT . '/system/config/' . $file . '.php';
            $updateMode = ob_get_contents();
            ob_end_clean();
            unset($file, $type, $language, $selector);
        } elseif (\Input::get('act') == 'overrideAll' && ($arrData['inputType'] == 'checkbox' || $arrData['inputType'] == 'checkboxWizard') && $arrData['eval']['multiple']) {
            $updateMode = '
</div>
<div>
  <fieldset class="tl_radio_container">
  <legend>' . $GLOBALS['TL_LANG']['MSC']['updateMode'] . '</legend>
    <input type="radio" name="' . $this->strInputName . '_update" id="opt_' . $this->strInputName . '_update_1" class="tl_radio" value="add" onfocus="Backend.getScrollOffset()"> <label for="opt_' . $this->strInputName . '_update_1">' . $GLOBALS['TL_LANG']['MSC']['updateAdd'] . '</label><br>
    <input type="radio" name="' . $this->strInputName . '_update" id="opt_' . $this->strInputName . '_update_2" class="tl_radio" value="remove" onfocus="Backend.getScrollOffset()"> <label for="opt_' . $this->strInputName . '_update_2">' . $GLOBALS['TL_LANG']['MSC']['updateRemove'] . '</label><br>
    <input type="radio" name="' . $this->strInputName . '_update" id="opt_' . $this->strInputName . '_update_0" class="tl_radio" value="replace" checked="checked" onfocus="Backend.getScrollOffset()"> <label for="opt_' . $this->strInputName . '_update_0">' . $GLOBALS['TL_LANG']['MSC']['updateReplace'] . '</label>
  </fieldset>';
        }
        $strPreview = '';
        // Show a preview image (see #4948)
        if ($this->strTable == 'tl_files' && $this->strField == 'name' && $this->objActiveRecord !== null && $this->objActiveRecord->type == 'file') {
            $objFile = new \File($this->objActiveRecord->path, true);
            if ($objFile->isImage) {
                $image = 'placeholder.png';
                if ($objFile->isSvgImage || $objFile->height <= \Config::get('gdMaxImgHeight') && $objFile->width <= \Config::get('gdMaxImgWidth')) {
                    if ($objFile->width > 699 || $objFile->height > 524) {
                        $image = \Image::get($objFile->path, 699, 524, 'box');
                    } else {
                        $image = $objFile->path;
                    }
                }
                $ctrl = 'ctrl_preview_' . substr(md5($image), 0, 8);
                $strPreview = '

<div id="' . $ctrl . '" class="tl_edit_preview" data-original-width="' . $objFile->width . '" data-original-height="' . $objFile->height . '">
' . \Image::getHtml($image) . '
</div>';
                // Add the script to mark the important part
                if ($image !== 'placeholder.png') {
                    $strPreview .= '<script>Backend.editPreviewWizard($(\'' . $ctrl . '\'));</script>';
                    if (\Config::get('showHelp')) {
                        $strPreview .= '<p class="tl_help tl_tip">' . $GLOBALS['TL_LANG'][$this->strTable]['edit_preview_help'] . '</p>';
                    }
                }
            }
        }
        return $strPreview . '
<div' . ($arrData['eval']['tl_class'] ? ' class="' . $arrData['eval']['tl_class'] . '"' : '') . '>' . $objWidget->parse() . $updateMode . (!$objWidget->hasErrors() ? $this->help($strHelpClass) : '') . '
</div>';
    }
예제 #2
0
 */
if ($GLOBALS['TL_CONFIG']['useRTE']) {
    ?>
<script>window.tinymce || document.write('<script src="<?php 
    echo TL_ASSETS_URL;
    ?>
assets/tinymce4/tinymce.gzip.js">\x3C/script>')</script>
<script>
window.tinymce && tinymce.init({
  skin: 'contao',
  selector: '#<?php 
    echo $selector;
    ?>
',
  language: '<?php 
    echo Backend::getTinyMceLanguage();
    ?>
',
  element_format: 'html',
  forced_root_block: false,
  document_base_url: '<?php 
    echo Environment::get('base');
    ?>
',
  entities: '160,nbsp,60,lt,62,gt,173,shy',
  setup: function(editor) {
    editor.getElement().removeAttribute('required');
  },
  init_instance_callback: function(editor) {
    editor.on('focus', function() { Backend.getScrollOffset(); });
  },
예제 #3
0
 /**
  * Function for pre-loading the tiny mce.
  *
  * @return void
  *
  * @throws \Exception When the rich text editor config file can not be found.
  *
  * @SuppressWarnings(PHPMD.Superglobals)
  * @SuppressWarnings(PHPMD.CamelCaseVariableName)
  */
 public function preLoadRichTextEditor()
 {
     foreach ($this->getEnvironment()->getDataDefinition()->getPropertiesDefinition()->getProperties() as $property) {
         /** @var PropertyInterface $property */
         $extra = $property->getExtra();
         if (!isset($extra['rte'])) {
             continue;
         }
         if (strncmp($extra['rte'], 'tiny', 4) !== 0 && strncmp($extra['rte'], 'ace', 3) !== 0) {
             continue;
         }
         list($file, $type) = explode('|', $extra['rte']);
         $selector = 'ctrl_' . $property->getName();
         if (version_compare(VERSION, '3.3', '<')) {
             $GLOBALS['TL_RTE'][$file][$selector] = array('id' => $selector, 'file' => $file, 'type' => $type);
         } else {
             if (!file_exists(TL_ROOT . '/system/config/' . $file . '.php')) {
                 throw new \Exception(sprintf('Cannot find editor configuration file "%s.php"', $file));
             }
             if (strncmp($extra['rte'], 'tiny', 4) !== 0) {
                 // Backwards compatibility
                 $language = \Backend::getTinyMceLanguage();
             }
             ob_start();
             include TL_ROOT . '/system/config/' . $file . '.php';
             $updateMode = ob_get_contents();
             ob_end_clean();
             $GLOBALS['TL_MOOTOOLS'][] = $updateMode;
         }
     }
 }