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" > - + + +