Skip to content

Commit

Permalink
Merge forwardport of #11064 to 2.3-develop branch
Browse files Browse the repository at this point in the history
Applied pull request patch https://github.com/magento/magento2/pull/11064.patch (created by @schmengler) based on commit(s):
  1. c3ea1f5
  2. 0c0393d
  3. 008bb5a

Fixed GitHub Issues in 2.3-develop branch:
  - #9008: Error Message Is Confusing When Code Base Is Behind Database Module Version (reported by @mpchadwick)
  - #9981: M2 suggests running setup:upgrade if version number of module is higher than expected (reported by @chickenland)
  • Loading branch information
magento-engcom-team authored Feb 5, 2018
2 parents 4ada797 + 46be4c7 commit c5d9a01
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 27 deletions.
63 changes: 58 additions & 5 deletions lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,22 @@ public function __construct(FrontendCacheInterface $cache, DbVersionInfo $dbVers
public function beforeDispatch(FrontController $subject, RequestInterface $request)
{
if (!$this->cache->load('db_is_up_to_date')) {
$errors = $this->dbVersionInfo->getDbVersionErrors();

if ($errors) {
list($versionTooLowErrors, $versionTooHighErrors) = array_values($this->getGroupedDbVersionErrors());
if ($versionTooHighErrors) {
$message = 'Please update your modules: '
. "Run \"composer install\" from the Magento root directory.\n"
. "The following modules are outdated:\n%1";
throw new LocalizedException(
new Phrase($message, [implode("\n", $this->formatVersionTooHighErrors($versionTooHighErrors))])
);
} elseif ($versionTooLowErrors) {
$message = 'Please upgrade your database: '
. "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n"
. "The following modules are outdated:\n%1";

throw new LocalizedException(new Phrase($message, [implode("\n", $this->formatErrors($errors))]));
throw new LocalizedException(
new Phrase($message, [implode("\n", $this->formatVersionTooLowErrors($versionTooLowErrors))])
);
} else {
$this->cache->save('true', 'db_is_up_to_date');
}
Expand All @@ -70,7 +78,7 @@ public function beforeDispatch(FrontController $subject, RequestInterface $reque
* @param array $errorsData array of error data from getOutOfDateDbErrors
* @return array Messages that can be used to log the error
*/
private function formatErrors($errorsData)
private function formatVersionTooLowErrors($errorsData)
{
$formattedErrors = [];

Expand All @@ -82,4 +90,49 @@ private function formatErrors($errorsData)

return $formattedErrors;
}

/**
* Format each error in the error data from getOutOfDataDbErrors into a single message
*
* @param array $errorsData array of error data from getOutOfDateDbErrors
* @return array Messages that can be used to log the error
*/
private function formatVersionTooHighErrors($errorsData)
{
$formattedErrors = [];
foreach ($errorsData as $error) {
$formattedErrors[] = $error[DbVersionInfo::KEY_MODULE] . ' ' . $error[DbVersionInfo::KEY_TYPE]
. ': code version - ' . $error[DbVersionInfo::KEY_REQUIRED]
. ', database version - ' . $error[DbVersionInfo::KEY_CURRENT];
}

return $formattedErrors;
}

/**
* Return DB version errors grouped by 'version_too_low' and 'version_too_high'
*
* @return mixed
*/
private function getGroupedDbVersionErrors()
{
$allDbVersionErrors = $this->dbVersionInfo->getDbVersionErrors();
return array_reduce(
(array)$allDbVersionErrors,
function ($carry, $item) {
if ($item[DbVersionInfo::KEY_CURRENT] === 'none'
|| $item[DbVersionInfo::KEY_CURRENT] < $item[DbVersionInfo::KEY_REQUIRED]
) {
$carry['version_too_low'][] = $item;
} else {
$carry['version_too_high'][] = $item;
}
return $carry;
},
[
'version_too_low' => [],
'version_too_high' => [],
]
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,28 +99,11 @@ public function testBeforeDispatchOutOfDateNoErrors()
$this->plugin->beforeDispatch($this->frontControllerMock, $this->requestMock);
}

public function testBeforeDispatchOutOfDateWithErrors()
/**
* @dataProvider beforeDispatchOutOfDateWithErrorsDataProvider
*/
public function testBeforeDispatchOutOfDateWithErrors(array $errors, string $expectedMessage)
{
$errors = [
[
DbVersionInfo::KEY_MODULE => 'Magento_Module1',
DbVersionInfo::KEY_TYPE => 'schema',
DbVersionInfo::KEY_CURRENT => '3.3.3',
DbVersionInfo::KEY_REQUIRED => '4.4.4'
],
[
DbVersionInfo::KEY_MODULE => 'Magento_Module2',
DbVersionInfo::KEY_TYPE => 'data',
DbVersionInfo::KEY_CURRENT => '2.8.7',
DbVersionInfo::KEY_REQUIRED => '5.1.6'
]
];
$message = 'Please upgrade your database: '
. "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n"
. "The following modules are outdated:\n"
. "Magento_Module1 schema: current version - 3.3.3, required version - 4.4.4\n"
. "Magento_Module2 data: current version - 2.8.7, required version - 5.1.6";

$this->cacheMock->expects(static::any())
->method('load')
->with('db_is_up_to_date')
Expand All @@ -131,7 +114,76 @@ public function testBeforeDispatchOutOfDateWithErrors()
$this->cacheMock->expects(static::never())
->method('save');

$this->expectException(LocalizedException::class, $message);
$this->expectException(LocalizedException::class, $expectedMessage);
$this->expectExceptionMessage($expectedMessage);
$this->plugin->beforeDispatch($this->frontControllerMock, $this->requestMock);
}

public static function beforeDispatchOutOfDateWithErrorsDataProvider()
{
return [
'module versions too low' => [
'errors' => [
[
DbVersionInfo::KEY_MODULE => 'Magento_Module1',
DbVersionInfo::KEY_TYPE => 'schema',
DbVersionInfo::KEY_CURRENT => 'none',
DbVersionInfo::KEY_REQUIRED => '4.4.4'
],
[
DbVersionInfo::KEY_MODULE => 'Magento_Module2',
DbVersionInfo::KEY_TYPE => 'data',
DbVersionInfo::KEY_CURRENT => '2.8.7',
DbVersionInfo::KEY_REQUIRED => '5.1.6'
],
],
'expectedMessage' => 'Please upgrade your database: '
. "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n"
. "The following modules are outdated:\n"
. "Magento_Module1 schema: current version - none, required version - 4.4.4\n"
. "Magento_Module2 data: current version - 2.8.7, required version - 5.1.6"
],
'module versions too high' => [
'errors' => [
[
DbVersionInfo::KEY_MODULE => 'Magento_Module3',
DbVersionInfo::KEY_TYPE => 'schema',
DbVersionInfo::KEY_CURRENT => '2.0.0',
DbVersionInfo::KEY_REQUIRED => '1.0.0'
],
[
DbVersionInfo::KEY_MODULE => 'Magento_Module4',
DbVersionInfo::KEY_TYPE => 'data',
DbVersionInfo::KEY_CURRENT => '1.0.1',
DbVersionInfo::KEY_REQUIRED => '1.0.0'
],
],
'expectedMessage' => "Please update your modules: "
. "Run \"composer install\" from the Magento root directory.\n"
. "The following modules are outdated:\n"
. "Magento_Module3 schema: code version - 1.0.0, database version - 2.0.0\n"
. "Magento_Module4 data: code version - 1.0.0, database version - 1.0.1",
],
'some versions too high, some too low' => [
'errors' => [
[
DbVersionInfo::KEY_MODULE => 'Magento_Module1',
DbVersionInfo::KEY_TYPE => 'schema',
DbVersionInfo::KEY_CURRENT => '2.0.0',
DbVersionInfo::KEY_REQUIRED => '1.0.0'
],
[
DbVersionInfo::KEY_MODULE => 'Magento_Module2',
DbVersionInfo::KEY_TYPE => 'schema',
DbVersionInfo::KEY_CURRENT => '1.0.0',
DbVersionInfo::KEY_REQUIRED => '2.0.0'
],
],
'expectedMessage' => "Please update your modules: "
. "Run \"composer install\" from the Magento root directory.\n"
. "The following modules are outdated:\n"
. "Magento_Module1 schema: code version - 1.0.0, database version - 2.0.0"
]
];
}
}

0 comments on commit c5d9a01

Please sign in to comment.