protected function getOptions()
 {
     // if flexicontent is not installed
     if (!JFolder::exists(JPATH_ROOT . DS . 'administrator' . DS . 'components' . DS . 'com_flexicontent')) {
         JPluginHelper::importPlugin('system', 'flexisystem');
         // add the root item
         $option = new stdClass();
         $option->text = JText::_('MOD_MAXIMENUCK_FLEXICONTENT_NOTFOUND');
         $option->value = '0';
         $options[] = $option;
         // Merge any additional options in the XML definition.
         $options = array_merge(parent::getOptions(), $options);
         return $options;
     }
     // For specific cache issues
     global $dump, $globalcats;
     if (empty($globalcats)) {
         if (FLEXI_SECTION || FLEXI_CAT_EXTENSION) {
             if (FLEXI_CACHE) {
                 // add the category tree to categories cache
                 $catscache = JFactory::getCache('com_flexicontent_cats');
                 $catscache->setCaching(1);
                 //force cache
                 $catscache->setLifeTime(84600);
                 //set expiry to one day
                 $globalcats = $catscache->call(array('plgSystemFlexisystem', 'getCategoriesTree'));
             } else {
                 $globalcats = plgSystemFlexisystem::getCategoriesTree();
             }
         }
     }
     foreach ($globalcats as $cat) {
         $option = new stdClass();
         $option->text = str_replace("<sup>", "", str_replace("</sup>", "", $cat->treename));
         $option->value = $cat->id;
         $options[] = $option;
     }
     // Merge any additional options in the XML definition.
     $options = array_merge(parent::getOptions(), $options);
     return $options;
 }
Esempio n. 2
0
 public static function getItems(&$params, $ordering)
 {
     global $dump, $globalcats;
     global $modfc_jprof, $mod_fc_run_times;
     $app = JFactory::getApplication();
     // For specific cache issues
     if (empty($globalcats)) {
         if (FLEXI_SECTION || FLEXI_CAT_EXTENSION) {
             JPluginHelper::importPlugin('system', 'flexisystem');
             if (FLEXI_CACHE) {
                 // add the category tree to categories cache
                 $catscache = JFactory::getCache('com_flexicontent_cats');
                 $catscache->setCaching(1);
                 //force cache
                 $catscache->setLifeTime(84600);
                 //set expiry to one day
                 $globalcats = $catscache->call(array('plgSystemFlexisystem', 'getCategoriesTree'));
             } else {
                 $globalcats = plgSystemFlexisystem::getCategoriesTree();
             }
         }
     }
     // Initialize variables
     $db = JFactory::getDBO();
     $user = JFactory::getUser();
     $view = JRequest::getVar('view');
     $option = JRequest::getVar('option');
     $fparams = $app->getParams('com_flexicontent');
     $show_noauth = $fparams->get('show_noauth', 0);
     // Date-Times are stored as UTC, we should use current UTC time to compare and not user time (requestTime),
     //  thus the items are published globally at the time the author specified in his/her local clock
     //$now		= $app->get('requestTime');
     $now = JFactory::getDate()->toSql();
     $nullDate = $db->getNullDate();
     // $display_category_data
     $apply_config_per_category = (int) $params->get('apply_config_per_category', 0);
     // *** METHODS that their 'ALL' value is 0, (these do not use current item information)
     // current item scope parameters
     $method_curitem = (int) $params->get('method_curitem', 0);
     // current language scope parameters
     $method_curlang = (int) $params->get('method_curlang', 0);
     // current item scope parameters
     $method_curuserfavs = (int) $params->get('method_curuserfavs', 0);
     // featured items scope parameters
     $method_featured = (int) $params->get('method_featured', 0);
     // featured items scope parameters
     $method_states = (int) $params->get('method_states', 0);
     $item_states = $params->get('item_states');
     $show_nocontent_msg = (int) $params->get('show_nocontent_msg', 1);
     // *** METHODS that their 'ALL' value is 1, that also have behaviour variable (most of them)
     // categories scope parameters
     $method_cat = (int) $params->get('method_cat', 1);
     $catids = $params->get('catids', array());
     $behaviour_cat = $params->get('behaviour_cat', 0);
     $treeinclude = $params->get('treeinclude');
     // types scope parameters
     $method_types = (int) $params->get('method_types', 1);
     $types = $params->get('types');
     $behaviour_types = $params->get('behaviour_types', 0);
     // authors scope parameters
     $method_auth = (int) $params->get('method_auth', 1);
     $authors = trim($params->get('authors'));
     $behaviour_auth = $params->get('behaviour_auth');
     // items scope parameters
     $method_items = (int) $params->get('method_items', 1);
     $items = trim($params->get('items'));
     $behaviour_items = $params->get('behaviour_items', 0);
     $excluded_tags = $params->get('excluded_tags', array());
     $excluded_tags = !is_array($excluded_tags) ? array($excluded_tags) : $excluded_tags;
     $relitems_fields = $params->get('relitems_fields', array());
     $relitems_fields = !is_array($relitems_fields) ? array($relitems_fields) : $relitems_fields;
     // tags scope parameters
     $method_tags = (int) $params->get('method_tags', 1);
     $tag_ids = $params->get('tag_ids', array());
     $tag_combine = $params->get('tag_combine', 0);
     // date scope parameters
     $method_dates = (int) $params->get('method_dates', 1);
     // parameter added later, maybe not to break compatibility this should be INCLUDE=3 by default ?
     $date_type = (int) $params->get('date_type', 0);
     $nulldates = (int) $params->get('nulldates', 0);
     $bdate = $params->get('bdate', '');
     $edate = $params->get('edate', '');
     $raw_bdate = $params->get('raw_bdate', 0);
     $raw_edate = $params->get('raw_edate', 0);
     $behaviour_dates = $params->get('behaviour_dates', 0);
     $date_compare = $params->get('date_compare', 0);
     $datecomp_field = (int) $params->get('datecomp_field', 0);
     // Server date
     $sdate = explode(' ', $now);
     $cdate = $sdate[0] . ' 00:00:00';
     // Set date comparators
     if ($date_type == 0) {
         // created
         $comp = 'i.created';
     } else {
         if ($date_type == 1) {
             // modified
             $comp = 'i.modified';
         } else {
             if ($date_type == 2) {
                 // publish up
                 $comp = 'i.publish_up';
             } else {
                 if ($date_type == 4) {
                     // publish down
                     $comp = 'i.publish_down';
                 } else {
                     // $date_type == 3
                     $comp = 'dfrel.value';
                 }
             }
         }
     }
     // custom field scope
     $method_filt = (int) $params->get('method_filt', 1);
     // parameter added later, maybe not to break compatibility this should be INCLUDE=3 by default ?
     $behaviour_filt = (int) $params->get('behaviour_filt', 0);
     $static_filters = $params->get('static_filters', '');
     $dynamic_filters = $params->get('dynamic_filters', '');
     // get module fetching parameters
     if ($params->get('skip_items', 0)) {
         $count = (int) $params->get('maxskipcount', 50);
     } else {
         $count = (int) $params->get('count', 5);
     }
     // get module display parameters
     $mod_image = $params->get('mod_image');
     // ************************************************************************************
     // filter by publication state, (except for item state which is a special scope, below)
     // ************************************************************************************
     $where = ' WHERE c.published = 1';
     $where .= FLEXI_J16GE ? '' : ' AND i.sectionid = ' . FLEXI_SECTION;
     $ignore_up_down_dates = $params->get('ignore_up_down_dates', 0);
     // 1: ignore publish_up, 2: ignore publish_donw, 3: ignore both
     $ignoreState = $params->get('use_list_items_in_any_state_acl', 0) && $user->authorise('flexicontent.ignoreviewstate', 'com_flexicontent');
     if (!$ignoreState && $ignore_up_down_dates != 3 && $ignore_up_down_dates != 1) {
         $where .= ' AND ( i.publish_up = ' . $db->Quote($nullDate) . ' OR i.publish_up <= ' . $db->Quote($now) . ' )';
     }
     if (!$ignoreState && $ignore_up_down_dates != 3 && $ignore_up_down_dates != 2) {
         $where .= ' AND ( i.publish_down = ' . $db->Quote($nullDate) . ' OR i.publish_down >= ' . $db->Quote($now) . ' )';
     }
     // *********************
     // filter by permissions
     // *********************
     $joinaccess = '';
     if (!$show_noauth) {
         $aid_arr = JAccess::getAuthorisedViewLevels($user->id);
         $aid_list = implode(",", $aid_arr);
         $where .= ' AND ty.access IN (0,' . $aid_list . ')';
         $where .= ' AND mc.access IN (0,' . $aid_list . ')';
         $where .= ' AND  i.access IN (0,' . $aid_list . ')';
     }
     // *******************************************************
     // NON-STATIC behaviors that need current item information
     // *******************************************************
     $isflexi_itemview = $option == 'com_flexicontent' && $view == FLEXI_ITEMVIEW && JRequest::getInt('id');
     $isflexi_catview = $option == 'com_flexicontent' && $view == 'category' && (JRequest::getInt('cid') || JRequest::getVar('cids'));
     $curritem_date_field_needed = $behaviour_dates && $date_compare && $date_type == 3 && $datecomp_field;
     // Date field selected
     if (($behaviour_cat || $behaviour_types || $behaviour_auth || $behaviour_items || $curritem_date_field_needed || $behaviour_filt) && $isflexi_itemview) {
         // initialize variables
         $cid = JRequest::getInt('cid');
         $id = JRequest::getInt('id');
         $Itemid = JRequest::getInt('Itemid');
         // Check for new item nothing to retrieve,
         // NOTE: aborting execution if current view is not item view, but item view is required
         // and also proper usage of current item, both of these will be handled by SCOPEs
         $sel_date = '';
         $join_date = '';
         if ($curritem_date_field_needed) {
             $sel_date = ', dfrel.value as custom_date';
             $join_date = '	LEFT JOIN #__flexicontent_fields_item_relations AS dfrel' . '   ON ( i.id = dfrel.item_id AND dfrel.valueorder = 1 AND dfrel.field_id = ' . $datecomp_field . ' )';
         }
         if ($id) {
             $query = 'SELECT i.*, ie.*, GROUP_CONCAT(ci.catid SEPARATOR ",") as itemcats' . $sel_date . ' FROM #__content as i' . ' LEFT JOIN #__flexicontent_items_ext AS ie on ie.item_id = i.id' . ' LEFT JOIN #__flexicontent_cats_item_relations AS ci on ci.itemid = i.id' . $join_date . ' WHERE i.id = ' . $id . ' GROUP BY ci.itemid';
             $db->setQuery($query);
             $curitem = $db->loadObject();
             // Get item dates
             $idate = null;
             if ($date_type == 0) {
                 // created
                 $idate = $curitem->created;
             } else {
                 if ($date_type == 1) {
                     // modified
                     $idate = $curitem->modified;
                 } else {
                     if ($date_type == 2) {
                         // publish up
                         $idate = $curitem->publish_up;
                     } else {
                         if (isset($curitem->custom_date)) {
                             // $date_type == 3
                             $idate = $curitem->custom_date;
                         }
                     }
                 }
             }
             if ($idate) {
                 $idate = explode(' ', $idate);
                 $cdate = $idate[0] . ' 00:00:00';
             }
             $curritemcats = explode(',', $curitem->itemcats);
         }
     }
     // ******************
     // current item scope
     // ******************
     $currid = JRequest::getInt('id');
     if ($method_curitem == 1) {
         // exclude method  ---  exclude current item
         $where .= ' AND i.id <> ' . $currid;
     } else {
         if ($method_curitem == 2) {
             // include method  ---  include current item ONLY
             $where .= ' AND i.id = ' . $currid;
         } else {
             // All Items including current
         }
     }
     // **********************
     // current language scope
     // **********************
     $lang = flexicontent_html::getUserCurrentLang();
     if ($method_curlang == 1) {
         // exclude method  ---  exclude items of current language
         $where .= ' AND ie.language NOT LIKE ' . $db->Quote($lang . '%');
     } else {
         if ($method_curlang == 2) {
             // include method  ---  include items of current language ONLY
             $where .= ' AND ( ie.language LIKE ' . $db->Quote($lang . '%') . (FLEXI_J16GE ? ' OR ie.language="*" ' : '') . ' ) ';
         } else {
             // Items of any language
         }
     }
     // *****************************
     // current user favourites scope
     // *****************************
     $curruserid = (int) $user->get('id');
     if ($method_curuserfavs == 1) {
         // exclude method  ---  exclude currently logged user favourites
         $join_favs = ' LEFT OUTER JOIN #__flexicontent_favourites AS fav ON fav.itemid = i.id AND fav.userid = ' . $curruserid;
         $where .= ' AND fav.itemid IS NULL';
     } else {
         if ($method_curuserfavs == 2) {
             // include method  ---  include currently logged user favourites
             $join_favs = ' LEFT JOIN #__flexicontent_favourites AS fav ON fav.itemid = i.id';
             $where .= ' AND fav.userid = ' . $curruserid;
         } else {
             // All Items regardless of being favoured by current user
             $join_favs = '';
         }
     }
     // ******************************
     // joomla featured property scope
     // ******************************
     if ($method_featured == 1) {
         // exclude method  ---  exclude currently logged user favourites
         $where .= ' AND i.featured=0';
     } else {
         if ($method_featured == 2) {
             // include method  ---  include currently logged user favourites
             $where .= ' AND i.featured=1';
         } else {
             // All Items regardless of being featured or not
         }
     }
     // *****************
     // item states scope
     // *****************
     $item_states = is_array($item_states) ? implode(',', $item_states) : $item_states;
     if ($method_states == 0) {
         if (!$ignoreState) {
             // method normal: Published item states
             $where .= ' AND i.state IN ( 1, -5 )';
         }
     } else {
         // exclude trashed
         $where .= ' AND i.state <> -2';
         if ($item_states) {
             if ($method_states == 1) {
                 // exclude method  ---  exclude specified item states
                 $where .= ' AND i.state NOT IN (' . $item_states . ')';
             } else {
                 if ($method_states == 2) {
                     // include method  ---  include specified item states
                     $where .= ' AND i.state IN (' . $item_states . ')';
                 }
             }
         } else {
             if ($method_states == 2) {
                 // misconfiguration, when using include method with no state selected ...
                 echo "<b>WARNING:</b> Misconfigured item states scope, select at least one state or set states scope to Normal <small>(Published)</small><br/>";
                 return;
             }
         }
     }
     // ****************
     // categories scope
     // ****************
     // ZERO 'behaviour' means statically selected records, but METHOD 1 is ALL records ... so NOTHING to do
     if (!$behaviour_cat && $method_cat == 1) {
         if ($apply_config_per_category) {
             echo "<b>WARNING:</b> Misconfiguration warning, APPLY CONFIGURATION PER CATEGORY is possible only if CATEGORY SCOPE is set to either (a) INCLUDE(static selection of categories) or (b) items in same category as current item / or current category of category view<br/>";
             return;
         }
     } else {
         if (!$behaviour_cat) {
             // Check for empty statically selected records, and abort with error message
             if (empty($catids)) {
                 echo "<b>WARNING:</b> Misconfigured category scope, select at least one category or set category scope to ALL<br/>";
                 return;
             }
             // Make sure categories is an array
             $catids = is_array($catids) ? $catids : array($catids);
             // Retrieve extra categories, such children or parent categories
             $catids_arr = flexicontent_cats::getExtraCats($catids, $treeinclude, array());
             if (empty($catids_arr)) {
                 if ($show_nocontent_msg) {
                     echo JText::_("No viewable content in Current View for your Access Level");
                 }
                 return;
             }
             if ($method_cat == 2) {
                 // exclude method
                 if ($apply_config_per_category) {
                     echo "<b>WARNING:</b> Misconfiguration warning, APPLY CONFIGURATION PER CATEGORY is possible only if CATEGORY SCOPE is set to either (a) INCLUDE(static selection of categories) or (b) items in same category as current item / or current category of category view<br/>";
                     return;
                 }
                 $where .= ' AND c.id NOT IN (' . implode(',', $catids_arr) . ')';
             } else {
                 if ($method_cat == 3) {
                     // include method
                     if (!$apply_config_per_category) {
                         $where .= ' AND c.id IN (' . implode(',', $catids_arr) . ')';
                     } else {
                         // *** Applying configuration per category ***
                         foreach ($catids_arr as $catid) {
                             // The items retrieval query will be executed ... once per EVERY category
                             $multiquery_cats[$catid] = ' AND c.id = ' . $catid;
                         }
                         $params->set('dynamic_catids', serialize($catids_arr));
                         // Set dynamic catids to be used by the getCategoryData
                     }
                 }
             }
         } else {
             if (($behaviour_cat == 2 || $behaviour_cat == 4) && $apply_config_per_category) {
                 echo "<b>WARNING:</b> Misconfiguration warning, APPLY CONFIGURATION PER CATEGORY is possible only if CATEGORY SCOPE is set to either (a) INCLUDE(static selection of categories) or (b) items in same category as current item / or current category of category view<br/>";
                 return;
             }
             $currcat_valid_case = $behaviour_cat == 1 && $isflexi_itemview || $behaviour_cat == 3 && $isflexi_catview;
             if (!$currcat_valid_case) {
                 return;
                 // current view is not item OR category view ... , nothing to display
             }
             // IF $cid is not set then use the main category id of the (current) item
             if ($isflexi_itemview) {
                 $cid = $cid ? $cid : $curitem->catid;
                 // Retrieve extra categories, such children or parent categories
                 $catids_arr = flexicontent_cats::getExtraCats(array($cid), $treeinclude, $curritemcats);
             } else {
                 if ($isflexi_catview) {
                     $cid = JRequest::getInt('cid', 0);
                     if (!$cid) {
                         $_cids = JRequest::getVar('cids', '');
                         if (!is_array($_cids)) {
                             $_cids = preg_replace('/[^0-9,]/i', '', (string) $_cids);
                             $_cids = explode(',', $_cids);
                         }
                         // make sure given data are integers ... !!
                         $cids = array();
                         foreach ($_cids as $i => $_id) {
                             if ((int) $_id) {
                                 $cids[] = (int) $_id;
                             }
                         }
                         // Retrieve extra categories, such children or parent categories
                         $catids_arr = flexicontent_cats::getExtraCats(array($cid), $treeinclude, array());
                     }
                 } else {
                     return;
                     // nothing to display
                 }
             }
             // Retrieve extra categories, such children or parent categories
             $catids_arr = flexicontent_cats::getExtraCats(array($cid), $treeinclude, $isflexi_itemview ? $curritemcats : array());
             if (empty($catids_arr)) {
                 if ($show_nocontent_msg) {
                     echo JText::_("No viewable content in Current View for your Access Level");
                 }
                 return;
             }
             if ($behaviour_cat == 1 || $behaviour_cat == 3) {
                 if (!$apply_config_per_category) {
                     $where .= ' AND c.id IN (' . implode(',', $catids_arr) . ')';
                 } else {
                     // *** Applying configuration per category ***
                     foreach ($catids_arr as $catid) {
                         // The items retrieval query will be executed ... once per EVERY category
                         $multiquery_cats[$catid] = ' AND c.id = ' . $catid;
                     }
                     $params->set('dynamic_catids', serialize($catids_arr));
                     // Set dynamic catids to be used by the getCategoryData
                 }
             } else {
                 $where .= ' AND c.id NOT IN (' . implode(',', $catids_arr) . ')';
             }
         }
     }
     // Now check if no items need to be retrieved
     if ($count == 0) {
         return;
     }
     // ***********
     // types scope
     // ***********
     // ZERO 'behaviour' means statically selected records, but METHOD 1 is ALL records ... so NOTHING to do
     if (!$behaviour_types && $method_types == 1) {
     } else {
         if (!$behaviour_types) {
             // Check for empty statically selected records, and abort with error message
             if (empty($types)) {
                 echo "<b>WARNING:</b> Misconfigured types scope, select at least one item type or set types scope to ALL<br/>";
                 return;
             }
             // Make types a comma separated string of ids
             $types = is_array($types) ? implode(',', $types) : $types;
             if ($method_types == 2) {
                 // exclude method
                 $where .= ' AND ie.type_id NOT IN (' . $types . ')';
             } else {
                 if ($method_types == 3) {
                     // include method
                     $where .= ' AND ie.type_id IN (' . $types . ')';
                 }
             }
         } else {
             if (!$isflexi_itemview) {
                 return;
                 // current view is not item view ... , nothing to display
             }
             if ($behaviour_types == 1) {
                 $where .= ' AND ie.type_id = ' . (int) $curitem->type_id;
             } else {
                 $where .= ' AND ie.type_id <> ' . (int) $curitem->type_id;
             }
         }
     }
     // ************
     // author scope
     // ************
     // ZERO 'behaviour' means statically selected records, but METHOD 1 is ALL records ... so NOTHING to do
     if (!$behaviour_auth && $method_auth == 1) {
     } else {
         if (!$behaviour_auth) {
             // Check for empty statically selected records, and abort with error message
             if (empty($authors)) {
                 echo "<b>WARNING:</b> Misconfigured author scope, select at least one author or set author scope to ALL<br/>";
                 return;
             }
             if ($method_auth == 2) {
                 // exclude method
                 $where .= ' AND i.created_by NOT IN (' . $authors . ')';
             } else {
                 if ($method_auth == 3) {
                     // include method
                     $where .= ' AND i.created_by IN (' . $authors . ')';
                 }
             }
         } else {
             if (!$isflexi_itemview && $behaviour_auth < 3) {
                 // Behaviour 3 is current user thus not related to current item
                 return;
                 // current view is not item view ... , nothing to display
             }
             if ($behaviour_auth == 1) {
                 $where .= ' AND i.created_by = ' . (int) $curitem->created_by;
             } else {
                 if ($behaviour_auth == 2) {
                     $where .= ' AND i.created_by <> ' . (int) $curitem->created_by;
                 } else {
                     // $behaviour_auth == 3
                     $where .= ' AND i.created_by = ' . (int) $user->id;
                 }
             }
         }
     }
     // ***********
     // items scope
     // ***********
     // ZERO 'behaviour' means statically selected records, but METHOD 1 is ALL records ... so NOTHING to do
     if (!$behaviour_items && $method_items == 1) {
     } else {
         if (!$behaviour_items) {
             // Check for empty statically selected records, and abort with error message
             if (empty($items)) {
                 echo "<b>WARNING:</b> Misconfigured items scope, select at least one item or set items scope to ALL<br/>";
                 return;
             }
             if ($method_items == 2) {
                 // exclude method
                 $where .= ' AND i.id NOT IN (' . $items . ')';
             } else {
                 if ($method_items == 3) {
                     // include method
                     $where .= ' AND i.id IN (' . $items . ')';
                 }
             }
         } else {
             if ($behaviour_items == 2 || $behaviour_items == 3) {
                 if (!$isflexi_itemview) {
                     return;
                     // current view is not item view ... , nothing to display
                 }
                 unset($related);
                 // make sure this is no set ...
                 if (count($relitems_fields)) {
                     $where2 = count($relitems_fields) > 1 ? ' AND field_id IN (' . implode(',', $relitems_fields) . ')' : ' AND field_id = ' . $relitems_fields[0];
                     // select the item ids related to current item via the relation fields
                     $query2 = 'SELECT DISTINCT ' . ($behaviour_items == 2 ? 'value' : 'item_id') . ' FROM #__flexicontent_fields_item_relations' . ' WHERE ' . ($behaviour_items == 2 ? 'item_id' : 'value') . ' = ' . (int) $id . $where2;
                     $db->setQuery($query2);
                     $related = $db->loadColumn();
                     $related = is_array($related) ? array_map('intval', $related) : $related;
                 }
                 if (isset($related) && count($related)) {
                     $where .= count($related) > 1 ? ' AND i.id IN (' . implode(',', $related) . ')' : ' AND i.id = ' . $related[0];
                 } else {
                     // No related items were found
                     return;
                 }
             } else {
                 if ($behaviour_items == 1) {
                     if (!$isflexi_itemview) {
                         return;
                         // current view is not item view ... , nothing to display
                     }
                     // select the tags associated to the item
                     $query2 = 'SELECT tid' . ' FROM #__flexicontent_tags_item_relations' . ' WHERE itemid = ' . (int) $id;
                     $db->setQuery($query2);
                     $tags = $db->loadColumn();
                     $tags = array_diff($tags, $excluded_tags);
                     unset($related);
                     if ($tags) {
                         $where2 = count($tags) > 1 ? ' AND tid IN (' . implode(',', $tags) . ')' : ' AND tid = ' . $tags[0];
                         // select the item ids related to current item via common tags
                         $query2 = 'SELECT DISTINCT itemid' . ' FROM #__flexicontent_tags_item_relations' . ' WHERE itemid <> ' . (int) $id . $where2;
                         $db->setQuery($query2);
                         $related = $db->loadColumn();
                     }
                     if (isset($related) && count($related)) {
                         $where .= count($related) > 1 ? ' AND i.id IN (' . implode(',', $related) . ')' : ' AND i.id = ' . $related[0];
                     } else {
                         // No related items were found
                         return;
                     }
                 }
             }
         }
     }
     // **********
     // tags scope
     // **********
     if ($method_tags > 1) {
         // Check for empty statically selected records, and abort with error message
         if (empty($tag_ids)) {
             echo "<b>WARNING:</b> Misconfigured tags scope, select at least one tag or set tags scope to ALL<br/>";
             return;
         }
         // Make sure tag_ids is an array
         $tag_ids = !is_array($tag_ids) ? array($tag_ids) : $tag_ids;
         // Create query to match item ids using the selected tags
         $query2 = 'SELECT ' . ($tag_combine ? 'itemid' : 'DISTINCT itemid') . ' FROM #__flexicontent_tags_item_relations' . ' WHERE tid IN (' . implode(',', $tag_ids) . ')' . ($tag_combine ? ' GROUP by itemid HAVING COUNT(*) >= ' . count($tag_ids) : '');
         if ($method_tags == 2) {
             // exclude method
             $where .= ' AND i.id NOT IN (' . $query2 . ')';
         } else {
             if ($method_tags == 3) {
                 // include method
                 $where .= ' AND i.id IN (' . $query2 . ')';
             }
         }
     }
     // **********
     // date scope
     // **********
     // ZERO 'behaviour' means statically selected records, but METHOD 1 is ALL records ... so NOTHING to do
     // NOTE: currently we only have ALL, INCLUDE methods
     if (!$behaviour_dates && $method_dates == 1) {
     } else {
         if (!$behaviour_dates) {
             $negate_op = $method_dates == 2 ? 'NOT' : '';
             if (!$raw_edate && $edate && !FLEXIUtilities::isSqlValidDate($edate)) {
                 echo "<b>WARNING:</b> Misconfigured date scope, you have entered invalid -END- date:<br>(a) Enter a valid date via callendar OR <br>(b) leave blank OR <br>(c) choose (non-static behavior 'custom offset') and enter custom offset e.g. five days ago (be careful with space character): -5 d<br/>";
                 return;
             } else {
                 if ($edate) {
                     $where .= ' AND ( ' . $negate_op . ' ( ' . $comp . ' <= ' . (!$raw_edate ? $db->Quote($edate) : $edate) . ' )' . ($nulldates ? ' OR ' . $comp . ' IS NULL OR ' . $comp . '="" ' : '') . ' )';
                 }
             }
             if (!$raw_bdate && $bdate && !FLEXIUtilities::isSqlValidDate($bdate)) {
                 echo "<b>WARNING:</b> Misconfigured date scope, you have entered invalid -BEGIN- date:<br>(a) Enter a valid date via callendar OR <br>(b) leave blank OR <br>(c) choose (non-static behavior 'custom offset') and enter custom offset e.g. five days ago (be careful with space character): -5 d<br/>";
                 return;
             } else {
                 if ($bdate) {
                     $where .= ' AND ( ' . $negate_op . ' ( ' . $comp . ' >= ' . (!$raw_bdate ? $db->Quote($bdate) : $bdate) . ' )' . ($nulldates ? ' OR ' . $comp . ' IS NULL OR ' . $comp . '="" ' : '') . ' )';
                 }
             }
         } else {
             if (!$isflexi_itemview && $date_compare == 1) {
                 return;
                 // date_compare == 1 means compare to current item, but current view is not an item view so we terminate
             }
             // FOR date_compare==0, $cdate is SERVER DATE
             // FOR date_compare==1, $cdate is CURRENT ITEM DATE of type created or modified or publish_up or CUSTOM date field
             switch ($behaviour_dates) {
                 case '1':
                     // custom offset
                     if ($edate) {
                         $edate = array(0 => preg_replace("/[^-+0-9\\s]/", "", $edate), 1 => preg_replace("/[0-9-+\\s]/", "", $edate));
                         if (empty($edate[1])) {
                             echo "<b>WARNING:</b> Misconfigured date scope, you have entered invalid -END- date:Custom offset is invalid e.g. in order to enter five days ago (be careful with space character) use: -5 d (DO NOT FORGET the space between e.g. '-5 d')<br/>";
                             return;
                         } else {
                             $where .= ' AND ( ' . $comp . ' < ' . $db->Quote(date_time::shift_dates($cdate, $edate[0], $edate[1])) . ($nulldates ? ' OR ' . $comp . ' IS NULL OR ' . $comp . '="" ' : '') . ' )';
                         }
                     }
                     if ($bdate) {
                         $bdate = array(0 => preg_replace("/[^-+0-9]/", "", $bdate), 1 => preg_replace("/[0-9-+]/", "", $bdate));
                         if (empty($bdate[1])) {
                             echo "<b>WARNING:</b> Misconfigured date scope, you have entered invalid -BEGIN- date: Custom offset is invalid e.g. in order to enter five days ago (be careful with space character) use: -5 d (DO NOT FORGET the space between e.g. '-5 d')<br/>";
                             return;
                         } else {
                             $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote(date_time::shift_dates($cdate, $bdate[0], $bdate[1])) . ($nulldates ? ' OR ' . $comp . ' IS NULL OR ' . $comp . '="" ' : '') . ' )';
                         }
                     }
                     break;
                 case '8':
                     // same day
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-' . $cdate[1] . '-' . $cdate[2] . ' 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote(date_time::shift_dates($cdate, 1, 'd')) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote($cdate) . ' )';
                     break;
                 case '2':
                     // same month
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-' . $cdate[1] . '-01 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote(date_time::shift_dates($cdate, 1, 'm')) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote($cdate) . ' )';
                     break;
                 case '3':
                     // same year
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-01-01 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote(date_time::shift_dates($cdate, 1, 'Y')) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote($cdate) . ' )';
                     break;
                 case '9':
                     // previous day
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-' . $cdate[1] . '-' . $cdate[2] . ' 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote($cdate) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote(date_time::shift_dates($cdate, -1, 'd')) . ' )';
                     break;
                 case '4':
                     // previous month
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-' . $cdate[1] . '-01 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote($cdate) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote(date_time::shift_dates($cdate, -1, 'm')) . ' )';
                     break;
                 case '5':
                     // previous year
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-01-01 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote($cdate) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote(date_time::shift_dates($cdate, -1, 'Y')) . ' )';
                     break;
                 case '10':
                     // next day
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-' . $cdate[1] . '-' . $cdate[2] . ' 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote(date_time::shift_dates($cdate, 2, 'd')) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote(date_time::shift_dates($cdate, 1, 'd')) . ' )';
                     break;
                 case '6':
                     // next month
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-' . $cdate[1] . '-01 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote(date_time::shift_dates($cdate, 2, 'm')) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote(date_time::shift_dates($cdate, 1, 'm')) . ' )';
                     break;
                 case '7':
                     // next year
                     $cdate = explode(' ', $cdate);
                     $cdate = explode('-', $cdate[0]);
                     $cdate = $cdate[0] . '-01-01 00:00:00';
                     $where .= ' AND ( ' . $comp . ' < ' . $db->Quote(date_time::shift_dates($cdate, 2, 'Y')) . ' )';
                     $where .= ' AND ( ' . $comp . ' >= ' . $db->Quote(date_time::shift_dates($cdate, 1, 'Y')) . ' )';
                     break;
                 case '11':
                     // same day of month, ignore year
                     $where .= ' AND ( DAYOFMONTH(' . $comp . ') = ' . 'DAYOFMONTH(' . $db->Quote($cdate) . ') AND MONTH(' . $comp . ') = ' . 'MONTH(' . $db->Quote($cdate) . ') )';
                     break;
                 case '12':
                     // [-3d,+3d] days of month, IGNORE YEAR
                     $where .= ' AND ((DAYOFMONTH(' . $db->Quote($cdate) . ')-3) <= DAYOFMONTH(' . $comp . ') AND DAYOFMONTH(' . $comp . ') <= (DAYOFMONTH(' . $db->Quote($cdate) . ')+4) AND MONTH(' . $comp . ') = ' . 'MONTH(' . $db->Quote($cdate) . ') )';
                     break;
                 case '13':
                     // same week of month, IGNORE YEAR
                     $week_start = (int) $params->get('week_start', 0);
                     // 0 is sunday, 5 is monday
                     $week_of_month = '(WEEK(%s,5) - WEEK(DATE_SUB(%s, INTERVAL DAYOFMONTH(%s)-1 DAY),5)+1)';
                     $where .= ' AND (' . str_replace('%s', $comp, $week_of_month) . ' = ' . str_replace('%s', $db->Quote($cdate), $week_of_month) . ' AND ( MONTH(' . $comp . ') = ' . 'MONTH(' . $db->Quote($cdate) . ') ) )';
                     break;
                 case '14':
                     // same week of year, IGNORE YEAR
                     $week_start = (int) $params->get('week_start', 0);
                     // 0 is sunday, 5 is monday
                     $where .= ' AND ( WEEK(' . $comp . ') = ' . 'WEEK(' . $db->Quote($cdate) . ',' . $week_start . ') )';
                     break;
                 case '15':
                     // same month of year, IGNORE YEAR
                     $where .= ' AND ( MONTH(' . $comp . ') = ' . 'MONTH(' . $db->Quote($cdate) . ') )';
                     break;
                 case '16':
                     // same day of month, IGNORE MONTH, YEAR
                     $where .= ' AND ( DAYOFMONTH(' . $comp . ') = ' . 'DAYOFMONTH(' . $db->Quote($cdate) . ') )';
                     break;
                 case '17':
                     // [-3d,+3d] days of month, IGNORE  MONTH, YEAR
                     $where .= ' AND ((DAYOFMONTH(' . $db->Quote($cdate) . ')-3) <= DAYOFMONTH(' . $comp . ') AND DAYOFMONTH(' . $comp . ') <= (DAYOFMONTH(' . $db->Quote($cdate) . ')+4) )';
                     break;
                 case '18':
                     // same week of month, IGNORE MONTH, YEAR
                     $week_start = (int) $params->get('week_start', 0);
                     // 0 is sunday, 5 is monday
                     $week_of_month = '(WEEK(%s,5) - WEEK(DATE_SUB(%s, INTERVAL DAYOFMONTH(%s)-1 DAY),5)+1)';
                     $where .= ' AND (' . str_replace('%s', $comp, $week_of_month) . ' = ' . str_replace('%s', $db->Quote($cdate), $week_of_month) . ' )';
                     break;
             }
         }
     }
     // *****************************
     // EXTRA joins for special cases
     // *****************************
     // EXTRA joins when comparing to custom date field
     $join_date = '';
     if ($behaviour_dates || $method_dates != 1) {
         // using date SCOPE: dynamic behaviour, or static behavior with (static) method != ALL(=1)
         if (($bdate || $edate || $behaviour_dates) && $date_type == 3) {
             if ($datecomp_field) {
                 $join_date = '	LEFT JOIN #__flexicontent_fields_item_relations AS dfrel' . '   ON ( i.id = dfrel.item_id AND dfrel.field_id = ' . $datecomp_field . ' )';
             } else {
                 echo "<b>WARNING:</b> Misconfigured date scope, you have set DATE TYPE as CUSTOM DATE Field, but have not select any specific DATE Field to be used<br/>";
                 //$join_date = '';
                 return;
             }
         }
     }
     // *****************************************************************************************************************************
     // Get orderby SQL CLAUSE ('ordering' is passed by reference but no frontend user override is used (we give empty 'request_var')
     // *****************************************************************************************************************************
     $orderby = flexicontent_db::buildItemOrderBy($params, $ordering, $request_var = '', $config_param = 'ordering', $item_tbl_alias = 'i', $relcat_tbl_alias = 'rel', $default_order = '', $default_order_dir = '', $sfx = '', $support_2nd_lvl = true);
     //echo "<br/>" . print_r($ordering, true) ."<br/>";
     // EXTRA join of field used in custom ordering
     // NOTE: if (1st/2nd level) custom field id is not set, THEN 'field' ordering was changed to level's default, by the ORDER CLAUSE creating function
     $orderby_join = '';
     // Create JOIN for ordering items by a custom field (Level 1)
     if ('field' == $ordering[1]) {
         $orderbycustomfieldid = (int) $params->get('orderbycustomfieldid', 0);
         $orderby_join .= ' LEFT JOIN #__flexicontent_fields_item_relations AS f ON f.item_id = i.id AND f.field_id=' . $orderbycustomfieldid;
     }
     // Create JOIN for ordering items by a custom field (Level 2)
     if ('field' == $ordering[2]) {
         $orderbycustomfieldid_2nd = (int) $params->get('orderbycustomfieldid' . '_2nd', 0);
         $orderby_join .= ' LEFT JOIN #__flexicontent_fields_item_relations AS f2 ON f2.item_id = i.id AND f2.field_id=' . $orderbycustomfieldid_2nd;
     }
     // Create JOIN for ordering items by author's name
     if (in_array('author', $ordering) || in_array('rauthor', $ordering)) {
         $orderby_join .= ' LEFT JOIN #__users AS u ON u.id = i.created_by';
     }
     // *****************************************************
     // Decide Select Sub-Clause and Join-Clause for comments
     // *****************************************************
     $display_comments = $params->get('display_comments');
     $display_comments_feat = $params->get('display_comments_feat');
     // Check (when needed) if jcomments are installed, and also clear 'commented' ordering if they jcomments is missing
     if ($display_comments_feat || $display_comments || in_array('commented', $ordering)) {
         // Handle jcomments integratio. No need to reset 'commented' ordering if jcomments not installed,
         // and neither print message, the ORDER CLAUSE creating function should have done this already
         if (!file_exists(JPATH_SITE . DS . 'components' . DS . 'com_jcomments' . DS . 'jcomments.php')) {
             //echo "jcomments not installed, you need jcomments to use 'Most commented' ordering OR display comments information.<br>\n";
             $jcomments_exist = false;
         } else {
             $jcomments_exist = true;
         }
     }
     // Decide to JOIN (or not) with comments TABLE, needed when displaying comments and/or when ordering by comments
     $add_comments = ($display_comments_feat || $display_comments || in_array('commented', $ordering)) && $jcomments_exist;
     // Additional select and joins for comments
     $select_comments = $add_comments ? ', COUNT(DISTINCT com.id) AS comments_total' : '';
     $join_comments_type = $ordering[1] == 'commented' ? ' INNER JOIN' : ' LEFT JOIN';
     // Do not require most commented for 2nd level ordering
     $join_comments = $add_comments ? $join_comments_type . ' #__jcomments AS com ON com.object_id = i.id AND com.object_group="com_flexicontent" AND com.published="1"' : '';
     // **********************************************************
     // Decide Select Sub-Clause and Join-Clause for voting/rating
     // **********************************************************
     $display_voting = $params->get('display_voting');
     $display_voting_feat = $params->get('display_voting_feat');
     // Decide to JOIN (or not) with rating TABLE, needed when displaying ratings and/or when ordering by ratings
     $add_rated = $display_voting_feat || $display_voting || in_array('rated', $ordering);
     // Additional select and joins for ratings
     $select_rated = in_array('rated', $ordering) ? ', (cr.rating_sum / cr.rating_count) * 20 AS votes' : '';
     $select_rated .= $add_rated ? ', cr.rating_sum as rating_sum, cr.rating_count as rating_count' : '';
     $join_rated_type = in_array('rated', $ordering) ? ' INNER JOIN' : ' LEFT JOIN';
     $join_rated = $add_rated ? $join_rated_type . ' #__content_rating AS cr ON cr.content_id = i.id' : '';
     // ***********************************************************
     // Finally put together the query to retrieve the listed items
     // ***********************************************************
     // ******************
     // Custom FIELD scope
     // ******************
     $where_field_filters = '';
     $join_field_filters = '';
     // ZERO 'behaviour' means statically selected records, but METHOD 1 is ALL records ... so NOTHING to do
     if (!$behaviour_filt && $method_filt == 1) {
     } else {
         if ($behaviour_filt == 0 || $behaviour_filt == 2) {
             $negate_op = $method_filt == 2 ? 'NOT' : '';
             // These field filters apply a STATIC filtering, regardless of current item being displayed.
             // Static Field Filters (These are a string that MAPs filter ID TO filter VALUES)
             $static_filters_data = FlexicontentFields::setFilterValues($params, 'static_filters', $is_persistent = 1, $set_method = "array");
             // Dynamic Field Filters (THIS is filter IDs list)
             // These field filters apply a DYNAMIC filtering, that depend on current item being displayed. The items that have same value as currently displayed item will be included in the list.
             //$dynamic_filters = FlexicontentFields::setFilterValues( $params, 'dynamic_filters', $is_persistent=0);
             foreach ($static_filters_data as $filter_id => $filter_values) {
                 // Handle single-valued filter as multi-valued
                 if (!is_array($filter_values)) {
                     $filter_values = array(0 => $filter_values);
                 }
                 // Single or Multi valued filter
                 if (isset($filter_values[0])) {
                     $in_values = array();
                     foreach ($filter_values as $val) {
                         $in_values[] = $db->Quote($val);
                     }
                     // Quote in case they are strings !!
                     $where_field_filters .= ' AND ' . $negate_op . ' (rel' . $filter_id . '.value IN (' . implode(',', $in_values) . ') ) ';
                 } else {
                     // Special case only one part of range provided ... must MATCH/INCLUDE empty values or NULL values ...
                     $value_empty = !strlen(@$filter_values[1]) && strlen(@$filter_values[2]) ? ' OR rel' . $filter_id . '.value="" OR rel' . $filter_id . '.value IS NULL ' : '';
                     if (strlen(@$filter_values[1]) || strlen(@$filter_values[2])) {
                         $where_field_filters .= ' AND ' . $negate_op . ' ( 1 ';
                         if (strlen(@$filter_values[1])) {
                             $where_field_filters .= ' AND (rel' . $filter_id . '.value >=' . $filter_values[1] . ') ';
                         }
                         if (strlen(@$filter_values[2])) {
                             $where_field_filters .= ' AND (rel' . $filter_id . '.value <=' . $filter_values[2] . $value_empty . ') ';
                         }
                         $where_field_filters .= ' )';
                     }
                 }
                 $join_field_filters .= ' JOIN #__flexicontent_fields_item_relations AS rel' . $filter_id . ' ON rel' . $filter_id . '.item_id=i.id AND rel' . $filter_id . '.field_id = ' . $filter_id;
             }
         }
     }
     if ($behaviour_filt == 1 || $behaviour_filt == 2) {
         if (!$isflexi_itemview) {
             return;
             // current view is not item view ... , nothing to display
         }
         // 1. Get ids of dynamic filters
         //$dynamic_filter_ids = preg_split("/[\s]*,[\s]*/", $dynamic_filters);
         $dynamic_filter_ids = FLEXIUtilities::paramToArray($dynamic_filters, "/[\\s]*,[\\s]*/", "intval");
         if (empty($dynamic_filter_ids)) {
             echo "Please enter at least 1 field in Custom field filtering SCOPE, or set behaviour to static";
         } else {
             // 2. Get values of dynamic filters
             $where2 = count($dynamic_filter_ids) > 1 ? ' AND field_id IN (' . implode(',', $dynamic_filter_ids) . ')' : ' AND field_id = ' . $dynamic_filter_ids[0];
             // select the item ids related to current item via the relation fields
             $query2 = 'SELECT DISTINCT value, field_id' . ' FROM #__flexicontent_fields_item_relations' . ' WHERE item_id = ' . (int) $id . $where2;
             $db->setQuery($query2);
             $curritem_vals = $db->loadObjectList();
             //echo "<pre>"; print_r($curritem_vals); echo "</pre>";
             // 3. Group values by field
             $_vals = array();
             foreach ($curritem_vals as $v) {
                 $_vals[$v->field_id][] = $v->value;
             }
             foreach ($dynamic_filter_ids as $filter_id) {
                 // Handle non-existent value by requiring that matching item do not have a value for this field either
                 if (!isset($_vals[$filter_id])) {
                     $where_field_filters .= ' AND reldyn' . $filter_id . '.value IS NULL';
                 } else {
                     $in_values = array();
                     foreach ($_vals[$filter_id] as $v) {
                         $in_values[] = $db->Quote($v);
                     }
                     $where_field_filters .= ' AND reldyn' . $filter_id . '.value IN (' . implode(',', $in_values) . ') ' . "\n";
                 }
                 $join_field_filters .= ' JOIN #__flexicontent_fields_item_relations AS reldyn' . $filter_id . ' ON reldyn' . $filter_id . '.item_id=i.id AND reldyn' . $filter_id . '.field_id = ' . $filter_id . "\n";
             }
             //echo "<pre>"."\n\n".$join_field_filters ."\n\n".$where_field_filters."</pre>";
         }
     }
     if (empty($items_query)) {
         // If a custom query has not been set above then use the default one ...
         $items_query = 'SELECT ' . ' i.id ' . (in_array('commented', $ordering) ? $select_comments : '') . (in_array('rated', $ordering) ? $select_rated : '') . ' FROM #__flexicontent_items_tmp AS i' . ' JOIN #__flexicontent_items_ext AS ie on ie.item_id = i.id' . ' JOIN #__flexicontent_types AS ty on ie.type_id = ty.id' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.itemid = i.id' . ' JOIN #__categories AS  c ON  c.id = rel.catid' . ' JOIN #__categories AS mc ON mc.id = i.catid' . $joinaccess . $join_favs . $join_date . (in_array('commented', $ordering) ? $join_comments : '') . (in_array('rated', $ordering) ? $join_rated : '') . $orderby_join . $join_field_filters . $where . ' ' . ($apply_config_per_category ? '__CID_WHERE__' : '') . $where_field_filters . ' GROUP BY i.id' . $orderby;
         // if using CATEGORY SCOPE INCLUDE ... then link though them ... otherwise via main category
         $_cl = !$behaviour_cat && $method_cat == 3 ? 'c' : 'mc';
         $items_query_data = 'SELECT ' . ' i.*, ie.*, ty.name AS typename' . $select_comments . $select_rated . ', mc.title AS maincat_title, mc.alias AS maincat_alias' . ', CASE WHEN CHAR_LENGTH(i.alias) THEN CONCAT_WS(\':\', i.id, i.alias) ELSE i.id END as slug' . ', CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', ' . $_cl . '.id, ' . $_cl . '.alias) ELSE ' . $_cl . '.id END as categoryslug' . ', GROUP_CONCAT(rel.catid SEPARATOR ",") as itemcats' . ' FROM #__content AS i' . ' JOIN #__flexicontent_items_ext AS ie on ie.item_id = i.id' . ' JOIN #__flexicontent_types AS ty on ie.type_id = ty.id' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.itemid = i.id' . ' JOIN #__categories AS  c ON  c.id = rel.catid' . ' JOIN #__categories AS mc ON mc.id = i.catid' . $joinaccess . $join_favs . $join_date . $join_comments . $join_rated . $orderby_join . ' WHERE i.id IN (__content__)' . ' GROUP BY i.id';
     }
     // **********************************
     // Execute query once OR per category
     // **********************************
     if (!isset($multiquery_cats)) {
         $multiquery_cats = array(0 => "");
     }
     foreach ($multiquery_cats as $catid => $cat_where) {
         $_microtime = $modfc_jprof->getmicrotime();
         // Get content list per given category
         $per_cat_query = str_replace('__CID_WHERE__', $cat_where, $items_query);
         $db->setQuery($per_cat_query, 0, $count);
         $content = $db->loadColumn(0);
         if ($db->getErrorNum()) {
             JFactory::getApplication()->enqueueMessage(__FUNCTION__ . '(): SQL QUERY ERROR:<br/>' . nl2br($db->getErrorMsg()), 'error');
         }
         @($mod_fc_run_times['query_items'] += $modfc_jprof->getmicrotime() - $_microtime);
         // Check for no content found for given category
         if (empty($content)) {
             $cat_items_arr[$catid] = array();
             continue;
         }
         $_microtime = $modfc_jprof->getmicrotime();
         // Get content list data per given category
         $per_cat_query = str_replace('__content__', implode(',', $content), $items_query_data);
         $db->setQuery($per_cat_query, 0, $count);
         $_rows = $db->loadObjectList('item_id');
         if ($db->getErrorNum()) {
             JFactory::getApplication()->enqueueMessage(__FUNCTION__ . '(): SQL QUERY ERROR:<br/>' . nl2br($db->getErrorMsg()), 'error');
         }
         @($mod_fc_run_times['query_items_sec'] += $modfc_jprof->getmicrotime() - $_microtime);
         // Secondary content list ordering and assign content list per category
         $rows = array();
         foreach ($content as $_id) {
             $rows[] = $_rows[$_id];
         }
         $cat_items_arr[$catid] = $rows;
         // Get Original content ids for creating some untranslatable fields that have share data (like shared folders)
         flexicontent_db::getOriginalContentItemids($cat_items_arr[$catid]);
     }
     // ************************************************************************************************
     // Return items indexed per category id OR via empty string if not apply configuration per category
     // ************************************************************************************************
     return $cat_items_arr;
 }