vendor/pimcore/pimcore/models/DataObject/ClassDefinition/Data/ManyToManyObjectRelation.php line 158

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 Pimcore\Model;
  16. use Pimcore\Model\DataObject;
  17. use Pimcore\Model\DataObject\ClassDefinition\Data\Relations\AbstractRelations;
  18. use Pimcore\Model\DataObject\Concrete;
  19. use Pimcore\Model\Element;
  20. use Pimcore\Normalizer\NormalizerInterface;
  21. class ManyToManyObjectRelation extends AbstractRelations implements QueryResourcePersistenceAwareInterfaceOptimizedAdminLoadingInterfaceTypeDeclarationSupportInterfaceVarExporterInterfaceNormalizerInterfaceIdRewriterInterfacePreGetDataInterfacePreSetDataInterfaceLayoutDefinitionEnrichmentInterface
  22. {
  23.     use Model\DataObject\ClassDefinition\Data\Extension\Relation;
  24.     use Extension\QueryColumnType;
  25.     use DataObject\ClassDefinition\Data\Relations\AllowObjectRelationTrait;
  26.     use DataObject\ClassDefinition\Data\Relations\ManyToManyRelationTrait;
  27.     use DataObject\ClassDefinition\Data\Extension\RelationFilterConditionParser;
  28.     /**
  29.      * Static type of this element
  30.      *
  31.      * @internal
  32.      *
  33.      * @var string
  34.      */
  35.     public $fieldtype 'manyToManyObjectRelation';
  36.     /**
  37.      * @internal
  38.      *
  39.      * @var string|int
  40.      */
  41.     public $width 0;
  42.     /**
  43.      * Type for the column to query
  44.      *
  45.      * @internal
  46.      *
  47.      * @var string|int
  48.      */
  49.     public $height 0;
  50.     /**
  51.      * @internal
  52.      *
  53.      * @var int|null
  54.      */
  55.     public $maxItems;
  56.     /**
  57.      * Type for the column to query
  58.      *
  59.      * @internal
  60.      *
  61.      * @var string
  62.      */
  63.     public $queryColumnType 'text';
  64.     /**
  65.      * @internal
  66.      *
  67.      * @var bool
  68.      */
  69.     public $relationType true;
  70.     /**
  71.      * @internal
  72.      *
  73.      * @var string|null
  74.      */
  75.     public $visibleFields;
  76.     /**
  77.      * @internal
  78.      *
  79.      * @var bool
  80.      */
  81.     public $allowToCreateNewObject true;
  82.     /**
  83.      * @internal
  84.      *
  85.      * @var bool
  86.      */
  87.     public $optimizedAdminLoading false;
  88.     /**
  89.      * @internal
  90.      *
  91.      * @var bool
  92.      */
  93.     public $enableTextSelection false;
  94.     /**
  95.      * @internal
  96.      *
  97.      * @var array
  98.      */
  99.     public $visibleFieldDefinitions = [];
  100.     /**
  101.      * @return bool
  102.      */
  103.     public function getObjectsAllowed()
  104.     {
  105.         return true;
  106.     }
  107.     /**
  108.      * {@inheritdoc}
  109.      */
  110.     protected function prepareDataForPersistence($data$object null$params = [])
  111.     {
  112.         $return = [];
  113.         if (is_array($data) && count($data) > 0) {
  114.             $counter 1;
  115.             foreach ($data as $object) {
  116.                 if ($object instanceof DataObject\Concrete) {
  117.                     $return[] = [
  118.                         'dest_id' => $object->getId(),
  119.                         'type' => 'object',
  120.                         'fieldname' => $this->getName(),
  121.                         'index' => $counter,
  122.                     ];
  123.                 }
  124.                 $counter++;
  125.             }
  126.             return $return;
  127.         } elseif (is_array($data) && count($data) === 0) {
  128.             //give empty array if data was not null
  129.             return [];
  130.         } else {
  131.             //return null if data was null - this indicates data was not loaded
  132.             return null;
  133.         }
  134.     }
  135.     /**
  136.      * {@inheritdoc}
  137.      */
  138.     protected function loadData(array $data$object null$params = [])
  139.     {
  140.         $objects = [
  141.             'dirty' => false,
  142.             'data' => [],
  143.         ];
  144.         foreach ($data as $relation) {
  145.             $o DataObject::getById($relation['dest_id']);
  146.             if ($o instanceof DataObject\Concrete) {
  147.                 $objects['data'][] = $o;
  148.             } else {
  149.                 $objects['dirty'] = true;
  150.             }
  151.         }
  152.         //must return array - otherwise this means data is not loaded
  153.         return $objects;
  154.     }
  155.     /**
  156.      * @see QueryResourcePersistenceAwareInterface::getDataForQueryResource
  157.      *
  158.      * @param mixed $data
  159.      * @param null|DataObject\Concrete $object
  160.      * @param mixed $params
  161.      *
  162.      * @throws \Exception
  163.      *
  164.      * @return string|null
  165.      */
  166.     public function getDataForQueryResource($data$object null$params = [])
  167.     {
  168.         //return null when data is not set
  169.         if (!$data) {
  170.             return null;
  171.         }
  172.         $ids = [];
  173.         if (is_array($data)) {
  174.             foreach ($data as $relation) {
  175.                 if ($relation instanceof DataObject\Concrete) {
  176.                     $ids[] = $relation->getId();
  177.                 }
  178.             }
  179.             return ',' implode(','$ids) . ',';
  180.         }
  181.         throw new \Exception('invalid data passed to getDataForQueryResource - must be array and it is: ' print_r($datatrue));
  182.     }
  183.     /**
  184.      * @see Data::getDataForEditmode
  185.      *
  186.      * @param array $data
  187.      * @param null|DataObject\Concrete $object
  188.      * @param mixed $params
  189.      *
  190.      * @return array
  191.      */
  192.     public function getDataForEditmode($data$object null$params = [])
  193.     {
  194.         $return = [];
  195.         $visibleFieldsArray $this->getVisibleFields() ? explode(','$this->getVisibleFields()) : [];
  196.         $gridFields = (array)$visibleFieldsArray;
  197.         // add data
  198.         if (is_array($data) && count($data) > 0) {
  199.             foreach ($data as $referencedObject) {
  200.                 if ($referencedObject instanceof DataObject\Concrete) {
  201.                     $return[] = DataObject\Service::gridObjectData($referencedObject$gridFieldsnull, ['purpose' => 'editmode']);
  202.                 }
  203.             }
  204.         }
  205.         return $return;
  206.     }
  207.     /**
  208.      * @see Data::getDataFromEditmode
  209.      *
  210.      * @param array|null|false $data
  211.      * @param null|DataObject\Concrete $object
  212.      * @param mixed $params
  213.      *
  214.      * @return array|null
  215.      */
  216.     public function getDataFromEditmode($data$object null$params = [])
  217.     {
  218.         //if not set, return null
  219.         if ($data === null || $data === false) {
  220.             return null;
  221.         }
  222.         $objects = [];
  223.         if (is_array($data) && count($data) > 0) {
  224.             foreach ($data as $object) {
  225.                 $o DataObject::getById($object['id']);
  226.                 if ($o) {
  227.                     $objects[] = $o;
  228.                 }
  229.             }
  230.         }
  231.         //must return array if data shall be set
  232.         return $objects;
  233.     }
  234.     /**
  235.      * @see Data::getDataFromEditmode
  236.      *
  237.      * @param array $data
  238.      * @param null|DataObject\Concrete $object
  239.      * @param mixed $params
  240.      *
  241.      * @return array
  242.      */
  243.     public function getDataFromGridEditor($data$object null$params = [])
  244.     {
  245.         return $this->getDataFromEditmode($data$object$params);
  246.     }
  247.     /**
  248.      * @param array|null $data
  249.      * @param DataObject\Concrete|null $object
  250.      * @param mixed $params
  251.      *
  252.      * @return array|null
  253.      */
  254.     public function getDataForGrid($data$object null$params = [])
  255.     {
  256.         return $this->getDataForEditmode($data$object$params);
  257.     }
  258.     /**
  259.      * @see Data::getVersionPreview
  260.      *
  261.      * @param Element\ElementInterface[]|null $data
  262.      * @param null|DataObject\Concrete $object
  263.      * @param mixed $params
  264.      *
  265.      * @return string|null
  266.      */
  267.     public function getVersionPreview($data$object null$params = [])
  268.     {
  269.         if (is_array($data) && count($data) > 0) {
  270.             $paths = [];
  271.             foreach ($data as $o) {
  272.                 if ($o instanceof Element\ElementInterface) {
  273.                     $paths[] = $o->getRealFullPath();
  274.                 }
  275.             }
  276.             return implode('<br />'$paths);
  277.         }
  278.         return null;
  279.     }
  280.     /**
  281.      * @return string|int
  282.      */
  283.     public function getWidth()
  284.     {
  285.         return $this->width;
  286.     }
  287.     /**
  288.      * @param string|int $width
  289.      *
  290.      * @return $this
  291.      */
  292.     public function setWidth($width)
  293.     {
  294.         if (is_numeric($width)) {
  295.             $width = (int)$width;
  296.         }
  297.         $this->width $width;
  298.         return $this;
  299.     }
  300.     /**
  301.      * @return string|int
  302.      */
  303.     public function getHeight()
  304.     {
  305.         return $this->height;
  306.     }
  307.     /**
  308.      * @param string|int $height
  309.      *
  310.      * @return $this
  311.      */
  312.     public function setHeight($height)
  313.     {
  314.         if (is_numeric($height)) {
  315.             $height = (int)$height;
  316.         }
  317.         $this->height $height;
  318.         return $this;
  319.     }
  320.     /**
  321.      * {@inheritdoc}
  322.      */
  323.     public function checkValidity($data$omitMandatoryCheck false$params = [])
  324.     {
  325.         if (!$omitMandatoryCheck && $this->getMandatory() && empty($data)) {
  326.             throw new Element\ValidationException('Empty mandatory field [ '.$this->getName().' ]');
  327.         }
  328.         if (is_array($data)) {
  329.             $this->performMultipleAssignmentCheck($data);
  330.             foreach ($data as $o) {
  331.                 if (empty($o)) {
  332.                     continue;
  333.                 }
  334.                 $allowClass $this->allowObjectRelation($o);
  335.                 if (!$allowClass || !($o instanceof DataObject\Concrete)) {
  336.                     if (!$allowClass && $o instanceof DataObject\Concrete) {
  337.                         $id $o->getId();
  338.                     } else {
  339.                         $id '??';
  340.                     }
  341.                     throw new Element\ValidationException('Invalid object relation to object ['.$id.'] in field ' $this->getName(). ' , tried to assign ' $o->getId());
  342.                 }
  343.             }
  344.             if ($this->getMaxItems() && count($data) > $this->getMaxItems()) {
  345.                 throw new Element\ValidationException('Number of allowed relations in field `' $this->getName() . '` exceeded (max. ' $this->getMaxItems() . ')');
  346.             }
  347.         }
  348.     }
  349.     /**
  350.      * {@inheritdoc}
  351.      */
  352.     public function getForCsvExport($object$params = [])
  353.     {
  354.         $data $this->getDataFromObjectParam($object$params);
  355.         if (is_array($data)) {
  356.             $paths = [];
  357.             foreach ($data as $eo) {
  358.                 if ($eo instanceof Element\ElementInterface) {
  359.                     $paths[] = $eo->getRealFullPath();
  360.                 }
  361.             }
  362.             return implode(','$paths);
  363.         }
  364.         return '';
  365.     }
  366.     /**
  367.      * @param DataObject\AbstractObject[]|null $data
  368.      *
  369.      * @return array
  370.      */
  371.     public function resolveDependencies($data)
  372.     {
  373.         $dependencies = [];
  374.         if (is_array($data) && count($data) > 0) {
  375.             foreach ($data as $o) {
  376.                 if ($o instanceof DataObject\AbstractObject) {
  377.                     $dependencies['object_' $o->getId()] = [
  378.                         'id' => $o->getId(),
  379.                         'type' => 'object',
  380.                     ];
  381.                 }
  382.             }
  383.         }
  384.         return $dependencies;
  385.     }
  386.     /**
  387.      * @param mixed $container
  388.      * @param array $params
  389.      *
  390.      * @return array
  391.      */
  392.     public function preGetData(/** mixed */ $container/** array */ $params = []) // : mixed
  393.     {
  394.         $data null;
  395.         if ($container instanceof DataObject\Concrete) {
  396.             $data $container->getObjectVar($this->getName());
  397.             if (!$container->isLazyKeyLoaded($this->getName())) {
  398.                 $data $this->load($container);
  399.                 $container->setObjectVar($this->getName(), $data);
  400.                 $this->markLazyloadedFieldAsLoaded($container);
  401.             }
  402.         } elseif ($container instanceof DataObject\Localizedfield) {
  403.             $data $params['data'];
  404.         } elseif ($container instanceof DataObject\Fieldcollection\Data\AbstractData) {
  405.             parent::loadLazyFieldcollectionField($container);
  406.             $data $container->getObjectVar($this->getName());
  407.         } elseif ($container instanceof DataObject\Objectbrick\Data\AbstractData) {
  408.             parent::loadLazyBrickField($container);
  409.             $data $container->getObjectVar($this->getName());
  410.         }
  411.         if (DataObject::doHideUnpublished() && is_array($data)) {
  412.             $publishedList = [];
  413.             foreach ($data as $listElement) {
  414.                 if (Element\Service::isPublished($listElement)) {
  415.                     $publishedList[] = $listElement;
  416.                 }
  417.             }
  418.             return $publishedList;
  419.         }
  420.         return is_array($data) ? $data : [];
  421.     }
  422.     /**
  423.      * { @inheritdoc }
  424.      */
  425.     public function preSetData(/** mixed */ $container/**  mixed */ $data/** array */ $params = []) // : mixed
  426.     {
  427.         if ($data === null) {
  428.             $data = [];
  429.         }
  430.         $this->markLazyloadedFieldAsLoaded($container);
  431.         return $data;
  432.     }
  433.     /**
  434.      * @param int|null $maxItems
  435.      *
  436.      * @return $this
  437.      */
  438.     public function setMaxItems($maxItems)
  439.     {
  440.         $this->maxItems $this->getAsIntegerCast($maxItems);
  441.         return $this;
  442.     }
  443.     /**
  444.      * @return int|null
  445.      */
  446.     public function getMaxItems()
  447.     {
  448.         return $this->maxItems;
  449.     }
  450.     /**
  451.      * {@inheritdoc}
  452.      */
  453.     public function isDiffChangeAllowed($object$params = [])
  454.     {
  455.         return true;
  456.     }
  457.     /** Generates a pretty version preview (similar to getVersionPreview) can be either html or
  458.      * a image URL. See the https://github.com/pimcore/object-merger bundle documentation for details
  459.      *
  460.      * @param Element\ElementInterface[]|null $data
  461.      * @param DataObject\Concrete|null $object
  462.      * @param mixed $params
  463.      *
  464.      * @return array
  465.      */
  466.     public function getDiffVersionPreview($data$object null$params = [])
  467.     {
  468.         $value = [];
  469.         $value['type'] = 'html';
  470.         $value['html'] = '';
  471.         if ($data) {
  472.             $html $this->getVersionPreview($data$object$params);
  473.             $value['html'] = $html;
  474.         }
  475.         return $value;
  476.     }
  477.     /**
  478.      * { @inheritdoc }
  479.      */
  480.     public function rewriteIds(/** mixed */ $container/** array */ $idMapping/** array */ $params = []) /** :mixed */
  481.     {
  482.         $data $this->getDataFromObjectParam($container$params);
  483.         $data $this->rewriteIdsService($data$idMapping);
  484.         return $data;
  485.     }
  486.     /**
  487.      * @param DataObject\ClassDefinition\Data\ManyToManyObjectRelation $masterDefinition
  488.      */
  489.     public function synchronizeWithMasterDefinition(DataObject\ClassDefinition\Data $masterDefinition)
  490.     {
  491.         $this->maxItems $masterDefinition->maxItems;
  492.         $this->relationType $masterDefinition->relationType;
  493.     }
  494.     /**
  495.      * {@inheritdoc}
  496.      */
  497.     public function enrichLayoutDefinition(/* ?Concrete */ $object/* array */ $context = []) // : static
  498.     {
  499.         if (!$this->visibleFields) {
  500.             return $this;
  501.         }
  502.         $classIds $this->getClasses();
  503.         if (empty($classIds[0]['classes'])) {
  504.             return $this;
  505.         }
  506.         $classId $classIds[0]['classes'];
  507.         if (is_numeric($classId)) {
  508.             $class DataObject\ClassDefinition::getById($classId);
  509.         } else {
  510.             $class DataObject\ClassDefinition::getByName($classId);
  511.         }
  512.         if (!$class) {
  513.             return $this;
  514.         }
  515.         $this->visibleFieldDefinitions = [];
  516.         $translator \Pimcore::getContainer()->get('translator');
  517.         $visibleFields explode(','$this->visibleFields);
  518.         foreach ($visibleFields as $field) {
  519.             $fd $class->getFieldDefinition($field$context);
  520.             if (!$fd) {
  521.                 $fieldFound false;
  522.                 /** @var Localizedfields|null $localizedfields */
  523.                 $localizedfields $class->getFieldDefinitions($context)['localizedfields'] ?? null;
  524.                 if ($localizedfields) {
  525.                     if ($fd $localizedfields->getFieldDefinition($field)) {
  526.                         $this->visibleFieldDefinitions[$field]['name'] = $fd->getName();
  527.                         $this->visibleFieldDefinitions[$field]['title'] = $fd->getTitle();
  528.                         $this->visibleFieldDefinitions[$field]['fieldtype'] = $fd->getFieldType();
  529.                         if ($fd instanceof DataObject\ClassDefinition\Data\Select || $fd instanceof DataObject\ClassDefinition\Data\Multiselect) {
  530.                             $this->visibleFieldDefinitions[$field]['options'] = $fd->getOptions();
  531.                         }
  532.                         $fieldFound true;
  533.                     }
  534.                 }
  535.                 if (!$fieldFound) {
  536.                     $this->visibleFieldDefinitions[$field]['name'] = $field;
  537.                     $this->visibleFieldDefinitions[$field]['title'] = $translator->trans($field, [], 'admin');
  538.                     $this->visibleFieldDefinitions[$field]['fieldtype'] = 'input';
  539.                 }
  540.             } else {
  541.                 $this->visibleFieldDefinitions[$field]['name'] = $fd->getName();
  542.                 $this->visibleFieldDefinitions[$field]['title'] = $fd->getTitle();
  543.                 $this->visibleFieldDefinitions[$field]['fieldtype'] = $fd->getFieldType();
  544.                 $this->visibleFieldDefinitions[$field]['noteditable'] = true;
  545.                 if ($fd instanceof DataObject\ClassDefinition\Data\Select || $fd instanceof DataObject\ClassDefinition\Data\Multiselect) {
  546.                     if ($fd->getOptionsProviderClass()) {
  547.                         $this->visibleFieldDefinitions[$field]['optionsProviderClass'] = $fd->getOptionsProviderClass();
  548.                     }
  549.                     $this->visibleFieldDefinitions[$field]['options'] = $fd->getOptions();
  550.                 }
  551.             }
  552.         }
  553.         return $this;
  554.     }
  555.     /**
  556.      * {@inheritdoc}
  557.      */
  558.     protected function getPhpdocType()
  559.     {
  560.         return implode(' | '$this->getPhpDocClassString(true));
  561.     }
  562.     /**
  563.      * {@inheritdoc}
  564.      */
  565.     public function normalize($value$params = [])
  566.     {
  567.         if (is_array($value)) {
  568.             $result = [];
  569.             foreach ($value as $element) {
  570.                 $type Element\Service::getElementType($element);
  571.                 $id $element->getId();
  572.                 $result[] = [
  573.                     'type' => $type,
  574.                     'id' => $id,
  575.                 ];
  576.             }
  577.             return $result;
  578.         }
  579.         return null;
  580.     }
  581.     /**
  582.      * {@inheritdoc}
  583.      */
  584.     public function denormalize($value$params = [])
  585.     {
  586.         if (is_array($value)) {
  587.             $result = [];
  588.             foreach ($value as $elementData) {
  589.                 $type $elementData['type'];
  590.                 $id $elementData['id'];
  591.                 $element Element\Service::getElementById($type$id);
  592.                 if ($element) {
  593.                     $result[] = $element;
  594.                 }
  595.             }
  596.             return $result;
  597.         }
  598.         return null;
  599.     }
  600.     /**
  601.      * Returns a ID which must be unique across the grid rows
  602.      *
  603.      * @internal
  604.      *
  605.      * @param array $item
  606.      *
  607.      * @return string
  608.      */
  609.     protected function buildUniqueKeyForDiffEditor($item)
  610.     {
  611.         return $item['id'];
  612.     }
  613.     /**
  614.      * @internal
  615.      */
  616.     protected function processDiffDataForEditMode($originalData$data$object null$params = [])
  617.     {
  618.         if ($data) {
  619.             $data $data[0];
  620.             $items $data['data'];
  621.             $newItems = [];
  622.             if ($items) {
  623.                 foreach ($items as $in) {
  624.                     $item = [];
  625.                     $item['id'] = $in['id'];
  626.                     $item['path'] = $in['fullpath'];
  627.                     $item['type'] = $in['type'];
  628.                     $unique $this->buildUniqueKeyForDiffEditor($item);
  629.                     $itemId json_encode($item);
  630.                     $raw $itemId;
  631.                     $newItems[] = [
  632.                         'itemId' => $itemId,
  633.                         'title' => $item['path'],
  634.                         'raw' => $raw,
  635.                         'gridrow' => $item,
  636.                         'unique' => $unique,
  637.                     ];
  638.                 }
  639.                 $data['data'] = $newItems;
  640.             }
  641.             $data['value'] = [
  642.                 'type' => 'grid',
  643.                 'columnConfig' => [
  644.                     'id' => [
  645.                         'width' => 60,
  646.                     ],
  647.                     'path' => [
  648.                         'flex' => 2,
  649.                     ],
  650.                 ],
  651.                 'html' => $this->getVersionPreview($originalData$object$params),
  652.             ];
  653.             $newData = [];
  654.             $newData[] = $data;
  655.             return $newData;
  656.         }
  657.         return $data;
  658.     }
  659.     /**
  660.      * {@inheritdoc}
  661.      */
  662.     public function getDiffDataForEditMode($data$object null$params = [])
  663.     {
  664.         $originalData $data;
  665.         $data parent::getDiffDataForEditMode($data$object$params);
  666.         $data $this->processDiffDataForEditMode($originalData$data$object$params);
  667.         return $data;
  668.     }
  669.     /** See parent class.
  670.      *
  671.      * @param array $data
  672.      * @param DataObject\Concrete|null $object
  673.      * @param mixed $params
  674.      *
  675.      * @return array|null
  676.      */
  677.     public function getDiffDataFromEditmode($data$object null$params = [])
  678.     {
  679.         if ($data) {
  680.             $tabledata $data[0]['data'];
  681.             $result = [];
  682.             if ($tabledata) {
  683.                 foreach ($tabledata as $in) {
  684.                     $out json_decode($in['raw'], true);
  685.                     $result[] = $out;
  686.                 }
  687.             }
  688.             return $this->getDataFromEditmode($result$object$params);
  689.         }
  690.         return null;
  691.     }
  692.     /**
  693.      * @param array|string|null $visibleFields
  694.      *
  695.      * @return $this
  696.      */
  697.     public function setVisibleFields($visibleFields)
  698.     {
  699.         if (is_array($visibleFields) && count($visibleFields)) {
  700.             $visibleFields implode(','$visibleFields);
  701.         }
  702.         $this->visibleFields $visibleFields;
  703.         return $this;
  704.     }
  705.     /**
  706.      * @return string|null
  707.      */
  708.     public function getVisibleFields()
  709.     {
  710.         return $this->visibleFields;
  711.     }
  712.     /**
  713.      * @return bool
  714.      */
  715.     public function isAllowToCreateNewObject(): bool
  716.     {
  717.         return $this->allowToCreateNewObject;
  718.     }
  719.     /**
  720.      * @param bool $allowToCreateNewObject
  721.      */
  722.     public function setAllowToCreateNewObject($allowToCreateNewObject)
  723.     {
  724.         $this->allowToCreateNewObject = (bool)$allowToCreateNewObject;
  725.     }
  726.     /**
  727.      * {@inheritdoc}
  728.      */
  729.     public function isOptimizedAdminLoading(): bool
  730.     {
  731.         return (bool) $this->optimizedAdminLoading;
  732.     }
  733.     /**
  734.      * @param bool $optimizedAdminLoading
  735.      */
  736.     public function setOptimizedAdminLoading($optimizedAdminLoading)
  737.     {
  738.         $this->optimizedAdminLoading $optimizedAdminLoading;
  739.     }
  740.     /**
  741.      * @return bool
  742.      */
  743.     public function isEnableTextSelection(): bool
  744.     {
  745.         return $this->enableTextSelection;
  746.     }
  747.     /**
  748.      * @param bool $enableTextSelection
  749.      */
  750.     public function setEnableTextSelection(bool $enableTextSelection): void
  751.     {
  752.         $this->enableTextSelection $enableTextSelection;
  753.     }
  754.     /**
  755.      * {@inheritdoc}
  756.      */
  757.     public function isFilterable(): bool
  758.     {
  759.         return true;
  760.     }
  761.     /**
  762.      * {@inheritdoc}
  763.      */
  764.     public function addListingFilter(DataObject\Listing $listing$data$operator '=')
  765.     {
  766.         if ($data instanceof DataObject\Concrete) {
  767.             $data $data->getId();
  768.         }
  769.         if ($operator === '=') {
  770.             $listing->addConditionParam('`'.$this->getName().'` LIKE ?''%,'.$data.',%');
  771.             return $listing;
  772.         }
  773.         return parent::addListingFilter($listing$data$operator);
  774.     }
  775.     /**
  776.      * Filter by relation feature
  777.      *
  778.      * @param array|string|null $value
  779.      * @param string            $operator
  780.      * @param array             $params
  781.      *
  782.      * @return string
  783.      */
  784.     public function getFilterConditionExt($value$operator$params = [])
  785.     {
  786.         $name $params['name'] ?: $this->name;
  787.         return $this->getRelationFilterCondition($value$operator$name);
  788.     }
  789. }