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

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