Skip to content
Snippets Groups Projects
SitemapService.php 5.97 KiB
<?php

/***************************************************************
 *  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!
 ***************************************************************/

namespace SGalinski\SgJobs\Service;

use Doctrine\DBAL\Exception;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
use TYPO3\CMS\Core\Context\LanguageAspect;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\Languagevisibility\Exception\TableNotSupportedException;
use TYPO3\Languagevisibility\Service\FrontendServices;

/**
 * Class SitemapService
 */
class SitemapService {
	/**
	 * The plugin name
	 */
	public const PLUGIN_NAME = 'sgjobs_jobapplication';

	/**
	 * Generate a pageList array for the sitemap generation
	 *
	 * @param int $sysLanguageUid
	 * @param int $rootPageId
	 * @return array
	 * @throws Exception
	 * @throws AspectNotFoundException
	 */
	public function generatePagesList(int $sysLanguageUid, int $rootPageId = 0): array {
		$pageList = [];
		// find sites where job detail plugin is added
		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
			->getQueryBuilderForTable('tt_content');
		$databaseResource = $queryBuilder->select('tt_content.pid', 'pages', 'tt_content.tstamp')
			->from('tt_content')
			->innerJoin(
				'tt_content',
				'pages',
				'pages',
				'pages.uid = tt_content.pid
				AND pages.no_search = 0'
			)
			->where(
				$queryBuilder->expr()->and(
					$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')),
					$queryBuilder->expr()->eq(
						'list_type',
						$queryBuilder->createNamedParameter(self::PLUGIN_NAME)
					),
					$queryBuilder->expr()->or(
						$queryBuilder->expr()->eq('tt_content.sys_language_uid', -1),
						$queryBuilder->expr()->eq(
							'tt_content.sys_language_uid',
							$queryBuilder->createNamedParameter($sysLanguageUid, Connection::PARAM_INT)
						)
					)
				)
			)
			->executeQuery();

		$context = GeneralUtility::makeInstance(Context::class);
		while ($row = $databaseResource->fetchAssociative()) {
			try {
				$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($row['pid']);
				if ($rootPageId > 0 && $site->getRootPageId() !== $rootPageId) {
					continue;
				}

				$jobs = $this->getJobsByPid($row['pages'], $sysLanguageUid);
				foreach ($jobs as $job) {
					$url = $site->getRouter($context)->generateUri(
						$row['pid'],
						[
							'_language' => $context->getPropertyFromAspect('language', 'id', 0),
							'tx_sgjobs_jobapplication' => [
								'jobId' => $job['uid']
							]
						]
					);
					$pageList[] = [
						'url' => htmlspecialchars($url),
						'title' => '',
						'SYS_LASTCHANGED' => $row['tstamp'],
					];
				}
			} catch (SiteNotFoundException $exception) {
				// No site configuration for the page found
			}
		}

		return $pageList;
	}

	/**
	 * Get all jobs stored on specific page ids
	 *
	 * @param string $pageList
	 * @param int $sysLanguageUid
	 * @return array|null
	 * @throws AspectNotFoundException
	 * @throws Exception
	 */
	private function getJobsByPid(string $pageList, int $sysLanguageUid): ?array {
		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
			->getQueryBuilderForTable('tx_sgjobs_domain_model_job');
		$databaseResource = $queryBuilder->select('*')
			->from('tx_sgjobs_domain_model_job')
			->where(
				$queryBuilder->expr()->and(
					$queryBuilder->expr()->in('pid', $queryBuilder->createNamedParameter($pageList)),
					$queryBuilder->expr()->in('sys_language_uid', '-1,0')
				)
			)
			->executeQuery();

		$visibleRows = [];
		$rows = $databaseResource->fetchAllAssociative();
		/** @var PageRepository $pageRepository */
		$pageRepository = GeneralUtility::makeInstance(PageRepository::class);
		$isLanguageVisibilityLoaded = ExtensionManagementUtility::isLoaded('languagevisibility');
		$languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
		$frontendServices = GeneralUtility::makeInstance(FrontendServices::class);
		foreach ($rows as $row) {
			$table = 'tx_sgjobs_domain_model_job';

			// get languagevisibility uid that is available (check for the correct uid to fall back to)
			if ($isLanguageVisibilityLoaded) {
				try {
					$element = $frontendServices->getElement($row, $table);
				} catch (TableNotSupportedException $exception) {
					continue;
				}

				$languageId = $frontendServices->getOverlayLanguageIdForElement($element, $sysLanguageUid);
				if ($languageId === FALSE) {
					continue;
				}
			} else {
				$languageId = $sysLanguageUid;
			}

			if ($languageId > 0) {
				/** @var LanguageAspect $languageAspect */
				$newLanguageAspect = new LanguageAspect(
					$languageId,
					$languageAspect->getContentId(),
					$languageAspect->getOverlayType()
				);
				$row = $pageRepository->getLanguageOverlay($table, $row, $newLanguageAspect);
				if (!is_array($row) || !count($row)) {
					continue;
				}
			}

			$visibleRows[] = $row;
		}

		return $visibleRows;
	}
}