/**
* Build the order clause of item listings
* precedence: $request_var ==> $order ==> $config_param ==> $default_order_col (& $default_order_dir)
* @access private
* @return string
*/
static function buildItemOrderBy(&$params=null, &$order='', $request_var='orderby', $config_param='orderby', $i_as='i', $rel_as='rel', $default_order_col_1st='', $default_order_dir_1st='', $sfx='', $support_2nd_lvl=false)
{
// Use global params ordering if parameters were not given
if (!$params) $params = JComponentHelper::getParams( 'com_flexicontent' );
$order_fallback = 'rdate'; // Use as default or when an invalid ordering is requested
$orderbycustomfield = (int) $params->get('orderbycustomfield'.$sfx, 1); // Backwards compatibility, defaults to enabled *
$orderbycustomfieldid = (int) $params->get('orderbycustomfieldid'.$sfx, 0); // * but this needs to be set in order for field ordering to be used
// 1. If a FORCED -ORDER- is not given, then use ordering parameters from configuration. NOTE: custom field ordering takes priority
if (!$order) {
$order = ($orderbycustomfield && $orderbycustomfieldid) ? 'field' : $params->get($config_param.$sfx, $order_fallback);
}
// 2. If allowing user ordering override, then get ordering from HTTP request variable
$order = $params->get('orderby_override') && ($request_order = JRequest::getVar($request_var.$sfx)) ? $request_order : $order;
// 3. Check various cases of invalid order, print warning, and reset ordering to default
if ($order=='field' && !$orderbycustomfieldid ) {
// This can occur only if field ordering was requested explicitly, otherwise an not set 'orderbycustomfieldid' will prevent 'field' ordering
echo "Custom field ordering was selected, but no custom field is selected to be used for ordering<br/>";
$order = $order_fallback;
}
if ($order=='commented') {
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";
$order = $order_fallback;
}
}
$order_col_1st = $default_order_col_1st;
$order_dir_1st = $default_order_dir_1st;
flexicontent_db::_getOrderByClause($params, $order, $i_as, $rel_as, $order_col_1st, $order_dir_1st, $sfx);
$order_arr[1] = $order;
$orderby = ' ORDER BY '.$order_col_1st.' '.$order_dir_1st;
// ****************************************************************
// 2nd level ordering, (currently only supported when no SFX given)
// ****************************************************************
if ($sfx!='' || !$support_2nd_lvl) {
$orderby .= $order_col_1st != $i_as.'.title' ? ', '.$i_as.'.title' : '';
$order_arr[2] = '';
$order = $order_arr;
return $orderby;
}
$order = ''; // Clear this, thus force retrieval from parameters (below)
$sfx='_2nd'; // Set suffix of second level ordering
$order_fallback = 'alpha'; // Use as default or when an invalid ordering is requested
$orderbycustomfield = (int) $params->get('orderbycustomfield'.$sfx, 1); // Backwards compatibility, defaults to enabled *
$orderbycustomfieldid = (int) $params->get('orderbycustomfieldid'.$sfx, 0); // * but this needs to be set in order for field ordering to be used
// 1. If a FORCED -ORDER- is not given, then use ordering parameters from configuration. NOTE: custom field ordering takes priority
if (!$order) {
$order = ($orderbycustomfield && $orderbycustomfieldid) ? 'field' : $params->get($config_param.$sfx, $order_fallback);
}
// 2. If allowing user ordering override, then get ordering from HTTP request variable
$order = $request_var && ($request_order = JRequest::getVar($request_var.$sfx)) ? $request_order : $order;
// 3. Check various cases of invalid order, print warning, and reset ordering to default
if ($order=='field' && !$orderbycustomfieldid ) {
// This can occur only if field ordering was requested explicitly, otherwise an not set 'orderbycustomfieldid' will prevent 'field' ordering
echo "Custom field ordering was selected, but no custom field is selected to be used for ordering<br/>";
$order = $order_fallback;
}
if ($order=='commented') {
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";
$order = $order_fallback;
}
}
$order_col_2nd = '';
$order_dir_2nd = '';
if ($order!='default') {
flexicontent_db::_getOrderByClause($params, $order, $i_as, $rel_as, $order_col_2nd, $order_dir_2nd, $sfx);
$order_arr[2] = $order;
$orderby .= ', '.$order_col_2nd.' '.$order_dir_2nd;
}
// Order by title after default ordering
$orderby .= ($order_col_1st != $i_as.'.title' && $order_col_2nd != $i_as.'.title') ? ', '.$i_as.'.title' : '';
$order = $order_arr;
return $orderby;
}
/**
* Method to build the WHERE clause
*
* @access private
* @return string
*/
function _buildItemWhere()
{
$user = JFactory::getUser();
$db = JFactory::getDBO();
// Get the view's parameters
$cparams = $this->_params;
// 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
//$app = JFactory::getApplication();
//$now = FLEXI_J16GE ? $app->requestTime : $app->get('requestTime'); // NOT correct behavior it should be UTC (below)
//$date = JFactory::getDate();
//$now = FLEXI_J16GE ? $date->toSql() : $date->toMySQL(); // NOT good if string passed to function that will be cached, because string continuesly different
$_nowDate = 'UTC_TIMESTAMP()';
//$db->Quote($now);
$nullDate = $db->getNullDate();
// First thing we need to do is to select only the requested FAVOURED items
$where = ' WHERE fav.userid = ' . (int) $user->get('id');
// Get privilege to view non viewable items (upublished, archived, trashed, expired, scheduled).
// NOTE: ACL view level is checked at a different place
if (FLEXI_J16GE) {
$ignoreState = $user->authorise('flexicontent.ignoreviewstate', 'com_flexicontent');
} else {
if (FLEXI_ACCESS) {
$ignoreState = $user->gid < 25 ? FAccess::checkComponentAccess('com_flexicontent', 'ignoreviewstate', 'users', $user->gmid) : 1;
} else {
$ignoreState = $user->gid > 19;
}
}
// author has 19 and editor has 20
if (!$ignoreState) {
// Limit by publication state. Exception: when displaying personal user items or items modified by the user
$where .= ' AND ( i.state IN (1, -5) OR ( i.created_by = ' . $user->id . ' AND i.created_by != 0 ) )';
//.' OR ( i.modified_by = '.$user->id.' AND i.modified_by != 0 ) )';
// Limit by publish up/down dates. Exception: when displaying personal user items or items modified by the user
$where .= ' AND ( ( i.publish_up = ' . $this->_db->Quote($nullDate) . ' OR i.publish_up <= ' . $_nowDate . ' ) OR ( i.created_by = ' . $user->id . ' AND i.created_by != 0 ) )';
//.' OR ( i.modified_by = '.$user->id.' AND i.modified_by != 0 ) )';
$where .= ' AND ( ( i.publish_down = ' . $this->_db->Quote($nullDate) . ' OR i.publish_down >= ' . $_nowDate . ' ) OR ( i.created_by = ' . $user->id . ' AND i.created_by != 0 ) )';
//.' OR ( i.modified_by = '.$user->id.' AND i.modified_by != 0 ) )';
}
$where .= !FLEXI_J16GE ? ' AND i.sectionid = ' . FLEXI_SECTION : '';
/*
* If we have a filter, and this is enabled... lets tack the AND clause
* for the filter onto the WHERE clause of the item query.
*/
// ****************************************
// Create WHERE clause part for Text Search
// ****************************************
$text = JRequest::getString('filter', JRequest::getString('q', ''), 'default');
// Check for LIKE %word% search, for languages without spaces
$filter_word_like_any = $cparams->get('filter_word_like_any', 0);
$phrase = $filter_word_like_any ? JRequest::getWord('searchphrase', JRequest::getWord('p', 'any'), 'default') : JRequest::getWord('searchphrase', JRequest::getWord('p', 'exact'), 'default');
$si_tbl = 'flexicontent_items_ext';
$search_prefix = $cparams->get('add_search_prefix') ? 'vvv' : '';
// SEARCH WORD Prefix
$text = !$search_prefix ? trim($text) : preg_replace('/(\\b[^\\s,\\.]+\\b)/u', $search_prefix . '$0', trim($text));
$words = preg_split('/\\s\\s*/u', $text);
if (strlen($text)) {
$ts = 'ie';
$escaped_text = FLEXI_J16GE ? $db->escape($text, true) : $db->getEscaped($text, true);
$quoted_text = $db->Quote($escaped_text, false);
switch ($phrase) {
case 'natural':
$_text_match = ' MATCH (' . $ts . '.search_index) AGAINST (' . $quoted_text . ') ';
break;
case 'natural_expanded':
$_text_match = ' MATCH (' . $ts . '.search_index) AGAINST (' . $quoted_text . ' WITH QUERY EXPANSION) ';
break;
case 'exact':
$stopwords = array();
$shortwords = array();
if (!$search_prefix) {
$words = flexicontent_db::removeInvalidWords($words, $stopwords, $shortwords, $si_tbl, 'search_index', $isprefix = 0);
}
if (empty($words)) {
// All words are stop-words or too short, we could try to execute a query that only contains a LIKE %...% , but it would be too slow
JRequest::setVar('ignoredwords', implode(' ', $stopwords));
JRequest::setVar('shortwords', implode(' ', $shortwords));
$_text_match = ' 0=1 ';
} else {
// speed optimization ... 2-level searching: first require ALL words, then require exact text
$newtext = '+' . implode(' +', $words);
$quoted_text = FLEXI_J16GE ? $db->escape($newtext, true) : $db->getEscaped($newtext, true);
$quoted_text = $db->Quote($quoted_text, false);
$exact_text = $db->Quote('%' . $escaped_text . '%', false);
$_text_match = ' MATCH (' . $ts . '.search_index) AGAINST (' . $quoted_text . ' IN BOOLEAN MODE) AND ' . $ts . '.search_index LIKE ' . $exact_text;
}
break;
case 'all':
$stopwords = array();
$shortwords = array();
if (!$search_prefix) {
$words = flexicontent_db::removeInvalidWords($words, $stopwords, $shortwords, $si_tbl, 'search_index', $isprefix = 1);
}
JRequest::setVar('ignoredwords', implode(' ', $stopwords));
//.........这里部分代码省略.........
/**
* Method to determine if J3.1+ associations should be used
*
* @return boolean True if using J3 associations; false otherwise.
*/
public function useAssociations()
{
return flexicontent_db::useAssociations();
}
//.........这里部分代码省略.........
// then the item is inside in an unpublished ancestor category, thus inaccessible
/*$query->select('CASE WHEN badcats.id is null THEN 1 ELSE 0 END AS ancestor_cats_published');
$subquery = ' (SELECT cat.id as id FROM #__categories AS cat JOIN #__categories AS parent ';
$subquery .= 'ON cat.lft BETWEEN parent.lft AND parent.rgt ';
$subquery .= 'WHERE parent.extension = ' . $db->Quote('com_content');
$subquery .= ' AND parent.published <= 0 GROUP BY cat.id)';
$query->join('LEFT', $subquery . ' AS badcats ON badcats.id = c.id');*/
if ($version) {
// NOTE: version_id is used by field helper file to load the specified version, the reason for left join here is to verify that the version exists
$query->join('LEFT', '#__flexicontent_versions AS ver ON ver.item_id = i.id AND ver.version_id = ' . $db->Quote($version));
}
// Join on contact table, to get contact data of author
//$query = 'SHOW TABLES LIKE "' . JFactory::getApplication()->getCfg('dbprefix') . 'contact_details"';
//$db->setQuery($query);
//$contact_details_tbl_exists = (boolean) count($db->loadObjectList());
//if ( $contact_details_tbl_exists) {
// $query->select('contact.id as contactid' ) ;
// $query->join('LEFT','#__contact_details AS contact on contact.user_id = i.created_by');
//}
// Join over the categories to get parent category titles
//$query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias');
//$query->join('LEFT', '#__categories as parent ON parent.id = c.parent_id');
$query->where('i.id = ' . (int) $this->_id);
//echo $db->replacePrefix($query);
} else {
// NOTE: version_id is used by field helper file to load the specified version, the reason for left join here is to verify that the version exists
$version_join = $version ? ' LEFT JOIN #__flexicontent_versions AS ver ON ver.item_id = i.id AND ver.version_id = ' . $db->Quote($version) : '';
$where = $this->_buildItemWhere();
$query = 'SELECT i.*, ie.*, ' . $select_access . ($version ? 'ver.version_id,' : '') . ' c.id AS catid, i.catid as maincatid,' . ' c.published AS catpublished,' . ' c.title AS category_title, c.alias AS category_alias,' . ' ty.name as typename, ty.alias as typealias,' . ' u.name AS author, u.usertype,' . ' v.rating_count as rating_count, ROUND( v.rating_sum / v.rating_count ) AS rating, ((v.rating_sum / v.rating_count)*20) as score,' . ' 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(\':\', c.id, c.alias) ELSE c.id END as categoryslug,' . ' CASE WHEN i.publish_up = ' . $nullDate . ' OR i.publish_up <= ' . $nowDate . ' THEN 0 ELSE 1 END as publication_scheduled,' . ' CASE WHEN i.publish_down = ' . $nullDate . ' OR i.publish_down >= ' . $nowDate . ' THEN 0 ELSE 1 END as publication_expired' . ' FROM #__content AS i' . ' LEFT JOIN #__flexicontent_items_ext AS ie ON ie.item_id = i.id' . ' LEFT JOIN #__flexicontent_types AS ty ON ie.type_id = ty.id' . ' LEFT JOIN #__flexicontent_cats_item_relations AS rel ON rel.itemid = i.id' . $limit_to_cid . ' LEFT JOIN #__categories AS c ON c.id = rel.catid' . ' LEFT JOIN #__categories AS mc ON mc.id = i.catid' . ' LEFT JOIN #__users AS u ON u.id = i.created_by' . ' LEFT JOIN #__content_rating AS v ON i.id = v.content_id' . $joinaccess . $version_join . $where;
}
$db->setQuery($query);
// Try to execute query directly and load the data as an object
if (FLEXI_FISH && $task == 'edit' && $option == 'com_flexicontent' && in_array($app->getCfg('dbtype'), array('mysqli', 'mysql'))) {
$data = flexicontent_db::directQuery($query);
$data = @$data[0];
//$data = $db->loadObject(null, false); // do not, translate, this is the JoomFish overridden method of Database extended Class
} else {
$data = $db->loadObject();
}
// Check for SQL error
if ($db->getErrorNum()) {
if (FLEXI_J16GE) {
throw new Exception($db->getErrorMsg(), 500);
} else {
JError::raiseError(500, $db->getErrorMsg());
}
}
//print_r($data); exit;
if (!$data) {
return false;
}
// item not found, return
if ($version && !$data->version_id) {
JError::raiseNotice(10, JText::sprintf('NOTICE: Requested item version %d was not found', $version));
}
$item =& $data;
}
// -- Create the description field called 'text' by appending introtext + readmore + fulltext
$item->text = $item->introtext;
$item->text .= JString::strlen(trim($item->fulltext)) ? '<hr id="system-readmore" />' . $item->fulltext : "";
//echo "<br/>Current version (Frontend Active): " . $item->version;
//echo "<br/>Version to load: ".$version;
//echo "<br/><b> *** db title:</b> ".$item->title;
//echo "<br/><b> *** db text:</b> ".$item->text;
//echo "<pre>*** item data: "; print_r($item); echo "</pre>"; exit;
// Set number of loaded version, IMPORTANT: zero means load unversioned data
//.........这里部分代码省略.........
// Add the templates css files if availables
if (isset($themes->category->{$clayout}->css)) {
foreach ($themes->category->{$clayout}->css as $css) {
$document->addStyleSheet($this->baseurl . '/' . $css);
}
}
// Add the templates js files if availables
if (isset($themes->category->{$clayout}->js)) {
foreach ($themes->category->{$clayout}->js as $js) {
$document->addScript($this->baseurl . '/' . $js);
}
}
// Set the template var
$tmpl = $themes->category->{$clayout}->tmplvar;
} else {
$tmpl = '.category.default';
}
// @TODO trigger the plugin selectively
// and delete the plugins tags if not active
if ($params->get('trigger_onprepare_content_cat')) {
JPluginHelper::importPlugin('content');
// Allow to trigger content plugins on category description
// NOTE: for J2.5, we will trigger the plugins as if description text was an article text, using ... 'com_content.article'
$category->text = $category->description;
$results = $dispatcher->trigger('onContentPrepare', array('com_content.article', &$category, &$params, 0));
JRequest::setVar('layout', $layout);
// Restore LAYOUT variable should some plugin have modified it
$category->description = $category->text;
}
// Maybe here not to import all plugins but just those for description field or add a parameter for this
// Anyway these events are usually not very time consuming as is the the event onPrepareContent(J1.5)/onContentPrepare(J1.6+)
JPluginHelper::importPlugin('content');
$noroute_cats = array_flip($globalnoroute);
$type_attribs = flexicontent_db::getTypeAttribs($force = true, $typeid = 0);
$type_params = array();
foreach ($items as $item) {
$item->event = new stdClass();
if (!isset($type_params[$item->type_id])) {
$type_params[$item->type_id] = new JRegistry($type_attribs[$item->type_id]);
}
$item->params = clone $type_params[$item->type_id];
$item->params->merge(new JRegistry($item->attribs));
//$item->cats = isset($item->cats) ? $item->cats : array();
// !!! The triggering of the event onPrepareContent(J1.5)/onContentPrepare(J1.6+) of content plugins
// !!! for description field (maintext) along with all other flexicontent
// !!! fields is handled by flexicontent.fields.php
// !!! Had serious performance impact
// CODE REMOVED
// We must check if the current category is in the categories of the item ..
$item_in_category = false;
if ($item->catid == $category->id) {
$item_in_category = true;
} else {
foreach ($item->cats as $cat) {
if ($cat->id == $category->id) {
$item_in_category = true;
break;
}
}
}
// ADVANCED CATEGORY ROUTING (=set the most appropriate category for the item ...)
// CHOOSE APPROPRIATE category-slug FOR THE ITEM !!! ( )
if ($item_in_category && !isset($noroute_cats[$category->id])) {
// 1. CATEGORY SLUG: CURRENT category
// Current category IS a category of the item and ALSO routing (creating links) to this category is allowed
$item->categoryslug = $category->slug;
请发表评论