From 76144e6b4fd22b9a34301300a3825bcee7e457dc Mon Sep 17 00:00:00 2001
From: Cameron <e107inc@gmail.com>
Date: Tue, 19 Jan 2021 07:54:13 -0800
Subject: [PATCH] Issue #4352 e107::canonical() method added. Use
 define('e_DEBUG_CANONICAL', true); in e107_config.php to test usage.

---
 contact.php                        |  2 +-
 e107_handlers/e107_class.php       | 38 ++++++++++++++++++++++++++++--
 e107_plugins/gsitemap/e_header.php |  5 ----
 e107_plugins/news/news.php         | 14 +++++++++--
 e107_tests/tests/unit/e107Test.php | 31 +++++++++++++++++++++---
 gsitemap.php                       |  2 ++
 6 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/contact.php b/contact.php
index 0944629e9..6c5687d2f 100644
--- a/contact.php
+++ b/contact.php
@@ -27,7 +27,7 @@ $sec_img = new secure_image;
 e107::lan('core','contact');
 
 define('PAGE_NAME', LANCONTACT_00);
-
+e107::canonical('contact');
 require_once(HEADERF);
 
 $tp = e107::getParser();
diff --git a/e107_handlers/e107_class.php b/e107_handlers/e107_class.php
index 0e2f93530..d9ccd12c2 100644
--- a/e107_handlers/e107_class.php
+++ b/e107_handlers/e107_class.php
@@ -775,11 +775,11 @@ class e107
 
 	/**
 	 * Get folder name (e107_config)
-	 * Replaces all $(*)_DIRECTORY globals
+	 * Replaces all $(*)_DIRECTORY globals.
 	 * @example
 	 * Example: <code>$e107->getFolder('images')</code>;
 	 *
-	 * @param string $for admin | plugin |
+	 * @param string $for admin | plugins | themes | files | handlers
 	 * @return string
 	 */
 	public static function getFolder($for)
@@ -3769,6 +3769,24 @@ class e107
 		return null;
 	}
 
+	/**
+	 * Quick method to set alias - uses e107::url format.
+	 * @param string $plugin
+	 * @param null $key
+	 * @param array $row
+	 */
+	public static function canonical($plugin = '', $key = 'index', $row = array())
+	{
+		if($url = e107::url($plugin, $key, $row, array('mode' => 'full')))
+		{
+			self::getJs()->addLink(array('rel'=>"canonical", "href" => $url));
+		}
+		if(deftrue('e_DEBUG_CANONICAL'))
+		{
+			self::getMessage()->addInfo("Debug Canonical URL: ".$url);
+		}
+	}
+
 	/**
 	 * Generate a plugin's search engine-friendly URL with HTML special characters escaped
 	 *
@@ -3805,6 +3823,22 @@ class e107
 
 			if (in_array($tmp[0], $legacy))
 			{
+				if(isset($options['mode']) && $options['mode'] === 'full')
+				{
+					if(is_array($row))
+					{
+						$row['full'] = 1;
+					}
+					elseif(is_string($row))
+					{
+						$row .= '&full=1';
+					}
+					elseif(is_null($row))
+					{
+						$row = 'full=1';
+					}
+				}
+
 				return self::getUrl()->create($plugin, $key, $row);
 			}
 
diff --git a/e107_plugins/gsitemap/e_header.php b/e107_plugins/gsitemap/e_header.php
index 4331d540b..8c7614da6 100644
--- a/e107_plugins/gsitemap/e_header.php
+++ b/e107_plugins/gsitemap/e_header.php
@@ -13,11 +13,6 @@
 
 if (!defined('e107_INIT')) { exit; }
 
-if(deftrue('USER_AREA') && (defset('e_PAGE') ===  'gsitemap.php'))
-{
-	$canonicalurl = e107::url('gsitemap', 'index', null, array('mode' => 'full'));
-	e107::link(array('rel'=>"canonical", "href" =>$canonicalurl));
-}
 
 
 
diff --git a/e107_plugins/news/news.php b/e107_plugins/news/news.php
index c1db4a95e..3eb954db9 100644
--- a/e107_plugins/news/news.php
+++ b/e107_plugins/news/news.php
@@ -348,6 +348,11 @@ class news_front
 					$newsRoute = 'list/'.$this->action;
 				break;
 
+				case 'item':
+				case 'extend':
+					$newsRoute = 'view/item';
+				break;
+
 				default:
 					$newsRoute = 'list/items';
 				break;
@@ -531,7 +536,10 @@ class news_front
 
 	}
 
-
+	/**
+	 * @param array $news news and category table row. ie. news_id, news_title, news_sef ... category_id etc.
+	 * @param string $type
+	 */
 	private function setNewsFrontMeta($news, $type='news')
 	{
 
@@ -545,6 +553,7 @@ class news_front
 
 			case "all":
 				e107::meta('robots', 'noindex');
+
 			break;
 
 			case "tag":
@@ -590,12 +599,13 @@ class news_front
 				break;
 
 			case "news":
-
+				e107::canonical($this->route, $news);
 			break;
 
 
 			default:
 				e107::meta('robots', 'noindex');
+			//	e107::canonical('news');
 		}
 
 
diff --git a/e107_tests/tests/unit/e107Test.php b/e107_tests/tests/unit/e107Test.php
index a2357e2a5..e27494701 100644
--- a/e107_tests/tests/unit/e107Test.php
+++ b/e107_tests/tests/unit/e107Test.php
@@ -972,16 +972,41 @@ class e107Test extends \Codeception\Test\Unit
 
 		$obj = $this->e107;
 
+		// Test FULL url option on Legacy url with new options['mode']
 		$tests = array(
 			0 => array(
-				'plugin'     => 'news',
-				'key'        => 'index',
+				'plugin'     => 'news/view/item',
+				'key'        => array('news_id' => 1, 'news_sef' => 'my-news-item', 'category_sef' => 'my-category'),
+				'row'        => array(),
+				'options'    => ['mode' => 'full'],
+			),
+			1 => array(
+				'plugin'     => 'news/view/item',
+				'key'        => array('news_id' => 1, 'news_sef' => 'my-news-item', 'category_sef' => 'my-category'),
+				'row'        => 'full=1&encode=0',
+				'options'    => ['mode' => 'full'],
+			),
+			2 => array(
+				'plugin'     => 'news/view/item',
+				'key'        => array('news_id' => 1, 'news_sef' => 'my-news-item', 'category_sef' => 'my-category'),
 				'row'        => '',
 				'options'    => ['mode' => 'full'],
-				'_expected_' => 'https://localhost/e107/news'
+			),
+			3 => array(
+				'plugin'     => 'news/view/item',
+				'key'        => array('news_id' => 1, 'news_sef' => 'my-news-item', 'category_sef' => 'my-category'),
+				'row'        => null,
+				'options'    => ['mode' => 'full'],
 			),
 
 		);
+		foreach($tests as $v)
+		{
+			$result = $obj::url($v['plugin'], $v['key'], $v['row'], $v['options']);
+			$this->assertStringContainsString('http', $result);
+		}
+
+
 
 		$tests = array();
 
diff --git a/gsitemap.php b/gsitemap.php
index 47daaf4a0..18357b66c 100644
--- a/gsitemap.php
+++ b/gsitemap.php
@@ -25,6 +25,8 @@ e107::lan('gsitemap');
 
 if(e_QUERY == "show" || !empty($_GET['show']))
 {
+	e107::canonical('gsitemap');
+
 	require_once(HEADERF);
 
 	$nfArray = $sql ->retrieve("gsitemap", "*", "gsitemap_active IN (".USERCLASS_LIST.") ORDER BY gsitemap_order ",true);