From 19bd0639097d528fc29fd1994642daec2f6fbeaf Mon Sep 17 00:00:00 2001 From: eSilverStrike Date: Tue, 7 Jan 2020 12:37:04 -0500 Subject: [PATCH] Fixed Autotags in Articles executing twice when viewing an Article For issue #1017 --- .../admin/install/classes/installer.class.php | 1 + public_html/admin/install/devel-db-update.php | 2 + public_html/article.php | 13 +++-- sql/mysql_tableanddata.php | 1 + sql/pgsql_tableanddata.php | 1 + sql/updates/mysql_2.2.0_to_2.2.1.php | 22 ++++++++ sql/updates/pgsql_2.2.0_to_2.2.1.php | 22 ++++++++ system/classes/article.class.php | 16 +++++- system/lib-article.php | 52 ++++++++++--------- 9 files changed, 97 insertions(+), 33 deletions(-) diff --git a/public_html/admin/install/classes/installer.class.php b/public_html/admin/install/classes/installer.class.php index 8ce7c4132..d45a190ae 100644 --- a/public_html/admin/install/classes/installer.class.php +++ b/public_html/admin/install/classes/installer.class.php @@ -2952,6 +2952,7 @@ private function doDatabaseUpgrades($currentGlVersion, $checkForMessage = false) update_ConfValuesFor221(); fixDuplicateUsernames221(); addStructuredDataSecurityRight221(); + calculateNumPagesArticles221(); } $currentGlVersion = '2.2.1'; break; diff --git a/public_html/admin/install/devel-db-update.php b/public_html/admin/install/devel-db-update.php index 23588b106..d058de0fc 100644 --- a/public_html/admin/install/devel-db-update.php +++ b/public_html/admin/install/devel-db-update.php @@ -92,6 +92,8 @@ function update_DatabaseFor221() // Add structured data type to article table and modified date $_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `structured_data_type` varchar(40) NOT NULL DEFAULT '' AFTER `commentcode`"; $_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `modified` DATETIME NULL DEFAULT NULL AFTER `date`"; + // For number of pages in an article. Needed for when article is cached and we need to figure out what page to put the comments on + $_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `numpages` tinyint(1) NOT NULL DEFAULT '1' AFTER `hits`"; if (DB_count($_TABLES['features'], 'ft_name', 'structureddata.autotag') == 0) { // Add `structureddata.autotag` feature diff --git a/public_html/article.php b/public_html/article.php index c1f60cda0..100639577 100644 --- a/public_html/article.php +++ b/public_html/article.php @@ -167,7 +167,7 @@ function extractExternalLinks($text) { 'professional' => 'layout/' . $theme . '/print.css', 'other' => 'layout/' . $theme . '/css/print.css', ); - + global $_SCRIPTS; foreach ($paths as $path) { if (file_exists($_CONF['path_html'] . $path)) { @@ -309,13 +309,13 @@ function extractExternalLinks($text) { ) ); } - + // Add hreflang link element if Multi Language Content is setup // Only allow hreflang link element to be visible when on canonical url // ie no second pages which can happen with comments, or if [page_break] is used or with extra trailing variables like from a search query if (strtolower(COM_getCurrentURL()) == strtolower($permalink)) { $headercode .= COM_createHREFLang('story', $article->getSid()); - } + } if ($article->DisplayElements('trackbackcode') == 0) { if ($_CONF['trackback_enabled']) { @@ -449,8 +449,9 @@ function extractExternalLinks($text) { $articleTemplate->set_var('formatted_article', STORY_renderArticle($article, 'n', $tmpl, $query)); - // display comments or not? - if ($_CONF['allow_page_breaks'] == 1) { + // display comments or not on this page of the article? + $page_break_count = $article->displayElements('numpages'); + if ($_CONF['allow_page_breaks'] == 1 && $page_break_count > 1) { if (!is_numeric($mode)) { $story_page = 1; } else { @@ -462,8 +463,6 @@ function extractExternalLinks($text) { $story_page = 1; } - $article_arr = explode('[page_break]', $article->displayElements('bodytext')); - $page_break_count = count($article_arr); if ($page_break_count > 1) { $conf = $_CONF['page_break_comments']; if ( diff --git a/sql/mysql_tableanddata.php b/sql/mysql_tableanddata.php index 8b3a7ce92..7ac2fa6e7 100644 --- a/sql/mysql_tableanddata.php +++ b/sql/mysql_tableanddata.php @@ -293,6 +293,7 @@ bodytext text, text_version tinyint(2) NOT NULL default '1', hits mediumint(8) unsigned NOT NULL default '0', + numpages tinyint(1) NOT NULL DEFAULT '1', numemails mediumint(8) unsigned NOT NULL default '0', comments mediumint(8) unsigned NOT NULL default '0', comment_expire datetime default NULL, diff --git a/sql/pgsql_tableanddata.php b/sql/pgsql_tableanddata.php index 0d32574e4..800d9dc61 100644 --- a/sql/pgsql_tableanddata.php +++ b/sql/pgsql_tableanddata.php @@ -291,6 +291,7 @@ bodytext text, text_version smallint NOT NULL default '1', hits smallint NOT NULL default '0', + numpages smallint NOT NULL DEFAULT '1', numemails smallint NOT NULL default '0', comments smallint NOT NULL default '0', comment_expire timestamp default NULL, diff --git a/sql/updates/mysql_2.2.0_to_2.2.1.php b/sql/updates/mysql_2.2.0_to_2.2.1.php index 4819c7223..6b4e689ca 100644 --- a/sql/updates/mysql_2.2.0_to_2.2.1.php +++ b/sql/updates/mysql_2.2.0_to_2.2.1.php @@ -18,6 +18,8 @@ // Add structured data type to article table and modified date $_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `structured_data_type` varchar(40) NOT NULL DEFAULT '' AFTER `commentcode`"; $_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `modified` DATETIME NULL DEFAULT NULL AFTER `date`"; +// For number of pages in an article. Needed for when article is cached and we need to figure out what page to put the comments on +$_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `numpages` tinyint(1) NOT NULL DEFAULT '1' AFTER `hits`"; // Language Override value can now be longer than 255 characters $_SQL[] = "ALTER TABLE {$_TABLES['language_items']} CHANGE `value` `value` TEXT"; @@ -306,3 +308,23 @@ function addStructuredDataSecurityRight221() return true; } + +function calculateNumPagesArticles221() +{ + global $_TABLES; + + // Calculate number of pages for articles (that have [page_break] in body text) + $sql = "SELECT sid, bodytext FROM {$_TABLES['stories']} WHERE bodytext != ''"; + $result = DB_query($sql); + $numRows = DB_numRows($result); + for ($i = 0; $i < $numRows; $i++) { + $A = DB_fetchArray($result); + + $numpages = (count(explode('[page_break]', $A['bodytext']))); + + // Save new name + DB_query("UPDATE {$_TABLES['stories']} SET numpages = $numpages WHERE sid = '" . DB_escapeString($A['sid']) . "'"); + } + + return true; +} diff --git a/sql/updates/pgsql_2.2.0_to_2.2.1.php b/sql/updates/pgsql_2.2.0_to_2.2.1.php index fca925e87..4d3f36f53 100644 --- a/sql/updates/pgsql_2.2.0_to_2.2.1.php +++ b/sql/updates/pgsql_2.2.0_to_2.2.1.php @@ -18,6 +18,8 @@ // Add structured data type to article table and modified date $_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `structured_data_type` varchar(40) NOT NULL DEFAULT '' AFTER `commentcode`"; $_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `modified` timestamp default NULL AFTER `date`"; +// For number of pages in an article. Needed for when article is cached and we need to figure out what page to put the comments on +$_SQL[] = "ALTER TABLE {$_TABLES['stories']} ADD `numpages` tinyint(1) NOT NULL DEFAULT '1' AFTER `hits`"; // Language Override value can now be longer than 255 characters $_SQL[] = "ALTER TABLE {$_TABLES['language_items']} CHANGE `value` `value` TEXT"; @@ -308,3 +310,23 @@ function addStructuredDataSecurityRight221() return true; } + +function calculateNumPagesArticles221() +{ + global $_TABLES; + + // Calculate number of pages for articles (that have [page_break] in body text) + $sql = "SELECT sid, bodytext FROM {$_TABLES['stories']} WHERE bodytext != ''"; + $result = DB_query($sql); + $numRows = DB_numRows($result); + for ($i = 0; $i < $numRows; $i++) { + $A = DB_fetchArray($result); + + $numpages = (count(explode('[page_break]', $A['bodytext']))); + + // Save new name + DB_query("UPDATE {$_TABLES['stories']} SET numpages = $numpages WHERE sid = '" . DB_escapeString($A['sid']) . "'"); + } + + return true; +} diff --git a/system/classes/article.class.php b/system/classes/article.class.php index c45ca7b35..d6a620c51 100644 --- a/system/classes/article.class.php +++ b/system/classes/article.class.php @@ -118,6 +118,7 @@ class Article var $_date; var $_modified; var $_hits; + var $_numpages; var $_numemails; var $_comment_expire; var $_comments; @@ -190,6 +191,7 @@ class Article 'bodytext' => 1, 'text_version' => 1, 'hits' => 1, + 'numpages' => 1, 'numemails' => 1, 'comments' => 1, 'trackbacks' => 1, @@ -455,7 +457,7 @@ public function loadFromDatabase($sid, $mode = 'edit') $sql['pgsql'] = "SELECT s.*, UNIX_TIMESTAMP(s.date) AS unixdate, UNIX_TIMESTAMP(s.modified) AS unixmodified, UNIX_TIMESTAMP(s.expire) as expireunix, UNIX_TIMESTAMP(s.comment_expire) as cmt_expire_unix, u.username, u.fullname, u.photo, u.email, t.tid, t.topic, t.imageurl FROM {$_TABLES['stories']} AS s, {$_TABLES['users']} AS u, {$_TABLES['topics']} AS t, {$_TABLES['topic_assignments']} AS ta WHERE ta.type = 'article' AND ta.id = sid AND ta.tdefault = 1 AND (s.uid = u.uid) AND (ta.tid = t.tid) AND (sid = '$sid') - GROUP BY s.sid, s.uid, s.title, s.page_title, s.draft_flag, s.introtext, s.bodytext, s.date, s.numemails, s.comments, s.modified, s.featured, s.comment_expire, s.commentcode, s.trackbacks, s.trackbackcode, s.related, s.hits, s.show_topic_icon, s.frontpage, s.statuscode, s.postmode, s.expire, s.advanced_editor_mode, s.owner_id, s.group_id, s.perm_owner, s.perm_group, s.perm_members, s.perm_anon, s.meta_description, s.meta_keywords, s.text_version, s.cache_time, s.structured_data_type, + GROUP BY s.sid, s.uid, s.title, s.page_title, s.draft_flag, s.introtext, s.bodytext, s.date, s.numemails, s.comments, s.modified, s.featured, s.comment_expire, s.commentcode, s.trackbacks, s.trackbackcode, s.related, s.hits, s.numpages, s.show_topic_icon, s.frontpage, s.statuscode, s.postmode, s.expire, s.advanced_editor_mode, s.owner_id, s.group_id, s.perm_owner, s.perm_group, s.perm_members, s.perm_anon, s.meta_description, s.meta_keywords, s.text_version, s.cache_time, s.structured_data_type, u.username, u.fullname, u.photo, u.email, t.tid, t.topic, t.imageurl "; } elseif (!empty($sid) && ($mode === 'editsubmission')) { /* Original @@ -525,6 +527,7 @@ public function loadFromDatabase($sid, $mode = 'edit') $this->_text_version = GLTEXT_LATEST_VERSION; $this->_hits = 0; + $this->_numpages = 1; $this->_comments = 0; $this->_trackbacks = 0; $this->_numemails = 0; @@ -693,6 +696,7 @@ public function loadFromDatabase($sid, $mode = 'edit') // reset counters $this->_hits = 0; + $this->_numpages = 1; $this->_comments = 0; $this->_trackbacks = 0; $this->_numemails = 0; @@ -811,6 +815,9 @@ public function saveToDatabase() $values = ''; reset($this->_dbFields); + // Count number of pages so we can figure out which page to put the comments on + $this->_numpages = (count(explode('[page_break]', $this->displayElements('bodytext')))); + $this->_text_version = GLTEXT_LATEST_VERSION; // Apply HTML filter to the text just before save @@ -1902,6 +1909,11 @@ public function DisplayElements($item = 'title') break; + case 'numpages': + $return = $this->_numpages; + + break; + case 'topic': $return = htmlspecialchars($this->_topic); @@ -2337,7 +2349,7 @@ private function _applyTextFilter($text, $postMode) } /** - * Perform some basic cleanups of data, dealing with empty required, defaultable fields. + * Perform some basic cleanups of data, dealing with empty required, default table fields. */ public function sanitizeData() { diff --git a/system/lib-article.php b/system/lib-article.php index f1e3d880d..2909b53cf 100644 --- a/system/lib-article.php +++ b/system/lib-article.php @@ -744,30 +744,34 @@ function STORY_renderArticle($story, $index = '', $storyTpl = 'articletext.thtml } } } else { - // Images are required by Google for article structured data rich snippets. - // lets look in the actual content of the article for an image and add it that way as long as it is locally stored and meets the min requirements - preg_match_all('~loadHTML(($introtext . $bodytext)); - $images = $articleDoc->getElementsByTagName('img'); - foreach ($images as $image) { - $src = $image->getAttribute('src'); - */ - if (substr($src, 0, 1) == "/" || substr($src, 0, strlen($_CONF['site_url'])) == $_CONF['site_url']) { - // COM_getImgSizeAttributes checks if file exists - $sizeAttributes = COM_getImgSizeAttributes($_CONF['path_html'] . substr($src, 1), false); - // Make sure image meets minimum sizes as we don't want to grab something really small - // Using old Geeklog image width and height defaults - if (is_array($sizeAttributes) - && $sizeAttributes['width'] >= 160 && $sizeAttributes['height'] >= 160) { - //&& $sizeAttributes['width'] <= $_CONF['max_image_width'] && $sizeAttributes['height'] <= $_CONF['max_image_height']) { - $_STRUCT_DATA->set_image_item('article', $story->getSid(), ($_CONF['site_url'] . $src), $sizeAttributes['width'], $sizeAttributes['height']); - - break; + // Before searching content for images, check if structured data already exist for image incase autotags used to insert images and/or structured data + // Structured Data Images are stored as arrays so just check for array, if found then skip checking content for images + if (!is_array($_STRUCT_DATA->get_param_item('article', $story->getSid(), 'image'))) { + // Images are required by Google for article structured data rich snippets. + // lets look in the actual content of the article for an image and add it that way as long as it is locally stored and meets the min requirements + preg_match_all('~loadHTML(($introtext . $bodytext)); + $images = $articleDoc->getElementsByTagName('img'); + foreach ($images as $image) { + $src = $image->getAttribute('src'); + */ + if (substr($src, 0, 1) == "/" || substr($src, 0, strlen($_CONF['site_url'])) == $_CONF['site_url']) { + // COM_getImgSizeAttributes checks if file exists + $sizeAttributes = COM_getImgSizeAttributes($_CONF['path_html'] . substr($src, 1), false); + // Make sure image meets minimum sizes as we don't want to grab something really small + // Using old Geeklog image width and height defaults + if (is_array($sizeAttributes) + && $sizeAttributes['width'] >= 160 && $sizeAttributes['height'] >= 160) { + //&& $sizeAttributes['width'] <= $_CONF['max_image_width'] && $sizeAttributes['height'] <= $_CONF['max_image_height']) { + $_STRUCT_DATA->set_image_item('article', $story->getSid(), ($_CONF['site_url'] . $src), $sizeAttributes['width'], $sizeAttributes['height']); + + break; + } } } }