From 5c2c25ed02342f30e84383b15123ea2ad65c779b Mon Sep 17 00:00:00 2001
From: Torsten Oppermann <torsten@sgalinski.de>
Date: Mon, 23 Jul 2018 17:19:40 +0200
Subject: [PATCH] [TASk] Finish file mapping and solvling repair translation
 issue

---
 .../Command/MigrateNewsCommandController.php  |  99 +++++++++++++++--
 Classes/Domain/Model/FileReference.php        |  34 ++++++
 .../Repository/FileReferenceRepository.php    | 100 ++++++++++++++++++
 Configuration/TypoScript/Common/setup.txt     |   6 ++
 4 files changed, 228 insertions(+), 11 deletions(-)
 create mode 100644 Classes/Domain/Model/FileReference.php
 create mode 100644 Classes/Domain/Repository/FileReferenceRepository.php

diff --git a/Classes/Command/MigrateNewsCommandController.php b/Classes/Command/MigrateNewsCommandController.php
index a2163b4..38868bc 100644
--- a/Classes/Command/MigrateNewsCommandController.php
+++ b/Classes/Command/MigrateNewsCommandController.php
@@ -32,15 +32,16 @@ use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
 use TYPO3\CMS\Core\Database\DatabaseConnection;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Domain\Model\FileReference;
 use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
 use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;
 use TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException;
+use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 
 /**
  * Command controller, that migrates data from tx_news to sg_news
  */
 class MigrateNewsCommandController extends CommandController {
-
 	/**
 	 * @var bool
 	 */
@@ -62,7 +63,13 @@ class MigrateNewsCommandController extends CommandController {
 	 * @var \SGalinski\SgNews\Domain\Repository\TagRepository
 	 * @inject
 	 */
-	protected $tagRepository;
+	private $tagRepository;
+
+	/**
+	 * @var \SGalinski\SgNews\Domain\Repository\FileReferenceRepository
+	 * @inject
+	 */
+	private $fileReferenceRepository;
 
 	/**
 	 * this array maps new pages to their original entry in the tx_news table
@@ -97,12 +104,21 @@ class MigrateNewsCommandController extends CommandController {
 	 *
 	 * @throws IllegalObjectTypeException
 	 * @throws UnknownObjectException
+	 * @throws \Exception
 	 */
 	public function runMigrateNewsCommand(
 		$copyPageId, $categoryPid, $year = 2015,
 		$languageMapAsJson = '{"3":1,"1":0,"2":2,"0":3}',
 		$categoryMapAsJson = '{"2":10,"3":11,"4":12,"5":13,"6":14,"7":15,"8":16,"9":17}'
 	) {
+		// fix repair translation bug where tsfee is missing from command controller, can be removed when v1.5 is released
+		if (!$GLOBALS['TSFE']) {
+			/** @var TypoScriptFrontendController $typoScriptController */
+			$GLOBALS['TSFE'] = $typoScriptController = $this->objectManager->get(
+				TypoScriptFrontendController::class, $GLOBALS['TYPO3_CONF_VARS'], 0, 0
+			);
+		}
+
 		$this->languageMap = json_decode($languageMapAsJson, TRUE);
 		$this->categoryMap = json_decode($categoryMapAsJson, TRUE);
 
@@ -126,7 +142,7 @@ class MigrateNewsCommandController extends CommandController {
 		$resultArray = [];
 		while ($row = $result->fetch_assoc()) {
 			// ignore the entry if its not within the given year
-			if ((int) date('Y', ($row['datetime'])) !== $year) {
+			if ((int) date('Y', $row['datetime']) !== $year) {
 				continue;
 			}
 			$resultArray[] = $row;
@@ -150,12 +166,34 @@ class MigrateNewsCommandController extends CommandController {
 				if ($newsPage !== NULL) {
 					$title = date('Y-m-d', $row['datetime']) . ' - ' . $row['title'];
 					$newsPage->setTitle($title);
+					$newsPage->setSubtitle($row['title']);
+
+					$date = new \DateTime('@' . $row['datetime']);
+					$newsPage->setLastUpdated($date);
 
 					$matchingTag = $this->getMatchingTag($row);
 					if ($matchingTag && $matchingTag instanceof Tag) {
 						$newsPage->addTag($matchingTag);
 					}
 
+					/** @var FileReference $image */
+					$image = $this->getMatchingImage($row);
+					if ($image !== NULL) {
+						$newsPage->addTeaser1Image($image);
+
+						$originalResource = $image->getOriginalResource();
+						if ($originalResource !== NULL) {
+							$originalFile = $originalResource->getOriginalFile();
+							if ($originalFile !== NULL) {
+								$teaserImage2 = $this->fileReferenceRepository->addFileReferenceFromFile(
+									$originalFile, $this->newsPagesMap[$row['uid']],
+									$this->newsPagesMap[$row['uid']], 'pages', 'tx_sgnews_teaser2_image'
+								);
+								$newsPage->addTeaser2Image($teaserImage2);
+							}
+						}
+					}
+
 					$this->newsRepository->update($newsPage);
 					$this->persistenceManager->persistAll();
 
@@ -170,11 +208,43 @@ class MigrateNewsCommandController extends CommandController {
 	}
 
 	/**
+	 * Get the image file matching the news
+	 *
 	 * @param array $row
-	 * @return Object $tag
+	 * @return null|FileReference
+	 */
+	private function getMatchingImage(array $row) {
+		/** @var DatabaseConnection $db */
+		$db = $GLOBALS['TYPO3_DB'];
+		$where = 'tablenames = "tx_news_domain_model_news" AND fieldname = "fal_media" AND uid_foreign = ' . $row['uid'];
+
+		/** @var \mysqli_result $result */
+		$result = $db->exec_SELECTgetSingleRow('uid, uid_local', 'sys_file_reference', $where);
+		if (!$result) {
+			return NULL;
+		}
+
+		$where = 'uid = ' . $result['uid'];
+		$db->exec_UPDATEquery(
+			'sys_file_reference',
+			$where,
+			['pid' => $this->newsPagesMap[$row['uid']], 'uid_foreign' => $this->newsPagesMap[$row['uid']], 'tablenames' => 'pages', 'fieldname' => 'tx_sgnews_teaser1_image']
+		);
+
+		$result = $this->fileReferenceRepository->findByUid((int) $result['uid']);
+		if ($result instanceof FileReference) {
+			$result->setPid($this->newsPagesMap[$row['uid']]);
+			return $result;
+		}
+
+		return NULL;
+	}
+
+	/**
+	 * Get the tag / category, matching the news
 	 *
-	 * @throws IllegalObjectTypeException
-	 * @throws UnknownObjectException
+	 * @param array $row
+	 * @return Object $tag
 	 */
 	private function getMatchingTag(array $row) {
 		// look up the correct category id, if they have changed
@@ -227,17 +297,24 @@ class MigrateNewsCommandController extends CommandController {
 
 			$where = 'uid = ' . (int) $parentId;
 			/** @var \mysqli_result $result */
-			$result = $db->exec_SELECTquery('title', 'pages', $where);
-
-			$where = 'pid = ' . (int) $parentId . ' AND sys_language_uid = ' . $this->languageMap[0];
-			$db->exec_UPDATEquery('pages_language_overlay', $where, ['title' => $result->fetch_row()[0]]);
+			$result = $db->exec_SELECTgetSingleRow('title, subtitle', 'pages', $where);
+			if ($result) {
+				$where = 'pid = ' . (int) $parentId . ' AND sys_language_uid = ' . $this->languageMap[0];
+				$db->exec_UPDATEquery(
+					'pages_language_overlay', $where,
+					['title' => $result['title'], 'subtitle' => $result['subtitle']]
+				);
+			}
 
 			$where = 'uid = ' . (int) $parentId;
 			$db->exec_UPDATEquery(
-				'pages', $where, ['title' => date('Y-m-d', $row['datetime']) . ' - ' . $row['title']]
+				'pages', $where, ['title' => date(
+						'Y-m-d', $row['datetime']
+					) . ' - ' . $row['title'], 'subtitle' => $row['title'], 'lastUpdated' => $row['datetime']]
 			);
 		} else {
 			// finally translate the page title if necessary
+			/** @noinspection NotOptimalIfConditionsInspection */
 			if (isset($this->languageMap[(int) $row['sys_language_uid']]) && $this->languageMap[(int) $row['sys_language_uid']] > 0) {
 				$where = 'pid = ' . (int) $parentId . ' AND sys_language_uid = ' . $this->languageMap[(int) $row['sys_language_uid']];
 			} else {
diff --git a/Classes/Domain/Model/FileReference.php b/Classes/Domain/Model/FileReference.php
new file mode 100644
index 0000000..63c7c7d
--- /dev/null
+++ b/Classes/Domain/Model/FileReference.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace SGalinski\SgNews\Domain\Model;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) sgalinski Internet Services (https://www.sgalinski.de)
+ *
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * FileReference
+ */
+class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference {
+
+}
diff --git a/Classes/Domain/Repository/FileReferenceRepository.php b/Classes/Domain/Repository/FileReferenceRepository.php
new file mode 100644
index 0000000..ef1cc95
--- /dev/null
+++ b/Classes/Domain/Repository/FileReferenceRepository.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace SGalinski\SgNews\Domain\Repository;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) sgalinski Internet Services (https://www.sgalinski.de)
+ *
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use SGalinski\SgNews\Domain\Model\FileReference;
+use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Resource\File;
+
+/**
+ * FileReference Repository
+ */
+class FileReferenceRepository extends AbstractRepository {
+
+	/**
+	 * Method creates a file reference entry in the database. This step is necessary because the
+	 * extbase can not handle the default TCA for FAL records. Without this method the FAL records will miss
+	 * the uid_foreign, field name and table names.
+	 *
+	 * @param File $file
+	 * @param int $uid
+	 * @param int $pid
+	 * @param string $tablename
+	 * @param string $fieldname
+	 * @return FileReference
+	 * @throws \Exception
+	 */
+	public function addFileReferenceFromFile(File $file, $uid, $pid, $tablename, $fieldname) {
+		$fileReferenceId = $this->addFileReferenceFromFileId(
+			$file->getUid(),
+			['uid' => $uid, 'pid' => $pid],
+			$tablename,
+			$fieldname
+		);
+
+		$fileReference = NULL;
+		if ($fileReferenceId > 0) {
+			/** @var FileReference $fileReference */
+			$fileReference = $this->findByUid($fileReferenceId);
+		}
+
+		return $fileReference;
+	}
+
+	/**
+	 * Method creates a file reference entry in the database. This step is necessary because the
+	 * extbase can not handle the default TCA for FAL records. Without this method the FAL records will miss
+	 * the uid_foreign, field name and table names.
+	 *
+	 * @param $fileId
+	 * @param array $reference
+	 * @param string $tablename
+	 * @param string $fieldname
+	 * @return int
+	 * @throws \Exception
+	 */
+	public function addFileReferenceFromFileId($fileId, array $reference, $tablename, $fieldname) {
+		/** @var DatabaseConnection $db */
+		$db = $GLOBALS['TYPO3_DB'];
+		$arguments = [
+			'crdate' => $GLOBALS['EXEC_TIME'],
+			'tstamp' => $GLOBALS['EXEC_TIME'],
+			'pid' => (int) $reference['pid'],
+			'table_local' => 'sys_file',
+			'uid_local' => $fileId,
+			'uid_foreign' => (int) $reference['uid'],
+			'tablenames' => $tablename,
+			'fieldname' => $fieldname,
+		];
+
+		if (!$db->exec_INSERTquery('sys_file_reference', $arguments)) {
+			throw new \Exception('An error occurred while adding a file reference record.', 1452590219);
+		}
+
+		return (int) $db->sql_insert_id();
+	}
+}
diff --git a/Configuration/TypoScript/Common/setup.txt b/Configuration/TypoScript/Common/setup.txt
index 221e404..2d416af 100644
--- a/Configuration/TypoScript/Common/setup.txt
+++ b/Configuration/TypoScript/Common/setup.txt
@@ -35,6 +35,12 @@ config.tx_extbase {
 					tableName = sys_category
 				}
 			}
+
+			SGalinski\SgNews\Domain\Model\FileReference {
+				mapping {
+					tableName = sys_file_reference
+				}
+			}
 		}
 	}
 }
-- 
GitLab