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

namespace SGalinski\SgJobs\Service;

use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\LanguageAspect;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
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
 *
 * @package SGalinski\SgJobs\Service
 */
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 \TYPO3\CMS\Core\Context\Exception\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()->andX(
					$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')),
					$queryBuilder->expr()->eq(
						'list_type',
						$queryBuilder->createNamedParameter(self::PLUGIN_NAME)
					),
					$queryBuilder->expr()->orX(
						$queryBuilder->expr()->eq('tt_content.sys_language_uid', -1),
						$queryBuilder->expr()->eq(
							'tt_content.sys_language_uid',
							$queryBuilder->createNamedParameter($sysLanguageUid, Connection::PARAM_INT)
						)
					)
				)
			)
			->execute();

		$context = GeneralUtility::makeInstance(Context::class);
		while ($row = $databaseResource->fetch()) {
			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
	 */
	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()->andX(
					$queryBuilder->expr()->in('pid', $queryBuilder->createNamedParameter($pageList)),
					$queryBuilder->expr()->in('sys_language_uid', '-1,0')
				)
			)
			->execute();

		$visibleRows = [];
		$rows = $databaseResource->fetchAll();
		$pageRepository = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Domain\Repository\PageRepository::class);
		$isLanguageVisibilityLoaded = ExtensionManagementUtility::isLoaded('languagevisibility');
		$languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
		$overlayType = $languageAspect->getLegacyOverlayType();
		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 */
				$row = $pageRepository->getRecordOverlay($table, $row, $languageId, $overlayType);
				if (!is_array($row) || !count($row)) {
					continue;
				}
			}

			$visibleRows[] = $row;
		}

		return $visibleRows;
	}
}