Skip to content
Snippets Groups Projects
NewsService.php 5.43 KiB
Newer Older
<?php

namespace SGalinski\SgNews\Domain\Service;

/***************************************************************
 *  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\Category;
use SGalinski\SgNews\Domain\Model\News;
use SGalinski\SgNews\Domain\Repository\NewsRepository;
Matthias Adrowski's avatar
Matthias Adrowski committed
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;

/**
 * This service takes care of meta data generation for the news objects
 */
class NewsService implements SingletonInterface {
	/**
	 * @var array
	 */
	protected $cachedSingleNews = [];

	/**
	 * Returns the metadata of the given news.
	 *
	 * @param News $news
	 * @param Category $category
	 * @return array
	 * @throws \InvalidArgumentException
	 * @throws \Doctrine\DBAL\DBALException
	 * @throws \Doctrine\DBAL\Driver\Exception
	 */
	public function getMetaDataForNews(News $news, Category $category): array {
		$newsId = $news->getUid();
		if (isset($this->cachedSingleNews[$newsId])) {
			return $this->cachedSingleNews[$newsId];
		}

		$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
		$fileObjects = $fileRepository->findByRelation('pages', 'media', $news->getUid());

		$singleNewsImageData = $this->getDataForSingleViewImage($news, $category);
		$teaserImageData = $this->getDataForTeaserImage($news, $category);

		// Use single news image data for teaser image data, if the teaser imaga data are empty.
		$teaserIsEmpty = $teaserImageData['teaserImage'] === NULL && $teaserImageData['teaserImageObject'] === NULL;
		$singleNewsIsEmpty = $singleNewsImageData['image'] === NULL && $singleNewsImageData['imageObject'] === NULL;
		if ($teaserIsEmpty && !$singleNewsIsEmpty) {
			$teaserImageData = [
				'teaserImage' => $singleNewsImageData['image'],
				'teaserImageObject' => $singleNewsImageData['imageObject'],
			];
		}

		// Overwrite the number of likes with the one from the default news entry and add possible likes from translated
		// entries to fix broken data in older instances.
		$newsRepository = GeneralUtility::makeInstance(NewsRepository::class);
		$totalLikes = $newsRepository->sumLikes($newsId);
		$news->setLikes($totalLikes);

		$newsRecord = array_merge(
			[
				'category' => $category,
				'news' => $news,
			],
			$singleNewsImageData,
			$teaserImageData,
			['media' => $fileObjects]
		);

		$this->cachedSingleNews[$newsId] = $newsRecord;

		return $newsRecord;
	}

	/**
	 * Returns the single view image data as an array for the given news and category as fallback.
	 *
	 * @param News $news
	 * @param Category $category
	 * @return array
	 * @throws \InvalidArgumentException
	 */
	public function getDataForSingleViewImage(News $news, Category $category): array {
		/** @var FileReference $singleNewsImage */
		$singleNewsImage = $singleNewsImageObject = NULL;
		$singleNewsImages = $news->getTeaser2Image();
		if (count($singleNewsImages)) {
			$singleNewsImage = $singleNewsImages->current();
		} else {
			$categoryImages = $category->getTeaser2Image();
			if (count($categoryImages)) {
				$singleNewsImage = $categoryImages->current();
			}
		}

		if ($singleNewsImage) {
			$singleNewsImageObject = $singleNewsImage;
			$originalResource = $singleNewsImage->getOriginalResource();
			if ($originalResource) {
				$singleNewsImage = $originalResource->getPublicUrl();
			}

			if ($singleNewsImage) {
				$singleNewsImage = $GLOBALS['TSFE']->absRefPrefix . $singleNewsImage;
			}
		}

		return [
			'image' => $singleNewsImage,
			'imageObject' => $singleNewsImageObject,
		];
	}

	/**
	 * Returns the teaser image data as an array for the given news and category as fallback.
	 *
	 * @param News $news
	 * @param Category $category
	 * @return array
	 * @throws \InvalidArgumentException
	 */
	public function getDataForTeaserImage(News $news, Category $category): array {
		/** @var FileReference $teaserImage */
		$teaserImage = $teaserImageObject = NULL;
		$teaserImages = $news->getTeaser1Image();
		if (count($teaserImages)) {
			$teaserImage = $teaserImages->current();
		} else {
			$categoryImages = $category->getTeaser1Image();
			if (count($categoryImages)) {
				$teaserImage = $categoryImages->current();
			}
		}

		if ($teaserImage) {
			$teaserImageObject = $teaserImage;
			$originalResource = $teaserImage->getOriginalResource();
			if ($originalResource) {
				$teaserImage = $originalResource->getPublicUrl();
			}

			if ($teaserImage) {
				$teaserImage = $GLOBALS['TSFE']->absRefPrefix . $teaserImage;
			}
		}

		return [
			'teaserImage' => $teaserImage,
			'teaserImageObject' => $teaserImageObject,
		];
	}
}