Commit 0bc0449c authored by Benni Mack's avatar Benni Mack
Browse files

[BUGFIX] Fix issues related to merging DB tables

Two changes are needed since the unification of the database tables

* When an extension version is uploaded or removed, the *_extension table
needs an update (which was not the case before) with the current version
information.
For this reason the "ExtensionKey" API has a "UpdateExtensionInformation"
method now, and some internal functions are moved to the ExtensionKey class

* When an extension version (or extension) is deleted, Extbase attempted
to also delete the information (which already happened in the TER)

The SolR Re-Indexing is now placed at a more central point.
parent f9037696
Pipeline #9412 passed with stages
in 8 minutes and 43 seconds
......@@ -11,6 +11,7 @@ namespace T3o\Ter\Api;
* of the License, or any later version.
*/
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
use T3o\Ter\Exception\ExtensionKeyAlreadyInUseException;
use T3o\Ter\Exception\ExtensionKeyNotFoundException;
use T3o\Ter\Exception\InternalServerErrorException;
......@@ -20,6 +21,7 @@ use T3o\Ter\Exception\UserNotFoundException;
use T3o\Ter\Exception\VersionExistsException;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
......@@ -232,8 +234,15 @@ class ExtensionKey
if ($this->hasUploadedVersions()) {
throw new VersionExistsException('Cannot delete an extension, versions still exist', ResultCodes::ERROR_DELETEEXTENSIONKEY_CANTDELETEBECAUSEVERSIONSEXIST);
}
$uid = $this->getUid();
$conn = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_terfe2_domain_model_extension');
$conn->delete('tx_terfe2_domain_model_extension', ['ext_key' => $this->extensionKey]);
// remove from index queue
if (ExtensionManagementUtility::isLoaded('solr')) {
$indexQueue = GeneralUtility::makeInstance(Queue::class);
$indexQueue->deleteItem('tx_terfe2_domain_model_extension', $uid);
}
}
public function hasUploadedVersions(): bool
......@@ -338,6 +347,67 @@ class ExtensionKey
return true;
}
/**
* Updates some integrity information of the extension. Used when a version is uploaded or removed.
*/
public function updateExtensionInformation()
{
$connection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_terfe2_domain_model_extension');
$connection->update(
'tx_terfe2_domain_model_extension',
[
'tstamp' => $GLOBALS['SIM_EXEC_TIME'],
'versions' => $this->getNumberOfVersions(),
'last_version', $this->getHighestVersion()
],
[
'ext_key' => $this->extensionKey
]
);
}
/**
* Gets the highest version number (UID) of the extension
*/
protected function getHighestVersion(): int
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder->getRestrictions()->removeAll();
$res = $queryBuilder
->select('uid', 'version_number')
->from('tx_terfe2_domain_model_version')
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('extension', $this->getUid())
)
->orderBy('version_number', 'DESC')
->setMaxResults(1)
->execute()
->fetch();
if (!empty($res)) {
return (int)$res['uid'];
}
return 0;
}
protected function getNumberOfVersions(): int
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder->getRestrictions()->removeAll();
return $queryBuilder
->count('uid')
->from('tx_terfe2_domain_model_version')
->where(
$queryBuilder->expr()->eq('extension', $this->getUid()),
$queryBuilder->expr()->eq('deleted', 0)
)
->execute()
->fetchColumn();
}
/**
* @todo: this method does not belong here, should be moved to a different location and return objects in the future
*
......
......@@ -275,6 +275,15 @@ class ExtensionVersion
@unlink($fullPathPrefix . $file);
}
}
// Reset the information about the current latest uploaded version of the extension
$this->extensionKey->updateExtensionInformation();
// remove from index queue, if there are no more versions
if (!$this->extensionKey->hasUploadedVersions() && ExtensionManagementUtility::isLoaded('solr')) {
$indexQueue = GeneralUtility::makeInstance(Queue::class);
$indexQueue->deleteItem('tx_terfe2_domain_model_extension', $this->extensionKey->getUid());
}
}
/**
......@@ -551,7 +560,7 @@ class ExtensionVersion
$this->addRelations($versionUid, $dependenciesArr);
}
$this->updateExtension($versionUid, $extUid);
$this->extensionKey->updateExtensionInformation();
// update the EXT:solr Index Queue
if (ExtensionManagementUtility::isLoaded('solr')) {
......@@ -628,47 +637,6 @@ class ExtensionVersion
}
}
/**
* @param int $versionUid
* @param int $extUid
*/
protected function updateExtension($versionUid, $extUid)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_terfe2_domain_model_extension');
$queryBuilder->getRestrictions()->removeAll();
$queryBuilder
->update('tx_terfe2_domain_model_extension')
->set('tstamp', $GLOBALS['SIM_EXEC_TIME'])
->set('versions', $this->getNumberOfVersions($extUid))
->set('last_version', $this->calculatedHighestVersion($versionUid, $extUid))
->where(
$queryBuilder->expr()->eq('ext_key', (string)$this->extensionKey)
)
->execute();
}
/**
* @param int $extUid
* @return int $numberOfVersions
*/
protected function getNumberOfVersions(int $extUid): int
{
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder->getRestrictions()->removeAll();
return $queryBuilder
->count('uid')
->from('tx_terfe2_domain_model_version')
->where(
$queryBuilder->expr()->eq('extension', $extUid),
$queryBuilder->expr()->eq('deleted', 0)
)
->execute()
->fetchColumn();
}
/**
* @param int $versionUid
* @param array $dependencies
......@@ -825,75 +793,4 @@ class ExtensionVersion
$maximum = (!empty($maximum) ? VersionNumberUtility::convertVersionNumberToInteger($maximum) : 0);
return [$minimum, $maximum];
}
/**
* Check which version is higher, so that we can se the right version in latest_version
*
* @param $versionUid
* @param $extUid
* @return int
*/
private function calculatedHighestVersion($versionUid, $extUid): int
{
$currentHighestVersion = $this->getHighestVersion($extUid);
if (empty($currentHighestVersion)) {
return $versionUid;
}
$newVersionNumber = $this->getVersionNumber($versionUid);
if ($newVersionNumber < $currentHighestVersion['version_number']) {
$versionUid = $currentHighestVersion['uid'];
}
return $versionUid;
}
/**
* Get the version number of the current version
*
* @param $versionUid
* @return int
*/
private function getVersionNumber($versionUid)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder->getRestrictions()->removeAll();
return (int)$queryBuilder
->select('version_number')
->from('tx_terfe2_domain_model_version')
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('uid', $versionUid)
)
->execute()
->fetchColumn();
}
/**
* Gets the highest version number
*
* @param $extUid
*
* @return array|false|null
*/
private function getHighestVersion($extUid): array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_terfe2_domain_model_version');
$queryBuilder->getRestrictions()->removeAll();
$res = $queryBuilder
->select('uid', 'version_number')
->from('tx_terfe2_domain_model_version')
->where(
$queryBuilder->expr()->eq('deleted', 0),
$queryBuilder->expr()->eq('extension', $extUid)
)
->orderBy('version_number', 'DESC')
->execute()
->fetch();
if (!empty($res)) {
return $res;
}
return [];
}
}
......@@ -15,7 +15,7 @@ namespace T3o\TerFe2\Controller;
*/
use ApacheSolrForTypo3\Solr\GarbageCollector;
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
use T3o\Ter\Api\ExtensionKey;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
......@@ -177,8 +177,6 @@ class RegisterkeyController extends \T3o\TerFe2\Controller\AbstractTerBasedContr
// Is it possible to assign the key to a new user
if ($this->terConnection->assignExtensionKey($extension->getExtKey(), $newUser, $error)) {
$extension->setFrontendUser($newUser);
$this->extensionRepository->update($extension);
$this->addFlashMessage($this->translate('registerkey.keyTransfered', [$extension->getExtKey(), $newUser]), '', \TYPO3\CMS\Core\Messaging\FlashMessage::OK);
} else {
$this->addFlashMessage(
......@@ -212,11 +210,9 @@ class RegisterkeyController extends \T3o\TerFe2\Controller\AbstractTerBasedContr
\TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
);
} elseif ((strtolower($extension->getFrontendUser()) == strtolower($GLOBALS['TSFE']->fe_user->user['username'])) || $this->securityRole->isAdmin()) {
// Deleted in ter, then delete the key in the ter_fe2 extension table
$extensionUid = $extension->getUid();
// Delete the version via API
if ($this->terConnection->deleteExtensionKey($extension->getExtKey())) {
$extensionUid = $extension->getUid();
$this->extensionRepository->remove($extension);
// ext:solr garbage collector
if (ExtensionManagementUtility::isLoaded('solr')) {
$garbageCollector = GeneralUtility::makeInstance(GarbageCollector::class);
......@@ -273,20 +269,8 @@ class RegisterkeyController extends \T3o\TerFe2\Controller\AbstractTerBasedContr
$this->redirect('index');
}
$redirectToIndexAction = false;
// Deleted in ter, then delete the version (and probably the extension) in the ter_fe2 extension table
// Deleted the version
if ($this->terConnection->deleteExtensionVersion($version->getExtension()->getExtKey(), $version->getVersionString())) {
$version->getExtension()->removeVersion($version);
$this->versionRepository->remove($version);
if (empty($version->getExtension()->getVersions())) {
$redirectToIndexAction = true;
// remove from index queue
if (ExtensionManagementUtility::isLoaded('solr')) {
$indexQueue = GeneralUtility::makeInstance(Queue::class);
$indexQueue->deleteItem('tx_terfe2_domain_model_extension', $version->getExtension()->getUid());
}
}
$this->addFlashMessage(
'',
$this->translate('registerkey.version_deleted', [$version->getVersionString(), $version->getExtension()->getExtKey()]),
......@@ -299,11 +283,7 @@ class RegisterkeyController extends \T3o\TerFe2\Controller\AbstractTerBasedContr
\TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
);
}
if ($redirectToIndexAction) {
$this->redirect('index', 'Registerkey', null);
} else {
$this->redirect('admin', 'Registerkey', null, ['extensionKey' => $version->getExtension()->getExtKey()]);
}
$this->redirect('admin', 'Registerkey', null, ['extensionKey' => $version->getExtension()->getExtKey()]);
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment