Skip to content

Instantly share code, notes, and snippets.

@georgringer
Created September 17, 2019 12:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save georgringer/694a859158eec741c6170af7aa322ee4 to your computer and use it in GitHub Desktop.
Save georgringer/694a859158eec741c6170af7aa322ee4 to your computer and use it in GitHub Desktop.
Allow fallbacks for hreflang in TYPO3 9
<?php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Seo\HrefLang\HrefLangGenerator::class] = [
'className' => \JosefGlatz\Theme\Xclass\HrefLangGeneratorXclass::class,
];
<?php
declare(strict_types=1);
namespace JosefGlatz\Theme\Xclass;
use JosefGlatz\Theme\Service\LanguageAvailability;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\DataProcessing\LanguageMenuProcessor;
use TYPO3\CMS\Seo\HrefLang\HrefLangGenerator;
class HrefLangGeneratorXclass extends HrefLangGenerator {
public function generate(): string
{
$hreflangs = [];
if ((int)$this->typoScriptFrontendController->page['no_index'] === 1) {
return '';
}
if ($this->request->getAttribute('site') instanceof Site) {
$languageMenu = GeneralUtility::makeInstance(LanguageMenuProcessor::class);
$languages = $languageMenu->process($this->cObj, [], [], []);
foreach ($languages['languagemenu'] as $language) {
if (LanguageAvailability::checkLanguageAvailability($language) && !empty($language['link'])) {
$href = $this->getAbsoluteUrl($language['link']);
$hreflangs[] =
'<link rel="alternate" hreflang="' . htmlspecialchars($language['hreflang']) . '" href="' . htmlspecialchars($href) . '"/>';
}
}
if (count($hreflangs) > 1) {
$href = $this->getAbsoluteUrl($languages['languagemenu'][0]['link']);
$hreflangs[] =
'<link rel="alternate" hreflang="x-default" href="' . htmlspecialchars($href) . '"/>' . LF;
$this->getTypoScriptFrontendController()->additionalHeaderData[] = implode(LF, $hreflangs);
}
}
return implode(LF, $hreflangs);
}
}
<?php
declare(strict_types=1);
namespace JosefGlatz\Theme\Service;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
class LanguageAvailability
{
/**
* @param $language
* @return bool
*/
public static function checkLanguageAvailability(array $language): bool
{
if ($language['available']) {
return true;
}
$currentPage = self::getTsfe()->page;
$currentSite = self::getCurrentSite();
if ($currentSite) {
$languageId = $language['languageId'];
/** @var SiteLanguage $languageConfiguration */
$languageConfiguration = $currentSite->getAllLanguages()[$languageId];
// check fallbacks
$fallbacks = $languageConfiguration->getFallbackLanguageIds();
foreach ($fallbacks as $fallbackLanguageId) {
if ($fallbackLanguageId === 0) {
return true;
}
$row = self::getTranslationOfPage($currentPage['uid'], $fallbackLanguageId);
if (is_array($row) && !empty($row)) {
return true;
}
}
}
return false;
}
protected static function getTranslationOfPage(int $pageId, int $languageId)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$row = $queryBuilder
->select('uid', 'title', 'pid')
->from('pages')
->where(
$queryBuilder->expr()->eq(
'l10n_parent',
$queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'sys_language_uid',
$queryBuilder->createNamedParameter($languageId, \PDO::PARAM_INT)
)
)
->execute()
->fetch();
return $row;
}
protected static function getTsfe(): TypoScriptFrontendController
{
return $GLOBALS['TSFE'];
}
protected static function getCurrentSite(): ?Site
{
if ($GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface
&& $GLOBALS['TYPO3_REQUEST']->getAttribute('site') instanceof Site) {
return $GLOBALS['TYPO3_REQUEST']->getAttribute('site');
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment