diff --git a/administrator/components/com_categories/models/categories.php b/administrator/components/com_categories/models/categories.php
index 3abca0d1ff985..334f183fee180 100644
--- a/administrator/components/com_categories/models/categories.php
+++ b/administrator/components/com_categories/models/categories.php
@@ -129,6 +129,7 @@ protected function getStoreId($id = '')
$id .= ':' . $this->getState('filter.extension');
$id .= ':' . $this->getState('filter.published');
$id .= ':' . $this->getState('filter.language');
+ $id .= ':' . serialize($this->getState('filter.tag'));
return parent::getStoreId($id);
}
@@ -151,7 +152,7 @@ protected function getListQuery()
$query->select(
$this->getState(
'list.select',
- 'a.id, a.title, a.alias, a.note, a.published, a.access' .
+ 'DISTINCT a.id, a.title, a.alias, a.note, a.published, a.access' .
', a.checked_out, a.checked_out_time, a.created_user_id' .
', a.path, a.parent_id, a.level, a.lft, a.rgt' .
', a.language'
@@ -250,17 +251,34 @@ protected function getListQuery()
$query->where('a.language = ' . $db->quote($language));
}
- // Filter by a single tag.
+ // Filter by a single or group of tags.
+ $hasTag = false;
$tagId = $this->getState('filter.tag');
if (is_numeric($tagId))
{
- $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId)
- ->join(
- 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
- . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
- . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote($extension . '.category')
- );
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId);
+ }
+ elseif (is_array($tagId))
+ {
+ JArrayHelper::toInteger($tagId);
+ $tagId = implode(',', $tagId);
+ if (!empty($tagId))
+ {
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' IN (' . $tagId . ')');
+ }
+ }
+
+ if ($hasTag)
+ {
+ $query->join('LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
+ . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
+ . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote($extension . '.category')
+ );
}
// Add the list ordering clause
diff --git a/administrator/components/com_categories/models/forms/filter_categories.xml b/administrator/components/com_categories/models/forms/filter_categories.xml
index f799bf39e181a..53eddd34feb6c 100644
--- a/administrator/components/com_categories/models/forms/filter_categories.xml
+++ b/administrator/components/com_categories/models/forms/filter_categories.xml
@@ -54,11 +54,12 @@
name="tag"
type="tag"
mode="nested"
+ multiple="true"
+ class="multipleTags"
label="JOPTION_FILTER_TAG"
description="JOPTION_FILTER_TAG_DESC"
onchange="this.form.submit();"
>
-
diff --git a/administrator/components/com_categories/views/categories/tmpl/default.php b/administrator/components/com_categories/views/categories/tmpl/default.php
index 3c289c8c78ad6..9984372e26092 100644
--- a/administrator/components/com_categories/views/categories/tmpl/default.php
+++ b/administrator/components/com_categories/views/categories/tmpl/default.php
@@ -14,6 +14,7 @@
JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
+JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG')));
JHtml::_('formbehavior.chosen', 'select');
$app = JFactory::getApplication();
diff --git a/administrator/components/com_content/models/articles.php b/administrator/components/com_content/models/articles.php
index ea58c35031545..bb8e5c18246cc 100644
--- a/administrator/components/com_content/models/articles.php
+++ b/administrator/components/com_content/models/articles.php
@@ -138,11 +138,12 @@ protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
- $id .= ':' . $this->getState('filter.access');
+ $id .= ':' . serialize($this->getState('filter.access'));
$id .= ':' . $this->getState('filter.published');
- $id .= ':' . $this->getState('filter.category_id');
- $id .= ':' . $this->getState('filter.author_id');
+ $id .= ':' . serialize($this->getState('filter.category_id'));
+ $id .= ':' . serialize($this->getState('filter.author_id'));
$id .= ':' . $this->getState('filter.language');
+ $id .= ':' . serialize($this->getState('filter.tag'));
return parent::getStoreId($id);
}
@@ -166,7 +167,7 @@ protected function getListQuery()
$query->select(
$this->getState(
'list.select',
- 'a.id, a.title, a.alias, a.checked_out, a.checked_out_time, a.catid' .
+ 'DISTINCT a.id, a.title, a.alias, a.checked_out, a.checked_out_time, a.catid' .
', a.state, a.access, a.created, a.created_by, a.created_by_alias, a.ordering, a.featured, a.language, a.hits' .
', a.publish_up, a.publish_down'
)
@@ -203,10 +204,18 @@ protected function getListQuery()
}
// Filter by access level.
- if ($access = $this->getState('filter.access'))
+ $access = $this->getState('filter.access');
+
+ if (is_numeric($access))
{
$query->where('a.access = ' . (int) $access);
}
+ elseif(is_array($access))
+ {
+ JArrayHelper::toInteger($access);
+ $access = implode(',', $access);
+ $query->where('a.access IN (' . $access . ')');
+ }
// Implement View Level Access
if (!$user->authorise('core.admin'))
@@ -263,6 +272,13 @@ protected function getListQuery()
$query->where('a.created_by ' . $type . (int) $authorId);
}
+ elseif (is_array($authorId))
+ {
+ JArrayHelper::toInteger($categoryId);
+ $authorId = implode(',', $authorId);
+ $query->where('a.created_by IN (' . $authorId . ')');
+ }
+
// Filter by search in title.
$search = $this->getState('filter.search');
@@ -290,17 +306,34 @@ protected function getListQuery()
$query->where('a.language = ' . $db->quote($language));
}
- // Filter by a single tag.
+ // Filter by a single or group of tags.
+ $hasTag = false;
$tagId = $this->getState('filter.tag');
if (is_numeric($tagId))
{
- $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId)
- ->join(
- 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
- . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
- . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article')
- );
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId);
+ }
+ elseif (is_array($tagId))
+ {
+ JArrayHelper::toInteger($tagId);
+ $tagId = implode(',', $tagId);
+ if (!empty($tagId))
+ {
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' IN (' . $tagId . ')');
+ }
+ }
+
+ if ($hasTag)
+ {
+ $query->join('LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
+ . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
+ . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article')
+ );
}
// Add the list ordering clause.
diff --git a/administrator/components/com_content/models/featured.php b/administrator/components/com_content/models/featured.php
index 34f40a941a7d8..b90a48f7bd4b0 100644
--- a/administrator/components/com_content/models/featured.php
+++ b/administrator/components/com_content/models/featured.php
@@ -79,7 +79,7 @@ protected function getListQuery($resolveFKs = true)
$query->select(
$this->getState(
'list.select',
- 'a.id, a.title, a.alias, a.checked_out, a.checked_out_time, a.catid, a.state, a.access, a.created, a.hits,' .
+ 'DISTINCT a.id, a.title, a.alias, a.checked_out, a.checked_out_time, a.catid, a.state, a.access, a.created, a.hits,' .
'a.featured, a.language, a.created_by_alias, a.publish_up, a.publish_down'
)
);
@@ -110,10 +110,18 @@ protected function getListQuery($resolveFKs = true)
->join('LEFT', '#__users AS ua ON ua.id = a.created_by');
// Filter by access level.
- if ($access = $this->getState('filter.access'))
+ $access = $this->getState('filter.access');
+
+ if (is_numeric($access))
{
$query->where('a.access = ' . (int) $access);
}
+ elseif(is_array($access))
+ {
+ JArrayHelper::toInteger($access);
+ $access = implode(',', $access);
+ $query->where('a.access IN (' . $access . ')');
+ }
// Filter by published state
$published = $this->getState('filter.published');
@@ -162,6 +170,13 @@ protected function getListQuery($resolveFKs = true)
$query->where('a.created_by ' . $type . (int) $authorId);
}
+ elseif (is_array($authorId))
+ {
+ JArrayHelper::toInteger($categoryId);
+ $authorId = implode(',', $authorId);
+ $query->where('a.created_by IN (' . $authorId . ')');
+ }
+
// Filter by search in title.
$search = $this->getState('filter.search');
@@ -184,17 +199,34 @@ protected function getListQuery($resolveFKs = true)
$query->where('a.language = ' . $db->quote($language));
}
- // Filter by a single tag.
+ // Filter by a single or group of tags.
+ $hasTag = false;
$tagId = $this->getState('filter.tag');
if (is_numeric($tagId))
{
- $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId)
- ->join(
- 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
- . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
- . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article')
- );
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId);
+ }
+ elseif (is_array($tagId))
+ {
+ JArrayHelper::toInteger($tagId);
+ $tagId = implode(',', $tagId);
+ if (!empty($tagId))
+ {
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' IN (' . $tagId . ')');
+ }
+ }
+
+ if ($hasTag)
+ {
+ $query->join('LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
+ . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
+ . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article')
+ );
}
// Add the list ordering clause.
diff --git a/administrator/components/com_content/models/forms/filter_articles.xml b/administrator/components/com_content/models/forms/filter_articles.xml
index e22ba2f57d25d..e3c00b0e5a489 100644
--- a/administrator/components/com_content/models/forms/filter_articles.xml
+++ b/administrator/components/com_content/models/forms/filter_articles.xml
@@ -19,12 +19,13 @@
-
-
-
-
diff --git a/administrator/components/com_content/models/forms/filter_featured.xml b/administrator/components/com_content/models/forms/filter_featured.xml
index 4781ed0330888..782d1fc096182 100644
--- a/administrator/components/com_content/models/forms/filter_featured.xml
+++ b/administrator/components/com_content/models/forms/filter_featured.xml
@@ -21,12 +21,13 @@
-
-
-
-
diff --git a/administrator/components/com_content/views/articles/tmpl/default.php b/administrator/components/com_content/views/articles/tmpl/default.php
index 7237ed8063122..7f56476169038 100644
--- a/administrator/components/com_content/views/articles/tmpl/default.php
+++ b/administrator/components/com_content/views/articles/tmpl/default.php
@@ -13,6 +13,10 @@
JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
+JHtml::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_ACCESS')));
+JHtml::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR')));
+JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY')));
+JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG')));
JHtml::_('formbehavior.chosen', 'select');
$app = JFactory::getApplication();
diff --git a/administrator/components/com_content/views/featured/tmpl/default.php b/administrator/components/com_content/views/featured/tmpl/default.php
index aa283ebb68440..87aab1be6e6d2 100644
--- a/administrator/components/com_content/views/featured/tmpl/default.php
+++ b/administrator/components/com_content/views/featured/tmpl/default.php
@@ -13,6 +13,10 @@
JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
+JHtml::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_ACCESS')));
+JHtml::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR')));
+JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY')));
+JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG')));
JHtml::_('formbehavior.chosen', 'select');
$user = JFactory::getUser();
diff --git a/administrator/components/com_modules/views/module/tmpl/edit.php b/administrator/components/com_modules/views/module/tmpl/edit.php
index b26837c294570..4e2b523b11f23 100644
--- a/administrator/components/com_modules/views/module/tmpl/edit.php
+++ b/administrator/components/com_modules/views/module/tmpl/edit.php
@@ -13,6 +13,8 @@
JHtml::_('behavior.formvalidator');
JHtml::_('behavior.combobox');
+JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY')));
+JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG')));
JHtml::_('formbehavior.chosen', 'select');
$hasContent = empty($this->item->module) || isset($this->item->xml->customContent);
diff --git a/administrator/components/com_newsfeeds/models/newsfeeds.php b/administrator/components/com_newsfeeds/models/newsfeeds.php
index e76a1fd7af092..72f80cc26ee59 100644
--- a/administrator/components/com_newsfeeds/models/newsfeeds.php
+++ b/administrator/components/com_newsfeeds/models/newsfeeds.php
@@ -44,6 +44,7 @@ public function __construct($config = array())
'publish_down', 'a.publish_down',
'cache_time', 'a.cache_time',
'numarticles',
+ 'tag'
);
$app = JFactory::getApplication();
@@ -128,6 +129,7 @@ protected function getStoreId($id = '')
$id .= ':' . $this->getState('filter.published');
$id .= ':' . $this->getState('filter.category_id');
$id .= ':' . $this->getState('filter.language');
+ $id .= ':' . serialize($this->getState('filter.tag'));
return parent::getStoreId($id);
}
@@ -149,7 +151,7 @@ protected function getListQuery()
$query->select(
$this->getState(
'list.select',
- 'a.id, a.name, a.alias, a.checked_out, a.checked_out_time, a.catid,' .
+ 'DISTINCT a.id, a.name, a.alias, a.checked_out, a.checked_out_time, a.catid,' .
' a.numarticles, a.cache_time,' .
' a.published, a.access, a.ordering, a.language, a.publish_up, a.publish_down'
)
@@ -238,17 +240,34 @@ protected function getListQuery()
$query->where('a.language = ' . $db->quote($language));
}
- // Filter by a single tag.
+ // Filter by a single or group of tags.
+ $hasTag = false;
$tagId = $this->getState('filter.tag');
if (is_numeric($tagId))
{
- $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId)
- ->join(
- 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
- . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
- . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed')
- );
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId);
+ }
+ elseif (is_array($tagId))
+ {
+ JArrayHelper::toInteger($tagId);
+ $tagId = implode(',', $tagId);
+ if (!empty($tagId))
+ {
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' IN (' . $tagId . ')');
+ }
+ }
+
+ if ($hasTag)
+ {
+ $query->join('LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
+ . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
+ . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed')
+ );
}
// Add the list ordering clause.
diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini
index d052cfa447a29..515cdfe1d3043 100644
--- a/administrator/language/en-GB/en-GB.ini
+++ b/administrator/language/en-GB/en-GB.ini
@@ -785,6 +785,7 @@ JOPTION_ACCESS_SHOW_ALL_ACCESS="Show All Access"
JOPTION_ACCESS_SHOW_ALL_GROUPS="Show All Groups"
JOPTION_ACCESS_SHOW_ALL_LEVELS="Show All Access Levels"
JOPTION_ALL_CATEGORIES="- All Categories -"
+JOPTION_ALL_TAGS="- All Tags -"
JOPTION_ANY_CATEGORY="Any Category"
JOPTION_ANY="Any"
JOPTION_DO_NOT_USE="- None Selected -"
diff --git a/components/com_content/models/articles.php b/components/com_content/models/articles.php
index 52bc89d514e62..53a4375ff7a4e 100644
--- a/components/com_content/models/articles.php
+++ b/components/com_content/models/articles.php
@@ -49,6 +49,7 @@ public function __construct($config = array())
'publish_down', 'a.publish_down',
'images', 'a.images',
'urls', 'a.urls',
+ 'tag'
);
}
@@ -157,6 +158,7 @@ protected function getStoreId($id = '')
$id .= ':' . $this->getState('filter.start_date_range');
$id .= ':' . $this->getState('filter.end_date_range');
$id .= ':' . $this->getState('filter.relative_date');
+ $id .= ':' . serialize($this->getState('filter.tag'));
return parent::getStoreId($id);
}
@@ -181,7 +183,7 @@ protected function getListQuery()
$query->select(
$this->getState(
'list.select',
- 'a.id, a.title, a.alias, a.introtext, a.fulltext, ' .
+ 'DISTINCT a.id, a.title, a.alias, a.introtext, a.fulltext, ' .
'a.checked_out, a.checked_out_time, ' .
'a.catid, a.created, a.created_by, a.created_by_alias, ' .
// Use created if modified is 0
@@ -517,6 +519,36 @@ protected function getListQuery()
$query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')');
}
+ // Filter by a single or group of tags.
+ $hasTag = false;
+ $tagId = $this->getState('filter.tag');
+
+ if (is_numeric($tagId))
+ {
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId);
+ }
+ elseif (is_array($tagId))
+ {
+ JArrayHelper::toInteger($tagId);
+ $tagId = implode(',', $tagId);
+ if (!empty($tagId))
+ {
+ $hasTag = true;
+
+ $query->where($db->quoteName('tagmap.tag_id') . ' IN (' . $tagId . ')');
+ }
+ }
+
+ if ($hasTag)
+ {
+ $query->join('LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap')
+ . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
+ . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article')
+ );
+ }
+
// Add the list ordering clause.
$query->order($this->getState('list.ordering', 'a.ordering') . ' ' . $this->getState('list.direction', 'ASC'));
diff --git a/modules/mod_articles_news/helper.php b/modules/mod_articles_news/helper.php
index 85effa7ed9fcf..f5774a88803cb 100644
--- a/modules/mod_articles_news/helper.php
+++ b/modules/mod_articles_news/helper.php
@@ -49,10 +49,6 @@ public static function getList(&$params)
$model->setState('filter.published', 1);
- $model->setState('list.select', 'a.fulltext, a.id, a.title, a.alias, a.introtext, a.state, a.catid, a.created, a.created_by, a.created_by_alias,' .
- ' a.modified, a.modified_by, a.publish_up, a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access,' .
- ' a.hits, a.featured, a.language');
-
// Access filter
$access = !JComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = JAccess::getAuthorisedViewLevels(JFactory::getUser()->get('id'));
@@ -64,6 +60,9 @@ public static function getList(&$params)
// Filter by language
$model->setState('filter.language', $app->getLanguageFilter());
+ // Filter by tag
+ $model->setState('filter.tag', $params->get('tag'), array());
+
// Set ordering
$ordering = $params->get('ordering', 'a.publish_up');
$model->setState('list.ordering', $ordering);
diff --git a/modules/mod_articles_news/mod_articles_news.xml b/modules/mod_articles_news/mod_articles_news.xml
index b3fd6c1a09eca..96542f318fdc3 100644
--- a/modules/mod_articles_news/mod_articles_news.xml
+++ b/modules/mod_articles_news/mod_articles_news.xml
@@ -28,12 +28,23 @@
type="category"
extension="com_content"
multiple="true"
+ class="multipleCategories"
default=""
size="10"
label="JCATEGORY"
description="MOD_ARTICLES_NEWS_FIELD_CATEGORY_DESC"
>
-
+
+
+