vendor/pimcore/pimcore/models/DataObject/ClassDefinition/Data/Select.php line 609

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Model\DataObject\ClassDefinition\Data;
  15. use InvalidArgumentException;
  16. use Pimcore\Model;
  17. use Pimcore\Model\DataObject;
  18. use Pimcore\Model\DataObject\ClassDefinition\Data;
  19. use Pimcore\Model\DataObject\ClassDefinition\Service;
  20. use Pimcore\Model\DataObject\Concrete;
  21. use Pimcore\Normalizer\NormalizerInterface;
  22. class Select extends Data implements
  23.     ResourcePersistenceAwareInterface,
  24.     QueryResourcePersistenceAwareInterface,
  25.     TypeDeclarationSupportInterface,
  26.     EqualComparisonInterface,
  27.     VarExporterInterface,
  28.     \JsonSerializable,
  29.     NormalizerInterface,
  30.     LayoutDefinitionEnrichmentInterface,
  31.     FieldDefinitionEnrichmentInterface
  32. {
  33.     use Model\DataObject\Traits\SimpleComparisonTrait;
  34.     use Extension\ColumnType;
  35.     use Extension\QueryColumnType;
  36.     use DataObject\Traits\SimpleNormalizerTrait;
  37.     use DataObject\Traits\DefaultValueTrait;
  38.     /**
  39.      * Static type of this element
  40.      *
  41.      * @internal
  42.      *
  43.      * @var string
  44.      */
  45.     public $fieldtype 'select';
  46.     /**
  47.      * Available options to select
  48.      *
  49.      * @internal
  50.      *
  51.      * @var array|null
  52.      */
  53.     public $options;
  54.     /**
  55.      * @internal
  56.      *
  57.      * @var string|int
  58.      */
  59.     public $width 0;
  60.     /**
  61.      * @internal
  62.      *
  63.      * @var string|null
  64.      */
  65.     public $defaultValue;
  66.     /**
  67.      * Options provider class
  68.      *
  69.      * @internal
  70.      *
  71.      * @var string
  72.      */
  73.     public $optionsProviderClass;
  74.     /**
  75.      * Options provider data
  76.      *
  77.      * @internal
  78.      *
  79.      * @var string
  80.      */
  81.     public $optionsProviderData;
  82.     /**
  83.      * Type for the column to query
  84.      *
  85.      * @internal
  86.      *
  87.      * @var string
  88.      */
  89.     public $queryColumnType 'varchar';
  90.     /**
  91.      * Type for the column
  92.      *
  93.      * @internal
  94.      *
  95.      * @var string
  96.      */
  97.     public $columnType 'varchar';
  98.     /**
  99.      * Column length
  100.      *
  101.      * @internal
  102.      *
  103.      * @var int
  104.      */
  105.     public $columnLength 190;
  106.     /**
  107.      * @internal
  108.      *
  109.      * @var bool
  110.      */
  111.     public $dynamicOptions false;
  112.     /**
  113.      * @return int
  114.      */
  115.     public function getColumnLength()
  116.     {
  117.         return $this->columnLength;
  118.     }
  119.     /**
  120.      * @param int|null $columnLength
  121.      *
  122.      * @return $this
  123.      */
  124.     public function setColumnLength($columnLength)
  125.     {
  126.         if ($columnLength) {
  127.             $this->columnLength $columnLength;
  128.         }
  129.         return $this;
  130.     }
  131.     /**
  132.      * Correct old column definitions (e.g varchar(255)) to the new format
  133.      *
  134.      * @param string $type
  135.      */
  136.     private function correctColumnDefinition($type)
  137.     {
  138.         if (preg_match("/(.*)\((\d+)\)/i"$this->$type$matches)) {
  139.             $this->{'set' ucfirst($type)}($matches[1]);
  140.             if ($matches[2] > 190) {
  141.                 $matches[2] = 190;
  142.             }
  143.             $this->setColumnLength($matches[2] <= 190 $matches[2] : 190);
  144.         }
  145.     }
  146.     /**
  147.      * {@inheritdoc}
  148.      */
  149.     public function getColumnType()
  150.     {
  151.         $this->correctColumnDefinition('columnType');
  152.         return $this->columnType '(' $this->getColumnLength() . ')';
  153.     }
  154.     /**
  155.      * {@inheritdoc}
  156.      */
  157.     public function getQueryColumnType()
  158.     {
  159.         $this->correctColumnDefinition('queryColumnType');
  160.         return $this->queryColumnType '(' $this->getColumnLength() . ')';
  161.     }
  162.     /**
  163.      * @return array
  164.      */
  165.     public function getOptions()
  166.     {
  167.         return $this->options;
  168.     }
  169.     /**
  170.      * @param array|null $options
  171.      *
  172.      * @return $this
  173.      */
  174.     public function setOptions(?array $options)
  175.     {
  176.         if (is_array($options)) {
  177.             $this->options = [];
  178.             foreach ($options as $option) {
  179.                 $option = (array)$option;
  180.                 if (!array_key_exists('key'$option) || !array_key_exists('value'$option)) {
  181.                     throw new InvalidArgumentException('Please provide select options as associative array with fields "key" and "value"');
  182.                 }
  183.                 $this->options[] = $option;
  184.             }
  185.         } else {
  186.             $this->options null;
  187.         }
  188.         return $this;
  189.     }
  190.     /**
  191.      * @return string|int
  192.      */
  193.     public function getWidth()
  194.     {
  195.         return $this->width;
  196.     }
  197.     /**
  198.      * @param string|int $width
  199.      *
  200.      * @return $this
  201.      */
  202.     public function setWidth($width)
  203.     {
  204.         if (is_numeric($width)) {
  205.             $width = (int)$width;
  206.         }
  207.         $this->width $width;
  208.         return $this;
  209.     }
  210.     /**
  211.      * @see ResourcePersistenceAwareInterface::getDataForResource
  212.      *
  213.      * @param string $data
  214.      * @param null|DataObject\Concrete $object
  215.      * @param mixed $params
  216.      *
  217.      * @return string
  218.      */
  219.     public function getDataForResource($data$object null$params = [])
  220.     {
  221.         $data $this->handleDefaultValue($data$object$params);
  222.         return $data;
  223.     }
  224.     /**
  225.      * @see ResourcePersistenceAwareInterface::getDataFromResource
  226.      *
  227.      * @param string $data
  228.      * @param null|DataObject\Concrete $object
  229.      * @param mixed $params
  230.      *
  231.      * @return string
  232.      */
  233.     public function getDataFromResource($data$object null$params = [])
  234.     {
  235.         return $data;
  236.     }
  237.     /**
  238.      * @see QueryResourcePersistenceAwareInterface::getDataForQueryResource
  239.      *
  240.      * @param string $data
  241.      * @param null|DataObject\Concrete $object
  242.      * @param mixed $params
  243.      *
  244.      * @return string
  245.      */
  246.     public function getDataForQueryResource($data$object null$params = [])
  247.     {
  248.         return $this->getDataForResource($data$object$params);
  249.     }
  250.     /**
  251.      * @see Data::getDataForEditmode
  252.      *
  253.      * @param string $data
  254.      * @param null|DataObject\Concrete $object
  255.      * @param mixed $params
  256.      *
  257.      * @return string
  258.      */
  259.     public function getDataForEditmode($data$object null$params = [])
  260.     {
  261.         return $this->getDataForResource($data$object$params);
  262.     }
  263.     /**
  264.      * @see Data::getDataFromEditmode
  265.      *
  266.      * @param string $data
  267.      * @param null|DataObject\Concrete $object
  268.      * @param mixed $params
  269.      *
  270.      * @return string
  271.      */
  272.     public function getDataFromEditmode($data$object null$params = [])
  273.     {
  274.         return $this->getDataFromResource($data$object$params);
  275.     }
  276.     /**
  277.      * @see Data::getVersionPreview
  278.      *
  279.      * @param string $data
  280.      * @param null|DataObject\Concrete $object
  281.      * @param mixed $params
  282.      *
  283.      * @return string
  284.      */
  285.     public function getVersionPreview($data$object null$params = [])
  286.     {
  287.         return htmlspecialchars($dataENT_QUOTES'UTF-8');
  288.     }
  289.     /**
  290.      * {@inheritdoc}
  291.      */
  292.     public function isDiffChangeAllowed($object$params = [])
  293.     {
  294.         return true;
  295.     }
  296.     /** See parent class.
  297.      * @param mixed $data
  298.      * @param DataObject\Concrete|null $object
  299.      * @param mixed $params
  300.      *
  301.      * @return array|null
  302.      */
  303.     public function getDiffDataForEditMode($data$object null$params = [])
  304.     {
  305.         $result = [];
  306.         $diffdata = [];
  307.         $diffdata['data'] = $data;
  308.         $diffdata['disabled'] = false;
  309.         $diffdata['field'] = $this->getName();
  310.         $diffdata['key'] = $this->getName();
  311.         $diffdata['type'] = $this->fieldtype;
  312.         $value '';
  313.         foreach ($this->options as $option) {
  314.             if ($option['value'] == $data) {
  315.                 $value $option['key'];
  316.                 break;
  317.             }
  318.         }
  319.         $diffdata['value'] = $value;
  320.         $diffdata['title'] = !empty($this->title) ? $this->title $this->name;
  321.         $result[] = $diffdata;
  322.         return $result;
  323.     }
  324.     /**
  325.      * {@inheritdoc}
  326.      */
  327.     public function checkValidity($data$omitMandatoryCheck false$params = [])
  328.     {
  329.         if (!$omitMandatoryCheck && $this->getMandatory() && $this->isEmpty($data)) {
  330.             throw new Model\Element\ValidationException('Empty mandatory field [ ' $this->getName() . ' ]');
  331.         }
  332.     }
  333.     /**
  334.      * @param string|null $data
  335.      *
  336.      * @return bool
  337.      */
  338.     public function isEmpty($data)
  339.     {
  340.         return strlen($data) < 1;
  341.     }
  342.     /**
  343.      * @param DataObject\ClassDefinition\Data\Select $masterDefinition
  344.      */
  345.     public function synchronizeWithMasterDefinition(DataObject\ClassDefinition\Data $masterDefinition)
  346.     {
  347.         $this->options $masterDefinition->options;
  348.         $this->columnLength $masterDefinition->columnLength;
  349.         $this->defaultValue $masterDefinition->defaultValue;
  350.         $this->optionsProviderClass $masterDefinition->optionsProviderClass;
  351.         $this->optionsProviderData $masterDefinition->optionsProviderData;
  352.     }
  353.     /**
  354.      * @return string|null
  355.      */
  356.     public function getDefaultValue()
  357.     {
  358.         return $this->defaultValue;
  359.     }
  360.     /**
  361.      * @param string|null $defaultValue
  362.      */
  363.     public function setDefaultValue($defaultValue)
  364.     {
  365.         $this->defaultValue $defaultValue;
  366.     }
  367.     /**
  368.      * @return string
  369.      */
  370.     public function getOptionsProviderClass()
  371.     {
  372.         return $this->optionsProviderClass;
  373.     }
  374.     /**
  375.      * @param string $optionsProviderClass
  376.      */
  377.     public function setOptionsProviderClass($optionsProviderClass)
  378.     {
  379.         $this->optionsProviderClass $optionsProviderClass;
  380.     }
  381.     /**
  382.      * @return string
  383.      */
  384.     public function getOptionsProviderData()
  385.     {
  386.         return $this->optionsProviderData;
  387.     }
  388.     /**
  389.      * @param string $optionsProviderData
  390.      */
  391.     public function setOptionsProviderData($optionsProviderData)
  392.     {
  393.         $this->optionsProviderData $optionsProviderData;
  394.     }
  395.     /**
  396.      * { @inheritdoc }
  397.      */
  398.     public function enrichFieldDefinition(/** array */ $context = []) /** : Data */
  399.     {
  400.         $optionsProvider DataObject\ClassDefinition\Helper\OptionsProviderResolver::resolveProvider(
  401.             $this->getOptionsProviderClass(),
  402.             DataObject\ClassDefinition\Helper\OptionsProviderResolver::MODE_SELECT
  403.         );
  404.         if ($optionsProvider) {
  405.             $context['fieldname'] = $this->getName();
  406.             $options $optionsProvider->{'getOptions'}($context$this);
  407.             $this->setOptions($options);
  408.         }
  409.         return $this;
  410.     }
  411.     /**
  412.      * {@inheritdoc}
  413.      */
  414.     public function enrichLayoutDefinition(/*?Concrete */ $object/**  array */ $context = []) // : self
  415.     {
  416.         $optionsProvider DataObject\ClassDefinition\Helper\OptionsProviderResolver::resolveProvider(
  417.             $this->getOptionsProviderClass(),
  418.             DataObject\ClassDefinition\Helper\OptionsProviderResolver::MODE_SELECT
  419.         );
  420.         if ($optionsProvider) {
  421.             $context['object'] = $object;
  422.             if ($object) {
  423.                 $context['class'] = $object->getClass();
  424.             }
  425.             $context['fieldname'] = $this->getName();
  426.             if (!isset($context['purpose'])) {
  427.                 $context['purpose'] = 'layout';
  428.             }
  429.             $inheritanceEnabled DataObject::getGetInheritedValues();
  430.             DataObject::setGetInheritedValues(true);
  431.             $options $optionsProvider->{'getOptions'}($context$this);
  432.             DataObject::setGetInheritedValues($inheritanceEnabled);
  433.             $this->setOptions($options);
  434.             $defaultValue $optionsProvider->{'getDefaultValue'}($context$this);
  435.             $this->setDefaultValue($defaultValue);
  436.             $hasStaticOptions $optionsProvider->{'hasStaticOptions'}($context$this);
  437.             $this->dynamicOptions = !$hasStaticOptions;
  438.         }
  439.         return $this;
  440.     }
  441.     /**
  442.      * @param string|null $data
  443.      * @param DataObject\Concrete|null $object
  444.      * @param array $params
  445.      *
  446.      * @return array|string
  447.      */
  448.     public function getDataForGrid($data$object null$params = [])
  449.     {
  450.         $optionsProvider DataObject\ClassDefinition\Helper\OptionsProviderResolver::resolveProvider(
  451.             $this->getOptionsProviderClass(),
  452.             DataObject\ClassDefinition\Helper\OptionsProviderResolver::MODE_SELECT
  453.         );
  454.         if ($optionsProvider) {
  455.             $context $params['context'] ?? [];
  456.             $context['object'] = $object;
  457.             if ($object) {
  458.                 $context['class'] = $object->getClass();
  459.             }
  460.             $context['fieldname'] = $this->getName();
  461.             $options $optionsProvider->{'getOptions'}($context$this);
  462.             $this->setOptions($options);
  463.             if (isset($params['purpose']) && $params['purpose'] == 'editmode') {
  464.                 $result $data;
  465.             } else {
  466.                 $result = ['value' => $data ?? null'options' => $this->getOptions()];
  467.             }
  468.             return $result;
  469.         }
  470.         return $data;
  471.     }
  472.     /**
  473.      * returns sql query statement to filter according to this data types value(s)
  474.      *
  475.      * @param string|array $value
  476.      * @param string $operator
  477.      * @param array $params optional params used to change the behavior
  478.      *
  479.      * @return string|null
  480.      */
  481.     public function getFilterConditionExt($value$operator$params = [])
  482.     {
  483.         $value is_array($value) ? current($value) : $value;
  484.         $name $params['name'] ?: $this->name;
  485.         $db \Pimcore\Db::get();
  486.         $key $db->quoteIdentifier($name);
  487.         if (!empty($params['brickPrefix'])) {
  488.             $key $params['brickPrefix'].$key;
  489.         }
  490.         if ($operator === '=') {
  491.             return $key.' = '."\"$value\"".' ';
  492.         }
  493.         if ($operator === 'LIKE') {
  494.             return $key.' LIKE '."\"%$value%\"".' ';
  495.         }
  496.         return null;
  497.     }
  498.     /**
  499.      * {@inheritdoc}
  500.      */
  501.     public function isFilterable(): bool
  502.     {
  503.         return true;
  504.     }
  505.     /**
  506.      * {@inheritdoc}
  507.      */
  508.     protected function doGetDefaultValue($object$context = [])
  509.     {
  510.         /** @var DataObject\ClassDefinition\DynamicOptionsProvider\SelectOptionsProviderInterface|null $optionsProvider */
  511.         $optionsProvider DataObject\ClassDefinition\Helper\OptionsProviderResolver::resolveProvider(
  512.             $this->getOptionsProviderClass(),
  513.             DataObject\ClassDefinition\Helper\OptionsProviderResolver::MODE_SELECT
  514.         );
  515.         if ($optionsProvider) {
  516.             $context['object'] = $object;
  517.             if ($object) {
  518.                 $context['class'] = $object->getClass();
  519.             }
  520.             $context['fieldname'] = $this->getName();
  521.             if (!isset($context['purpose'])) {
  522.                 $context['purpose'] = 'layout';
  523.             }
  524.             return $optionsProvider->getDefaultValue($context$this);
  525.         }
  526.         return $this->getDefaultValue();
  527.     }
  528.     /**
  529.      * @return $this
  530.      */
  531.     public function jsonSerialize()
  532.     {
  533.         if ($this->getOptionsProviderClass() && Service::doRemoveDynamicOptions()) {
  534.             $this->options null;
  535.         }
  536.         return $this;
  537.     }
  538.     /**
  539.      * {@inheritdoc}
  540.      */
  541.     public function resolveBlockedVars(): array
  542.     {
  543.         $blockedVars parent::resolveBlockedVars();
  544.         if ($this->getOptionsProviderClass()) {
  545.             $blockedVars[] = 'options';
  546.         }
  547.         return $blockedVars;
  548.     }
  549.     /**
  550.      * {@inheritdoc}
  551.      */
  552.     public function getParameterTypeDeclaration(): ?string
  553.     {
  554.         return '?string';
  555.     }
  556.     /**
  557.      * {@inheritdoc}
  558.      */
  559.     public function getReturnTypeDeclaration(): ?string
  560.     {
  561.         return '?string';
  562.     }
  563.     /**
  564.      * {@inheritdoc}
  565.      */
  566.     public function getPhpdocInputType(): ?string
  567.     {
  568.         return 'string|null';
  569.     }
  570.     /**
  571.      * {@inheritdoc}
  572.      */
  573.     public function getPhpdocReturnType(): ?string
  574.     {
  575.         return 'string|null';
  576.     }
  577. }