FOF30\Model\DataModel\Behaviour\RelationFilters::onAfterBuildQuery PHP Method

onAfterBuildQuery() public method

This event runs after we have built the query used to fetch a record list in a model. It is used to apply automatic query filters based on model relations.
public onAfterBuildQuery ( &$model, &$query ) : void
return void
    public function onAfterBuildQuery(&$model, &$query)
    {
        $relationFilters = $model->getRelationFilters();
        foreach ($relationFilters as $filterState) {
            $relationName = $filterState['relation'];
            $tableAlias = $model->getBehaviorParam('tableAlias', null);
            $subQuery = $model->getRelations()->getCountSubquery($relationName, $tableAlias);
            // Callback method needs different handling
            if (isset($filterState['method']) && $filterState['method'] == 'callback') {
                call_user_func_array($filterState['value'], array(&$subQuery));
                $filterState['method'] = 'search';
                $filterState['operator'] = '>=';
                $filterState['value'] = '1';
            }
            $options = new JRegistry($filterState);
            $filter = new DataModel\Filter\Relation($model->getDbo(), $relationName, $subQuery);
            $methods = $filter->getSearchMethods();
            $method = $options->get('method', $filter->getDefaultSearchMethod());
            if (!in_array($method, $methods)) {
                $method = 'exact';
            }
            switch ($method) {
                case 'between':
                case 'outside':
                    $sql = $filter->{$method}($options->get('from', null), $options->get('to'));
                    break;
                case 'interval':
                    $sql = $filter->{$method}($options->get('value', null), $options->get('interval'));
                    break;
                case 'search':
                    $sql = $filter->{$method}($options->get('value', null), $options->get('operator', '='));
                    break;
                default:
                    $sql = $filter->{$method}($options->get('value', null));
                    break;
            }
            if ($sql) {
                $query->where($sql);
            }
        }
    }

Usage Example

Beispiel #1
0
 /**
  * @group           Behaviour
  * @group           RelationFiltersOnAfterBuildQuery
  * @covers          FOF30\Model\DataModel\Behaviour\RelationFilters::onAfterBuildQuery
  * @dataProvider    RelationFiltersDataprovider::getTestOnAfterBuildQuery
  */
 public function testOnAfterBuildQuery($test, $check)
 {
     \PHPUnit_Framework_Error_Warning::$enabled = false;
     $msg = 'RelationFilters::onAfterBuildQuery %s - Case: ' . $check['case'];
     $config = array('relations' => array(array('itemName' => 'children', 'type' => 'hasMany', 'foreignModelClass' => 'Children', 'localKey' => 'fakeapp_parent_id', 'foreignKey' => 'fakeapp_parent_id')));
     /** @var \FOF30\Model\DataModel $model */
     $model = new Parents(static::$container, $config);
     $query = \JFactory::getDbo()->getQuery(true)->select('*')->from('test');
     $dispatcher = $model->getBehavioursDispatcher();
     $filter = new RelationFilters($dispatcher);
     // I have to setup a filter
     $model->has('children', $test['operator'], $test['value']);
     $filter->onAfterBuildQuery($model, $query);
     $this->assertEquals($check['query'], trim((string) $query), sprintf($msg, 'Failed to build the search query'));
 }
RelationFilters