From 4cfcbae4472a3f7712caf9a0b207f39d08a7a620 Mon Sep 17 00:00:00 2001
From: Kevin Ditscheid <kevin.ditscheid@sgalinski.de>
Date: Tue, 26 Jul 2022 16:00:25 +0200
Subject: [PATCH] [TASK] Add schemald from sg_seo

---
 Classes/Controller/SingleViewController.php   | 19 +++---
 Classes/Domain/Service/NewsService.php        | 28 ++++++--
 Configuration/TCA/Overrides/pages.php         |  5 +-
 .../Private/Partials/SingleViewSchema.html    | 65 +++++++++++--------
 composer.json                                 |  3 +-
 ext_emconf.php                                |  3 +-
 6 files changed, 78 insertions(+), 45 deletions(-)

diff --git a/Classes/Controller/SingleViewController.php b/Classes/Controller/SingleViewController.php
index 1031ef7..620d479 100644
--- a/Classes/Controller/SingleViewController.php
+++ b/Classes/Controller/SingleViewController.php
@@ -1,7 +1,4 @@
 <?php
-
-namespace SGalinski\SgNews\Controller;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -26,15 +23,15 @@ namespace SGalinski\SgNews\Controller;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+namespace SGalinski\SgNews\Controller;
+
 use SGalinski\SgNews\Domain\Model\Category;
 use SGalinski\SgNews\Domain\Model\News;
 use SGalinski\SgNews\Domain\Repository\CategoryRepository;
 use SGalinski\SgNews\Domain\Repository\NewsRepository;
 use SGalinski\SgNews\Domain\Repository\TagRepository;
 use SGalinski\SgNews\Domain\Service\NewsService;
-use SGalinski\SgNews\Service\HeaderMetaDataService;
 use TYPO3\CMS\Core\Charset\CharsetConverter;
-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 
 /**
  * Controller that handles the news single view page
@@ -82,9 +79,9 @@ class SingleViewController extends AbstractController {
 				'<'
 			)) {
 				return NULL;
-			} else {
-				return $this->htmlResponse();
 			}
+
+			return $this->htmlResponse();
 		}
 
 		/** @var Category $newsCategory */
@@ -96,9 +93,9 @@ class SingleViewController extends AbstractController {
 				'<'
 			)) {
 				return NULL;
-			} else {
-				return $this->htmlResponse();
 			}
+
+			return $this->htmlResponse();
 		}
 
 		$newsMetaData = $this->newsService->getMetaDataForNews($news, $newsCategory);
@@ -120,9 +117,9 @@ class SingleViewController extends AbstractController {
 		);
 		if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
 			return NULL;
-		} else {
-			return $this->htmlResponse();
 		}
+
+		return $this->htmlResponse();
 	}
 
 	/**
diff --git a/Classes/Domain/Service/NewsService.php b/Classes/Domain/Service/NewsService.php
index ec24fca..7fe59ba 100644
--- a/Classes/Domain/Service/NewsService.php
+++ b/Classes/Domain/Service/NewsService.php
@@ -1,7 +1,4 @@
 <?php
-
-namespace SGalinski\SgNews\Domain\Service;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -26,10 +23,15 @@ namespace SGalinski\SgNews\Domain\Service;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+namespace SGalinski\SgNews\Domain\Service;
+
 use SGalinski\SgNews\Domain\Model\Category;
 use SGalinski\SgNews\Domain\Model\News;
 use TYPO3\CMS\Core\Resource\FileRepository;
+use TYPO3\CMS\Core\Database\Connection;
+use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\SingletonInterface;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Domain\Model\FileReference;
 
@@ -72,6 +74,23 @@ class NewsService implements SingletonInterface {
 			];
 		}
 
+		$customSchemaJson = '';
+		if (ExtensionManagementUtility::isLoaded('sg_seo')) {
+			$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+				->getQueryBuilderForTable('pages');
+			$schemaJson = $queryBuilder->select('tx_sgseo_schemajson')
+				->from('pages')
+				->where(
+					$queryBuilder->expr()->eq(
+						'uid',
+						$queryBuilder->createNamedParameter($newsId, Connection::PARAM_INT)
+					)
+				)->execute()->fetchOne();
+			if (!empty($schemaJson)) {
+				$customSchemaJson = $schemaJson;
+			}
+		}
+
 		$newsRecord = array_merge(
 			[
 				'category' => $category,
@@ -79,7 +98,8 @@ class NewsService implements SingletonInterface {
 			],
 			$singleNewsImageData,
 			$teaserImageData,
-			['media' => $fileObjects]
+			['media' => $fileObjects],
+			['customSchemaJson' => $customSchemaJson]
 		);
 
 		$this->cachedSingleNews[$newsId] = $newsRecord;
diff --git a/Configuration/TCA/Overrides/pages.php b/Configuration/TCA/Overrides/pages.php
index dff98d1..17bf55d 100644
--- a/Configuration/TCA/Overrides/pages.php
+++ b/Configuration/TCA/Overrides/pages.php
@@ -1,6 +1,5 @@
 <?php
 
-defined('TYPO3') or die();
 /**
  *
  * Copyright notice
@@ -26,6 +25,8 @@ defined('TYPO3') or die();
  * This copyright notice MUST APPEAR in all copies of the script!
  */
 
+defined('TYPO3') or die();
+
 $localLangDbPath = 'LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:';
 $localLangBackendPath = 'LLL:EXT:sg_news/Resources/Private/Language/locallang_backend.xlf:';
 foreach (
@@ -65,6 +66,7 @@ $GLOBALS['TCA']['pages']['types'][\SGalinski\SgNews\Utility\BackendNewsUtility::
 		tx_sgnews_content_from_another_page, tx_sgnews_related_news, tx_sgnews_tags,
 	--div--;LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.tabs.seo,
 			--palette--;;seo,
+			' . (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('sg_seo') ? 'tx_sgseo_schemajson,' : '') . '
 			--palette--;;robots,
 			--palette--;;canonical,
 			--palette--;;sitemap,
@@ -95,6 +97,7 @@ $GLOBALS['TCA']['pages']['types'][\SGalinski\SgNews\Utility\BackendNewsUtility::
 		title, slug, tx_projectbase_path_segment, tx_projectbase_excludefromsluggeneration, tx_realurl_pathsegment, tx_realurl_exclude,
 	--div--;LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.tabs.seo,
 			--palette--;;seo,
+			' . (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('sg_seo') ? 'tx_sgseo_schemajson,' : '') . '
 			--palette--;;robots,
 			--palette--;;canonical,
 			--palette--;;sitemap,
diff --git a/Resources/Private/Partials/SingleViewSchema.html b/Resources/Private/Partials/SingleViewSchema.html
index 55435e6..5540038 100644
--- a/Resources/Private/Partials/SingleViewSchema.html
+++ b/Resources/Private/Partials/SingleViewSchema.html
@@ -1,29 +1,40 @@
 <f:alias map="{leftBrace: '{', rightBrace: '}'}">
-		<script type="application/ld+json">
-			{leftBrace}
-				"@context": "http://schema.org/",
-				"@type": "NewsArticle",
-				"mainEntityOfPage": {leftBrace}
-					"@type": "WebPage",
-					"@id": "<f:uri.page absolute="TRUE"/>"
-				{rightBrace},
-				"author": "{newsMetaData.news.author}",
-				"publisher": {leftBrace}
-					"@type": "Organization"{f:if(condition: settings.publisher, then:',')}
-					<f:if condition="{settings.publisher}">"name": "{settings.publisher}"{f:if(condition: settings.publisherLogo, then:',')}</f:if>
-					<f:if condition="{settings.publisherLogo}">"logo": {leftBrace}
-						"@type": "ImageObject",
-						"url": "{settings.publisherLogo}"
-					{rightBrace}</f:if>
-				{rightBrace},
-				<f:if condition="{newsMetaData.imageObject}">
-				"image": "<f:uri.image absolute="TRUE" image="{newsMetaData.imageObject}" />",
-				</f:if>
-				"headline": "{newsMetaData.news.navTitle}",
-				"description": "{newsMetaData.news.description}",
-				"dateCreated": "<f:format.date format="Y-m-d">{newsMetaData.news.creationDate}</f:format.date>",
-				"datePublished": "<f:format.date format="Y-m-d">{newsMetaData.news.creationDate}</f:format.date>",
-				"dateModified": "<f:format.date format="Y-m-d">{newsMetaData.news.lastUpdated}</f:format.date>"
-			{rightBrace}
-		</script>
+	<script type="application/ld+json">
+		{leftBrace}
+			<f:if condition="{newsMetaData.customSchemaJson}">
+				<f:then>
+					<f:format.raw>{newsMetaData.customSchemaJson}</f:format.raw>
+				</f:then>
+				<f:else>
+					<f:render section="default" arguments="{_all}"/>
+				</f:else>
+			</f:if>
+		{rightBrace}
+	</script>
 </f:alias>
+
+<f:section name="default">
+"@context": "http://schema.org/",
+"@type": "NewsArticle",
+"mainEntityOfPage": {leftBrace}
+	"@type": "WebPage",
+	"@id": "<f:uri.page absolute="TRUE"/>"
+{rightBrace},
+"author": "{newsMetaData.news.author}",
+"publisher": {leftBrace}
+	"@type": "Organization"{f:if(condition: settings.publisher, then:',')}
+	<f:if condition="{settings.publisher}">"name": "{settings.publisher}"{f:if(condition: settings.publisherLogo, then:',')}</f:if>
+	<f:if condition="{settings.publisherLogo}">"logo": {leftBrace}
+		"@type": "ImageObject",
+		"url": "{settings.publisherLogo}"
+	{rightBrace}</f:if>
+{rightBrace},
+<f:if condition="{newsMetaData.imageObject}">
+"image": "<f:uri.image absolute="TRUE" image="{newsMetaData.imageObject}" />",
+</f:if>
+"headline": "{newsMetaData.news.navTitle}",
+"description": "{newsMetaData.news.description}",
+"dateCreated": "<f:format.date format="Y-m-d">{newsMetaData.news.creationDate}</f:format.date>",
+"datePublished": "<f:format.date format="Y-m-d">{newsMetaData.news.creationDate}</f:format.date>",
+"dateModified": "<f:format.date format="Y-m-d">{newsMetaData.news.lastUpdated}</f:format.date>"
+</f:section>
diff --git a/composer.json b/composer.json
index 25c141d..cad7b38 100644
--- a/composer.json
+++ b/composer.json
@@ -21,7 +21,8 @@
     },
     "suggest": {
         "sgalinski/sg-ajax": "Required for the like feature",
-        "sgalinski/sg-comments": "Flexible comments system"
+        "sgalinski/sg-comments": "Flexible comments system",
+        "sgalinski/sg-seo": "For additional SEO features"
     },
     "replace": {
         "sgalinski/sg_news": "self.version"
diff --git a/ext_emconf.php b/ext_emconf.php
index a308df0..52eec3d 100644
--- a/ext_emconf.php
+++ b/ext_emconf.php
@@ -28,7 +28,8 @@ $EM_CONF['sg_news'] = [
 		'conflicts' => [],
 		'suggests' => [
 			'sg_comments' => '6.0.0',
-			'sg_ajax' => '4.0.0'
+			'sg_ajax' => '4.0.0',
+			'sg_seo' => ''
 		],
 	],
 	'suggests' => [],
-- 
GitLab