Пример #1
0
 /**
  * Fetch the options for a certain property.
  *
  * @param EnvironmentInterface $environment The environment.
  *
  * @param ModelInterface       $model       The model.
  *
  * @param PropertyInterface    $property    The property.
  *
  * @return array
  */
 protected function getOptions($environment, $model, $property)
 {
     $options = $property->getOptions();
     $event = new GetPropertyOptionsEvent($environment, $model);
     $event->setPropertyName($property->getName());
     $event->setOptions($options);
     $environment->getEventPropagator()->propagate($event::NAME, $event, $environment->getDataDefinition()->getName(), $property->getName());
     if ($event->getOptions() !== $options) {
         $options = $event->getOptions();
     }
     return $options;
 }
Пример #2
0
 /**
  * Calculate the label of a property to se in "show" view.
  *
  * @param PropertyInterface $property The property for which the label shall be calculated.
  *
  * @return string
  */
 protected function getPropertyLabel(PropertyInterface $property)
 {
     $environment = $this->getEnvironment();
     $definition = $environment->getDataDefinition();
     $label = $environment->getTranslator()->translate($property->getLabel(), $definition->getName());
     if (!$label) {
         $label = $environment->getTranslator()->translate('MSC.' . $property->getName());
     }
     if (is_array($label)) {
         $label = $label[0];
     }
     if (!$label) {
         $label = $property->getName();
     }
     return $label;
 }
 /**
  * Append wizard icons.
  *
  * @param PropertyInterface    $propInfo    The property for which the wizards shall be generated.
  *
  * @param EnvironmentInterface $environment The environment.
  *
  * @return string
  *
  * @SuppressWarnings(PHPMD.Superglobals)
  * @SuppressWarnings(PHPMD.CamelCaseVariableName)
  */
 public static function getWizard($propInfo, EnvironmentInterface $environment)
 {
     $wizard = '';
     $dispatcher = $environment->getEventDispatcher();
     $translator = $environment->getTranslator();
     $propExtra = $propInfo->getExtra();
     $assetsPath = 'assets/mootools/colorpicker/' . $GLOBALS['TL_ASSETS']['COLORPICKER'] . '/images/';
     if (array_key_exists('colorpicker', $propExtra) && $propExtra['colorpicker']) {
         $pickerText = $translator->translate('colorpicker', 'MSC');
         $event = new GenerateHtmlEvent('pickcolor.gif', $pickerText, sprintf('style="%s" title="%s" id="moo_%s"', 'vertical-align:top;cursor:pointer', specialchars($pickerText), $propInfo->getName()));
         $dispatcher->dispatch(ContaoEvents::IMAGE_GET_HTML, $event);
         // Support single fields as well (see contao/core#5240)
         $strKey = $propExtra['multiple'] ? $propInfo->getName() . '_0' : $propInfo->getName();
         $wizard .= sprintf(' %1$s <script>var cl;window.addEvent("domready", function() { new MooRainbow("moo_%2$s", {' . 'id: "ctrl_%3$s", startColor: ((cl = $("ctrl_%3$s").value.hexToRgb(true)) ? cl : [255, 0, 0]),' . 'imgPath: "%4$s", onComplete: function(color) {$("ctrl_%3$s").value = color.hex.replace("#", "");}});' . '});</script>', $event->getHtml(), $propInfo->getName(), $strKey, $assetsPath);
     }
     return $wizard;
 }
Пример #4
0
 /**
  * Fetch the options for a certain property.
  *
  * @param EnvironmentInterface $environment The environment.
  *
  * @param ModelInterface       $model       The model.
  *
  * @param PropertyInterface    $property    The property.
  *
  * @return array
  */
 protected static function getOptions($environment, $model, $property)
 {
     $options = $property->getOptions();
     $event = new GetPropertyOptionsEvent($environment, $model);
     $event->setPropertyName($property->getName());
     $event->setOptions($options);
     $environment->getEventDispatcher()->dispatch(sprintf('%s', $event::NAME), $event);
     if ($event->getOptions() !== $options) {
         $options = $event->getOptions();
     }
     return $options;
 }
 /**
  * Handle a property in a cloned model.
  *
  * @param ModelInterface        $model        The cloned model.
  *
  * @param PropertyInterface     $property     The property to handle.
  *
  * @param DataProviderInterface $dataProvider The data provider the model originates from.
  *
  * @return void
  */
 private function handleClonedModelProperty(ModelInterface $model, PropertyInterface $property, DataProviderInterface $dataProvider)
 {
     $extra = $property->getExtra();
     $propName = $property->getName();
     // Check doNotCopy.
     if (isset($extra['doNotCopy']) && $extra['doNotCopy'] === true) {
         $model->setProperty($propName, null);
         return;
     }
     // Check uniqueness.
     if (isset($extra['unique']) && $extra['unique'] === true && !$dataProvider->isUniqueValue($propName, $model->getProperty($propName))) {
         // Implicit "do not copy" unique values, they cannot be unique anymore.
         $model->setProperty($propName, null);
     }
 }
 /**
  * Parse the label of a single property.
  *
  * @param PropertyInterface $property The property to parse the label for.
  *
  * @param string|array      $label    The label value.
  *
  * @return void
  */
 protected function parseSinglePropertyLabel(PropertyInterface $property, $label)
 {
     if (!$property->getLabel()) {
         if (is_array($label)) {
             $lang = $label;
             $label = reset($lang);
             $description = next($lang);
             $property->setDescription($description);
         }
         $property->setLabel($label);
     }
 }
Пример #7
0
 /**
  * Build a widget for a given property.
  *
  * @param PropertyInterface $property The property.
  *
  * @param ModelInterface    $model    The current model.
  *
  * @return \Widget
  *
  * @throws DcGeneralRuntimeException When not running in TL_MODE BE.
  *
  * @SuppressWarnings(PHPMD.Superglobals)
  * @SuppressWarnings(PHPMD.CamelCaseVariableName)
  */
 public function buildWidget(PropertyInterface $property, ModelInterface $model)
 {
     if (TL_MODE !== 'BE') {
         throw new DcGeneralRuntimeException(sprintf('WidgetBuilder only supports TL_MODE "BE". Running in TL_MODE "%s".', TL_MODE));
     }
     $environment = $this->getEnvironment();
     $dispatcher = $environment->getEventDispatcher();
     $propertyName = $property->getName();
     $propExtra = $property->getExtra();
     $defName = $environment->getDataDefinition()->getName();
     $strClass = $this->getWidgetClass($property);
     $event = new DecodePropertyValueForWidgetEvent($environment, $model);
     $event->setProperty($propertyName)->setValue($model->getProperty($propertyName));
     $dispatcher->dispatch($event::NAME, $event);
     $varValue = $event->getValue();
     if (isset($propExtra['rgxp']) && in_array($propExtra['rgxp'], array('date', 'time', 'datim')) && empty($propExtra['mandatory']) && is_numeric($varValue) && $varValue == 0) {
         $varValue = '';
     }
     $propExtra['required'] = $varValue == '' && !empty($propExtra['mandatory']);
     $arrConfig = array('inputType' => $property->getWidgetType(), 'label' => array($property->getLabel(), $property->getDescription()), 'options' => $this->getOptionsForWidget($property, $model), 'eval' => $propExtra);
     if (isset($propExtra['reference'])) {
         $arrConfig['reference'] = $propExtra['reference'];
     }
     $event = new GetAttributesFromDcaEvent($arrConfig, $property->getName(), $varValue, $propertyName, $defName, new DcCompat($environment, $model, $propertyName));
     $dispatcher->dispatch(ContaoEvents::WIDGET_GET_ATTRIBUTES_FROM_DCA, $event);
     $arrPrepared = $event->getResult();
     if ($arrConfig['inputType'] == 'checkbox' && isset($GLOBALS['TL_DCA'][$defName]['subpalettes']) && is_array($GLOBALS['TL_DCA'][$defName]['subpalettes']) && in_array($propertyName, array_keys($GLOBALS['TL_DCA'][$defName]['subpalettes'])) && $arrConfig['eval']['submitOnChange']) {
         // We have to override the onclick, do not append to it as Contao adds it's own code here in
         // \Widget::getAttributesFromDca() which kills our sub palette handling!
         $arrPrepared['onclick'] = "Backend.autoSubmit('" . $defName . "');";
     }
     $objWidget = new $strClass($arrPrepared, new DcCompat($environment, $model, $propertyName));
     // OH: what is this? source: DataContainer 232.
     $objWidget->currentRecord = $model->getId();
     $objWidget->xlabel .= $this->getXLabel($property);
     $event = new ManipulateWidgetEvent($environment, $model, $property, $objWidget);
     $dispatcher->dispatch(ManipulateWidgetEvent::NAME, $event);
     return $objWidget;
 }
Пример #8
0
    /**
     * Get special labels.
     *
     * @param PropertyInterface $propInfo The property for which the X label shall be generated.
     *
     * @return string
     */
    protected function getXLabel($propInfo)
    {
        $strXLabel = '';
        $environment = $this->getEnvironment();
        $defName = $environment->getDataDefinition()->getName();
        $translator = $environment->getTranslator();
        // Toggle line wrap (textarea).
        if ($propInfo->getWidgetType() === 'textarea' && !array_key_exists('rte', $propInfo->getExtra())) {
            $event = new GenerateHtmlEvent('wrap.gif', $translator->translate('wordWrap', 'MSC'), sprintf('title="%s" class="toggleWrap" onclick="Backend.toggleWrap(\'ctrl_%s\');"', specialchars($translator->translate('wordWrap', 'MSC')), $propInfo->getName()));
            $environment->getEventPropagator()->propagate(ContaoEvents::IMAGE_GET_HTML, $event);
            $strXLabel .= ' ' . $event->getHtml();
        }
        // Add the help wizard.
        if ($propInfo->getExtra() && array_key_exists('helpwizard', $propInfo->getExtra())) {
            $event = new GenerateHtmlEvent('about.gif', $translator->translate('helpWizard', 'MSC'), 'style="vertical-align:text-bottom;"');
            $environment->getEventPropagator()->propagate(ContaoEvents::IMAGE_GET_HTML, $event);
            $strXLabel .= sprintf(' <a href="contao/help.php?table=%s&amp;field=%s"
				title="%s"
				onclick="Backend.openWindow(this, 600, 500); return false;">%s</a>', $defName, $propInfo->getName(), specialchars($translator->translate('helpWizard', 'MSC')), $event->getHtml());
        }
        // Add the popup file manager.
        if ($propInfo->getWidgetType() === 'fileTree') {
            // In Contao 3 it is always a file picker - no need for the button.
            if (version_compare(VERSION, '3.0', '<')) {
                $event = new GenerateHtmlEvent('filemanager.gif', $translator->translate('fileManager', 'MSC'), 'style="vertical-align:text-bottom;"');
                $environment->getEventPropagator()->propagate(ContaoEvents::IMAGE_GET_HTML, $event);
                $strXLabel .= sprintf(' <a href="contao/files.php"
					title="%s"
					onclick="Backend.getScrollOffset(); Backend.openWindow(this, 750, 500); return false;">%s</a>', specialchars($translator->translate('fileManager', 'MSC')), $event->getHtml());
            }
        } elseif ($propInfo->getWidgetType() === 'tableWizard') {
            $urlEvent = new AddToUrlEvent('key=table');
            $importTableEvent = new GenerateHtmlEvent('tablewizard.gif', $translator->translate('importTable.0', $defName), 'style="vertical-align:text-bottom;"');
            $shrinkEvent = new GenerateHtmlEvent('demagnify.gif', $translator->translate('shrink.0', $defName), sprintf('title="%s" style="vertical-align:text-bottom; cursor:pointer;" onclick="Backend.tableWizardResize(0.9);"', specialchars($translator->translate('shrink.1', $defName))));
            $expandEvent = new GenerateHtmlEvent('magnify.gif', $translator->translate('expand.0', $defName), sprintf('title="%s" style="vertical-align:text-bottom; cursor:pointer;" onclick="Backend.tableWizardResize(1.1);"', specialchars($translator->translate('expand.1', $defName))));
            $environment->getEventPropagator()->propagate(ContaoEvents::BACKEND_ADD_TO_URL, $urlEvent);
            $environment->getEventPropagator()->propagate(ContaoEvents::IMAGE_GET_HTML, $importTableEvent);
            $environment->getEventPropagator()->propagate(ContaoEvents::IMAGE_GET_HTML, $shrinkEvent);
            $environment->getEventPropagator()->propagate(ContaoEvents::IMAGE_GET_HTML, $expandEvent);
            $strXLabel .= sprintf(' <a href="%s" title="%s" onclick="Backend.getScrollOffset();">%s</a> %s%s', ampersand($urlEvent->getUrl()), specialchars($translator->translate('importTable.1', $defName)), $importTableEvent->getHtml(), $shrinkEvent->getHtml(), $expandEvent->getHtml());
        } elseif ($propInfo->getWidgetType() === 'listWizard') {
            $urlEvent = new AddToUrlEvent('key=list');
            $importListEvent = new GenerateHtmlEvent('tablewizard.gif', $translator->translate('importList.0', $defName), 'style="vertical-align:text-bottom;"');
            $environment->getEventPropagator()->propagate(ContaoEvents::BACKEND_ADD_TO_URL, $urlEvent);
            $environment->getEventPropagator()->propagate(ContaoEvents::IMAGE_GET_HTML, $importListEvent);
            $strXLabel .= sprintf(' <a href="%s" title="%s" onclick="Backend.getScrollOffset();">%s</a>', ampersand($urlEvent->getUrl()), specialchars($translator->translate('importList.1', $defName)), $importListEvent->getHtml());
        }
        return $strXLabel;
    }
 /**
  * Evaluate the contao 2 sorting flag into grouping length.
  *
  * @param ListingConfigInterface|PropertyInterface $config The property to evaluate the flag for.
  *
  * @param int                                      $flag   The flag to be evaluated.
  *
  * @return void
  */
 protected function evalFlagGroupingLength($config, $flag)
 {
     if ($flag == 1 || $flag == 2) {
         $config->setGroupingLength(1);
     } elseif ($flag == 3 || $flag == 4) {
         $config->setGroupingLength(2);
     }
 }
Пример #10
0
 /**
  * Create a widget for naming contexts. Use the language and translation information from the MetaModel.
  *
  * @param EnvironmentInterface $environment   The environment.
  *
  * @param PropertyInterface    $property      The property.
  *
  * @param IMetaModel           $metaModel     The MetaModel.
  *
  * @param string               $languageLabel The label to use for the language indicator.
  *
  * @param string               $valueLabel    The label to use for the input field.
  *
  * @param bool                 $isTextArea    If true, the widget will become a textarea, false otherwise.
  *
  * @param array                $arrValues     The values for the widget, needed to highlight the fallback language.
  *
  * @return void
  */
 public static function prepareLanguageAwareWidget(EnvironmentInterface $environment, PropertyInterface $property, IMetaModel $metaModel, $languageLabel, $valueLabel, $isTextArea, $arrValues)
 {
     if (!$metaModel->isTranslated()) {
         $extra = $property->getExtra();
         $extra['tl_class'] .= 'w50';
         $property->setWidgetType('text')->setExtra($extra);
         return;
     }
     $fallback = $metaModel->getFallbackLanguage();
     $languages = self::buildLanguageArray($metaModel, $environment->getTranslator());
     $neededKeys = array_keys($languages);
     // Ensure we have values for all languages present.
     if (array_diff_key(array_keys($arrValues), $neededKeys)) {
         foreach ($neededKeys as $langCode) {
             $arrValues[$langCode] = '';
         }
     }
     $rowClasses = array();
     foreach (array_keys($arrValues) as $langCode) {
         $rowClasses[] = $langCode == $fallback ? 'fallback_language' : 'normal_language';
     }
     $extra = $property->getExtra();
     $extra['minCount'] = $extra['maxCount'] = count($languages);
     $extra['disableSorting'] = true;
     $extra['tl_class'] = 'clr';
     $extra['columnFields'] = array('langcode' => array('label' => $languageLabel, 'exclude' => true, 'inputType' => 'justtextoption', 'options' => $languages, 'eval' => array('rowClasses' => $rowClasses, 'valign' => 'center', 'style' => 'min-width:75px;display:block;')), 'value' => array('label' => $valueLabel, 'exclude' => true, 'inputType' => $isTextArea ? 'textarea' : 'text', 'eval' => array('rowClasses' => $rowClasses, 'style' => 'width:400px;', 'rows' => 3)));
     $property->setWidgetType('multiColumnWizard')->setExtra($extra);
 }
Пример #11
0
 /**
  * Render a property option.
  *
  * @param RenderReadablePropertyValueEvent $event    The event to store the value to.
  * @param PropertyInterface                $property The property holding the options.
  * @param mixed                            $value    The value to format.
  *
  * @return void
  */
 private static function renderOptionValueReadable(RenderReadablePropertyValueEvent $event, $property, $value)
 {
     $options = $property->getOptions();
     if (!$options) {
         $options = self::getOptions($event->getEnvironment(), $event->getModel(), $event->getProperty());
         if ($options) {
             $property->setOptions($options);
         }
     }
     if (array_is_assoc($options)) {
         $event->setRendered($options[$value]);
     }
 }
Пример #12
0
 /**
  * Get for a field the readable value.
  *
  * @param EnvironmentInterface $environment The environment.
  *
  * @param PropertyInterface    $property    The property to be rendered.
  *
  * @param ModelInterface       $model       The model from which the property value shall be retrieved from.
  *
  * @return mixed
  */
 public static function getReadableFieldValue(EnvironmentInterface $environment, PropertyInterface $property, ModelInterface $model)
 {
     $event = new RenderReadablePropertyValueEvent($environment, $model, $property, $model->getProperty($property->getName()));
     $environment->getEventDispatcher()->dispatch($event::NAME, $event);
     if ($event->getRendered() !== null) {
         return $event->getRendered();
     }
     return $event->getValue();
 }
Пример #13
0
 /**
  * Get for a field the readable value.
  *
  * @param PropertyInterface $property The property to be rendered.
  *
  * @param ModelInterface    $model    The model from which the property value shall be retrieved from.
  *
  * @param mixed             $value    The value for the property.
  *
  * @return mixed
  */
 public function getReadableFieldValue(PropertyInterface $property, ModelInterface $model, $value)
 {
     $event = new RenderReadablePropertyValueEvent($this->getEnvironment(), $model, $property, $value);
     $this->getEnvironment()->getEventPropagator()->propagate($event::NAME, $event, array($this->getEnvironment()->getDataDefinition()->getName(), $property->getName()));
     if ($event->getRendered() !== null) {
         return $event->getRendered();
     }
     return $value;
 }
Пример #14
0
 /**
  * Build a widget for a given property.
  *
  * @param PropertyInterface $property The property.
  *
  * @param ModelInterface    $model    The current model.
  *
  * @return \Widget
  *
  * @throws DcGeneralRuntimeException When not running in TL_MODE BE.
  *
  * @SuppressWarnings(PHPMD.Superglobals)
  * @SuppressWarnings(PHPMD.CamelCaseVariableName)
  */
 public function buildWidget(PropertyInterface $property, ModelInterface $model)
 {
     if (TL_MODE !== 'BE') {
         throw new DcGeneralRuntimeException(sprintf('WidgetBuilder only supports TL_MODE "BE". Running in TL_MODE "%s".', TL_MODE));
     }
     $environment = $this->getEnvironment();
     $dispatcher = $environment->getEventDispatcher();
     $propertyName = $property->getName();
     $propExtra = $property->getExtra();
     $defName = $environment->getDataDefinition()->getName();
     $strClass = $this->getWidgetClass($property);
     $event = new DecodePropertyValueForWidgetEvent($environment, $model);
     $event->setProperty($propertyName)->setValue($model->getProperty($propertyName));
     $dispatcher->dispatch($event::NAME, $event);
     $varValue = $event->getValue();
     if (isset($propExtra['rgxp']) && in_array($propExtra['rgxp'], array('date', 'time', 'datim')) && empty($propExtra['mandatory']) && is_numeric($varValue) && $varValue == 0) {
         /*
             FIXME TEMPORARY WORKAROUND! To be fixed in the core:
             @see \Widget::getAttributesFromDca()
         */
         $varValue = '';
     }
     // OH: why not $required = $mandatory always? source: DataContainer 226.
     // OH: the whole prepareForWidget(..) thing is an only mess
     // Widgets should parse the configuration by themselves, depending on what they need.
     $propExtra['required'] = $varValue == '' && !empty($propExtra['mandatory']);
     $arrConfig = array('inputType' => $property->getWidgetType(), 'label' => array($property->getLabel(), $property->getDescription()), 'options' => $this->getOptionsForWidget($property, $model), 'eval' => $propExtra);
     if (isset($propExtra['reference'])) {
         $arrConfig['reference'] = $propExtra['reference'];
     }
     $event = new GetAttributesFromDcaEvent($arrConfig, $property->getName(), $varValue, $propertyName, $defName, new DcCompat($environment, $model, $propertyName));
     $dispatcher->dispatch(ContaoEvents::WIDGET_GET_ATTRIBUTES_FROM_DCA, $event);
     $arrPrepared = $event->getResult();
     // Bugfix CS: ajax subpalettes are really broken.
     // Therefore we reset to the default checkbox behaviour here and submit the entire form.
     // This way, the javascript needed by the widget (wizards) will be correctly evaluated.
     if ($arrConfig['inputType'] == 'checkbox' && isset($GLOBALS['TL_DCA'][$defName]['subpalettes']) && is_array($GLOBALS['TL_DCA'][$defName]['subpalettes']) && in_array($propertyName, array_keys($GLOBALS['TL_DCA'][$defName]['subpalettes'])) && $arrConfig['eval']['submitOnChange']) {
         // We have to override the onclick, do not append to it as Contao adds it's own code here in
         // \Widget::getAttributesFromDca() which kills our sub palette handling!
         $arrPrepared['onclick'] = "Backend.autoSubmit('" . $defName . "');";
     }
     $objWidget = new $strClass($arrPrepared, new DcCompat($environment, $model, $propertyName));
     // OH: what is this? source: DataContainer 232.
     $objWidget->currentRecord = $model->getId();
     $objWidget->xlabel .= $this->getXLabel($property);
     $event = new ManipulateWidgetEvent($environment, $model, $property, $objWidget);
     $dispatcher->dispatch(ManipulateWidgetEvent::NAME, $event);
     return $objWidget;
 }
 /**
  * Get special labels.
  *
  * @param EnvironmentInterface $environment The environment.
  *
  * @param PropertyInterface    $propInfo    The property for which the options shall be retrieved.
  *
  * @param ModelInterface       $model       The model.
  *
  * @return string
  */
 private function getOptionsForWidget(EnvironmentInterface $environment, PropertyInterface $propInfo, ModelInterface $model)
 {
     $dispatcher = $environment->getEventDispatcher();
     $options = $propInfo->getOptions();
     $event = new GetPropertyOptionsEvent($environment, $model);
     $event->setPropertyName($propInfo->getName());
     $event->setOptions($options);
     $dispatcher->dispatch(GetPropertyOptionsEvent::NAME, $event);
     if ($event->getOptions() !== $options) {
         return $event->getOptions();
     }
     return $options;
 }