4

I'm using Smart Map to find locations ordered by distance. But I can only set 3 parameters: target, range and units. However, when my range goes beyond the country borders I obviously get results in other countries. I want to list all locations within a country by distance, but limited to that country.

Is it possible to do this? I tried related items, but can't seem to get it to work. And I don't see any option in Smart Map either.

Lindsey D
  • 23,974
  • 5
  • 53
  • 110
Tom De Smet
  • 1,456
  • 8
  • 28

2 Answers2

5

What I've done to do something very similar is to add a template variable to my BusinessLogic plugin, that takes the ElementCriteriaModel, prepared with all other parameters e.g. section, limit and SmartMap set. The plugin then translates the model into a Yii CDbCommand using buildElementsQuery, adds the additional conditions to the query and returns the further filtered entry models to the template.

Here's my service function with modifications for your country filtering needs. It#s untested but should probably work as is:

public function addCountryCriteria(ElementCriteriaModel $criteria, $country)
{
    $query = craft()->elements->buildElementsQuery($criteria);

    // Add where condition for country filter
    $params = array(':country' => $country);
    $conditions = array('smartmap_addresses.country = :country');

    $query->andWhere($conditions, $params);

    // Join addresses table to bring in the state
    $query->leftJoin('smartmap_addresses smartmap_addresses', 'smartmap_addresses.elementId = entries.id');

    // Get query results and populate entry models
    $results = $query->queryAll();

    return EntryModel::populateModels($results);
}

Also have a look at my other answers on how to add conditions to CDbCommand from the template:

carlcs
  • 36,220
  • 5
  • 62
  • 139
4

At the moment, there's no in-plugin way to handle this. However, you can probably do it out-of-plugin, once you've retrieved a larger set of results.

So first, you'd get the largest possible results set:

{% set params = {
    target: targetLocation,
    range:  10000,
    units:  'kilometers'
} %}

{% set entries = craft.entries.myFieldHandle(params).order('distance').find() %}

Then, you'd cycle through those results to filter only the entries from your desired country:

{% set desiredCountry = 'France' %}
{% set filteredByCountry = [] %}

{% for entry in entries %} {% if entry.myFieldHandle.country == desiredCountry %} {% set filteredByCountry = filteredByCountry|merge([entry]) %} {% endif %} {% endfor %}

Once you've done that, you'll have a filteredByCountry array of entries, which should be exactly the results set you were looking for.

Lindsey D
  • 23,974
  • 5
  • 53
  • 110
  • I did it the exact same way before I read your post :) Thanks anyway for the quick response! Love the power of Twig! – Tom De Smet Aug 12 '15 at 11:35