diff --git a/administrator/components/com_categories/models/categories.php b/administrator/components/com_categories/models/categories.php index 5750db24708b4..e16fd4d4cdc2b 100644 --- a/administrator/components/com_categories/models/categories.php +++ b/administrator/components/com_categories/models/categories.php @@ -130,7 +130,7 @@ protected function getStoreId($id = '') $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.language'); $id .= ':' . $this->getState('filter.level'); - $id .= ':' . $this->getState('filter.tag'); + $id .= ':' . serialize($this->getState('filter.tag')); return parent::getStoreId($id); } @@ -153,7 +153,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' @@ -247,17 +247,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 @@ -360,7 +377,7 @@ public function getItems() /** * Method to load the countItems method from the extensions - * + * * @param stdClass[] &$items The category items * @param string $extension The category extension * diff --git a/administrator/components/com_categories/models/forms/filter_categories.xml b/administrator/components/com_categories/models/forms/filter_categories.xml index 3dd53359d3527..c46ae1297adc6 100644 --- a/administrator/components/com_categories/models/forms/filter_categories.xml +++ b/administrator/components/com_categories/models/forms/filter_categories.xml @@ -45,12 +45,13 @@ - + > 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 5e525fed1236d..1a5011fa551dd 100644 --- a/administrator/components/com_content/models/articles.php +++ b/administrator/components/com_content/models/articles.php @@ -144,11 +144,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); } @@ -172,7 +173,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' ) @@ -209,10 +210,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')) @@ -269,6 +278,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'); @@ -296,17 +312,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 f5d2ef8faeb59..ae8aa12f4c785 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'); @@ -189,17 +204,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 51e0dca100994..ed5b7f03c0026 100644 --- a/administrator/components/com_content/models/forms/filter_articles.xml +++ b/administrator/components/com_content/models/forms/filter_articles.xml @@ -20,32 +20,35 @@ - - - - + name="author_id" + type="author" + multiple="true" + class="multipleAuthors" + label="COM_CONTENT_FILTER_AUTHOR" + description="COM_CONTENT_FILTER_AUTHOR_DESC" + onchange="this.form.submit();" + > + - - + + + + + - - - - - - - - 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 161469ce2be31..a1a02696324a9 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 a51f41fdd9016..649502b7b58bc 100644 --- a/administrator/components/com_modules/views/module/tmpl/edit.php +++ b/administrator/components/com_modules/views/module/tmpl/edit.php @@ -14,6 +14,8 @@ JHtml::_('behavior.formvalidator'); JHtml::_('behavior.combobox'); JHtml::_('formbehavior.chosen', 'select', null, array('disable_search_threshold' => 0)); +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'))); $hasContent = empty($this->item->module) || isset($this->item->xml->customContent); $hasContentFieldName = "content"; diff --git a/administrator/components/com_newsfeeds/models/newsfeeds.php b/administrator/components/com_newsfeeds/models/newsfeeds.php index fb5ca49e8e8a6..8c4ef22ac8c8f 100644 --- a/administrator/components/com_newsfeeds/models/newsfeeds.php +++ b/administrator/components/com_newsfeeds/models/newsfeeds.php @@ -46,6 +46,7 @@ public function __construct($config = array()) 'numarticles', 'tag', 'level', 'c.level', + 'tag', ); $assoc = JLanguageAssociations::isEnabled(); @@ -130,8 +131,8 @@ protected function getStoreId($id = '') $id .= ':' . $this->getState('filter.category_id'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.language'); - $id .= ':' . $this->getState('filter.tag'); $id .= ':' . $this->getState('filter.level'); + $id .= ':' . serialize($this->getState('filter.tag')); return parent::getStoreId($id); } @@ -153,7 +154,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' ) @@ -248,17 +249,34 @@ protected function getListQuery() $query->where($db->quoteName('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 2ff06b3d36883..97fc33c74b3d9 100644 --- a/administrator/language/en-GB/en-GB.ini +++ b/administrator/language/en-GB/en-GB.ini @@ -799,6 +799,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 15d0fa8f61967..ffee9300d685c 100644 --- a/components/com_content/models/articles.php +++ b/components/com_content/models/articles.php @@ -50,7 +50,8 @@ public function __construct($config = array()) 'publish_down', 'a.publish_down', 'images', 'a.images', 'urls', 'a.urls', - 'filter_tag' + 'filter_tag', + 'tag' ); } @@ -162,6 +163,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); } @@ -186,7 +188,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 @@ -532,17 +534,34 @@ protected function getListQuery() $query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); } - // Filter by a single tag. + // Filter by a single or group of tags. + $hasTag = false; $tagId = $this->getState('filter.tag'); - if (!empty($tagId) && is_numeric($tagId)) + 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/modules/mod_articles_news/helper.php b/modules/mod_articles_news/helper.php index d41ceebf2620a..414fbb5e8a0bd 100644 --- a/modules/mod_articles_news/helper.php +++ b/modules/mod_articles_news/helper.php @@ -58,6 +58,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 9eba4e0ce235b..1d1a675a8437c 100644 --- a/modules/mod_articles_news/mod_articles_news.xml +++ b/modules/mod_articles_news/mod_articles_news.xml @@ -25,14 +25,25 @@ - + label="JCATEGORY" + description="MOD_ARTICLES_NEWS_FIELD_CATEGORY_DESC" + > + + +