Commit 8ac9370c authored by Andreas Wolf's avatar Andreas Wolf

Merge branch 'issue-277-ter-fe2-doctrine' into 'develop'

Rework scheduler tasks to Doctrine

See merge request t3o/ter!266
parents 8b6590ee b0cc1775
Pipeline #2742 passed with stages
in 6 minutes and 56 seconds
......@@ -14,6 +14,7 @@ namespace T3o\TerFe2\Task;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Extbase\Scheduler\Task;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Backend\Utility\BackendUtility;
......@@ -43,84 +44,152 @@ class CheckForExpiredExtensions extends Task
'typo3v4',
'docteam'
];
$expiringExtensions = $this->getDatabaseConnection()->exec_SELECTgetRows(
'uid, ext_key, frontend_user',
'tx_terfe2_domain_model_extension',
'NOT deleted AND NOT expire AND versions = 0 AND tstamp <= ' . strtotime('-1 year'),
'',
'frontend_user'
);
$expiredExtensionsByOwner = $this->getExpiredExtensionsByOwner();
foreach ($expiredExtensionsByOwner as $username => $extensions) {
if (in_array($username, $this->blacklistUsers, true)) {
continue;
}
$this->notifyUser($username, $extensions);
}
// remove expired extensions
$this->removeExpiredExtensions();
return true;
}
/**
* @return array
*/
private function getExpiredExtensionsByOwner(): array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_terfe2_domain_model_extension')
->createQueryBuilder();
$queryBuilder->select('uid', 'ext_key', 'frontend_user')
->from('tx_terfe2_domain_model_extension')
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('expire', 0),
$queryBuilder->expr()->eq('versions', 0),
$queryBuilder->expr()->lte('tstamp', strtotime('-1 year'))
)
->orderBy('frontend_user');
$statement = $queryBuilder->execute();
$statement->execute();
// group extensions by owner
$expiredExtensionsByOwner = [];
foreach ($expiringExtensions as $expiringExtension) {
while ($expiringExtension = $statement->fetch(\PDO::FETCH_ASSOC)) {
if ($expiringExtension['ext_key'] && $expiringExtension['frontend_user']) {
$expiredExtensionsByOwner[$expiringExtension['frontend_user']][] = $expiringExtension;
}
}
return $expiredExtensionsByOwner;
}
foreach ($expiredExtensionsByOwner as $username => $extensions) {
if (in_array($username, $this->blacklistUsers, true)) {
continue;
}
$frontendUser = $this->getDatabaseConnection()->exec_SELECTgetSingleRow(
'uid, username, email',
'fe_users',
'username = ' . $this->getDatabaseConnection()->fullQuoteStr($username, 'fe_users')
. BackendUtility::BEenableFields('fe_users')
. BackendUtility::deleteClause('fe_users')
/**
* @param $username
* @param $extensions
* @return mixed
*/
private function notifyUser($username, $extensions)
{
$frontendUserConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('fe_users');
$queryBuilder = $frontendUserConnection->createQueryBuilder();
$queryBuilder->select('uid', 'username', 'email')
->from('fe_users')
->where($queryBuilder->expr()->eq('username', $queryBuilder->createNamedParameter($username)));
$statement = $queryBuilder->execute();
$statement->execute();
$frontendUser = $statement->fetch(\PDO::FETCH_ASSOC);
if (!empty($frontendUser) && GeneralUtility::validEmail($frontendUser['email'])) {
$to = $frontendUser['email'];
$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'
)
);
if (!empty($frontendUser) && GeneralUtility::validEmail($frontendUser['email'])) {
$to = $frontendUser['email'];
$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->assign('extensions', $extensions);
$body->assign('user', $frontendUser);
/** @var MailMessage $mail */
$mail = GeneralUtility::makeInstance(MailMessage::class);
$mail->addFrom('maintenance@typo3.org');
$mail->setTo($to);
$mail->setSubject($subject);
$mail->setBody($body->render());
if ($mail->send()) {
// set every extension of the owner to expire in 30 days
foreach ($extensions as $extension) {
$this->getDatabaseConnection()->exec_UPDATEquery(
'tx_terfe2_domain_model_extension',
'uid = ' . (int)$extension['uid'],
array(
'expire' => strtotime('+30 days')
)
);
}
}
$body->assign('extensions', $extensions);
$body->assign('user', $frontendUser);
/** @var MailMessage $mail */
$mail = GeneralUtility::makeInstance(MailMessage::class);
$mail->addFrom('maintenance@typo3.org');
$mail->setTo($to);
$mail->setSubject($subject);
$mail->setBody($body->render());
if ($mail->send()) {
// set every extension of the owner to expire in 30 days
$this->updateExpirationTimeOfExtensions($extensions);
}
}
return $queryBuilder;
}
// remove expired extensions
$expiredExtensions = $this->getDatabaseConnection()->exec_SELECTgetRows(
'uid, ext_key',
'tx_terfe2_domain_model_extension',
'NOT deleted AND expire > 0 AND expire <= ' . time() . ' AND versions = 0'
);
/**
* @param $extensions
* @param $extensionTableConnection
*/
private function updateExpirationTimeOfExtensions($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']
]
);
}
}
private function removeExpiredExtensions()
{
$extensionTableConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_terfe2_domain_model_extension');
$queryBuilder = $extensionTableConnection->createQueryBuilder();
$queryBuilder->select('uid', 'ext_key', 'frontend_user')
->from('tx_terfe2_domain_model_extension')
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->gt('expire', 0),
$queryBuilder->expr()->lt('expire', time()),
$queryBuilder->expr()->eq('versions', 0)
)
->orderBy('frontend_user');
$expiredExtensions = $queryBuilder->execute();
foreach ($expiredExtensions as $expiredExtension) {
$uidsToDelete = [];
while ($expiredExtension = $expiredExtensions->fetch(\PDO::FETCH_ASSOC)) {
// Deleted in ter, then delete the key in the ter_fe2 extension table
if ($expiredExtension['ext_key'] && $this->deleteExtensionKeyInTer($expiredExtension['ext_key'])) {
$this->getDatabaseConnection()->exec_DELETEquery(
'tx_terfe2_domain_model_extension',
'uid = ' . $expiredExtension['uid']
);
$uidsToDelete[] = $expiredExtension['uid'];
}
}
return true;
if (count($uidsToDelete) > 0) {
$queryBuilder = $extensionTableConnection->createQueryBuilder();
$queryBuilder->delete('tx_terfe2_domain_model_extension')
->where(
$queryBuilder->expr()->in('uid', $uidsToDelete)
);
$queryBuilder->execute()->execute();
}
}
/**
......@@ -130,28 +199,27 @@ class CheckForExpiredExtensions extends Task
protected function deleteExtensionKeyInTer($extensionKey)
{
// check if there are extension versions
$extensionsConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_ter_extensions');
$versions = $this->getDatabaseConnection()->exec_SELECTcountRows(
$versionCount = $extensionsConnection->count(
'extensionkey',
'tx_ter_extensions',
'extensionkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($extensionKey, 'tx_ter_extensions')
[
'extensionkey' => $extensionKey
]
);
if (!$versions || $versions === 0) {
return $this->getDatabaseConnection()->exec_DELETEquery(
if (!$versionCount || $versionCount === 0) {
return $extensionsConnection->delete(
'tx_ter_extensionkeys',
'extensionkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($extensionKey, 'tx_ter_extensions')
[
'extensionkey' => $extensionKey
]
);
}
return false;
}
/**
* @return \TYPO3\CMS\Core\Database\DatabaseConnection
*/
protected function getDatabaseConnection()
{
return $GLOBALS['TYPO3_DB'];
}
}
......@@ -15,6 +15,7 @@ namespace T3o\TerFe2\Task;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Extbase\Scheduler\Task;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
......@@ -119,15 +120,24 @@ class CheckForOutdatedExtensions extends Task
*/
public function getNotOutdatedAndSecureVersions()
{
$rows = $this->getDatabaseConnection()->exec_SELECTgetRows(
'uid',
'tx_terfe2_domain_model_version',
'NOT deleted AND NOT hidden AND review_state >= 0',
'',
'upload_date ASC'
);
return $rows;
$tableName = 'tx_terfe2_domain_model_version';
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$statement = $queryBuilder
->select('uid')
->from($tableName)
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('hidden', 0),
$queryBuilder->expr()->gte('review_state', 0)
)
->orderBy('upload_date', 'ASC')
->execute();
$statement->execute();
return $statement->fetchAll(\PDO::FETCH_ASSOC);
}
/**
......@@ -265,22 +275,27 @@ class CheckForOutdatedExtensions extends Task
}
if ($isOutdated) {
$this->getDatabaseConnection()->exec_UPDATEquery(
'tx_terfe2_domain_model_version',
'uid = ' . $version->getUid(),
[
'review_state' => -2
]
);
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder
->update('tx_terfe2_domain_model_version')
->set('review_state', -2)
->where(
$queryBuilder->expr()->eq('uid', $version->getUid())
)
->execute();
if ($version->getExtension() && $version->getExtension()->getUid()) {
$this->getDatabaseConnection()->exec_UPDATEquery(
'tx_terfe2_domain_model_extension',
'uid = ' . $version->getExtension()->getUid(),
[
'tstamp' => time()
]
);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_terfe2_domain_model_extension');
$queryBuilder
->update('tx_terfe2_domain_model_extension')
->set('tstamp', time())
->where(
$queryBuilder->expr()->eq('uid', $version->getUid())
)
->execute();
$this->solrIndexQueue->updateItem('tx_terfe2_domain_model_extension', $version->getExtension()->getUid());
}
}
......@@ -304,11 +319,4 @@ class CheckForOutdatedExtensions extends Task
}
}
/**
* @return \TYPO3\CMS\Core\Database\DatabaseConnection
*/
private function getDatabaseConnection()
{
return $GLOBALS['TYPO3_DB'];
}
}
......@@ -15,6 +15,7 @@ namespace T3o\TerFe2\Task;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Extbase\Scheduler\Task;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
......@@ -85,11 +86,17 @@ class ImportExtensionsFromQueueTask extends Task
*/
public function removeExtensionFromQueue($extUid)
{
$updateQueue = [
'tstamp' => time(),
'imported_to_fe' => 1
];
$this->getDatabaseConnection()->exec_UPDATEquery('tx_ter_extensionqueue', 'extensionuid = ' . $extUid, $updateQueue);
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_ter_extensionqueue');
$queryBuilder
->update('tx_ter_extensionqueue')
->where(
$queryBuilder->expr()->eq('extensionuid', $extUid)
)
->set('tstamp', time())
->set('imported_to_fe', 1)
->execute();
}
/**
......@@ -100,15 +107,22 @@ class ImportExtensionsFromQueueTask extends Task
*/
public function getExtensionsFromQueue()
{
$extensions = $this->getDatabaseConnection()->exec_SELECTgetRows(
'extensionuid,crdate',
'tx_ter_extensionqueue',
'NOT deleted AND NOT imported_to_fe',
false,
'crdate'
);
return $extensions;
$tableName = 'tx_ter_extensionqueue';
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$statement = $queryBuilder
->select('extensionuid', 'crdate')
->from($tableName)
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('imported_to_fe', 0)
)
->orderBy('crdate')
->execute();
$statement->execute();
return $statement->fetchAll(\PDO::FETCH_ASSOC);
}
/**
......@@ -120,13 +134,24 @@ class ImportExtensionsFromQueueTask extends Task
*/
public function getExtensionData($extensionUid)
{
$extData = $this->getDatabaseConnection()->exec_SELECTgetSingleRow(
'tx_ter_extensions.*, tx_ter_extensiondetails.*',
'tx_ter_extensions LEFT JOIN tx_ter_extensiondetails ON tx_ter_extensions.uid = tx_ter_extensiondetails.extensionuid',
'tx_ter_extensions.uid = ' . (int)$extensionUid
);
return $extData;
$tableName = 'tx_ter_extensions';
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$statement = $queryBuilder
->select('exts.*', 'extdetails.*')
->from($tableName, 'exts')
->leftJoin('exts', 'tx_ter_extensiondetails', 'extdetails',
$queryBuilder->expr()->eq('exts.uid', $queryBuilder->quoteIdentifier('extdetails.extensionuid'))
)
->where(
$queryBuilder->expr()->eq('exts.uid', (int)$extensionUid)
)
->execute();
$statement->execute();
return $statement->fetch(\PDO::FETCH_ASSOC);
}
/**
......@@ -139,16 +164,26 @@ class ImportExtensionsFromQueueTask extends Task
*/
public function versionExists($extData)
{
$res = $this->getDatabaseConnection()->exec_SELECTquery(
'tx_terfe2_domain_model_version.uid',
'tx_terfe2_domain_model_version
LEFT JOIN tx_terfe2_domain_model_extension ON tx_terfe2_domain_model_extension.uid = tx_terfe2_domain_model_version.extension',
'NOT tx_terfe2_domain_model_version.deleted
AND tx_terfe2_domain_model_version.version_string = "' . $GLOBALS['TYPO3_DB']->fullQuoteStr($extData['version'], '') . '"
AND tx_terfe2_domain_model_extension.ext_key = "' . $GLOBALS['TYPO3_DB']->fullQuoteStr($extData['extensionkey'], '') . '"'
);
return (boolean)$this->getDatabaseConnection()->sql_num_rows($res);
$tableName = 'tx_terfe2_domain_model_version';
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$statement = $queryBuilder
->count('ver.uid')
->from($tableName, 'ver')
->leftJoin('ver', 'tx_terfe2_domain_model_extension', 'ext',
$queryBuilder->expr()->eq('ext.uid', $queryBuilder->quoteIdentifier('ver.extension'))
)
->where(
$queryBuilder->expr()->eq('ver.deleted', 0),
$queryBuilder->expr()->eq('ver.version_string', $queryBuilder->createNamedParameter($extData['version'])),
$queryBuilder->expr()->eq('ext.ext_key', $queryBuilder->createNamedParameter($extData['extensionkey']))
)
->execute();
$statement->execute();
return $statement->fetch(\PDO::FETCH_ASSOC);
}
/**
......@@ -158,11 +193,20 @@ class ImportExtensionsFromQueueTask extends Task
*/
public function extensionExists($extData)
{
$extRec = $this->getDatabaseConnection()->exec_SELECTgetSingleRow(
'uid',
'tx_terfe2_domain_model_extension',
'NOT deleted AND ext_key = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($extData['extensionkey'], '')
);
$tableName = 'tx_terfe2_domain_model_extension';
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$statement = $queryBuilder
->select('uid')
->from($tableName)
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('ext_key', $queryBuilder->createNamedParameter($extData['extensionkey']))
)
->execute();
$statement->execute();
$extRec = $statement->fetch(\PDO::FETCH_ASSOC);
if ($extRec) {
return $extRec['uid'];
}
......@@ -189,9 +233,13 @@ class ImportExtensionsFromQueueTask extends Task
'tstamp' => time()
];
$this->getDatabaseConnection()->exec_INSERTquery('tx_terfe2_domain_model_extension', $insertExtension);
$tableName = 'tx_terfe2_domain_model_extension';
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
return $this->getDatabaseConnection()->sql_insert_id();
$queryBuilder->insert($tableName)->values($insertExtension)->execute()->execute();
return $connectionPool->getConnectionForTable($tableName)->lastInsertId($tableName);
}
/**
......@@ -263,9 +311,13 @@ class ImportExtensionsFromQueueTask extends Task
'zip_file_size' => 0
];
$this->getDatabaseConnection()->exec_INSERTquery('tx_terfe2_domain_model_version', $insertVersion);
$tableName = 'tx_terfe2_domain_model_version';
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
$queryBuilder->insert($tableName)->values($insertVersion)->execute()->execute();
return $this->getDatabaseConnection()->sql_insert_id();
return $connectionPool->getConnectionForTable($tableName)->lastInsertId($tableName);
}
/**
......@@ -277,16 +329,21 @@ class ImportExtensionsFromQueueTask extends Task
{
$highestVersionUid = $this->calculatedHighestVersion($versionUid, $extUid);
$updateExtension = [
'tstamp' => time(),
'versions' => $this->getNumberOfVersions($extUid),
'last_version' => $highestVersionUid
];
$this->getDatabaseConnection()->exec_UPDATEquery(
'tx_terfe2_domain_model_extension',
'uid = ' . $extUid,
$updateExtension
);
$tableName = 'tx_terfe2_domain_model_extension';
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$queryBuilder
->update($tableName)
->set('tstamp', time())
->set('versions', $this->getNumberOfVersions($extUid))
->set('last_version', $highestVersionUid)
->where(
$queryBuilder->expr()->eq('uid', $extUid)
)
->execute()
->execute();
}
/**
......@@ -296,13 +353,22 @@ class ImportExtensionsFromQueueTask extends Task
*/
public function getNumberOfVersions($extUid)
{
$res = $this->getDatabaseConnection()->exec_SELECTquery(
'uid',
'tx_terfe2_domain_model_version',
'extension = ' . $extUid . ' AND NOT deleted'
);
return $this->getDatabaseConnection()->sql_num_rows($res);
$tableName = 'tx_terfe2_domain_model_version';
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
$queryBuilder->getRestrictions()->removeAll();
$statement = $queryBuilder
->count('uid')
->from($tableName)
->where(
$queryBuilder->expr()->eq('extension', $extUid),
$queryBuilder->expr()->eq('deleted', 0)
)
->execute();
$statement->execute();