diff --git a/composer.json b/composer.json index 9d5e6717b..9b6375ffe 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,8 @@ "contao-community-alliance/dependency-container": "~1.6", "contao-community-alliance/event-dispatcher": "~1.3", "contao-community-alliance/events-contao-bindings": "~3.2", - "doctrine/cache": "~1.3" + "doctrine/cache": "~1.3", + "symfony/expression-language": "^3.3" }, "require-dev": { "cyberspectrum/contao-toolbox": "~0.6", diff --git a/contao/config/event_listeners.php b/contao/config/event_listeners.php index a4cf53389..af1d6c947 100644 --- a/contao/config/event_listeners.php +++ b/contao/config/event_listeners.php @@ -22,6 +22,10 @@ */ use ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Event\GetPropertyOptionsEvent; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\ModelRelationship\FilterBuilder; +use ContaoCommunityAlliance\DcGeneral\Factory\Event\BuildDataDefinitionEvent; +use MetaModels\Attribute\IAttribute; +use MetaModels\DcGeneral\DataDefinition\IMetaModelDataDefinition; use MetaModels\DcGeneral\Events\MetaModel\CreateVariantButton; use MetaModels\DcGeneral\Events\MetaModel\CutButton; use MetaModels\DcGeneral\Events\MetaModel\DuplicateModel; @@ -40,8 +44,11 @@ use MetaModels\Filter\Setting\Events\CreateFilterSettingFactoryEvent; use MetaModels\Filter\Setting\SimpleLookupFilterSettingTypeFactory; use MetaModels\Filter\Setting\StaticIdListFilterSettingTypeFactory; +use MetaModels\IMetaModelsServiceContainer; use MetaModels\MetaModelsEvents; +use MultiColumnWizard\Event\GetOptionsEvent; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; return array( MetaModelsEvents::SUBSYSTEM_BOOT => array( @@ -93,6 +100,69 @@ function (CreateFilterSettingFactoryEvent $event) { ->addTypeFactory(new ConditionOrFilterSettingTypeFactory()); } ), + GetOptionsEvent::NAME => array( + function (GetOptionsEvent $event) { + if (('tl_metamodel_dca' !== $event->getEnvironment()->getDataDefinition()->getName()) + || ('additionalFilters' !== $event->getPropertyName()) + || ('property' !== $event->getSubPropertyName())) { + return; + } + + /** @var IMetaModelsServiceContainer $serviceContainer */ + $serviceContainer = $GLOBALS['container']['metamodels-service-container']; + + $metaModel = $serviceContainer->getFactory()->getMetaModel('mm_employee'); + + $options = array_values(array_merge( + $GLOBALS['METAMODELS_SYSTEM_COLUMNS'], + array_map( + function ( + /** @var IAttribute $attr */ + $attr + ) { + return $attr->getColName(); + }, + $metaModel->getAttributes() + ) + )); + + $event->setOptions($options); + } + ), + BuildDataDefinitionEvent::NAME => array( + [function (BuildDataDefinitionEvent $event) { + $container = $event->getContainer(); + if (!$container instanceof IMetaModelDataDefinition) { + return; + } + $definition = $container->getBasicDefinition(); + $screenId = $container->getMetaModelDefinition()->getActiveInputScreen(); + $dca = \Database::getInstance() + ->prepare('SELECT * FROM tl_metamodel_dca WHERE id=?') + ->execute($screenId); + + if (empty($dca->additionalFilters)) { + return; + } + + // Fetch current filter + $additionalFilter = $definition->getAdditionalFilter($definition->getDataProvider()) ?: []; + $filterBuilder = FilterBuilder::fromArrayForRoot($additionalFilter)->getFilter(); + + $language = new ExpressionLanguage(); + $exprVars = ['user' => $GLOBALS['container']['user']]; + + foreach (deserialize($dca->additionalFilters,true) as $f) { + $value = $language->evaluate($f['expression'], $exprVars); + $filterBuilder->andPropertyEquals($f['property'], $value); + } + + $definition->setAdditionalFilter( + $definition->getDataProvider(), + $filterBuilder->getAllAsArray() + ); + }, -500], + ), // deprecated since 2.0, to be removed in 3.0. MetaModelsEvents::PARSE_ITEM => array( array( diff --git a/contao/dca/tl_metamodel_dca.php b/contao/dca/tl_metamodel_dca.php index 11c67c6fd..d7b561b2d 100644 --- a/contao/dca/tl_metamodel_dca.php +++ b/contao/dca/tl_metamodel_dca.php @@ -244,6 +244,7 @@ 'iseditable', 'iscreatable', 'isdeleteable', + 'additionalFilters' ), ) ), @@ -488,6 +489,43 @@ function ($langCode) { 'tl_class' => 'w50 m12 cbx', ), 'sql' => "char(1) NOT NULL default ''" - ) + ), + 'additionalFilters' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_metamodel_dca']['additionalFilters'], + 'exclude' => true, + 'inputType' => 'multiColumnWizard', + 'eval' => array + ( + 'tl_class' => 'clr', + 'columnFields' => array + ( + 'property' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_metamodel_dca']['addfilter_property'], + 'exclude' => true, + 'inputType' => 'select', + 'eval' => array + ( + 'tl_class' => 'clr', + 'style' => 'width:200px', + 'includeBlankOption' => true, + 'chosen' => 'true', + ) + ), + 'expression' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_metamodel_dca']['addfilter_expression'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => array + ( + 'style' => 'width:180px', + ) + ), + ), + ), + 'sql' => "text NULL" + ), ) );