<p>You can only modify a <code>craft.entries</code> criteria model with a field (→ <a href="https://craftcms.stackexchange.com/q/11875/125">Add custom element criteria attribute without a field type?</a>). So what you have to do is to create a new custom field type with your plugin, and add such a field to the entry types you want to filter.</p>

<pre><code>{% set entries = craft.entries.section('mySection').country('germany') %}
</code></pre>

<p>With that criteria model you would pass the value "germany" to your custom field type field "country". The field type would then use this parameter to modify criteria model's query.</p>

<p>Here's some code that should help you putting this together:</p>

<pre><code>public function getInputHtml($name, $value)
{
    return;
}

public function modifyElementsQuery(DbCommand $query, $params)
{
    if ($params !== null)
    {
        craft()-&gt;businessLogic-&gt;addCountryCriteria($query, $params);
    }
}
</code></pre>

<p>You don't want the field to show up as an input field in the edit entry view, so we let <code>getInputHtml()</code> return null.</p>

<p>In our <code>modifyElementsQuery</code> method we just check if there's a parameter submitted (the country), before passing the criteria model's query to the service.</p>

<pre><code>public function addCountryCriteria(DbCommand $query, $country)
{
    // Add conditons to the query 
    $query-&gt;andWhere($conditions, $params);
}
</code></pre>

<p>Your <code>addCountryCriteria</code> service can basically stay untouched, except that you can remove <code>buildElementsQuery()</code>, <code>queryAll()</code> and <code>populateModels()</code>. As you only want to modify the query.</p>

CC BY-SA 3.0
2015-10-30T13:31:33.087Z
Thanks for your quick and perfect answer! This is my first time handling with custom fieldtypes, but your clear explanation makes it very easy to understand. I'm going to dive into plugin development for Craft, it looks promising to me this way. For now I've got it up and running thanks to you.
ctigelaar
CC BY-SA 3.0
2015-11-28T15:34:54.767Z
wow that is a very cool way to go about it. i'm sure that will come in handy for me in the future.
bhu Boue vidya
CC BY-SA 3.0
2015-10-30T11:36:55.477Z
2015-10-30T11:36:55.477Z
2017-04-13T12:51:00.253Z
carlcs
<p>First some context. I'm using <a href="https://plugins.doublesecretagency.com/smart-map/" rel="nofollow noreferrer">Smart Map</a> for Craft to display some location based events in a listing. My structure is as follows:</p>
<ul>
<li>Events channel</li>
<li>Locations channel</li>
</ul>
<p>Each event can occur multiple times, so I created a matrix field for this, where they can add blocks with a time and select a location.</p>
<p>The problem occurs when I want to filter the list of results based on the city of the location. Smartmaps <a href="https://craftcms.stackexchange.com/questions/10875/filter-locations-by-country-in-smart-map">doesn't support filtering by cities</a> and I do want to use pagination, so I went with the <a href="https://craftcms.stackexchange.com/a/10878/3937">custom plugin solution mentioned</a> in that question. Unfortunately I can't comment yet on that answer, so therefore I created my new question.</p>
<p>The problem is that Craft <code>{% paginate %}</code> doesn't work with the <code>Array</code> result of <code>EntryModel::populateModels</code>. I'm getting the following error in my search results page:</p>
<blockquote>
<p>Argument 1 passed to Craft\TemplateHelper::paginateCriteria() must be an instance of Craft\ElementCriteriaModel, array given</p>
</blockquote>
<p>So my question is, how can I modify the <code>ElementCriteriaModel</code> to join content from different tables (in this case Smartmaps') and still return an <code>ElementCriteriaModel</code> to be used by the Craft pagination?</p>
<p>I also have read some more <a href="https://craftcms.stackexchange.com/questions/2763/whats-the-difference-between-elementcriteriamodel-and-dbcommand">explanation about <code>ElementCriteriaModel</code></a> and some similar issues like <a href="https://craftcms.stackexchange.com/questions/11992/search-across-entries-and-assets-and-paginate">this one</a> and <a href="https://craftcms.stackexchange.com/questions/2786/how-can-i-do-more-complicated-queries-with-an-elementcriteriamodel">this one</a>, but without any luck. Maybe there is a much simpler solution, but I'm out of options for now.</p>

<plugin-development><elementcriteriamodel><pagination><plugin-smartmap>
Modify ElementCriteria and use it for paginate
# Modify ElementCriteria and use it for paginate

(Asked by: username_0 on 2015-10-30)

First some context. I'm using [Smart Map](https://plugins.doublesecretagency.com/smart-map/) for Craft to display some location based events in a listing. My structure is as follows:

* Events channel
* Locations channel

Each event can occur multiple times, so I created a matrix field for this, where they can add blocks with a time and select a location.

The problem occurs when I want to filter the list of results based on the city of the location. Smartmaps [doesn't support filtering by cities](https://craftcms.stackexchange.com/questions/10875/filter-locations-by-country-in-smart-map) and I do want to use pagination, so I went with the [custom plugin solution mentioned](https://craftcms.stackexchange.com/a/10878/3937) in that question. Unfortunately I can't comment yet on that answer, so therefore I created my new question.

The problem is that Craft `{% paginate %}` doesn't work with the `Array` result of `EntryModel::populateModels`. I'm getting the following error in my search results page:

> Argument 1 passed to Craft\TemplateHelper::paginateCriteria() must be an instance of Craft\ElementCriteriaModel, array given

So my question is, how can I modify the `ElementCriteriaModel` to join content from different tables (in this case Smartmaps') and still return an `ElementCriteriaModel` to be used by the Craft pagination?

I also have read some more [explanation about `ElementCriteriaModel`](https://craftcms.stackexchange.com/questions/2763/whats-the-difference-between-elementcriteriamodel-and-dbcommand) and some similar issues like [this one](https://craftcms.stackexchange.com/questions/11992/search-across-entries-and-assets-and-paginate) and [this one](https://craftcms.stackexchange.com/questions/2786/how-can-i-do-more-complicated-queries-with-an-elementcriteriamodel), but without any luck. Maybe there is a much simpler solution, but I'm out of options for now.

**Tags:** plugin-development, elementcriteriamodel, pagination, plugin-smartmap

---

## 1 answers

### Answer by username_1 on 2015-10-30. Score: 5 | Accepted answer

You can only modify a craft.entries criteria model with a field (→ Add custom element criteria attribute without a field type?). So what you have to do is to create a new custom field type with your plugin, and add such a field to the entry types you want to filter.
{% set entries = craft.entries.section('mySection').country('germany') %}

With that criteria model you would pass the value "germany" to your custom field type field "country". The field type would then use this parameter to modify criteria model's query.
Here's some code that should help you putting this together:
public function getInputHtml($name, $value)
{
    return;
}

public function modifyElementsQuery(DbCommand $query, $params)
{
    if ($params !== null)
    {
        craft()->businessLogic->addCountryCriteria($query, $params);
    }
}

You don't want the field to show up as an input field in the edit entry view, so we let getInputHtml() return null.
In our modifyElementsQuery method we just check if there's a parameter submitted (the country), before passing the criteria model's query to the service.
public function addCountryCriteria(DbCommand $query, $country)
{
    // Add conditons to the query 
    $query->andWhere($conditions, $params);
}

Your addCountryCriteria service can basically stay untouched, except that you can remove buildElementsQuery(), queryAll() and populateModels(). As you only want to modify the query.

> **Comments:**
> **username_0**: Thanks for your quick and perfect answer! This is my first time handling with custom fieldtypes, but your clear explanation makes it very easy to understand. I'm going to dive into plugin development for Craft, it looks promising to me this way. For now I've got it up and running thanks to you.  
> **username_2**: wow that is a very cool way to go about it. i'm sure that will come in handy for me in the future.  

---

