2

I have articles with a multi-select named theme.

This works fine in a template:

{% set entries = craft.entries.section('article').search('theme:themeFoobar') %}
<p>{{ entries | length }}</p>

I'm working on a plugin to create a custom source containing only those articles that have themeFoobar selected in their multi-select, this is what I have:

public function modifyEntrySources(&$sources, $context)
{
  $sources[] = array('heading' => 'Themes');

  $sources['theme:foobar'] = array(
    'label' => 'Theme: Foobar',
    'criteria' => array(
      'section' => 'article',
      'search' => 'theme:themeFoobar'
    )
  );
}

The result of this is that the source contains all articles, it looks like the search criteria is completely ignored.

Is search not the correct criteria to use here? Is there another criteria I can use to find only the articles with themeFoobar selected in the multi-select?

Further information

The multi-select used to be just a dropdown. When it was a dropdown, this plugin worked fine:

public function modifyEntrySources(&$sources, $context)
{
  $sources[] = array('heading' => 'Themes');

  $sources['theme:foobar'] = array(
    'label' => 'Theme: Foobar',
    'criteria' => array(
      'section' => 'article',
      'theme' => 'themeFoobar'
    )
  );
}
Esseb
  • 151
  • 5

1 Answers1

3

My solution, thanks to @carlcs:

public function modifyEntrySources(&$sources, $context)
{
    $sources[] = array('heading' => Craft::t('Themes'));

    $themes = array(
        'THEME_FOO' => 'themeFoo',
        'THEME_BAR' => 'themeBar'
    );

    $criteria = craft()->elements->getCriteria(ElementType::Entry);
    $criteria->section = 'article';
    $articles = $criteria->find();

    foreach ($themes as $theme => $label)
    {
        // Loop through all articles and check if they contain the current theme.
        // If they do, add it to the ids array which we will later use to filter
        // just the articles with this theme.
        $ids = [];
        foreach ($articles as $article)
        {
            foreach ($article->theme as $articleTheme)
            {
                if ($articleTheme == $themes[$theme])
                {
                    array_push($ids, $article->id);
                    break;
                }
            }
        }

        $sources['theme:' . $label] = array(
            'label' => Craft::t('Theme') . ': ' . Craft::t($theme),
            'criteria' => array(
                'section' => 'article',
                'id' => $ids
            )
        );
    }
}

The PHP itself could be cleaned up, but this works for now.

Categories would probably have been a simpler solution had I gone for that originally.

Esseb
  • 151
  • 5