Commit 3bd919c8 authored by Helmut Hummel's avatar Helmut Hummel Committed by Thomas Löffler

Improve consistency and usability for composer name handling

Issue validation error when given composer name does not match
the one in latest version.

Remove composer name on import, when persisted composer name does not match
the one in uploaded version.

Simplify eID again, as we can now rely on composer_name in extension table
being correct.
parent f0cb84eb
......@@ -65,17 +65,11 @@ class ExtensionController
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_terfe2_domain_model_extension');
$expr = $queryBuilder->expr();
$result = $queryBuilder->select('tx_terfe2_domain_model_extension.composer_name', 'tx_terfe2_domain_model_version.composer_info')
$result = $queryBuilder->select(
'tx_terfe2_domain_model_extension.ext_key',
'tx_terfe2_domain_model_extension.composer_name'
)
->from('tx_terfe2_domain_model_extension')
->join(
'tx_terfe2_domain_model_extension',
'tx_terfe2_domain_model_version',
'tx_terfe2_domain_model_version',
$expr->eq(
'tx_terfe2_domain_model_extension.last_version',
'tx_terfe2_domain_model_version.uid'
)
)
->where(
$expr->neq(
'tx_terfe2_domain_model_extension.composer_name',
......@@ -85,10 +79,6 @@ class ExtensionController
->execute();
while ($extension = $result->fetch()) {
$latestVersionComposerInfo = @json_decode($extension['composer_info'], true);
if (empty($latestVersionComposerInfo['name']) || $latestVersionComposerInfo['name'] !== $extension['composer_name']) {
continue;
}
$this->jsonArray['data'][$extension['ext_key']] = array(
'composer_name' => $extension['composer_name'],
);
......
......@@ -15,7 +15,6 @@ namespace T3o\TerFe2\Controller;
*/
use T3o\TerFe2\Validation\Validator\ComposerNameValidator;
use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;
/**
* Controller for the extension object
......@@ -255,6 +254,9 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
* @param \T3o\TerFe2\Domain\Model\Extension $extension extension to update
* @param string $tag
* @param string $save
*
* @validate $extension \T3o\TerFe2\Validation\Validator\ExtensionArgumentValidator
*
* @return void
*/
public function updateAction(\T3o\TerFe2\Domain\Model\Extension $extension, $tag = '', $save = '')
......@@ -295,7 +297,6 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
$this->addFlashMessage('Tag "' . htmlspecialchars($tag) . '" added to extension');
}
}
$extension->setComposerName($extension->getValidatedComposerName());
$this->extensionRepository->update($extension);
if (!empty($save)) {
$this->redirectWithMessage(
......
......@@ -586,17 +586,6 @@ class Extension extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
return $this->composerName;
}
/**
* @return string
*/
public function getValidatedComposerName()
{
if (empty($this->composerName) || $this->lastVersion === null) {
return '';
}
return $this->composerName === $this->lastVersion->getComposerName() ? $this->composerName : '';
}
/**
* @param string $composerName
*/
......
......@@ -104,7 +104,7 @@ class TerIndexer extends \ApacheSolrForTypo3\Solr\IndexQueue\Indexer
// composer support
$document->setField('supportsComposer_boolS', false);
$document->setField('composerName_stringS', '');
if ($extension->getValidatedComposerName()) {
if ($extension->getComposerName()) {
$document->setField('supportsComposer_boolS', true);
$document->setField('composerName_stringS', $extension->getLastVersion()->getComposerName());
}
......
......@@ -324,6 +324,8 @@ class ImportExtensionsFromQueueTask extends Task
'composer_info' => $extData['composerinfo']
];
$this->ensureValidComposerNameInExtension($extUid, $extData['composerinfo']);
$tableName = 'tx_terfe2_domain_model_version';
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
......@@ -333,6 +335,37 @@ class ImportExtensionsFromQueueTask extends Task
return $connectionPool->getConnectionForTable($tableName)->lastInsertId($tableName);
}
private function ensureValidComposerNameInExtension(int $extUid, string $composerInfoJson)
{
$composerInfo = @\json_decode($composerInfoJson, true);
if (empty($composerInfo['name'])) {
return;
}
$tableName = 'tx_terfe2_domain_model_extension';
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
$persistedComposerName = $queryBuilder->select('composer_name')
->from($tableName)
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($extUid, \PDO::PARAM_INT))
)
->execute()
->fetchColumn();
if (empty($persistedComposerName) || $persistedComposerName === $composerInfo['name']) {
return;
}
$queryBuilder = $connectionPool->getQueryBuilderForTable($tableName);
$queryBuilder->update($tableName)
->set('composer_name', '')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($extUid, \PDO::PARAM_INT))
)
->execute();
}
/**
* @param int $versionUid
* @param int $extUid
......
......@@ -14,9 +14,6 @@ namespace T3o\TerFe2\Validation\Validator;
* The TYPO3 project - inspiring people to share!
*/
use GuzzleHttp\Exception\RequestException;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
/**
......@@ -48,10 +45,6 @@ class ComposerNameValidator extends AbstractValidator
$this->addError('This composer name is not valid.', 1527501477);
return false;
}
if (!$this->isRegisteredOnPackagist($value)) {
$this->addError('This composer name is not registered on packagist.org.', 1527500413);
return false;
}
return true;
}
......@@ -67,22 +60,4 @@ class ComposerNameValidator extends AbstractValidator
return $cleanedComposerName === $composerName;
}
private function isRegisteredOnPackagist(string $composerName): bool
{
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
try {
$response = $requestFactory->request(
'https://packagist.org/packages/' . $composerName,
'HEAD',
[
'connect_timeout' => 2,
'allow_redirects' => false,
]
);
return $response->getStatusCode() === 200;
} catch (RequestException $e) {
return false;
}
}
}
<?php
namespace T3o\TerFe2\Validation\Validator;
/*
* This file is part of the TYPO3 CMS project.
*
* 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 GuzzleHttp\Exception\RequestException;
use T3o\TerFe2\Domain\Model\Extension;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
/**
* Validator for composer name on packagist.org
*/
class ExtensionArgumentValidator extends AbstractValidator
{
/**
* Returns false, if given composer name is not registered on packagist.org
*
* @param mixed $value The value that should be validated
* @return boolean TRUE if the value is valid, FALSE if an error occured
*/
public function isValid($value)
{
if (!$value instanceof Extension) {
$this->addError('This argument is not of type Extension.', 1527537602);
return false;
}
if (empty($value->getComposerName())) {
return true;
}
if (!$this->composerNameMatchesComposerNameInLatestVersion($value)) {
$this->addError('This composer name does not match composer name in last version of uploaded extension.', 1527538363);
return false;
}
if (!$this->isRegisteredOnPackagist($value->getComposerName())) {
$this->addError('This composer name is not registered on packagist.org.', 1527500413);
return false;
}
return true;
}
private function composerNameMatchesComposerNameInLatestVersion(Extension $extension)
{
return $extension->getLastVersion() !== null && $extension->getComposerName() === $extension->getLastVersion()->getComposerName();
}
private function isRegisteredOnPackagist(string $composerName): bool
{
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
try {
$response = $requestFactory->request(
'https://packagist.org/packages/' . $composerName,
'HEAD',
[
'connect_timeout' => 2,
'allow_redirects' => false,
]
);
return $response->getStatusCode() === 200;
} catch (RequestException $e) {
return false;
}
}
}
......@@ -18,7 +18,7 @@
<f:translate key="tx_terfe2_domain_model_extension.packagist_confirm" />
</label>
<div class="col-9">
<f:form.checkbox id="packagistConfirm" name="packagistConfirm" value="1" checked="{f:if(condition: '{extension.validatedComposerName}', then: '1', else: '0')}" />
<f:form.checkbox id="packagistConfirm" name="packagistConfirm" value="1" checked="{f:if(condition: '{extension.composerName}', then: '1', else: '0')}" />
&nbsp;<f:translate key="tx_terfe2_domain_model_extension.packagist_confirm_message" />
</div>
</div>
......@@ -27,7 +27,7 @@
<f:translate key="tx_terfe2_domain_model_extension.composer_name" />
</label>
<div class="col-9">
<f:form.textfield class="form-control" id="composerName" property="composerName" value="{extension.validatedComposerName}" additionalAttributes="{placeholder:'{extension.lastVersion.composerName}'}" />
<f:form.textfield class="form-control" id="composerName" property="composerName" value="{extension.composerName}" additionalAttributes="{placeholder:'{extension.lastVersion.composerName}'}" />
</div>
</div>
</f:if>
......
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