diff --git a/modules/system/classes/VersionManager.php b/modules/system/classes/VersionManager.php index 04a199d18..482fe40f4 100644 --- a/modules/system/classes/VersionManager.php +++ b/modules/system/classes/VersionManager.php @@ -94,6 +94,7 @@ class VersionManager } $newUpdates = $this->getNewFileVersions($code, $databaseVersion); + foreach ($newUpdates as $version => $details) { $this->applyPluginUpdate($code, $version, $details); @@ -125,14 +126,7 @@ class VersionManager */ protected function applyPluginUpdate($code, $version, $details) { - if (is_array($details)) { - $comment = array_shift($details); - $scripts = $details; - } - else { - $comment = $details; - $scripts = []; - } + list($comments, $scripts) = $this->extractScriptsAndComments($details); /* * Apply scripts, if any @@ -149,12 +143,14 @@ class VersionManager * Register the comment and update the version */ if (!$this->hasDatabaseHistory($code, $version)) { - $this->applyDatabaseComment($code, $version, $comment); + foreach ($comments as $comment) { + $this->applyDatabaseComment($code, $version, $comment); + + $this->note(sprintf('- v%s: %s', $version, $comment)); + } } $this->setDatabaseVersion($code, $version); - - $this->note(sprintf('- v%s: %s', $version, $comment)); } /** @@ -393,6 +389,7 @@ class VersionManager if (!File::isFile($updateFile)) { $this->note('- v' . $version . ': Migration file "' . $script . '" not found'); + return; } $this->updater->setUp($updateFile); @@ -524,4 +521,29 @@ class VersionManager return $this; } + + /** + * @param $details + * + * @return array + */ + protected function extractScriptsAndComments($details) + { + if (is_array($details)) { + $fileNamePattern = '/^[a-z_\-0-9]*\.php$/i'; + + $comments = array_values(array_filter($details, function ($detail) use ($fileNamePattern) { + return !preg_match($fileNamePattern, $detail); + })); + + $scripts = array_values(array_filter($details, function ($detail) use ($fileNamePattern) { + return preg_match($fileNamePattern, $detail); + })); + } else { + $comments = (array)$details; + $scripts = []; + } + + return array($comments, $scripts); +} } diff --git a/modules/system/controllers/Updates.php b/modules/system/controllers/Updates.php index 8f0aaf12f..9e32b990b 100644 --- a/modules/system/controllers/Updates.php +++ b/modules/system/controllers/Updates.php @@ -181,17 +181,27 @@ class Updates extends Controller $contents = []; try { - $updates = Yaml::parseFile($path.'/'.$filename); - $updates = is_array($updates) ? array_reverse($updates) : []; + $updates = (array) Yaml::parseFile($path.'/'.$filename); foreach ($updates as $version => $details) { - $contents[$version] = is_array($details) - ? array_shift($details) - : $details; + if (!is_array($details)) { + $details = (array)$details; + } + + //Filter out update scripts + $details = array_filter($details, function($string) use ($path) { + return !preg_match('/^[a-z_\-0-9]*\.php$/i', $string) || !File::exists($path . '/updates/' . $string); + }); + + $contents[$version] = $details; } } catch (Exception $ex) {} + uksort($contents, function ($a, $b) { + return version_compare($b, $a); + }); + return $contents; } diff --git a/modules/system/controllers/updates/details.htm b/modules/system/controllers/updates/details.htm index 96bf9f99e..9979edca0 100644 --- a/modules/system/controllers/updates/details.htm +++ b/modules/system/controllers/updates/details.htm @@ -76,10 +76,12 @@
- $comment): ?> -
-
- + $comments): ?> + $comment): ?> +
+
+ +

diff --git a/tests/TestCase.php b/tests/TestCase.php index a6928a163..ee25a6f42 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -19,4 +19,34 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase return $app; } + // + // Helpers + // + + protected static function callProtectedMethod($object, $name, $params = []) + { + $className = get_class($object); + $class = new ReflectionClass($className); + $method = $class->getMethod($name); + $method->setAccessible(true); + return $method->invokeArgs($object, $params); + } + + public static function getProtectedProperty($object, $name) + { + $className = get_class($object); + $class = new ReflectionClass($className); + $property = $class->getProperty($name); + $property->setAccessible(true); + return $property->getValue($object); + } + + public static function setProtectedProperty($object, $name, $value) + { + $className = get_class($object); + $class = new ReflectionClass($className); + $property = $class->getProperty($name); + $property->setAccessible(true); + return $property->setValue($object, $value); + } } diff --git a/tests/fixtures/plugins/october/tester/updates/create_blog_settings_table.php b/tests/fixtures/plugins/october/tester/updates/create_blog_settings_table.php new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/plugins/october/tester/updates/create_comments_table.php b/tests/fixtures/plugins/october/tester/updates/create_comments_table.php new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/plugins/october/tester/updates/version.yaml b/tests/fixtures/plugins/october/tester/updates/version.yaml index eff3993b2..7f9156ee8 100644 --- a/tests/fixtures/plugins/october/tester/updates/version.yaml +++ b/tests/fixtures/plugins/october/tester/updates/version.yaml @@ -1,12 +1,18 @@ +1.0.5: + - Create blog settings table + - Another update message + - Yet one more update message + - create_blog_settings_table.php +1.0.4: Another fix +1.0.3: Bug fix update that uses no scripts +1.0.2: + - Create blog post comments table + - Multiple update messages are allowed + - create_comments_table.php 1.0.1: - Added some upgrade file and some seeding - some_upgrade_file.php - some_seeding_file.php -1.0.2: - - Create blog post comments table - - create_comments_table.php -1.0.3: Bug fix update that uses no scripts -1.0.4: Another fix -1.0.5: - - Create blog settings table - - create_blog_settings_table.php \ No newline at end of file + + + diff --git a/tests/unit/backend/models/ExportModelTest.php b/tests/unit/backend/models/ExportModelTest.php index 38d73cfb7..367bc1e9d 100644 --- a/tests/unit/backend/models/ExportModelTest.php +++ b/tests/unit/backend/models/ExportModelTest.php @@ -26,19 +26,6 @@ class ExampleExportModel extends ExportModel class ExportModelTest extends TestCase { - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - // // Tests // diff --git a/tests/unit/backend/models/ImportModelTest.php b/tests/unit/backend/models/ImportModelTest.php index 401e3e67a..0512e82e9 100644 --- a/tests/unit/backend/models/ImportModelTest.php +++ b/tests/unit/backend/models/ImportModelTest.php @@ -17,19 +17,6 @@ class ExampleImportModel extends ImportModel class ImportModelTest extends TestCase { - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - // // Tests // diff --git a/tests/unit/cms/classes/CmsExceptionTest.php b/tests/unit/cms/classes/CmsExceptionTest.php index 81d0bf636..fbe493b98 100644 --- a/tests/unit/cms/classes/CmsExceptionTest.php +++ b/tests/unit/cms/classes/CmsExceptionTest.php @@ -11,37 +11,6 @@ use October\Rain\Exception\SystemException; class CmsExceptionTest extends TestCase { - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - - public static function getProtectedProperty($object, $name) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->getValue($object); - } - - public static function setProtectedProperty($object, $name, $value) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->setValue($object, $value); - } - // // Tests // diff --git a/tests/unit/system/classes/CombineAssetsTest.php b/tests/unit/system/classes/CombineAssetsTest.php index 68e7de01b..60e639c94 100644 --- a/tests/unit/system/classes/CombineAssetsTest.php +++ b/tests/unit/system/classes/CombineAssetsTest.php @@ -12,37 +12,6 @@ class CombineAssetsTest extends TestCase CombineAssets::resetCache(); } - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - - public static function getProtectedProperty($object, $name) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->getValue($object); - } - - public static function setProtectedProperty($object, $name, $value) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->setValue($object, $value); - } - // // Tests // diff --git a/tests/unit/system/classes/MarkupManagerTest.php b/tests/unit/system/classes/MarkupManagerTest.php index 373d9a43a..405c933d8 100644 --- a/tests/unit/system/classes/MarkupManagerTest.php +++ b/tests/unit/system/classes/MarkupManagerTest.php @@ -12,37 +12,6 @@ class MarkupManagerTest extends TestCase include_once base_path().'/tests/fixtures/plugins/october/tester/Plugin.php'; } - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - - public static function getProtectedProperty($object, $name) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->getValue($object); - } - - public static function setProtectedProperty($object, $name, $value) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->setValue($object, $value); - } - // // Tests // diff --git a/tests/unit/system/classes/PluginManagerTest.php b/tests/unit/system/classes/PluginManagerTest.php index 7b472d583..1271fc247 100644 --- a/tests/unit/system/classes/PluginManagerTest.php +++ b/tests/unit/system/classes/PluginManagerTest.php @@ -12,37 +12,6 @@ class PluginManagerTest extends TestCase include_once base_path().'/tests/fixtures/plugins/october/tester/Plugin.php'; } - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - - public static function getProtectedProperty($object, $name) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->getValue($object); - } - - public static function setProtectedProperty($object, $name, $value) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->setValue($object, $value); - } - // // Tests // diff --git a/tests/unit/system/classes/UpdatesControllerTest.php b/tests/unit/system/classes/UpdatesControllerTest.php new file mode 100644 index 000000000..6535f37e3 --- /dev/null +++ b/tests/unit/system/classes/UpdatesControllerTest.php @@ -0,0 +1,51 @@ +getMockBuilder(Updates::class)->disableOriginalConstructor()->getMock(); + + $expectedVersions = [ + '1.0.5' => [ + 'Create blog settings table', + 'Another update message', + 'Yet one more update message' + ], + '1.0.4' => [ + 'Another fix' + ], + '1.0.3' => [ + 'Bug fix update that uses no scripts' + ], + '1.0.2' => [ + 'Create blog post comments table', + 'Multiple update messages are allowed' + ], + '1.0.1' => [ + 'Added some upgrade file and some seeding', + 'some_upgrade_file.php', //does not exist + 'some_seeding_file.php' //does not exist + ] + ]; + + $versions = self::callProtectedMethod( + $controller, + 'getPluginVersionFile', + [ + base_path().'/tests/fixtures/plugins/october/tester/', + 'updates/version.yaml' + ] + ); + + $this->assertNotNull($versions); + $this->assertEquals($expectedVersions, $versions); + } +} diff --git a/tests/unit/system/classes/VersionManagerTest.php b/tests/unit/system/classes/VersionManagerTest.php index 3345a9cca..6311d1619 100644 --- a/tests/unit/system/classes/VersionManagerTest.php +++ b/tests/unit/system/classes/VersionManagerTest.php @@ -14,37 +14,6 @@ class VersionManagerTest extends TestCase include_once base_path().'/tests/fixtures/plugins/october/noupdates/Plugin.php'; } - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - - public static function getProtectedProperty($object, $name) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->getValue($object); - } - - public static function setProtectedProperty($object, $name, $value) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $property = $class->getProperty($name); - $property->setAccessible(true); - return $property->setValue($object, $value); - } - // // Tests // @@ -119,4 +88,89 @@ class VersionManagerTest extends TestCase $this->assertArrayHasKey('1.0.5', $result); } + /** + * @dataProvider versionInfoProvider + * + * @param $versionInfo + * @param $expectedComments + * @param $expectedScripts + */ + public function testExtractScriptsAndComments($versionInfo, $expectedComments, $expectedScripts) + { + $manager = VersionManager::instance(); + list($comments, $scripts) = self::callProtectedMethod($manager, 'extractScriptsAndComments', [$versionInfo]); + + $this->assertInternalType('array', $comments); + $this->assertInternalType('array', $scripts); + + $this->assertEquals($expectedComments, $comments); + $this->assertEquals($expectedScripts, $scripts); + } + + public function versionInfoProvider() + { + return [ + [ + 'A single update comment string', + [ + 'A single update comment string' + ], + [] + ], + [ + [ + 'A classic update comment string followed by script', + 'update_script.php' + ], + [ + 'A classic update comment string followed by script' + ], + [ + 'update_script.php' + ] + ], + [ + [ + 'scripts_can_go_first.php', + 'An update comment string after the script', + ], + [ + 'An update comment string after the script' + ], + [ + 'scripts_can_go_first.php' + ] + ], + [ + [ + 'scripts_can_go_first.php', + 'An update comment string after the script', + 'scripts_can_go_anywhere.php', + ], + [ + 'An update comment string after the script' + ], + [ + 'scripts_can_go_first.php', + 'scripts_can_go_anywhere.php' + ] + ], + [ + [ + 'scripts_can_go_first.php', + 'The first update comment', + 'scripts_can_go_anywhere.php', + 'The second update comment', + ], + [ + 'The first update comment', + 'The second update comment' + ], + [ + 'scripts_can_go_first.php', + 'scripts_can_go_anywhere.php' + ] + ] + ]; + } } diff --git a/tests/unit/system/traits/AssetMakerTest.php b/tests/unit/system/traits/AssetMakerTest.php index 2d247dcf3..352d66107 100644 --- a/tests/unit/system/traits/AssetMakerTest.php +++ b/tests/unit/system/traits/AssetMakerTest.php @@ -16,19 +16,6 @@ class AssetMakerTest extends TestCase $this->stub = new AssetMakerStub(); } - // - // Helpers - // - - protected static function callProtectedMethod($object, $name, $params = []) - { - $className = get_class($object); - $class = new ReflectionClass($className); - $method = $class->getMethod($name); - $method->setAccessible(true); - return $method->invokeArgs($object, $params); - } - // // Tests //