diff --git a/plugins/baser-core/src/BaserCorePlugin.php b/plugins/baser-core/src/BaserCorePlugin.php index 9421950842..96ee5378b2 100644 --- a/plugins/baser-core/src/BaserCorePlugin.php +++ b/plugins/baser-core/src/BaserCorePlugin.php @@ -636,7 +636,6 @@ public function console(CommandCollection $commands): CommandCollection { $commands->add('setup test', SetupTestCommand::class); $commands->add('composer', ComposerCommand::class); - $commands->add('update', UpdateCommand::class); $commands->add('create release', CreateReleaseCommand::class); $commands->add('setup install', SetupInstallCommand::class); return $commands; diff --git a/plugins/baser-core/src/Command/UpdateCommand.php b/plugins/baser-core/src/Command/UpdateCommand.php deleted file mode 100644 index 2d7dd34c1d..0000000000 --- a/plugins/baser-core/src/Command/UpdateCommand.php +++ /dev/null @@ -1,75 +0,0 @@ - - * Copyright (c) NPO baser foundation - * - * @copyright Copyright (c) NPO baser foundation - * @link https://basercms.net baserCMS Project - * @since 5.0.0 - * @license https://basercms.net/license/index.html MIT License - */ - -namespace BaserCore\Command; - -use BaserCore\Service\PluginsServiceInterface; -use BaserCore\Utility\BcContainerTrait; -use Cake\Command\Command; -use Cake\Console\Arguments; -use Cake\Console\ConsoleIo; -use Psr\Log\LogLevel; -use BaserCore\Annotation\UnitTest; -use BaserCore\Annotation\NoTodo; -use BaserCore\Annotation\Checked; - -/** - * UpdateCommand - */ -class UpdateCommand extends Command -{ - - /** - * Trait - */ - use BcContainerTrait; - - /** - * buildOptionParser - * - * @param \Cake\Console\ConsoleOptionParser $parser - * @return \Cake\Console\ConsoleOptionParser - * @checked - * @noTodo - */ - protected function buildOptionParser(\Cake\Console\ConsoleOptionParser $parser): \Cake\Console\ConsoleOptionParser - { - $parser->addOption('connection', [ - 'help' => __d('baser_core', 'データベース接続名'), - 'default' => 'default' - ]); - return $parser; - } - - /** - * execute - * - * @param Arguments $args - * @param ConsoleIo $io - * @return int|void|null - * @checked - * @noTodo - */ - public function execute(Arguments $args, ConsoleIo $io) - { - $connection = $args->getOption('connection'); - $pluginsService = $this->getService(PluginsServiceInterface::class); - if($pluginsService->update('BaserCore', $connection)) { - $io->out(__d('baser_core', 'Migration と アップデーターによるアップデートが完了しました。')); - } else { - $message = __d('baser_core', 'Migration と アップデーターによるアップデートが失敗しました。'); - $this->log($message, LogLevel::ERROR, 'update'); - $io->out($message); - exit(1); - } - } - -} diff --git a/plugins/baser-core/src/Controller/Admin/PluginsController.php b/plugins/baser-core/src/Controller/Admin/PluginsController.php index 6f33781ddc..34d72c7154 100644 --- a/plugins/baser-core/src/Controller/Admin/PluginsController.php +++ b/plugins/baser-core/src/Controller/Admin/PluginsController.php @@ -107,7 +107,7 @@ public function install(PluginsAdminServiceInterface $service, string $name) /** * アップデート実行 - * @param PluginsService $service + * @param PluginsAdminServiceInterface|PluginsAdminService $service * @param string $name * @return void|Response * @checked @@ -116,7 +116,6 @@ public function install(PluginsAdminServiceInterface $service, string $name) */ public function update(PluginsAdminServiceInterface $service, $name = '') { - BcUtil::clearAllCache(); $plugin = $this->Plugins->getPluginConfig($name); $this->set($service->getViewVarsForUpdate($plugin)); @@ -138,31 +137,60 @@ public function update(PluginsAdminServiceInterface $service, $name = '') if (!$this->request->is(['put', 'post'])) return; try { - if($plugin->name === 'BaserCore') { - $request = $this->getRequest(); - $service->updateCore( - $request->getData('currentVersion'), - $request->getData('targetVersion'), - $request->getData('php'), - $request->getData('connection') ?? 'default' - ); - $this->BcMessage->setInfo(__d('baser_core', '全てのアップデート処理が完了しました。 {0} にログを出力しています。', LOGS . 'update.log')); - return $this->redirect(['action' => 'update']); - } else { - $service->update($plugin->name, $this->request->getData('connection') ?? 'default'); + if($service->update($plugin->name, $this->request->getData('connection') ?? 'default')) { $this->BcMessage->setInfo(__d('baser_core', 'アップデート処理が完了しました。画面下部のアップデートログを確認してください。')); - return $this->redirect(['action' => 'update', $name]); + } else { + $this->BcMessage->setError(__d('baser_core', 'アップデート処理に失敗しました。画面下部のアップデートログを確認してください。')); } } catch (\Throwable $e) { - $this->BcMessage->setError($e->getMessage()); + $this->BcMessage->setError(__d('baser_core', 'アップデート処理に失敗しました。画面下部のアップデートログを確認してください。') . $e->getMessage()); if($plugin->name === 'BaserCore') { - return $this->redirect(['action' => 'update']); - } else { - return $this->redirect(['action' => 'update', $name]); + $request = $this->getRequest(); + try { + $service->rollbackCore( + $request->getData('currentVersion'), + $request->getData('php'), + ); + $this->BcMessage->setError(__d('baser_core', 'コアファイルを元に戻しました。')); + } catch (\Throwable $e) { + $this->BcMessage->setError($e->getMessage()); + } } } + if($plugin->name === 'BaserCore') { + return $this->redirect(['action' => 'update']); + } else { + return $this->redirect(['action' => 'update', $name]); + } } + /** + * コアアップデートを取得する + * @param PluginsAdminServiceInterface $service + * @return Response|null + * @checked + * @noTodo + * @unitTest + */ + public function get_core_update(PluginsAdminServiceInterface $service) + { + if (!$this->request->is(['put', 'post'])) { + $this->BcMessage->setError(__d('baser_core', '無効な処理です。')); + return $this->redirect(['action' => 'update']); + } + $request = $this->getRequest(); + try { + $service->getCoreUpdate( + $request->getData('targetVersion')?? '', + $request->getData('php')?? 'php', + ); + } catch (\Throwable $e) { + $this->BcMessage->setError($e->getMessage()); + } + $this->BcMessage->setSuccess(__d('baser_core', '最新版のダウンロードが完了しました。アップデートを実行してください。')); + return $this->redirect(['action' => 'update']); + } + /** * 無効化 * diff --git a/plugins/baser-core/src/Controller/Api/Admin/PluginsController.php b/plugins/baser-core/src/Controller/Api/Admin/PluginsController.php index a281ede698..220981b873 100644 --- a/plugins/baser-core/src/Controller/Api/Admin/PluginsController.php +++ b/plugins/baser-core/src/Controller/Api/Admin/PluginsController.php @@ -378,4 +378,28 @@ public function get_available_core_version_info(PluginsServiceInterface $service $this->viewBuilder()->setOption('serialize', ['availableCoreVersionInfo']); } + /** + * コアファイルの最新版を反映する + * + * @param PluginsServiceInterface $service + * @checked + * @noTodo + * @unitTest + */ + public function update_core_files(PluginsServiceInterface $service) + { + $this->request->allowMethod(['post', 'put']); + try { + $service->updateCoreFiles(); + $message = __d('baser_core', 'コアファイルの最新版への更新が完了しました。'); + } catch (\Throwable $e) { + $message = __d('baser_core', 'コアファイルの最新版への更新中にエラーが発生しました。' . $e->getMessage()); + $this->setResponse($this->response->withStatus(500)); + } + $this->set([ + 'message' => $message + ]); + $this->viewBuilder()->setOption('serialize', ['message']); + } + } diff --git a/plugins/baser-core/src/Service/Admin/PluginsAdminService.php b/plugins/baser-core/src/Service/Admin/PluginsAdminService.php index a349a5ea3f..f07c1ecf0f 100644 --- a/plugins/baser-core/src/Service/Admin/PluginsAdminService.php +++ b/plugins/baser-core/src/Service/Admin/PluginsAdminService.php @@ -13,6 +13,7 @@ use BaserCore\Service\PluginsService; use BaserCore\Utility\BcUtil; +use Cake\Cache\Cache; use Cake\Core\Configure; use Cake\Core\Plugin as CakePlugin; use Cake\Datasource\EntityInterface; @@ -60,15 +61,15 @@ public function getViewVarsForUpdate(EntityInterface $entity): array $dbVersion = BcUtil::getDbVersion($entity->name); BcUtil::includePluginClass($entity->name); $plugin = CakePlugin::getCollection()->create($entity->name); - $scriptNum = count($plugin->getUpdaters()); - $scriptMessages = $plugin->getUpdateScriptMessages(); + $scriptNum = count($plugin->getUpdaters('', true)); + $scriptMessages = $plugin->getUpdateScriptMessages('', true); if ($entity->name === 'BaserCore') { $availableVersion = $this->getAvailableCoreVersion(); $corePlugins = Configure::read('BcApp.corePlugins'); foreach($corePlugins as $corePlugin) { - $scriptNum += count($plugin->getUpdaters($corePlugin)); - $scriptMessages += $plugin->getUpdateScriptMessages($corePlugin); + $scriptNum += count($plugin->getUpdaters($corePlugin, true)); + $scriptMessages += $plugin->getUpdateScriptMessages($corePlugin, true); } } else { $availableVersion = null; @@ -94,9 +95,9 @@ public function getViewVarsForUpdate(EntityInterface $entity): array 'requireUpdate' => $this->isRequireUpdate( $programVersion, $dbVersion, - $availableVersion, - $scriptNum + $availableVersion ), + 'coreDownloaded' => Cache::read('coreDownloaded', '_bc_update_'), 'php' => $this->whichPhp(), 'isWritableVendor' => $isWritableVendor, 'isWritableComposerJson' => $isWritableComposerJson, @@ -120,7 +121,7 @@ public function whichPhp() /** * アップデートが必要がどうか - * + * DBのバージョンと利用可能なバージョンが違う場合に必要とする * @param string $programVersion * @param string $dbVersion * @param string $availableVersion @@ -129,7 +130,7 @@ public function whichPhp() * @checked * @noTodo */ - public function isRequireUpdate(string $programVersion, ?string $dbVersion, ?string $availableVersion, $scriptNum) + public function isRequireUpdate(string $programVersion, ?string $dbVersion, ?string $availableVersion) { $programVerPoint = BcUtil::verpoint($programVersion); $dbVerPoint = BcUtil::verpoint($dbVersion); @@ -140,14 +141,16 @@ public function isRequireUpdate(string $programVersion, ?string $dbVersion, ?str if ($programVerPoint === false || $dbVerPoint === false || $availableVerPoint === false) { return false; } - if ($availableVerPoint !== true) { - if ($availableVersion !== $programVersion) return true; - } - if ($programVersion !== $dbVersion || $scriptNum) { - return true; + + if(is_null($availableVersion)) { + // プラグインの場合 プログラムのバージョンを利用可能なバージョンとする + $availableVersion = $programVersion; } else { - return false; + // コアの場合は、プログラムのバージョンとDBのバージョンが違う場合はアップデート不可 + if ($programVersion !== $dbVersion) return false; } + if ($availableVersion !== $dbVersion) return true; + return false; } /** diff --git a/plugins/baser-core/src/Service/Admin/PluginsAdminServiceInterface.php b/plugins/baser-core/src/Service/Admin/PluginsAdminServiceInterface.php index 32dc967836..a1e68642ea 100644 --- a/plugins/baser-core/src/Service/Admin/PluginsAdminServiceInterface.php +++ b/plugins/baser-core/src/Service/Admin/PluginsAdminServiceInterface.php @@ -31,6 +31,6 @@ public function getViewVarsForInstall(EntityInterface $plugin): array; * @param EntityInterface $plugin * @return array */ - public function getViewVarsForUpdate(EntityInterface $plugin): array; + public function getViewVarsForUpdate(EntityInterface $entity): array; } diff --git a/plugins/baser-core/src/Service/PluginsService.php b/plugins/baser-core/src/Service/PluginsService.php index 80a97fd111..cd183642e3 100644 --- a/plugins/baser-core/src/Service/PluginsService.php +++ b/plugins/baser-core/src/Service/PluginsService.php @@ -174,10 +174,11 @@ public function install($name, bool $permission = true, $connection = 'default') * @noTodo * @unitTest */ - public function update($pluginName, $connection = 'default'): ?bool + public function update(string $name, string $connection = 'default'): ?bool { $options = ['connection' => $connection]; - BcUtil::includePluginClass($pluginName); + BcUtil::clearAllCache(); + BcUtil::includePluginClass($name); if (function_exists('ini_set')) { ini_set('max_execution_time', 0); @@ -188,11 +189,11 @@ public function update($pluginName, $connection = 'default'): ?bool } $ids = []; - if ($pluginName === 'BaserCore') { - $names = array_merge(['BaserCore'], Configure::read('BcApp.corePlugins')); + if ($name === 'BaserCore') { + $pluginNames = array_merge(['BaserCore'], Configure::read('BcApp.corePlugins')); $ids = $this->detachAll(); } else { - $names = [$pluginName]; + $pluginNames = [$name]; } TableRegistry::getTableLocator()->clear(); @@ -201,14 +202,14 @@ public function update($pluginName, $connection = 'default'): ?bool $plugins = []; // マイグレーション実行 - foreach($names as $name) { - if ($name !== 'BaserCore') { - $entity = $this->Plugins->getPluginConfig($name); + foreach($pluginNames as $pluginName) { + if ($pluginName !== 'BaserCore') { + $entity = $this->Plugins->getPluginConfig($pluginName); if (!$entity->registered) continue; } - $targetVersion = BcUtil::getVersion($name); - BcUpdateLog::set(__d('baser_core', '{0} プラグイン {1} へのアップデートを開始します。', $name, $targetVersion)); - $plugin = $pluginCollection->create($name); + $targetVersion = BcUtil::getVersion($pluginName); + BcUpdateLog::set(__d('baser_core', '{0} プラグイン {1} へのアップデートを開始します。', $pluginName, $targetVersion)); + $plugin = $pluginCollection->create($pluginName); $migrate = false; if (method_exists($plugin, 'migrate')) { try { @@ -223,13 +224,19 @@ public function update($pluginName, $connection = 'default'): ?bool } $migrate = true; } - $plugins[$name] = [ + $plugins[$pluginName] = [ 'instance' => $plugin, 'migrate' => $migrate, 'version' => $targetVersion ]; } + if(!$plugins) { + BcUpdateLog::set(__d('baser_core', '登録済のプラグインが見つかりませんでした。先にインストールを実行してください。')); + BcUpdateLog::save(); + return false; + } + // アップデートスクリプト実行 try { foreach($plugins as $plugin) { @@ -254,9 +261,9 @@ public function update($pluginName, $connection = 'default'): ?bool // バージョン番号更新 try { $pluginsTable = TableRegistry::getTableLocator()->get('BaserCore.Plugins'); - foreach($plugins as $name => $plugin) { - $pluginsTable->update($name, $plugin['version']); - BcUpdateLog::set(__d('baser_core', '{0} プラグイン {1} へのアップデートが完了しました。', $name, $plugin['version'])); + foreach($plugins as $pluginName => $plugin) { + $pluginsTable->update($pluginName, $plugin['version']); + BcUpdateLog::set(__d('baser_core', '{0} プラグイン {1} へのアップデートが完了しました。', $pluginName, $plugin['version'])); } } catch (\Throwable $e) { foreach($plugins as $plugin) { @@ -282,38 +289,56 @@ public function update($pluginName, $connection = 'default'): ?bool } /** - * BaserCoreをアップデートする + * コアファイルをロールバックする * * @param string $currentVersion - * @param string $targetVersion - * @param string $connection + * @param string $php + * @return void * @checked * @noTodo + * @unitTest */ - public function updateCore(string $currentVersion, string $targetVersion, string $php, $connection = 'default') + public function rollbackCore(string $currentVersion, string $php): void { - // Composer 実行 - $command = $php . ' ' . ROOT . DS . 'bin' . DS . 'cake.php composer ' . $targetVersion . ' --php ' . $php; - exec($command, $out, $code); - if ($code !== 0) throw new BcException(__d('baser_core', 'プログラムファイルのアップデートに失敗しました。ログを確認してください。')); - - // マイグレーション、アップデートスクリプト実行、バージョン番号更新 - // マイグレーションファイルがプログラムに反映されないと実行できないため、別プロセスとして実行する - $command = $php . ' ' . ROOT . DS . 'bin' . DS . 'cake.php update --connection ' . $connection; - $out = $code = null; + // 元のバージョンに戻す + $command = $php . ' ' . ROOT . DS . 'bin' . DS . 'cake.php composer ' . $currentVersion; exec($command, $out, $code); if ($code !== 0) { - // 失敗した場合は元のバージョンに戻す - $command = $php . ' ' . ROOT . DS . 'bin' . DS . 'cake.php composer ' . $currentVersion; - exec($command, $out, $code); - if ($code !== 0) { - throw new BcException(__d('baser_core', 'アップデートスクリプトの処理が失敗したので、プログラムファイルを元に戻そうとしましたが失敗しました。。ログを確認してください。')); - } else { - throw new BcException(__d('baser_core', 'アップデートスクリプトの処理が失敗したので、プログラムファイルを元に戻しました。。ログを確認してください。')); - } + throw new BcException(__d('baser_core', 'コアファイルを元に戻そうとしましたが失敗しました。ログを確認してください。')); } } + /** + * コアファイルを更新 + * @return void + * @checked + * @noTodo + * @unitTest + */ + public function updateCoreFiles() + { + if(!is_dir(TMP . 'update' . DS . 'vendor')) { + throw new BcException(__d('baser_core', 'ダウンロードした最新版が見つかりませんでした。')); + } + + // バックアップ作成 + $zip = new BcZip(); + $zip->create(ROOT . DS . 'vendor', TMP . 'update' . DS . 'vendor.zip'); + + // コアファイルを削除 + (new Folder())->delete(ROOT . DS . 'vendor'); + + // 最新版に更新 + if(!(new Folder(TMP . 'update' . DS . 'vendor'))->copy(ROOT . DS . 'vendor')) { + $zip->extract(TMP . 'update' . DS . 'vendor.zip', ROOT . DS . 'vendor'); + throw new BcException(__d('baser_core', '最新版のファイルをコピーできませんでした。')); + } + + // composer.json, composer.lock を更新 + copy(TMP . 'update' . DS . 'composer.json', ROOT . DS . 'composer.json'); + copy(TMP . 'update' . DS . 'composer.lock', ROOT . DS . 'composer.lock'); + } + /** * プラグインを全て無効化する * @@ -751,6 +776,44 @@ public function getAvailableCoreVersionInfo() } } + /** + * コアの最新版を取得する + * tmp/update に最新版をダウンロードする + * @param string $targetVersion + * @param string $php + * @return void + * @checked + * @noTodo + * @unitTest + */ + public function getCoreUpdate(string $targetVersion, string $php) + { + if (function_exists('ini_set')) { + ini_set('max_execution_time', 0); + ini_set('memory_limit', '512M'); + } + if (file_exists(LOGS . 'update.log')) { + unlink(LOGS . 'update.log'); + } + + if(!is_dir(TMP . 'update')) { + mkdir(TMP . 'update', 0777); + } + if(!is_dir(TMP . 'update' . DS . 'vendor')) { + $folder = new Folder(ROOT . DS . 'vendor'); + $folder->copy(TMP . 'update' . DS . 'vendor'); + } + copy(ROOT . DS . 'composer.json', TMP . 'update' . DS . 'composer.json'); + copy(ROOT . DS . 'composer.lock', TMP . 'update' . DS . 'composer.lock'); + + // Composer 実行 + $command = $php . ' ' . ROOT . DS . 'bin' . DS . 'cake.php composer ' . $targetVersion . ' --php ' . $php . ' --dir ' . TMP . 'update'; + exec($command, $out, $code); + if ($code !== 0) throw new BcException(__d('baser_core', '最新版のダウンロードに失敗しました。ログを確認してください。')); + + Cache::write('coreDownloaded', true, '_bc_update_'); + } + /** * 利用可能なコアの最新のバーションを取得 * diff --git a/plugins/baser-core/tests/TestCase/Controller/Admin/PluginsControllerTest.php b/plugins/baser-core/tests/TestCase/Controller/Admin/PluginsControllerTest.php index 7849ce40fa..353d8410ae 100644 --- a/plugins/baser-core/tests/TestCase/Controller/Admin/PluginsControllerTest.php +++ b/plugins/baser-core/tests/TestCase/Controller/Admin/PluginsControllerTest.php @@ -260,7 +260,7 @@ public function testUpdateCore(): void 'targetVersion' => '5.0.1' ]); $this->assertRedirect('/baser/admin/baser-core/plugins/update'); - $this->assertFlashMessage(sprintf('全てのアップデート処理が完了しました。 %s にログを出力しています。', LOGS . 'update.log')); + $this->assertFlashMessage('アップデート処理が完了しました。画面下部のアップデートログを確認してください。'); rename(BASER . 'VERSION.bak.txt', BASER . 'VERSION.txt'); rename(ROOT . DS . 'composer.json.bak', ROOT . DS . 'composer.json'); rename(ROOT . DS . 'composer.lock.bak', ROOT . DS . 'composer.lock'); @@ -340,4 +340,29 @@ public function test_add() $folder->delete(BASER_PLUGINS . $plugin); $folder->delete($zipSrcPath); } + + /** + * test get_core_update + */ + public function test_get_core_update() + { + $this->enableSecurityToken(); + $this->enableCsrfToken(); + $this->post('/baser/admin/baser-core/plugins/get_core_update'); + $this->assertFlashMessage('最新版のダウンロードに失敗しました。ログを確認してください。'); + + $this->post('/baser/admin/baser-core/plugins/get_core_update', [ + 'targetVersion' => '5.0.15', + 'php' => 'php', + ]); + $this->assertResponseCode(302); + $this->assertFlashMessage('最新版のダウンロードが完了しました。アップデートを実行してください。'); + $this->assertRedirect([ + 'plugin' => 'BaserCore', + 'prefix' => 'Admin', + 'controller' => 'plugins', + 'action' => 'update' + ]); + } + } diff --git a/plugins/baser-core/tests/TestCase/Controller/Api/Admin/PluginsControllerTest.php b/plugins/baser-core/tests/TestCase/Controller/Api/Admin/PluginsControllerTest.php index cf378a2651..73954245fa 100644 --- a/plugins/baser-core/tests/TestCase/Controller/Api/Admin/PluginsControllerTest.php +++ b/plugins/baser-core/tests/TestCase/Controller/Api/Admin/PluginsControllerTest.php @@ -12,6 +12,8 @@ namespace BaserCore\Test\TestCase\Controller\Api\Admin; use BaserCore\TestSuite\BcTestCase; +use BaserCore\Utility\BcComposer; +use BaserCore\Utility\BcZip; use Cake\Core\App; use Cake\Core\Configure; use Cake\Core\Configure\Engine\PhpConfig; @@ -264,4 +266,38 @@ public function test_batch() $this->assertEquals('一括処理が完了しました。', $result->message); } + /** + * test update_core_files + */ + public function test_update_core_files() + { + // composer.json をバックアップ + copy(ROOT . DS . 'composer.json', ROOT . DS . 'composer.bak.json'); + copy(ROOT . DS . 'composer.lock', ROOT . DS . 'composer.bak.lock'); + + // composer.json を配布用に更新 + BcComposer::setupComposerForDistribution(ROOT . DS); + + // vendor を一時フォルダにコピー + (new Folder(ROOT . DS . 'vendor'))->copy(TMP . 'update' . DS . 'vendor'); + + // 最新版を反映 + $this->post('/baser/api/admin/baser-core/plugins/update_core_files.json?token=' . $this->accessToken); + $this->assertResponseOk(); + $result = json_decode((string)$this->_response->getBody()); + $this->assertEquals('コアファイルの最新版への更新が完了しました。', $result->message); + + // vendor を元に戻す + (new Folder())->delete(ROOT . DS . 'vendor'); + $zip = new BcZip(); + $zip->extract(TMP . 'update' . DS . 'vendor.zip', ROOT . DS . 'vendor'); + + // 一時ファイルを削除 + (new Folder())->delete(TMP . 'update'); + + // composer.json を元に戻す + rename(ROOT . DS . 'composer.bak.json', ROOT . DS . 'composer.json'); + rename(ROOT . DS . 'composer.bak.lock', ROOT . DS . 'composer.lock'); + } + } diff --git a/plugins/baser-core/tests/TestCase/Service/Admin/PluginsAdminServiceTest.php b/plugins/baser-core/tests/TestCase/Service/Admin/PluginsAdminServiceTest.php index 8704b121bd..2b1480adcb 100644 --- a/plugins/baser-core/tests/TestCase/Service/Admin/PluginsAdminServiceTest.php +++ b/plugins/baser-core/tests/TestCase/Service/Admin/PluginsAdminServiceTest.php @@ -88,6 +88,7 @@ public function test_getViewVarsForUpdate() 'availableVersion', 'log', 'requireUpdate', + 'coreDownloaded', 'php', 'isWritableVendor', 'isWritableComposerJson', diff --git a/plugins/baser-core/tests/TestCase/Service/PluginsServiceTest.php b/plugins/baser-core/tests/TestCase/Service/PluginsServiceTest.php index a5c2114ea3..1cdf154269 100644 --- a/plugins/baser-core/tests/TestCase/Service/PluginsServiceTest.php +++ b/plugins/baser-core/tests/TestCase/Service/PluginsServiceTest.php @@ -15,7 +15,9 @@ use BaserCore\Test\Factory\PluginFactory; use BaserCore\Test\Factory\SiteConfigFactory; use BaserCore\TestSuite\BcTestCase; +use BaserCore\Utility\BcComposer; use BaserCore\Utility\BcUtil; +use BaserCore\Utility\BcZip; use Cake\Cache\Cache; use Cake\Core\Configure; use Cake\Core\Plugin; @@ -112,6 +114,7 @@ public function testGetIndex($sortMode, $expectedPlugin): void $this->assertNotContains('BcTest', $pluginNames); } } + public function indexDataprovider() { return [ @@ -158,6 +161,7 @@ public function testGetByName() $this->assertEquals('BcBlog', $this->Plugins->getByName('BcBlog')->name); $this->assertNull($this->Plugins->getByName('Test')); } + /** * test resetDb * @throws \Exception @@ -312,11 +316,12 @@ public function test_detachAll() * test attachAllFromIds * @return void */ - public function test_attachAllFromIds(){ + public function test_attachAllFromIds() + { $plugins = $this->Plugins->getIndex(false); $this->assertTrue($plugins[1]->status); - $ids = [1,2]; + $ids = [1, 2]; $this->Plugins->detachAll(); @@ -332,7 +337,8 @@ public function test_attachAllFromIds(){ * test attachAllFromIds with 配列:null * @return void */ - public function test_attachAllFromIds_false(){ + public function test_attachAllFromIds_false() + { $ids = null; $rs = $this->Plugins->attachAllFromIds($ids); @@ -343,7 +349,8 @@ public function test_attachAllFromIds_false(){ * test getMarketPlugins * @return void */ - public function testGetMarketPlugins(){ + public function testGetMarketPlugins() + { $this->markTestIncomplete('TODO 直接外部ではなく Mockのテストに切り替える'); $rs = $this->Plugins->getMarketPlugins(); $this->assertNotEmpty($rs, 'baserマーケットのデータが読み込めませんでした。テストを再実行してください。'); @@ -556,4 +563,73 @@ public function createReleaseRss(array $versions) $file->close(); } + /** + * test getCoreUpdate + * @return void + */ + public function testGetCoreUpdateAndUpdateCoreFiles() + { + // composer.json をバックアップ + copy(ROOT . DS . 'composer.json', ROOT . DS . 'composer.bak.json'); + copy(ROOT . DS . 'composer.lock', ROOT . DS . 'composer.bak.lock'); + + // composer.json を配布用に更新 + BcComposer::setupComposerForDistribution(ROOT . DS); + + // getCoreUpdate 実行 + $this->Plugins->getCoreUpdate('5.0.15', 'php'); + + // バージョンを確認 + $this->assertEquals('5.0.15', BcUtil::getVersion('BaserCore', true)); + + // coreDownloaded を確認 + $this->assertTrue(Cache::read('coreDownloaded', '_bc_update_')); + + // updateCoreFiles 実行 + $this->Plugins->updateCoreFiles(); + // バージョンを確認 + $file = new File(ROOT . DS . 'vendor' . DS . 'baserproject' . DS . 'baser-core' . DS . 'VERSION.txt'); + $versionData = $file->read(); + $aryVersionData = explode("\n", $versionData); + $this->assertEquals('5.0.15', $aryVersionData[0]); + + // vendor を元に戻す + (new Folder())->delete(ROOT . DS . 'vendor'); + $zip = new BcZip(); + $zip->extract(TMP . 'update' . DS . 'vendor.zip', ROOT . DS . 'vendor'); + + // 一時ファイルを削除 + (new Folder())->delete(TMP . 'update'); + + // composer.json を元に戻す + rename(ROOT . DS . 'composer.bak.json', ROOT . DS . 'composer.json'); + rename(ROOT . DS . 'composer.bak.lock', ROOT . DS . 'composer.lock'); + } + + /** + * test rollbackCore + * @return void + */ + public function testRollbackCore() + { + // composer.json をバックアップ + copy(ROOT . DS . 'composer.json', ROOT . DS . 'composer.bak.json'); + // composer.json を配布用に更新 + BcComposer::setupComposerForDistribution(ROOT . DS); + + // ロールバック + $this->Plugins->rollbackCore('5.0.15', 'php'); + + // バージョンを確認 + $file = new File(ROOT . DS . 'vendor' . DS . 'baserproject' . DS . 'baser-core' . DS . 'VERSION.txt'); + $versionData = $file->read(); + $aryVersionData = explode("\n", $versionData); + $this->assertEquals('5.0.15', $aryVersionData[0]); + + // composer.json を元に戻す + rename(ROOT . DS . 'composer.bak.json', ROOT . DS . 'composer.json'); + // vendor 内の baserproject を削除 + (new Folder())->delete(ROOT . DS . 'vendor' . DS . 'baserproject'); + } + } diff --git a/plugins/bc-admin-third/src/js/admin/plugins/update.js b/plugins/bc-admin-third/src/js/admin/plugins/update.js index 638ab195a2..3460dfb1cc 100644 --- a/plugins/bc-admin-third/src/js/admin/plugins/update.js +++ b/plugins/bc-admin-third/src/js/admin/plugins/update.js @@ -7,6 +7,7 @@ * @since 5.0.0 * @license https://basercms.net/license/index.html MIT License */ +import axios from "axios"; const updateForm = { @@ -36,17 +37,48 @@ const updateForm = { */ registerEvents() { $("#BtnUpdate").on('click', this.update); + $("#BtnDownload").on('click', $.bcUtil.showLoader); $("#php").on('change', this.toggleUpdate); }, /** * アップデート実行 + * コアのアップデートの場合、ダウンロードした最新版のファイルを適用してからリクエストを送信する + * マイグレーションファイルがプログラムに反映されないと実行できないため、別プロセスとして実行する * @returns {boolean} */ update() { if (confirm(bcI18n.confirmMessage1)) { - $.bcUtil.showLoader(); - return true; + if(updateForm.plugin !== 'BaserCore') { + $.bcUtil.showLoader(); + return true; + } + $.bcToken.check(function() { + $.bcUtil.showLoader(); + $.bcUtil.hideMessage(); + axios.post($.bcUtil.apiAdminBaseUrl + 'baser-core/plugins/update_core_files.json', {}, { + headers: { + 'X-CSRF-Token': $.bcToken.key + } + }) + .then(response => { + let message = response.data.message + bcI18n.updateMessage1; + $.bcUtil.showNoticeMessage(message); + $(window).scrollTop(0); + $.bcUtil.showLoader(); + // フォーム送信 + $("#PluginUpdateForm").submit(); + }) + .catch(error => { + if (error.response.status === 500) { + $.bcUtil.showAlertMessage(error.response.data.message); + } else { + $.bcUtil.showAlertMessage('予期せぬエラーが発生しました。システム管理者に連絡してください。'); + } + $.bcUtil.hideLoader(); + $(window).scrollTop(0); + }); + }, {hideLoader: false}); } return false; }, @@ -56,17 +88,21 @@ const updateForm = { */ toggleUpdate() { const $btnUpdate = $("#BtnUpdate"); + const $btnDownload = $("#BtnDownload"); const $phpNotice = $(".php-notice"); if(updateForm.plugin !== 'BaserCore') return; if($("#php").val()) { - $btnUpdate.removeAttr('disabled'); + if($btnUpdate.length) $btnUpdate.removeAttr('disabled'); + if($btnDownload.length) $btnDownload.removeAttr('disabled'); $phpNotice.hide(); } else { - $btnUpdate.attr('disabled', 'disabled'); + if($btnUpdate.length) $btnUpdate.attr('disabled', 'disabled'); + if($btnDownload.length) $btnDownload.attr('disabled', 'disabled'); $phpNotice.show(); } if(!updateForm.isWritablePackage) { - $btnUpdate.attr('disabled', 'disabled'); + if($btnUpdate.length) $btnUpdate.attr('disabled', 'disabled'); + if($btnDownload.length) $btnDownload.attr('disabled', 'disabled'); } } diff --git a/plugins/bc-admin-third/templates/Admin/Plugins/update.php b/plugins/bc-admin-third/templates/Admin/Plugins/update.php index b61f6ee9eb..db0a538658 100755 --- a/plugins/bc-admin-third/templates/Admin/Plugins/update.php +++ b/plugins/bc-admin-third/templates/Admin/Plugins/update.php @@ -27,10 +27,12 @@ * @var bool $requireUpdate * @var string $php * @var bool $isWritablePackage + * @var bool $coreDownloaded */ -$this->BcAdmin->setTitle(sprintf(__d('baser_core', '%s|データベースアップデート'), ($plugin->name === 'BaserCore')? __d('baser_core', 'baserCMSコア') : $plugin->title . __d('baser_core', 'プラグイン'))); +$this->BcAdmin->setTitle(sprintf(__d('baser_core', '%s|アップデート'), ($plugin->name === 'BaserCore')? __d('baser_core', 'baserCMSコア') : $plugin->title . __d('baser_core', 'プラグイン'))); $this->BcBaser->i18nScript([ 'confirmMessage1' => __d('baser_core', 'アップデートを実行します。よろしいですか?'), + 'updateMessage1' => __d('baser_core', '続いてアップデートを実行します。しばらくお待ちください。'), ]); $this->BcBaser->js('admin/plugins/update.bundle', false, [ 'id' => 'AdminPluginsUpdateScript', @@ -38,6 +40,15 @@ 'data-plugin' => $plugin->name, 'data-isWritablePackage' => $isWritablePackage ]); +if ($plugin->name !== 'BaserCore' || $coreDownloaded) { + $formAction = 'update'; + $h2 = __d('baser_core', 'アップデート実行'); + $description = __d('baser_core', '「アップデート実行」をクリックしてプラグインのアップデートを完了させてください。'); +} else { + $formAction = 'get_core_update'; + $h2 = __d('baser_core', '最新版をダウンロード'); + $description = __d('baser_core', 'アップデートを実行する前に、最新版をダウンロードしてください。'); +} ?> @@ -49,11 +60,9 @@
@@ -61,7 +70,7 @@

-

%s つ あります。'), $scriptNum) ?>

+

@@ -80,7 +89,7 @@
- +

@@ -88,10 +97,15 @@

name === 'BaserCore'): ?> - + BcBaser->getLink(__d('baser_core', 'データベースメンテナンス'), ['controller' => 'Utilities', 'action' => 'maintenance']) + ) ?>
-
+ +

@@ -113,11 +127,22 @@

- +

-

- BcAdminForm->create($plugin) ?> +

+ name === 'BaserCore'): ?> +

+ BcBaser->getLink('baserCMSの制作・開発パートナー', 'https://basercms.net/partners/', ['target' => '_blank']) + ) ?> +

+ + BcAdminForm->create($plugin, [ + 'url' => ['action' => $formAction, $this->getRequest()->getParam('pass.0')], + 'id' => 'PluginUpdateForm' + ]) ?> BcAdminForm->control('update', ['type' => 'hidden', 'value' => true]) ?> BcAdminForm->control('currentVersion', ['type' => 'hidden', 'value' => $programVersion]) ?> BcAdminForm->control('targetVersion', ['type' => 'hidden', 'value' => $availableVersion]) ?> @@ -145,28 +170,34 @@ ]) ?>
- BcAdminForm->submit(__d('baser_core', 'アップデート実行'), [ - 'class' => 'button bca-btn bca-actions__item', - 'data-bca-btn-size' => 'lg', - 'data-bca-btn-width' => 'lg', - 'data-bca-btn-type' => 'save', - 'id' => 'BtnUpdate', - 'div' => false, - ]) ?> + name !== 'BaserCore' || $coreDownloaded): ?> + BcAdminForm->submit(__d('baser_core', 'アップデート実行'), [ + 'class' => 'bca-btn bca-actions__item', + 'data-bca-btn-size' => 'lg', + 'data-bca-btn-width' => 'lg', + 'data-bca-btn-type' => 'save', + 'id' => 'BtnUpdate', + 'div' => false, + ]) ?> + + BcAdminForm->submit(__d('baser_core', '最新版をダウンロード'), [ + 'class' => 'bca-btn bca-actions__item', + 'data-bca-btn-size' => 'lg', + 'data-bca-btn-width' => 'lg', + 'data-bca-btn-type' => 'save', + 'id' => 'BtnDownload', + 'div' => false, + ]) ?> +
BcAdminForm->end() ?>
- name === 'BaserCore'): ?> -

- BcBaser->getLink('baserCMSの制作・開発パートナー', 'https://basercms.net/partners/', ['target' => '_blank']) - ) ?> -

+ name === 'BaserCore' && $dbVersion !== $programVersion): ?> +

プログラムのバージョンに合わせて データベースの site_configs テーブルの version フィールドを更新してください。') ?>

-

+

@@ -184,18 +215,16 @@
- -
-

- -

- BcAdminForm->control('log', [ - 'type' => 'textarea', - 'value' => $log, - 'style' => 'width:99%;height:200px;font-size:12px', - 'readonly' => 'readonly' - ]); ?> -
- +
+

+ +

+ BcAdminForm->control('log', [ + 'type' => 'textarea', + 'value' => $log, + 'style' => 'width:99%;height:200px;font-size:12px', + 'readonly' => 'readonly' + ]); ?> +
diff --git a/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js b/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js index f17a5f6d93..0d04a7ac74 100644 --- a/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js +++ b/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js @@ -1,4 +1,4 @@ -(()=>{ +(()=>{"use strict";var e,t={1096:(e,t,r)=>{var i=r(8071),a={plugin:null,isWritablePackage:!1,mounted:function(){var e=$("#AdminPluginsUpdateScript");this.plugin=e.attr("data-plugin"),this.isWritablePackage=e.attr("data-isWritablePackage"),this.registerEvents(),this.toggleUpdate()},registerEvents:function(){$("#BtnUpdate").on("click",this.update),$("#BtnDownload").on("click",$.bcUtil.showLoader),$("#php").on("change",this.toggleUpdate)},update:function(){if(confirm(bcI18n.confirmMessage1)){if("BaserCore"!==a.plugin)return $.bcUtil.showLoader(),!0;$.bcToken.check((function(){$.bcUtil.showLoader(),$.bcUtil.hideMessage(),i.Z.post($.bcUtil.apiAdminBaseUrl+"baser-core/plugins/update_core_files.json",{},{headers:{"X-CSRF-Token":$.bcToken.key}}).then((function(e){var t=e.data.message+bcI18n.updateMessage1;$.bcUtil.showNoticeMessage(t),$(window).scrollTop(0),$.bcUtil.showLoader(),$("#PluginUpdateForm").submit()})).catch((function(e){500===e.response.status?$.bcUtil.showAlertMessage(e.response.data.message):$.bcUtil.showAlertMessage("予期せぬエラーが発生しました。システム管理者に連絡してください。"),$.bcUtil.hideLoader(),$(window).scrollTop(0)}))}),{hideLoader:!1})}return!1},toggleUpdate:function(){var e=$("#BtnUpdate"),t=$("#BtnDownload"),r=$(".php-notice");"BaserCore"===a.plugin&&($("#php").val()?(e.length&&e.removeAttr("disabled"),t.length&&t.removeAttr("disabled"),r.hide()):(e.length&&e.attr("disabled","disabled"),t.length&&t.attr("disabled","disabled"),r.show()),a.isWritablePackage||(e.length&&e.attr("disabled","disabled"),t.length&&t.attr("disabled","disabled")))}}; /** * baserCMS : Based Website Development Project * Copyright (c) NPO baser foundation @@ -7,6 +7,5 @@ * @link https://basercms.net baserCMS Project * @since 5.0.0 * @license https://basercms.net/license/index.html MIT License - */ -var t={plugin:null,isWritablePackage:!1,mounted:function(){var t=$("#AdminPluginsUpdateScript");this.plugin=t.attr("data-plugin"),this.isWritablePackage=t.attr("data-isWritablePackage"),this.registerEvents(),this.toggleUpdate()},registerEvents:function(){$("#BtnUpdate").on("click",this.update),$("#php").on("change",this.toggleUpdate)},update:function(){return!!confirm(bcI18n.confirmMessage1)&&($.bcUtil.showLoader(),!0)},toggleUpdate:function(){var e=$("#BtnUpdate"),a=$(".php-notice");"BaserCore"===t.plugin&&($("#php").val()?(e.removeAttr("disabled"),a.hide()):(e.attr("disabled","disabled"),a.show()),t.isWritablePackage||e.attr("disabled","disabled"))}};t.mounted()})(); + */a.mounted()}},r={};function i(e){var a=r[e];if(void 0!==a)return a.exports;var o=r[e]={exports:{}};return t[e].call(o.exports,o,o.exports,i),o.exports}i.m=t,e=[],i.O=(t,r,a,o)=>{if(!r){var n=1/0;for(c=0;c=o)&&Object.keys(i.O).every((e=>i.O[e](r[l])))?r.splice(l--,1):(s=!1,o0&&e[c-1][2]>o;c--)e[c]=e[c-1];e[c]=[r,a,o]},i.d=(e,t)=>{for(var r in t)i.o(t,r)&&!i.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.j=1106,(()=>{var e={1106:0};i.O.j=t=>0===e[t];var t=(t,r)=>{var a,o,[n,s,l]=r,d=0;if(n.some((t=>0!==e[t]))){for(a in s)i.o(s,a)&&(i.m[a]=s[a]);if(l)var c=l(i)}for(t&&t(r);di(1096)));a=i.O(a)})(); //# sourceMappingURL=update.bundle.js.map \ No newline at end of file diff --git a/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js.map b/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js.map index 7dca1f65f5..1319b137b9 100644 --- a/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js.map +++ b/plugins/bc-admin-third/webroot/js/admin/plugins/update.bundle.js.map @@ -1 +1 @@ -{"version":3,"file":"js/admin/plugins/update.bundle.js","mappings":";;;;;;;;;;AAUA,IAAMA,EAAa,CAKfC,OAAQ,KAKRC,mBAAmB,EAKnBC,QAAO,WACH,IAAMC,EAASC,EAAE,6BACjBC,KAAKL,OAASG,EAAOG,KAAK,eAC1BD,KAAKJ,kBAAoBE,EAAOG,KAAK,0BACrCD,KAAKE,iBACLF,KAAKG,cACT,EAKAD,eAAc,WACVH,EAAE,cAAcK,GAAG,QAASJ,KAAKK,QACjCN,EAAE,QAAQK,GAAG,SAAUJ,KAAKG,aAChC,EAMAE,OAAM,WACF,QAAIC,QAAQC,OAAOC,mBACfT,EAAEU,OAAOC,cACF,EAGf,EAKAP,aAAY,WACR,IAAMQ,EAAaZ,EAAE,cACfa,EAAab,EAAE,eACI,cAAtBL,EAAWC,SACXI,EAAE,QAAQc,OACTF,EAAWG,WAAW,YACtBF,EAAWG,SAEXJ,EAAWV,KAAK,WAAY,YAC5BW,EAAWI,QAEXtB,EAAWE,mBACXe,EAAWV,KAAK,WAAY,YAEpC,GAIJP,EAAWG,S","sources":["webpack://bc-admin-third/./src/js/admin/plugins/update.js"],"sourcesContent":["/**\n * baserCMS : Based Website Development Project \n * Copyright (c) NPO baser foundation \n *\n * @copyright Copyright (c) NPO baser foundation\n * @link https://basercms.net baserCMS Project\n * @since 5.0.0\n * @license https://basercms.net/license/index.html MIT License\n */\n\nconst updateForm = {\n\n /**\n * プラグイン名\n */\n plugin: null,\n\n /**\n * vendor / composer に書き込み権限があるか\n */\n isWritablePackage: false,\n\n /**\n * 起動処理\n */\n mounted() {\n const script = $(\"#AdminPluginsUpdateScript\");\n this.plugin = script.attr('data-plugin');\n this.isWritablePackage = script.attr('data-isWritablePackage');\n this.registerEvents();\n this.toggleUpdate();\n },\n\n /**\n * イベント登録\n */\n registerEvents() {\n $(\"#BtnUpdate\").on('click', this.update);\n $(\"#php\").on('change', this.toggleUpdate);\n },\n\n /**\n * アップデート実行\n * @returns {boolean}\n */\n update() {\n if (confirm(bcI18n.confirmMessage1)) {\n $.bcUtil.showLoader();\n return true;\n }\n return false;\n },\n\n /**\n * アップデートボタン切り替え\n */\n toggleUpdate() {\n const $btnUpdate = $(\"#BtnUpdate\");\n const $phpNotice = $(\".php-notice\");\n if(updateForm.plugin !== 'BaserCore') return;\n if($(\"#php\").val()) {\n $btnUpdate.removeAttr('disabled');\n $phpNotice.hide();\n } else {\n $btnUpdate.attr('disabled', 'disabled');\n $phpNotice.show();\n }\n if(!updateForm.isWritablePackage) {\n $btnUpdate.attr('disabled', 'disabled');\n }\n }\n\n};\n\nupdateForm.mounted();\n\n"],"names":["updateForm","plugin","isWritablePackage","mounted","script","$","this","attr","registerEvents","toggleUpdate","on","update","confirm","bcI18n","confirmMessage1","bcUtil","showLoader","$btnUpdate","$phpNotice","val","removeAttr","hide","show"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"js/admin/plugins/update.bundle.js","mappings":"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","sources":["webpack://bc-admin-third/webpack/runtime/chunk loaded","webpack://bc-admin-third/./src/js/admin/plugins/update.js","webpack://bc-admin-third/webpack/bootstrap","webpack://bc-admin-third/webpack/runtime/define property getters","webpack://bc-admin-third/webpack/runtime/global","webpack://bc-admin-third/webpack/runtime/hasOwnProperty shorthand","webpack://bc-admin-third/webpack/runtime/make namespace object","webpack://bc-admin-third/webpack/runtime/runtimeId","webpack://bc-admin-third/webpack/runtime/jsonp chunk loading","webpack://bc-admin-third/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","/**\n * baserCMS : Based Website Development Project \n * Copyright (c) NPO baser foundation \n *\n * @copyright Copyright (c) NPO baser foundation\n * @link https://basercms.net baserCMS Project\n * @since 5.0.0\n * @license https://basercms.net/license/index.html MIT License\n */\nimport axios from \"axios\";\n\nconst updateForm = {\n\n /**\n * プラグイン名\n */\n plugin: null,\n\n /**\n * vendor / composer に書き込み権限があるか\n */\n isWritablePackage: false,\n\n /**\n * 起動処理\n */\n mounted() {\n const script = $(\"#AdminPluginsUpdateScript\");\n this.plugin = script.attr('data-plugin');\n this.isWritablePackage = script.attr('data-isWritablePackage');\n this.registerEvents();\n this.toggleUpdate();\n },\n\n /**\n * イベント登録\n */\n registerEvents() {\n $(\"#BtnUpdate\").on('click', this.update);\n $(\"#BtnDownload\").on('click', $.bcUtil.showLoader);\n $(\"#php\").on('change', this.toggleUpdate);\n },\n\n /**\n * アップデート実行\n * コアのアップデートの場合、ダウンロードした最新版のファイルを適用してからリクエストを送信する\n * マイグレーションファイルがプログラムに反映されないと実行できないため、別プロセスとして実行する\n * @returns {boolean}\n */\n update() {\n if (confirm(bcI18n.confirmMessage1)) {\n if(updateForm.plugin !== 'BaserCore') {\n $.bcUtil.showLoader();\n return true;\n }\n $.bcToken.check(function() {\n $.bcUtil.showLoader();\n $.bcUtil.hideMessage();\n axios.post($.bcUtil.apiAdminBaseUrl + 'baser-core/plugins/update_core_files.json', {}, {\n headers: {\n 'X-CSRF-Token': $.bcToken.key\n }\n })\n .then(response => {\n let message = response.data.message + bcI18n.updateMessage1;\n $.bcUtil.showNoticeMessage(message);\n $(window).scrollTop(0);\n $.bcUtil.showLoader();\n // フォーム送信\n $(\"#PluginUpdateForm\").submit();\n })\n .catch(error => {\n if (error.response.status === 500) {\n $.bcUtil.showAlertMessage(error.response.data.message);\n } else {\n $.bcUtil.showAlertMessage('予期せぬエラーが発生しました。システム管理者に連絡してください。');\n }\n $.bcUtil.hideLoader();\n $(window).scrollTop(0);\n });\n }, {hideLoader: false});\n }\n return false;\n },\n\n /**\n * アップデートボタン切り替え\n */\n toggleUpdate() {\n const $btnUpdate = $(\"#BtnUpdate\");\n const $btnDownload = $(\"#BtnDownload\");\n const $phpNotice = $(\".php-notice\");\n if(updateForm.plugin !== 'BaserCore') return;\n if($(\"#php\").val()) {\n if($btnUpdate.length) $btnUpdate.removeAttr('disabled');\n if($btnDownload.length) $btnDownload.removeAttr('disabled');\n $phpNotice.hide();\n } else {\n if($btnUpdate.length) $btnUpdate.attr('disabled', 'disabled');\n if($btnDownload.length) $btnDownload.attr('disabled', 'disabled');\n $phpNotice.show();\n }\n if(!updateForm.isWritablePackage) {\n if($btnUpdate.length) $btnUpdate.attr('disabled', 'disabled');\n if($btnDownload.length) $btnDownload.attr('disabled', 'disabled');\n }\n }\n\n};\n\nupdateForm.mounted();\n\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.j = 1106;","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t1106: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkbc_admin_third\"] = self[\"webpackChunkbc_admin_third\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [5000], () => (__webpack_require__(1096)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","updateForm","plugin","isWritablePackage","mounted","script","$","this","attr","registerEvents","toggleUpdate","on","update","bcUtil","showLoader","confirm","bcI18n","confirmMessage1","bcToken","check","hideMessage","axios","post","apiAdminBaseUrl","headers","key","then","response","message","data","updateMessage1","showNoticeMessage","window","scrollTop","submit","error","status","showAlertMessage","hideLoader","$btnUpdate","$btnDownload","$phpNotice","val","length","removeAttr","hide","show","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","call","m","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","fulfilled","j","Object","keys","every","splice","r","d","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","obj","prop","prototype","hasOwnProperty","Symbol","toStringTag","value","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","id","chunkLoadingGlobal","self","forEach","bind","push","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/vendor/.gitkeep b/vendor/.gitkeep old mode 100644 new mode 100755