From b23d477f268f985550d217a5de0d00fecbeac313 Mon Sep 17 00:00:00 2001
From: Cameron <e107inc@gmail.com>
Date: Fri, 20 May 2016 15:06:36 -0700
Subject: [PATCH] Optimized News listing pages for less SQL lookups.
 Enhancement: News article listing by author.

---
 .../shortcodes/batch/news_shortcodes.php      | 26 +++++++-
 e107_core/url/news/sef_full_url.php           |  5 +-
 e107_core/url/news/sef_noid_url.php           | 14 ++++-
 e107_core/url/news/sef_url.php                |  4 +-
 e107_core/url/news/url.php                    |  8 ++-
 news.php                                      | 62 ++++++++++++++++---
 6 files changed, 101 insertions(+), 18 deletions(-)

diff --git a/e107_core/shortcodes/batch/news_shortcodes.php b/e107_core/shortcodes/batch/news_shortcodes.php
index 5bd0d0931..a522831b3 100644
--- a/e107_core/shortcodes/batch/news_shortcodes.php
+++ b/e107_core/shortcodes/batch/news_shortcodes.php
@@ -291,6 +291,27 @@ class news_shortcodes extends e_shortcode
 		return $this->sc_newsauthor($parm);
 	}
 
+	public function sc_news_author_avatar($parm=null)
+	{
+		return $this->sc_newsavatar($parm);
+	}
+
+	public function sc_news_author_signature($parm=null)
+	{
+
+		$user = e107::user($this->news_item['user_id']);
+
+		if(!empty($user['user_signature']))
+		{
+			return e107::getParser()->toHtml($user['user_signature'], true, 'DESCRIPTION');
+		}
+	}
+
+	public function sc_news_author_items_url($parm=null)
+	{
+		return e107::getUrl()->create('news/list/author',array('author'=>$this->news_item['user_name'])); // e_BASE."news.php?author=".$val
+	}
+
 	public function sc_news_summary($parm=null)
 	{
 		return $this->sc_newssummary($parm);
@@ -369,7 +390,10 @@ class news_shortcodes extends e_shortcode
 
 	function sc_newsavatar($parm=null)
 	{
-		return vartrue($this->news_item['user_id']) ? e107::getParser()->parseTemplate("{USER_AVATAR=".$this->news_item['user_id']."}",true) : '';
+		if(!empty($this->news_item['user_id']))
+		{
+			return e107::getParser()->toAvatar($this->news_item['user_id'], $parm);
+		}
 	} 
 
 	/**
diff --git a/e107_core/url/news/sef_full_url.php b/e107_core/url/news/sef_full_url.php
index f7a9eccb7..3958d118d 100644
--- a/e107_core/url/news/sef_full_url.php
+++ b/e107_core/url/news/sef_full_url.php
@@ -39,8 +39,9 @@ class core_news_sef_full_url extends eUrlConfig
 				'Short/<id:{number}>' 						=> array('list/short', 	'allowVars' => array('page'), 'mapVars' => array('category_id' => 'id'), 'legacyQuery' => 'cat.{id}.{page}'),				
 				'Day/<id:{number}>' 						=> array('list/day', 	'allowVars' => array('page'), 'legacyQuery' => 'day.{id}.{page}'),
 				'Month/<id:{number}>' 						=> array('list/month', 	'allowVars' => array('page'), 'legacyQuery' => 'month.{id}.{page}'),
-				'Tag/<tag:{secure}>' 						=> array('list/tag', 	'allowVars' => array('page'), 'legacyQuery' => 'tag={tag}'),
-				
+				'Tag/<tag:{secure}>' 						=> array('list/tag', 	'allowVars' => array('page'), 'legacyQuery' => 'tag={tag}&page={page}'),
+				'Author/<author:{secure}>' 					=> array('list/author', 'allowVars' => array('page'), 'legacyQuery' => 'author={author}&page={$page}'),
+
 				'<category:{sefsecure}>/<name:{sefsecure}>' => array('view/item', 'mapVars' => array('category_sef' => 'category', 'news_sef' => 'name'), 'legacyQuery' => 'extend.{name}', 'parseCallback' => 'itemIdByTitle'),
 				'<name:{sefsecure}>' 						=> array('view/item', 'mapVars' => array('news_id' => 'id', 'news_sef' => 'name'), 'legacyQuery' => 'extend.{name}', 'parseCallback' => 'itemIdByTitle'),
 				'<id:{number}>' 							=> array('view/item', 'mapVars' => array('news_id' => 'id'), 'legacyQuery' => 'extend.{id}'),
diff --git a/e107_core/url/news/sef_noid_url.php b/e107_core/url/news/sef_noid_url.php
index dd1cdab5c..147bd062c 100644
--- a/e107_core/url/news/sef_noid_url.php
+++ b/e107_core/url/news/sef_noid_url.php
@@ -102,7 +102,14 @@ class core_news_sef_noid_url extends eUrlConfig
 				
 				case 'tag':				// news/tag/xxxx
 					$r[0] = 'tag';
-					$r[1] = $params['tag']; 
+					$r[1] = $params['tag'];
+					if($page) $parm = array('page' => $page);
+				break;
+
+				case 'author':				// news/author/xxxx
+					$r[0] = 'author';
+					$r[1] = $params['author'];
+					if($page) $parm = array('page' => $page);
 				break;
 				
 				case 'category':
@@ -250,6 +257,11 @@ class core_news_sef_noid_url extends eUrlConfig
 				$this->legacyQueryString = 'tag='.$parts[1];
 				return 'list/tag';
 			break;
+
+			case 'author': // url: news/author/xxxxx
+				$this->legacyQueryString = 'author='.$parts[1].'&page='.$page;
+				return 'list/author';
+			break;
 			
 			# force not found
 			default:
diff --git a/e107_core/url/news/sef_url.php b/e107_core/url/news/sef_url.php
index 7f07e63ef..00fb395b2 100644
--- a/e107_core/url/news/sef_url.php
+++ b/e107_core/url/news/sef_url.php
@@ -107,9 +107,9 @@ class core_news_sef_url extends eUrlConfig
 				
 				'View/<id:{number}>' 		=> array('view/item', 'mapVars' => array('news_id' => 'id'), 'legacyQuery' => 'extend.{id}'),
 				
-				'Tag/<tag:{secure}>' 	=> array('list/tag', 'allowVars' => array('page'), 'legacyQuery' => 'tag={tag}'),
+				'Tag/<tag:{secure}>' 	=> array('list/tag', 'allowVars' => array('page'), 'legacyQuery' => 'tag={tag}&page={page}'),
 			
-				
+				'Author/<author:{secure}>' 	=> array('list/author', 'allowVars' => array('page'), 'legacyQuery' => 'author={author}&page={page}'),
 			) 
 		);
 	}
diff --git a/e107_core/url/news/url.php b/e107_core/url/news/url.php
index c735c2a70..13e82db9a 100644
--- a/e107_core/url/news/url.php
+++ b/e107_core/url/news/url.php
@@ -134,8 +134,8 @@ class core_news_url extends eUrlConfig
 						 $url .= 'default.0.'.$page;
 					}
 					else 
-					{
-						$url .= 'list.'.$params['id'].'.'.$page;	// 'category_id' would break news_categories_menu. 
+					{
+						$url .= 'list.'.$params['id'].'.'.$page;	// 'category_id' would break news_categories_menu. 
 					}
 				break;
 					
@@ -146,6 +146,10 @@ class core_news_url extends eUrlConfig
 				case 'tag':
 					$url .= 'tag='.$params['tag'].'&page='.$page;
 				break;
+
+				case 'author':
+					$url .= 'author='.$params['author'].'&page='.$page;
+				break;
 				
 				case 'short':
 					$url .= 'cat.'.$params['id'].'.'.$page;
diff --git a/news.php b/news.php
index 0c9b8e544..5e08c827e 100644
--- a/news.php
+++ b/news.php
@@ -155,18 +155,36 @@ $nobody_regexp = "'(^|,)(".str_replace(",", "|", e_UC_NOBODY).")(,|$)'";
 
 if(vartrue($_GET['tag']) || substr($action,0,4) == 'tag=')
 {
-	
-	$newsRoute = 'news/list/tag';	
+
+	$newsRoute = 'news/list/tag';
 	if(!vartrue($_GET['tag']))
 	{
-		list($action,$word) = explode("=",$action,2);	
+		list($action,$word) = explode("=",$action,2);
 		$_GET['tag'] = $word;
 		unset($word,$tmp);
 	}
 
+	$newsUrlparms['tag'] = $tp->filter($_GET['tag']);
 	$newsfrom = intval(varset($_GET['page'],0));
 }
 
+if(!empty($_GET['author']) || substr($action,0,4) == 'author=')
+{
+
+	$newsRoute = 'news/list/author';
+	if(!vartrue($_GET['author']))
+	{
+		list($action,$author) = explode("=",$action,2);
+		$_GET['author'] = $author;
+		unset($author,$tmp);
+	}
+
+	$newsUrlparms['author'] = $tp->filter($_GET['author']);
+	$newsfrom = intval(varset($_GET['page'],0));
+
+}
+
+
 if(E107_DBG_PATH)
 {
 	echo "<div class='alert alert-info'>";
@@ -184,7 +202,7 @@ if(E107_DBG_PATH)
 //------------------------------------------------------
 // Just title and a few other details
 
-if ($action == 'cat' || $action == 'all' || vartrue($_GET['tag']))
+if ($action == 'cat' || $action == 'all' || !empty($_GET['tag']) || !empty($_GET['author']))
 {	// --> Cache
 	if($newsCachedPage = checkCache($cacheString))
 	{
@@ -214,9 +232,9 @@ if ($action == 'cat' || $action == 'all' || vartrue($_GET['tag']))
 			$renTypeQry = " AND (n.news_render_type REGEXP '(^|,)(".implode("|", $pref['news_list_templates']).")(,|$)')";
 		}
 		
-		$news_total = $sql->count("news", "(*)", "WHERE news_class REGEXP '".e_CLASS_REGEXP."' AND NOT (news_class REGEXP ".$nobody_regexp.") AND news_start < ".time()." AND (news_end=0 || news_end>".time().")". str_replace("n.news", "news", $renTypeQry));
+	//	$news_total = $sql->count("news", "(*)", "WHERE news_class REGEXP '".e_CLASS_REGEXP."' AND NOT (news_class REGEXP ".$nobody_regexp.") AND news_start < ".time()." AND (news_end=0 || news_end>".time().")". str_replace("n.news", "news", $renTypeQry));
 		$query = "
-		SELECT n.*, u.user_id, u.user_name, u.user_customtitle, nc.category_id, nc.category_name, nc.category_sef, nc.category_icon,
+		SELECT SQL_CALC_FOUND_ROWS n.*, u.user_id, u.user_name, u.user_customtitle, nc.category_id, nc.category_name, nc.category_sef, nc.category_icon,
 		nc.category_meta_keywords, nc.category_meta_description
 		FROM #news AS n
 		LEFT JOIN #user AS u ON n.news_author = u.user_id
@@ -235,10 +253,10 @@ if ($action == 'cat' || $action == 'all' || vartrue($_GET['tag']))
 	elseif ($action == 'cat') // show archive of all news items in a particular category using list-style template.
 	{
 		
-		$news_total = $sql->count("news", "(*)", "WHERE news_class REGEXP '".e_CLASS_REGEXP."' AND NOT (news_class REGEXP ".$nobody_regexp.") AND news_start < ".time()." AND (news_end=0 || news_end>".time().") AND news_category=".intval($sub_action));
+	//	$news_total = $sql->count("news", "(*)", "WHERE news_class REGEXP '".e_CLASS_REGEXP."' AND NOT (news_class REGEXP ".$nobody_regexp.") AND news_start < ".time()." AND (news_end=0 || news_end>".time().") AND news_category=".intval($sub_action));
 		
 		$query = "
-		SELECT n.*, u.user_id, u.user_name, u.user_customtitle, nc.category_id, nc.category_name, nc.category_sef, nc.category_icon, nc.category_meta_keywords,
+		SELECT SQL_CALC_FOUND_ROWS n.*, u.user_id, u.user_name, u.user_customtitle, nc.category_id, nc.category_name, nc.category_sef, nc.category_icon, nc.category_meta_keywords,
 		nc.category_meta_description
 		FROM #news AS n
 		LEFT JOIN #user AS u ON n.news_author = u.user_id
@@ -254,7 +272,7 @@ if ($action == 'cat' || $action == 'all' || vartrue($_GET['tag']))
 		$tagsearch = e107::getParser()->filter($_GET['tag']);
 
 		$query = "
-		SELECT n.*, u.user_id, u.user_name, u.user_customtitle, nc.category_id, nc.category_name, nc.category_sef, nc.category_icon, nc.category_meta_keywords,
+		SELECT SQL_CALC_FOUND_ROWS n.*, u.user_id, u.user_name, u.user_customtitle, nc.category_id, nc.category_name, nc.category_sef, nc.category_icon, nc.category_meta_keywords,
 		nc.category_meta_description
 		FROM #news AS n
 		LEFT JOIN #user AS u ON n.news_author = u.user_id
@@ -266,12 +284,33 @@ if ($action == 'cat' || $action == 'all' || vartrue($_GET['tag']))
 		LIMIT ".intval($newsfrom).",".NEWSLIST_LIMIT;	
 		$category_name = 'Tag: "'.$tagsearch.'"';
 		
+	}
+	elseif(!empty($_GET['author']))
+	{
+		$authorSearch = e107::getParser()->filter($_GET['author']);
+
+		$query = "
+		SELECT SQL_CALC_FOUND_ROWS n.*, u.user_id, u.user_name, u.user_customtitle, nc.category_id, nc.category_name, nc.category_sef, nc.category_icon, nc.category_meta_keywords,
+		nc.category_meta_description
+		FROM #news AS n
+		LEFT JOIN #user AS u ON n.news_author = u.user_id
+		LEFT JOIN #news_category AS nc ON n.news_category = nc.category_id
+		WHERE u.user_name = '".$authorSearch."'
+		AND n.news_start < ".time()." AND (n.news_end=0 || n.news_end>".time().")
+		AND n.news_class REGEXP '".e_CLASS_REGEXP."' AND NOT (n.news_class REGEXP ".$nobody_regexp.")
+		ORDER BY n.news_datestamp DESC
+		LIMIT ".intval($newsfrom).",".NEWSLIST_LIMIT;
+		$category_name = 'Author: "'.$authorSearch.'"';
+
+
+
 	}
 
 	$newsList = array();
 	
 	if($sql->gen($query))
 	{
+		$news_total = $sql->foundRows();
 		$newsList = $sql->db_getList();
 		$ogImageCount = 0;
 		foreach($newsList as $row)
@@ -392,7 +431,10 @@ if ($action == 'cat' || $action == 'all' || vartrue($_GET['tag']))
 	$nitems 	= defined('NEWS_NEXTPREV_NAVCOUNT') ? '&navcount='.NEWS_NEXTPREV_NAVCOUNT : '' ;
 	$url 		= rawurlencode(e107::getUrl()->create($newsRoute, $newsUrlparms));
 	$parms  	= 'tmpl_prefix='.deftrue('NEWS_NEXTPREV_TMPL', 'default').'&total='.$news_total.'&amount='.$amount.'&current='.$newsfrom.$nitems.'&url='.$url;
-	
+
+
+	// e107::getDebug()->log($newsUrlparms);
+
 	$text  		.= $tp->parseTemplate("{NEXTPREV={$parms}}");
 
 	if(varset($template['caption'])) // v2.x