Commit 95811232 authored by Thomas Löffler's avatar Thomas Löffler
Browse files

Merge branch 'develop' into feature/soap-middleware

parents f76aa938 fbb4b194
Pipeline #9562 failed with stages
in 2 minutes and 22 seconds
......@@ -35,20 +35,6 @@ test:unit:
script:
- composer install --ignore-platform-reqs
- composer test:unit
layout:
stage: layout
image: node:8
before_script:
- cd private/typo3conf/ext/t3olayout/Build
script:
- npm install
- npm run build
after_script:
- rm -Rf private/typo3conf/ext/t3olayout/Build/node_modules
artifacts:
paths:
- ./
expire_in: '4h'
dependencies:
- build
reports:
junit: build/*-report.xml
......@@ -18,4 +18,9 @@
<directory>../../extensions/ter_fe2/Tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../../extensions/ter_fe2/Classes/</directory>
</whitelist>
</filter>
</phpunit>
......@@ -58,6 +58,8 @@ set('bin_folder', 'vendor/bin/');
task('typo3', function() {
run('cd {{release_path}} && {{php}} {{bin_folder}}typo3cms install:generatepackagestates');
run('cd {{release_path}} && {{php}} {{bin_folder}}typo3cms install:extensionsetupifpossible');
run('cd {{release_path}} && {{php}} {{bin_folder}}typo3cms upgrade:prepare -q');
run('cd {{release_path}} && {{php}} {{bin_folder}}typo3cms upgrade:run databaseRowsUpdateWizard pagesLanguageOverlayBeGroupsAccessRights');
});
task('solr:host', function() {
......
......@@ -31,19 +31,17 @@
"ext-json": "*",
"ext-pdo": "*",
"ext-zlib": "*",
"apache-solr-for-typo3/solr": "^11.0",
"gordalina/cachetool": "^4.0",
"helhum/typo3-console": "^5.7",
"helhum/typo3-secure-web": "^0.2.9",
"nikic/php-parser": "^4.0",
"t3o/t3olayout": "^4.0",
"nimut/testing-framework": "^5.0",
"t3o/t3olayout": "^5.0",
"t3o/ter-frontend": "^0.5.0",
"t3o/ter-layout": "^0.2.0",
"t3o/ter-soap": "^2.1",
"typo3/cms-adminpanel": "^9.5",
"typo3/cms-seo": "^9.5"
"typo3/cms-adminpanel": "^10.4",
"typo3/cms-seo": "^10.4"
},
"require-dev": {
"nimut/testing-framework": "^4.0",
"codeception/codeception": "^4.1",
"codeception/module-phpbrowser": "^1.0",
"codeception/module-asserts": "^1.2"
......@@ -63,7 +61,7 @@
},
"scripts": {
"test:unit": [
"./vendor/bin/phpunit -c .gitlab-ci/Tests/UnitTests.xml"
"./vendor/bin/phpunit -c .gitlab-ci/Tests/UnitTests.xml --log-junit build/junit-report.xml --coverage-text --colors=never"
],
"test:api": [
"./vendor/bin/codecept run api --steps"
......
This diff is collapsed.
......@@ -16,56 +16,56 @@ namespace T3o\Ter\Api;
*/
class ResultCodes
{
public const ERROR_GENERAL_EXTREPDIRDOESNTEXIST = '100';
public const ERROR_GENERAL_NOUSERORPASSWORD = '101';
public const ERROR_GENERAL_USERNOTFOUND = '102';
public const ERROR_GENERAL_WRONGPASSWORD = '103';
public const ERROR_GENERAL_DATABASEERROR = '104';
public const ERROR_GENERAL_EXTENSIONCONTAINSNOFILES = '105';
public const ERROR_GENERAL_EXTREPDIRDOESNTEXIST = 100;
public const ERROR_GENERAL_NOUSERORPASSWORD = 101;
public const ERROR_GENERAL_USERNOTFOUND = 102;
public const ERROR_GENERAL_WRONGPASSWORD = 103;
public const ERROR_GENERAL_DATABASEERROR = 104;
public const ERROR_GENERAL_EXTENSIONCONTAINSNOFILES = 105;
public const ERROR_UPLOADEXTENSION_EXTENSIONDOESNTEXIST = '202';
public const ERROR_UPLOADEXTENSION_EXTENSIONCONTAINSNOFILES = '203';
public const ERROR_UPLOADEXTENSION_WRITEERRORWHILEWRITINGFILES = '204';
public const ERROR_UPLOADEXTENSION_EXTENSIONTOOBIG = '205';
public const ERROR_UPLOADEXTENSION_EXISTINGEXTENSIONRECORDNOTFOUND = '206';
public const ERROR_UPLOADEXTENSION_FILEMD5DOESNOTMATCH = '207';
public const ERROR_UPLOADEXTENSION_ACCESSDENIED = '208';
public const ERROR_UPLOADEXTENSION_TYPO3DEPENDENCYINCORRECT = '209';
public const ERROR_UPLOADEXTENSION_TYPO3DEPENDENCYCHECKFAILED = '210';
public const ERROR_UPLOADEXTENSION_EXTENSIONVERSIONEXISTS = '211';
public const ERROR_UPLOADEXTENSION_NOUPLOADCOMMENT = '212';
public const ERROR_UPLOADEXTENSION_EXTENSIONDOESNTEXIST = 202;
public const ERROR_UPLOADEXTENSION_EXTENSIONCONTAINSNOFILES = 203;
public const ERROR_UPLOADEXTENSION_WRITEERRORWHILEWRITINGFILES = 204;
public const ERROR_UPLOADEXTENSION_EXTENSIONTOOBIG = 205;
public const ERROR_UPLOADEXTENSION_EXISTINGEXTENSIONRECORDNOTFOUND = 206;
public const ERROR_UPLOADEXTENSION_FILEMD5DOESNOTMATCH = 207;
public const ERROR_UPLOADEXTENSION_ACCESSDENIED = 208;
public const ERROR_UPLOADEXTENSION_TYPO3DEPENDENCYINCORRECT = 209;
public const ERROR_UPLOADEXTENSION_TYPO3DEPENDENCYCHECKFAILED = 210;
public const ERROR_UPLOADEXTENSION_EXTENSIONVERSIONEXISTS = 211;
public const ERROR_UPLOADEXTENSION_NOUPLOADCOMMENT = 212;
public const ERROR_REGISTEREXTENSIONKEY_DBERRORWHILEINSERTINGKEY = '300';
public const ERROR_REGISTEREXTENSIONKEY_DBERRORWHILEINSERTINGKEY = 300;
public const ERROR_DELETEEXTENSIONKEY_ACCESSDENIED = '500';
public const ERROR_DELETEEXTENSIONKEY_KEYDOESNOTEXIST = '501';
public const ERROR_DELETEEXTENSIONKEY_CANTDELETEBECAUSEVERSIONSEXIST = '502';
public const ERROR_DELETEEXTENSIONKEY_ACCESSDENIED = 500;
public const ERROR_DELETEEXTENSIONKEY_KEYDOESNOTEXIST = 501;
public const ERROR_DELETEEXTENSIONKEY_CANTDELETEBECAUSEVERSIONSEXIST = 502;
public const ERROR_MODIFYEXTENSIONKEY_ACCESSDENIED = '600';
public const ERROR_MODIFYEXTENSIONKEY_SETTINGTOTHISOWNERISNOTPOSSIBLE = '601';
public const ERROR_MODIFYEXTENSIONKEY_KEYDOESNOTEXIST = '602';
public const ERROR_MODIFYEXTENSIONKEY_ACCESSDENIED = 600;
public const ERROR_MODIFYEXTENSIONKEY_SETTINGTOTHISOWNERISNOTPOSSIBLE = 601;
public const ERROR_MODIFYEXTENSIONKEY_KEYDOESNOTEXIST = 602;
public const ERROR_SETREVIEWSTATE_NOUSERGROUPDEFINED = '700';
public const ERROR_SETREVIEWSTATE_ACCESSDENIED = '701';
public const ERROR_SETREVIEWSTATE_EXTENSIONVERSIONDOESNOTEXIST = '702';
public const ERROR_SETREVIEWSTATE_NOUSERGROUPDEFINED = 700;
public const ERROR_SETREVIEWSTATE_ACCESSDENIED = 701;
public const ERROR_SETREVIEWSTATE_EXTENSIONVERSIONDOESNOTEXIST = 702;
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_NOUSERGROUPDEFINED = '800';
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_ACCESSDENIED = '801';
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_EXTENSIONVERSIONDOESNOTEXIST = '802';
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_INCREMENTORNOTPOSITIVEINTEGER = '803';
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_EXTENSIONKEYDOESNOTEXIST = '804';
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_NOUSERGROUPDEFINED = 800;
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_ACCESSDENIED = 801;
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_EXTENSIONVERSIONDOESNOTEXIST = 802;
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_INCREMENTORNOTPOSITIVEINTEGER = 803;
public const ERROR_INCREASEEXTENSIONDOWNLOADCOUNTER_EXTENSIONKEYDOESNOTEXIST = 804;
public const ERROR_DELETEEXTENSION_ACCESS_DENIED = '900';
public const ERROR_DELETEEXTENSION_EXTENSIONDOESNTEXIST = '901';
public const ERROR_DELETEEXTENSION_ACCESS_DENIED = 900;
public const ERROR_DELETEEXTENSION_EXTENSIONDOESNTEXIST = 901;
// Result codes:
public const RESULT_GENERAL_OK = '10000';
public const RESULT_ERRORS_OCCURRED = '10001';
public const RESULT_GENERAL_OK = 10000;
public const RESULT_ERRORS_OCCURRED = 10001;
public const RESULT_EXTENSIONKEYALREADYEXISTS = '10500';
public const RESULT_EXTENSIONKEYDOESNOTEXIST = '10501';
public const RESULT_EXTENSIONKEYNOTVALID = '10502';
public const RESULT_EXTENSIONKEYSUCCESSFULLYREGISTERED = '10503';
public const RESULT_EXTENSIONSUCCESSFULLYUPLOADED = '10504';
public const RESULT_EXTENSIONSUCCESSFULLYDELETED = '10505';
public const RESULT_EXTENSIONKEYALREADYEXISTS = 10500;
public const RESULT_EXTENSIONKEYDOESNOTEXIST = 10501;
public const RESULT_EXTENSIONKEYNOTVALID = 10502;
public const RESULT_EXTENSIONKEYSUCCESSFULLYREGISTERED = 10503;
public const RESULT_EXTENSIONSUCCESSFULLYUPLOADED = 10504;
public const RESULT_EXTENSIONSUCCESSFULLYDELETED = 10505;
}
......@@ -394,10 +394,10 @@ class TerSoapV1Handler
/**
* Returns the structure of th simple SOAP result.
*
* @param string $resultCode
* @param int $resultCode
* @return array
*/
protected function formatAsSimpleResult(string $resultCode): array
protected function formatAsSimpleResult(int $resultCode): array
{
return [
'resultCode' => $resultCode,
......
<?php
namespace T3o\TerFe2\Task;
declare(strict_types = 1);
namespace T3o\TerFe2\Command;
/*
* This file is part of the TYPO3 CMS project.
* This file is part of a TYPO3 extension.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
......@@ -14,51 +15,43 @@ namespace T3o\TerFe2\Task;
* The TYPO3 project - inspiring people to share!
*/
use Psr\Log\LoggerInterface;
use T3o\Ter\Api\ExtensionKey;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Scheduler\Task;
use TYPO3\CMS\Fluid\View\StandaloneView;
/**
* Class CheckForExpiredExtensions
*/
class CheckForExpiredExtensions extends Task
class CheckForExpiredExtensions extends Command implements \Psr\Log\LoggerAwareInterface
{
use \Psr\Log\LoggerAwareTrait;
/**
* @var array
*/
protected $blacklistUsers = [];
protected $blacklistUsers = [
'abandoned_extensions',
'typo3v4',
'docteam'
];
/**
* @var LoggerInterface
*/
protected $logger;
protected function configure()
{
$this->setDescription('Checks all extension keys if there is no upload since a year.');
}
/**
* Execute Task
*
* @return bool
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
public function execute()
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
$this->logger->info('Task CheckForExpiredExtensions started');
$this->blacklistUsers = [
'abandoned_extensions',
'typo3v4',
'docteam'
];
$io = new SymfonyStyle($input, $output);
$io->section('Fetching extension keys without versions');
$expiredExtensionsByOwner = $this->getExpiredExtensionsByOwner();
$this->logger->info(sprintf('Found %d expired extensions', count($expiredExtensionsByOwner)));
$io->success('Found ' . count($expiredExtensionsByOwner) . ' expired extensions.');
foreach ($expiredExtensionsByOwner as $username => $extensions) {
if (in_array($username, $this->blacklistUsers, true)) {
......@@ -76,15 +69,13 @@ class CheckForExpiredExtensions extends Task
return true;
}
/**
* @return array
*/
private function getExpiredExtensionsByOwner(): array
protected function getExpiredExtensionsByOwner(): ?array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_terfe2_domain_model_extension')
->createQueryBuilder();
$queryBuilder->select('uid', 'ext_key', 'frontend_user')
$queryBuilder
->select('uid', 'ext_key', 'frontend_user')
->from('tx_terfe2_domain_model_extension')
->where(
$queryBuilder->expr()->eq('deleted', 0),
......@@ -103,23 +94,22 @@ class CheckForExpiredExtensions extends Task
$expiredExtensionsByOwner[$expiringExtension['frontend_user']][] = $expiringExtension;
}
}
return $expiredExtensionsByOwner;
}
/**
* @param $username
* @param $extensions
* @return mixed
*/
private function notifyUser($username, $extensions)
private function notifyUser(string $username, array $extensions)
{
$frontendUserConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('fe_users');
$queryBuilder = $frontendUserConnection->createQueryBuilder();
$queryBuilder->select('uid', 'username', 'email')
$queryBuilder
->select('uid', 'username', 'email')
->from('fe_users')
->where($queryBuilder->expr()->eq('username', $queryBuilder->createNamedParameter($username)));
->where(
$queryBuilder->expr()->eq('username', $queryBuilder->createNamedParameter($username))
);
$statement = $queryBuilder->execute();
$statement->execute();
......@@ -130,56 +120,42 @@ class CheckForExpiredExtensions extends Task
$subject = 'Your extension keys are going to expire!';
/** @var StandaloneView $body */
$body = GeneralUtility::makeInstance(StandaloneView::class);
$body->setTemplatePathAndFilename(
GeneralUtility::getFileAbsFileName(
'EXT:ter_fe2/Resources/Private/Templates/Mail/ExpiredExtensions.html'
)
);
$body->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:ter_fe2/Resources/Private/Templates/Mail/ExpiredExtensions.html'));
$body->assign('extensions', $extensions);
$body->assign('user', $frontendUser);
$emailBody = $body->render();
/** @var MailMessage $mail */
$mail = GeneralUtility::makeInstance(MailMessage::class);
$mail->addFrom('maintenance@typo3.org');
$mail->setTo($to);
$mail->setSubject($subject);
$mail->setBody($body->render());
$mail->html($emailBody);
if ($mail->send()) {
$this->logger->info(sprintf(
'Sent email to user %s (%s)',
$frontendUser['username'],
$to
));
$this->logger->info(sprintf('Sent email to user %s (%s)', $frontendUser['username'], $to));
// set every extension of the owner to expire in 30 days
$this->updateExpirationTimeOfExtensions($extensions);
}
} else {
$this->logger->warning(sprintf(
'Could not find frontend user with username %s',
$username
));
$this->logger->warning(sprintf('Could not find frontend user with username %s', $username));
}
return $queryBuilder;
}
/**
* @param $extensions
* @param $extensionTableConnection
*/
private function updateExpirationTimeOfExtensions($extensions)
private function updateExpirationTimeOfExtensions(array $extensions)
{
$extensionTableConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_terfe2_domain_model_extension');
foreach ($extensions as $extension) {
$extensionTableConnection->update(
'tx_terfe2_domain_model_extension',
[
'expire' => strtotime('+30 days')
],
[
'uid' => (int)$extension['uid']
]
);
$extensionTableConnection
->update(
'tx_terfe2_domain_model_extension',
[
'expire' => strtotime('+30 days')
],
[
'uid' => (int)$extension['uid']
]
);
$this->logger->info(
sprintf('Updated expiration time of extension %s (uid %d)', $extension['ext_key'], $extension['uid'])
......@@ -193,7 +169,8 @@ class CheckForExpiredExtensions extends Task
->getConnectionForTable('tx_terfe2_domain_model_extension');
$queryBuilder = $extensionTableConnection->createQueryBuilder();
$queryBuilder->select('uid', 'ext_key', 'frontend_user')
$queryBuilder
->select('uid', 'ext_key', 'frontend_user')
->from('tx_terfe2_domain_model_extension')
->where(
$queryBuilder->expr()->eq('deleted', 0),
......@@ -206,24 +183,19 @@ class CheckForExpiredExtensions extends Task
$uidsToDelete = [];
while ($expiredExtension = $expiredExtensions->fetch(\PDO::FETCH_ASSOC)) {
$extensionKey = new ExtensionKey($expiredExtension['ext_key']);
$extensionKey = new \T3o\Ter\Api\ExtensionKey($expiredExtension['ext_key']);
if (!$extensionKey->hasUploadedVersions()) {
$uidsToDelete[] = $expiredExtension['uid'];
}
}
if (count($uidsToDelete) > 0) {
$queryBuilder = $extensionTableConnection->createQueryBuilder();
$queryBuilder->delete('tx_terfe2_domain_model_extension')
->where(
$queryBuilder->expr()->in('uid', $uidsToDelete)
);
$queryBuilder->delete('tx_terfe2_domain_model_extension')->where($queryBuilder->expr()->in('uid', $uidsToDelete));
$queryBuilder->execute();
$this->logger->info(sprintf(
'Deleted %d expired extensions (uids %s)',
count($uidsToDelete),
implode(', ', $uidsToDelete)
));
$this->logger->info(
sprintf('Deleted %d expired extensions (uids %s)', count($uidsToDelete), implode(', ', $uidsToDelete))
);
}
}
}
<?php
declare(strict_types = 1);
namespace T3o\TerFe2\Command;
/*
* This file is part of a TYPO3 extension.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class CheckForOutdatedExtensions extends Command implements \Psr\Log\LoggerAwareInterface
{
use \Psr\Log\LoggerAwareTrait;
protected function configure()
{
$this->setDescription('Checks all versions if they are outdated (not supporting an actively supported TYPO3 CMS version).');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$io->section('Fetching not outdated and not insecure versions');
$versions = $this->getAllNonOutdatedAndNotInsecureVersions();
$io->success('Found ' . count($versions) . ' versions to check.');
$outdatedVersions = 0;
if ($versions) {
$progressBar = new \Symfony\Component\Console\Helper\ProgressBar($output, count($versions));
$progressBar->setFormat('very_verbose');
$outdatedVersionService = GeneralUtility::makeInstance(\T3o\TerFe2\Service\OutdatedVersionService::class);
$io->section('Checking versions...');
$progressBar->start();
foreach ($versions as $version) {
[$minimumVersion, $maximumVersion] = $this->getTypo3Dependency($version['uid']);
if (!$outdatedVersionService->isVersionDependingOnAnActiveSupportedTypo3Version($minimumVersion, $maximumVersion)) {
$this->setVersionAsOutdated($version['uid']);
$outdatedVersions++;
}
$progressBar->advance();
}
$progressBar->finish();
$io->writeln('');
}
$io->success('Set ' . $outdatedVersions . ' versions as outdated');
}
protected function getAllNonOutdatedAndNotInsecureVersions(): ?array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder->getRestrictions()->removeAll();
return $queryBuilder
->select('uid')
->from('tx_terfe2_domain_model_version')
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('hidden', 0),
$queryBuilder->expr()->gte('review_state', 0)
)
->orderBy('upload_date', 'ASC')
->execute()
->fetchAll(\PDO::FETCH_ASSOC);
}
protected function getTypo3Dependency(int $versionUid): array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_terfe2_domain_model_relation');
$queryBuilder->getRestrictions()->removeAll();
$typo3Dependency = $queryBuilder
->select(...['minimum_version', 'maximum_version'])
->from('tx_terfe2_domain_model_relation')
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('hidden', 0),
$queryBuilder->expr()->eq('relation_key', $queryBuilder->createNamedParameter('typo3')),
$queryBuilder->expr()->eq('version', $versionUid)
)
->execute()
->fetch(\PDO::FETCH_ASSOC);
return [
$typo3Dependency['minimum_version'],
$typo3Dependency['maximum_version'],
];
}
protected function setVersionAsOutdated(int $versionUid)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder
->update('tx_terfe2_domain_model_version')
->set('review_state', -2)
->where($queryBuilder->expr()->eq('uid', $versionUid))
->execute();
}
}
......@@ -205,6 +205,13 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
$this->view->assign('notification', $currentUser->getNotifiedExtensions()->contains($extension));
}
}
$metaTagManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry::class)->getManagerForProperty('og:title');
$metaTagManager->addProperty('og:title', $extension->getLastVersion()->getTitle() . ' (' . $extension->getExtKey() . ')');
$metaTagManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry::class)->getManagerForProperty('og:description');
$metaTagManager->addProperty('og:description', $extension->getLastVersion()->getDescription());
$GLOBALS['TSFE']->page['title'] = $extension->getLastVersion()->getTitle();
}
}
......@@ -245,7 +252,7 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController